2

I never worked with ffmpeg before and I'm wondering which optimization I can take for my situation.

In a loop I have multiple input.mp4 files which I first convert one by one to have a common scale and audio rate with this command:

ffmpeg -i input_01.mp4 -vf 'scale=1280:720,setdar=16/9' -ar 44100 -ac 1 input_01_tmp.mp4

Later I add images to each input.mp4 files again one by one:

ffmpeg -i input_01_tmp.mp4 -i input_01_logo.png -filter_complex "[0:v][1:v]overlay=10:10:enable='between(t,2,11)',fade=t=in:start_time=1.5:d=0.5:alpha=1,fade=t=out:start_time=10.5:d=0.5:alpha=1[fg];[0][fg]overlay=format=auto,format=yuv420p" -c:a copy input_01_unified.mp4

Finally after the loop I combine them with mkvmerge:

mkvmerge -o output.mkv \+ input_01_unified.mp4 +\ input_02_unified.mp4 ...

I'm sure this is not the optimal solution and wondering how I should change it.

Is it possible to do all of this in one command? Either for each file or for the whole process.

2
  • Can be done in one command. Share entire command for 1st and 2nd step
    – Gyan
    Oct 5, 2018 at 17:12
  • @Gyan thanks! added the missing parts to the commands in the question
    – cquests
    Oct 5, 2018 at 17:29

1 Answer 1

3

The single command will be long, but here's an example for 3 inputs.

ffmpeg -i input_01.mp4 -loop 1 -t 11 -i input_01_logo.png
       -i input_02.mp4 -loop 1 -t 11 -i input_02_logo.png
       -i input_03.mp4 -loop 1 -t 11 -i input_03_logo.png
       -filter_complex
        "[0]scale=1280:720,setsar=1[0v];
         [1]fade=t=in:st=1.5:d=0.5:alpha=1,fade=t=out:st=10.5:d=0.5:alpha=1[0l];
         [2]scale=1280:720,setsar=1[1v];
         [3]fade=t=in:st=1.5:d=0.5:alpha=1,fade=t=out:st=10.5:d=0.5:alpha=1[1l];
         [4]scale=1280:720,setsar=1[2v];
         [5]fade=t=in:st=1.5:d=0.5:alpha=1,fade=t=out:st=10.5:d=0.5:alpha=1[2l];
         [0v][0l]overlay=10:10:format=auto:enable='between(t,2,11)'[0vl];
         [1v][1l]overlay=10:10:format=auto:enable='between(t,2,11)'[1vl];
         [2v][2l]overlay=10:10:format=auto:enable='between(t,2,11)'[2vl];
         [0]pan=1c,aresample=r=44100[0a];
         [2]pan=1c,aresample=r=44100[1a];
         [4]pan=1c,aresample=r=44100[2a];
         [0vl][0a][1vl][1a][2vl][2a]concat=n=2:v=1:a=1[v][a]"
        -map "[v]" -map "[a]" -pix_fmt yuv420p output.mkv

You may need single quotes in the map depending on your shell.

Use a recent version of ffmpeg, at least 4.0

5
  • Thank you! I'll try this out today and accept the answer. Besides time saving, has this any effects on better quality in comparison to what I did?
    – cquests
    Oct 6, 2018 at 11:34
  • Thanks @Gyan I didn't forget and accept the answer. Much appreciate your help <3
    – cquests
    Oct 12, 2018 at 19:52
  • For clarification, is it beneficial to combine filters like this? Does it ensure that everything will be done in one encode, or will it still encode multiple times just like running each operation separately? Mar 2, 2021 at 23:53
  • 1
    Yes, this is the standard method and only carries out single encoding operation after all filtering.
    – Gyan
    Mar 3, 2021 at 11:12
  • 1
    What if we have some hundreds of input files and overcome the command line characters limits (for example, in Windows it is 8192 chars). The "filter_complex" could be written into a file and use "-filter_complex_script" instead. But what about the "-loop" commands? Is there a way to "shrink" the loops in some way? Or another way to have the same result with a shorter command line? I ask because I have this specific problem right now... Sep 14, 2021 at 15:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.