ffmpeg concatenate a large number of videos with different codecs and resolutions
Asked Answered
S

1

7

The videos I am trying to concatenate can have different technical metadata, like codec, resolution, etc. So I wrote a filtergraph that works for my purposes. My complete command can look like this:

ffmpeg -i "vid1.mp4" -i "vid2.mp4" -i "vid3.mp4" -filter_complex_script "filtergraph.txt" -map "[outv]" -map "[outa]" -c:v libx264 -r 60 -preset medium -crf 24 -c:a aac -b:a 160k "output.mp4"

And "filtergraph.txt" looks like this (autogenerated by my own script before). I have the filters to change all input resolutions to Full HD. (Newlines in the following snippet are just introduced for readability, they are not contained in my filtergraph.txt)

[0:v]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,setsar=1[v0];
[1:v]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,setsar=1[v1];
[2:v]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,setsar=1[v2];
[v0][0:a][v1][1:a][v2][2:a]concat=n=3:v=1:a=1[outv][outa]

Now in this case, it works, I have the three source videos, they can have different resolutions, codecs or even different framerates - they are all combinded into one Full HD 60 FPS output video.

The problem is, that I want to concatenate a large number of video files and get the error, that the command contains too many characters for cmd. That's why I already put the filtergraph to a seperate file and read it using -filter_complex_script which works.

But it can still get too long if I have a few hundred source files that I want to concat.

As far as I tested it, I can't use -f concat -i listOfFiles.txt because every source file would have to be in the same codec, resolution etc then, and I could not use the filtergraph for scaling due to the fact that ffmpeg would try to concat before demuxed output goes into filter.

So, how could I concat hundreds of videos while resizing them all to Full HD and applying the other filters, but keep the cmd line short?

Is there something similar to -filter_complex_script but for input files? Or will I have to encode each source video to my desired target format first and then concat them with stream copy?

Sillsby answered 8/1, 2020 at 23:32 Comment(0)
I
1

Regarding length of the command: cmd command limit could be around 8000 characters, while for powershell it's around 32000 characters. Thus, test your many-character command in powershell or maybe even in bash for Windows. If still not working or experiencing freezes I suggest two following solutions.

HOWEVER, to my experience, with many input files, ffmpeg concat-procedure makes PC to freeze for SOME time - loading to memory? so I'd avoid test this with hundreds of files - I've just tested Option 1 for 100 source 3gp-files.

  1. Loop over the files and encode them 1 by 1 with same resolution, sar, dar, fps (in this example putting all in the same folder)

  2. In the above mentioned folder make list of new files filelist.txt with the following content:

    file 'source_001.mp4'

    file 'source_002.mp4'

    ...

  3. Go to the above mentioned folder and run ffmpeg -f concat -safe 0 -i filelist.txt -c copy output.mp4

Another approach is Option 2 with powershell or bash - because I don't know how to loop in cmd :

Preparation:

  1. set resolution etc ffmpeg parameters for the encoding
  2. encode source_1 into output.mp4
  3. optional - delete source_1

Loop (starts with i=2 in this example):

  1. copy output.mp4 to temporary.mp4 (keep both files and AVOID encoding file into itself). Possible to copy with fdmpeg and adtionally you can add metadata to comment how many files have been merged for any force major.
  2. encode source_i into i.mp4
  3. optional - deletesource_i
  4. concat temporary.mp4 with i.mp4 into output.mp4, by forcing ffmpeg -y to overwrite output.mp4 and use -c copy.
  5. delete i.mp4

After loop

  1. delete temporary.mp4. optionally manually, because it's it's a reserve copy, really good if it contains metadata comment about number of the processed files.

P.S. Different codecs, fps, etc of the source files don't matter for concat - simply rescale all videos to one resolution, SAR and DAR

ffmpeg -i h263.3gp -i Win_Media_Video.wmv -filter_complex "[0:v]scale=640x480,setsar=1/1,setdar=4/3,setpts=PTS-STARTPTS[v0];[0:a]asetpts=PTS-STARTPTS[a0];[1:v]scale=640x480,setsar=1/1,setdar=4/3,setpts=PTS-STARTPTS[v1];[1:a]asetpts=PTS-STARTPTS[a1];[v0][a0][v1][a1]concat=n=2:v=1:a=1[outv][outa]" -map [outv] -map [outa] -map_chapters -1 -map_metadata -1 -c:v libx265 -c:a libmp3lame -q:a 8 -ar 44100 -r 24 11.mp4

Setting setsar... setdar... is important, without it I was getting error

Inelegant answered 21/4 at 7:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.