FFmpeg is a free and open-source video editing tool capable of trimming, cropping, concatenating, muxing, and transcoding almost any type of media file you throw at it.
It's also a very robust solution for implementing video automation, as we use it extensively in our own video editing API. For this tutorial we'll use FFmpeg 5.1.2, but any recent version will do.
The following command can be used to merge two videos into one:
$ ffmpeg -i video1.mp4 -i video2.mp4 -filter_complex "[0:v][0:a][1:v][1:a]concat=n=2:v=1:a=1" -vsync vfr output.mp4
In the same way as the example above, you can concatenate more than two video files simply by adding more inputs to the concat filter. Using an additional input stream, the following example highlights the difference between the previous example:
$ ffmpeg -i video1.mp4 -i video2.mp4 -i video3.mp4 -filter_complex "[0:v][0:a][1:v][1:a][2:v][2:a]concat=n=3:v=1:a=1" -vsync vfr output.mp4
Here are a few issues you may encounter while using FFmpeg's concat filter.
This error message shows up when there's no audio stream in one of the input videos. If neither of your input videos has an audio stream, make FFmpeg only concatenate the video streams:
$ ffmpeg -i video1.mp4 -i video2.mp4 -filter_complex "[0:v][1:v]concat=n=2:v=1:a=0" -vsync vfr output.mp4
Alternatively, you can make both videos have an audio track by adding a silent track to the video that doesn't have one:
$ ffmpeg -i input.mp4 -f lavfi -i anullsrc -map 0:v -map 1:a -c:v copy -shortest output.mp4
This message appears when you concatenate two videos with different frame rates. Additionally, it will provide a message stating "Please consider specifying a lower framerate, a different muxer or setting vsync/fps_mode to vfr". This can be fixed by adding the -vsync vfr argument. More info can be found in the FFmpeg documentation under -vsync. Here's an example:
$ ffmpeg -i video1.mp4 -i video2.mp4 -filter_complex "[0:v][0:a][1:v][1:a]concat=n=2:v=1:a=1" -vsync vfr output.mp4