How can I merge all the videos in a folder to make a single video file using FFMPEG
Solution 1
This is what I've ended up using...
find *.mp4 | sed 's:\ :\\\ :g'| sed 's/^/file /' > fl.txt; ffmpeg -f concat -i fl.txt -c copy output.mp4; rm fl.txt
It's ugliness pains me but it seems to work ok and it handles spaces in the file names. Also, not sure why OP was asking about python - no need to use something lovely like python when some dirty old bash/sed will do the trick! ;)
ps: I know this is an old post but if googling "ffmpeg concat" brought me here it will probably bring other poor souls here too. Note the above will probably only work if all your files have the same settings/codecs.
pps: @Stackdave says he managed to delete his video folder with this back in the day! I've really no idea how that could have happened and I've had no complaints since but as always when copying and pasting randomish snippets of bash you found on the internet Caveat Emptor!
Solution 2
can be a single line bash command:
for f in *.mp4 ; do echo file \'$f\' >> list.txt; done && ffmpeg -f concat -safe 0 -i list.txt -c copy stitched-video.mp4 && rm list.txt
make sure all video files are exactly the same frame size and audio-video codecs.
Else you may convert them while concatenating:
for f in *.mp4 ; do echo file \'$f\' >> list.txt; done && ffmpeg -f concat -safe 0 -i list.txt -s 1280x720 -crf 24 stitched-video.mp4 && rm list.txt
Solution 3
Use this:
cat *.mp4 | ffmpeg -i pipe: -c:a copy -c:v copy all.mp4
Another solution:
create a text file like this:
mylist.txt
file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'
and use ffmpeg concat:
ffmpeg -f concat -i mylist.txt -c copy all.mp4
Solution 4
Here's a Windows batch file to concatenate all .avi
files in a directory:
for %%f in (*.avi) do (
echo file %%f >> list.txt
)
ffmpeg -f concat -safe 0 -i list.txt -c copy output.avi
del list.txt
See Concatenate in ffmpeg docs.
Solution 5
If ffmpeg won't like the *.mp4 you can just do this in place of the file list;
ls -1 *.mp4 | perl -0pe 's/\n/|/g;s/\|$//g'
but I think your example is not following specification, so you may want this:
for F in *.mp4 ; do
ffmpeg -i $F -c copy -bsf:v h264_mp4toannexb -f mpegts $(echo $F | perl -pe 's/mp4$/ts/g');
done
ffmpeg -i "concat:$(ls -1 *.ts | perl -0pe 's/\n/|/g;s/\|$//g')" -c copy -bsf:a aac_adtstoasc outputfile.mp4
also see this similar question
X_1
Updated on April 22, 2021Comments
-
X_1 about 3 years
I have a folder with 20+ video files and I need to merge them to make one long video file. How can I achieve this using FFMPEG in Python?
I know the following command
ffmpeg -vcodec copy -isync -i \ "concat:file1.mp4|file2.mp4|...|fileN.mp4" \
outputfile.mp4
But I'd rather not type all the names of the 20+ files.
-
Dietrich Epp over 9 yearsOr just
echo *.mp4 | tr ' ' '|'
, if your files have no spaces in their names. -
stackdave over 6 yearsi've deleted all my files on the folder video with your script ! warning
-
Roger Heathcote over 6 yearsSorry to hear that Dave! reddit.com/r/ProgrammerHumor/comments/7u92m8/…
-
Gaurang Arora almost 5 yearsThanks llogan. Fixed.
-
Dami about 4 yearsThis works for me. Always safe to convert and concat with second command. Thank You.
-
soywiz over 3 yearsThanks! I had a list of videos like
video-1.mp4
,video-2.mp4
,video-10.mp4
..., and the files needed to be sorted. Here a version sorting the files with mixed strings a numbers:rm list.txt; for f in *.mp4 ; do echo file \'$f\' >> list.txt; done && sort -V list.txt > list-sort.txt && ffmpeg -f concat -safe 0 -i list-sort.txt -c copy stitched-video.mp4 ; rm list.txt list-sort.txt
-
Billy over 3 yearswindows not woking
-
gimmegimme about 3 yearsThank unfortunately, the file i'm dealing with has spaces in it's file name. echo file "%%f" >> list.txt was not enough. cmd stops once it encounters the first space character.
-
gimmegimme about 3 yearsNVM, the following helped, superuser.com/questions/1574718/… . Instead of double quotes, use single quote, echo file '%%f' >> list.txt, then after the for function block AND before the statement "ffmpeg -f concat -safe...", place the following statement on its own line, sed -i "s/\"/'/g" list.txt