1

I have an input file that I am encoding with multiple output resolutions. I want to use the exact same audio encoding parameters for each output video file (-c:a aac -b:a 64k -ac 1). For a performance boost, is there a way to not have to encode the same audio three different times?

I know I could encode audio separately and mux it later, but could the audio only be encoded once and applied to all the output files all in a single command?

I've done plenty of searching around, but can't find an answer.

Here's my encode string:

ffmpeg -i in.flv -r 30 -filter_complex "[0:v]hqdn3d=0:0:6:6,setpts=PTS-STARTPTS[dn]; [dn]split=3[dn1][dn2][dn3]; 
[dn1]copy[v1out]; [dn2]scale=w=854:h=480[v2out]; [dn3]scale=w=640:h=360[v3out]" 
-map [v1out] -c:v:0 libx264 -x264-params "keyint=150:min-keyint=150" -preset slow -crf 26 -map 0:a:0 -c:a:0 aac -b:a:0 64k -ac 1 -f mp4 out.720.mp4 
-map [v2out] -c:v:1 libx264 -x264-params "keyint=150:min-keyint=150" -preset slow -crf 26 -map 0:a:0 -c:a:1 aac -b:a:1 64k -ac 1 -f mp4 out.480.mp4 
-map [v3out] -c:v:2 libx264 -x264-params "keyint=150:min-keyint=150" -preset slow -crf 26 -map 0:a:0 -c:a:2 aac -b:a:2 64k -ac 1 -f mp4 out.360.mp4

1 Answer 1

2

We may use Tee pseudo-muxer as described here:

ffmpeg -y -i in.flv -filter_complex "[0:v]fps=30,hqdn3d=0:0:6:6,setpts=PTS-STARTPTS[dn];[dn]split=3[dn1][dn2][dn3];[dn1]copy[v1out];[dn2]scale=w=854:h=480[v2out]; [dn3]scale=w=640:h=360[v3out]" -map [v1out] -map [v2out] -map [v3out] -map 0:a:0 -c:v:0 libx264 -x264-params "keyint=150:min-keyint=150" -preset:v:0 slow -crf:0 26 -c:v:1 libx264 -x264-params "keyint=150:min-keyint=150" -preset:v:1 slow -crf:1 26 -c:v:2 libx264 -x264-params "keyint=150:min-keyint=150" -preset:v:2 slow -crf:2 26 -c:a aac -ac 1 -b:a 64k -f tee "[select=\'v:0,a\']out.720.mp4|[select=\'v:1,a\']out.480.mp4|[select=\'v:2,a\']out.360.mp4"

-f tee "[select=\'v:0,a\']out.720.mp4|[select=\'v:1,a\']out.480.mp4|[select=\'v:2,a\']out.360.mp4"

Mux the same encoded audio stream, with the three different video streams.


Testing:

Build 1280x720 synthetic video pattern (used as input for testing):

ffmpeg -y -f lavfi -i testsrc=size=1280x720:rate=1 -f lavfi -i sine=frequency=400 -c:v libx264 -acodec aac -ar 24000 -pix_fmt yuv420p -t 10 in.flv

Execute the original command with some modifications.
Note:

  • FFmpeg complained about the ordering and stream selection of your original command.

Updated command:

ffmpeg -y -i in.flv -filter_complex "[0:v]fps=30,hqdn3d=0:0:6:6,setpts=PTS-STARTPTS[dn];[dn]split=3[dn1][dn2][dn3];[dn1]copy[v1out];[dn2]scale=w=854:h=480[v2out]; [dn3]scale=w=640:h=360[v3out]" -b:a:0 64k -b:a:1 64k -b:a:2 64k -preset:v:0 slow -preset:v:1 slow -preset:v:2 slow -crf:0 26 -crf:1 26 -crf:2 26 -map [v1out] -c:v:0 libx264 -x264-params "keyint=150:min-keyint=150" -map 0:a:0 -c:a:0 aac -ac:0 1 -f mp4 out.720.mp4 -map [v2out] -c:v:1 libx264 -x264-params "keyint=150:min-keyint=150" -map 0:a:0 -c:a:1 aac -ac:1 1 -f mp4 out.480.mp4 -map [v3out] -c:v:2 libx264 -x264-params "keyint=150:min-keyint=150" -map 0:a:0 -c:a:2 aac -ac:2 1 -f mp4 out.360.mp4

Execute the command with the tee muxer, and compare the results.


Something with the video streams is a little different between the outputs of the two commands.
I can't figure out the problem - I wonder if it could be something to do with internal parallelization?

1
  • Thank you @Rotem! The tee pseudo-muxer was exactly what I was looking for. Thank you for your comprehensive answer. Much appreciated!
    – pkSML
    Commented Jan 24 at 15:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .