-1

I wish to optimize the process of video transcoding. Exactly I need to get two different video resolutions with the same audio stream options, but now I transcode audio stream twice (as I think ffmpeg works).

Source video has such audio stream:

ffprobe /v
 /v: Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, 5.1, fltp, 437 kb/s (default)

Now I use these options for transcode one video into two qualities:

ffmpeg -to 00:00:10 -i /v \
  -c:a mp3 -ab 42k -vcodec libx264 -s 1920x1080 -b:v 4000k -preset fast -vprofile main -g 50 -f flv 1.mp4 \
  -c:a mp3 -ab 42k -vcodec libx264 -s 1280x720 -b:v 2000k -preset fast -vprofile main -g 50 -f flv 2.mp4

As you can see, I define audio stream settings twice for each output, and I think ffmpeg transcodes audio stream twice (does he?). I get audio stream parameters as expected:

ffprobe 1.mp4
ffprobe 2.mp4
    1.mp4: Stream #0:1: Audio: mp3, 48000 Hz, stereo, fltp, 42 kb/s
    2.mp4: Stream #0:1: Audio: mp3, 48000 Hz, stereo, fltp, 42 kb/s

I wish to transcode audio stream once and use its output for two output files. How to do that? I tried this, but got different audio stream parameters:

ffmpeg -to 00:00:10 -i /v \
  -c:a mp3 -ab 42k \
  -vcodec libx264 -s 1920x1080 -b:v 4000k -preset fast -vprofile main -g 50 -f flv 1.mp4 \
  -vcodec libx264 -s 1280x720 -b:v 2000k -preset fast -vprofile main -g 50 -f flv 2.mp4
ffprobe 1.mp4
ffprobe 2.mp4
    1.mp4: Stream #0:1: Audio: mp3, 48000 Hz, stereo, fltp, 42 kb/s
    2.mp4: Stream #0:1: Audio: mp3, 48000 Hz, stereo, fltp, 128 kb/s

As you can see, 2.mp4 has audio bitratte 128 Kb/s instead of 42 Kb/s. I tried to read about -map and -filter_complex, but hope on your help.

youni
  • 7
  • 2

1 Answers1

0

AFAIK, there is no way to copy an output stream from one output file to another. If OK to encode for each file, you can run

ffmpeg -to 00:00:10 -i /v \
  -c:a mp3 -ab 42k \
  -vcodec libx264 -s 1920x1080 -b:v 4000k -preset fast -vprofile main -g 50 -f flv 1.mp4 \
  -c:a mp3 -ab 42k \
  -vcodec libx264 -s 1280x720 -b:v 2000k -preset fast -vprofile main -g 50 -f flv 2.mp4

All the codec options must be specified for each output file.

If the audio encoding does take substantial amount of time (typically it is insignificant compared to video encoding), you can try to chain 2 ffmpeg calls, piping one output to another. Something like:

First command:

ffmpeg -to 00:00:10 -i /v \
  -f mp3 -ab 42k -

Second command:

ffmpeg -to 00:00:10 -i /v -f mp3 - \
  -map 0:v -map 1:a -vcodec libx264 -s 1920x1080 -b:v 4000k -preset fast -vprofile main -g 50 -f flv 1.mp4 \
  -map 0:v -map 1:a -vcodec libx264 -s 1280x720 -b:v 2000k -preset fast -vprofile main -g 50 -f flv 2.mp4

The caveat of this approach is audio/video synchronization. They may be out-of-sync due to how they were cut. So, YMMV.

[update] As par Gyan's comment, re: -f tee, you can combine the two using something like:

ffmpeg -to 00:00:10 -i /v \
  -c:a mp3 -ab 42k \
  -vcodec libx264 -preset fast -vprofile main -g 50 \
  -f tee "[f=flv:s=1920x1080:b:v=4000k]1.mp4|[f=flv:s=1280x720:b:v=2000k]2.mp4"

Note: I'm not 100% on the escaping (especially b:v of which colon may need to be escaped.

kesh
  • 4,515
  • 2
  • 12
  • 20
  • The tee muxer is meant for this: http://www.ffmpeg.org/ffmpeg-formats.html#tee-1 – Gyan Jul 20 '22 at 03:52
  • yes, you are right. using pipe I can convert audio and copy video stream as is. And in the second call of ffmpeg convert video. – youni Jul 20 '22 at 07:21
  • ffmpeg -to 00:00:10 -i /v -c:a mp3 -ab 42k -c:v copy -f flv - | ffmpeg -i - -c:a copy -vcodec libx264 -s 1920x1080 -b:v 4000k -preset fast -vprofile main -g 50 -f flv 1.mp4 -c:a copy -vcodec libx264 -s 1280x720 -b:v 2000k -preset fast -vprofile main -g 50 -f flv 2.mp4 – youni Jul 20 '22 at 07:22
  • @Gyan - pretty cool. Thanks for the tip. I've added the `-f tee` alternative to the post. – kesh Jul 20 '22 at 15:26