Is it possible to provide input files list to FFmpeg in a text file instead of on command line?

Viewed 4131

I need to provide many small file inputs to ffmpeg executable on command line and I am way beyond the maximum command length for the command line. I need to provide the input list as a file. Is it possible?

3 Answers

Yes, just pass input files to -i option:

ffmpeg -f concat -i concat.txt -c:v hevc_nvenc 1.mp4

concat.txt:

file '001.mp4'
file '003.mp4'

Short answer: It's possible, but you'll probably run into other limitations doing it.

Concatenating large numbers of images can be done using FFmpeg's pattern_type "sequence" and "glob" features. Concatenating other media can be done using concat files.

However, these features clump all files into a single concatenated stream. If you want to treat them as separate inputs in -filter_complex, then a different strategy is needed. That said, it's highly unlikely that anyone would use a complex filter with so many inputs for anything other than concatenating files (like what kind of overlay or interleaving or mixing could possibly involve that many files?).

For simplicity, let's use a drawtext filter customized for individual image files (just draw the file number on each image):

ffmpeg -i 0.png -i 1.png -filter_complex "[0]drawtext=text=0[i0];[1]drawtext=text=1[i1];[i0][i1]concat=2" output.mp4

With this format, command-line length gets to >46k at just over 1000 inputs before seeing this error message from FFmpeg:

1020.png: Too many open files

So for me, command-line length isn't the bottleneck (note that I'm on Linux). However, if I wanted to shorten the command-line, then one easy step is to move the complex filter into a file:

ffmpeg -i 0.png -i 1.png -filter_complex_script script_file.txt output.mp4

And this reduces the same command to 11k + a script file. If this is not enough, then the next step is to replace the input files with the movie filter (amovie for audio) as exampled in the concat documentation. In this case, script_file.txt looks like:

movie=0.png,drawtext=text=0[i0];
movie=1.png,drawtext=text=1[i1];
[i0][i1]concat=2

And the command is just:

ffmpeg -filter_complex_script script_file.txt output.mp4

The movie/amovie filters are not perfect replacements for inputs (I ran into this very minor bug), but are close enough for most use-cases.

In any case, this does not get around the limitation of open files, so if you exceed that limit, then you will probably have to generate video segments containing the maximum number of files, and concatenate those segments into a complete video afterwards.

ffmpeg $(ls *.mp4 |sort|xargs -i echo -i {})

Related