FFmpeg recipe

FFmpeg: Merge / Concatenate Two MP4 Videos

For videos with identical codec / resolution / fps, concat demuxer is lossless and instant. Otherwise use the concat filter to re-encode.

Command

# Step 1: build a list file
echo "file 'clip1.mp4'
file 'clip2.mp4'" > list.txt

# Step 2: concat (lossless)
ffmpeg -f concat -safe 0 -i list.txt -c copy -y output.mp4
Prefer no terminal?
Use the Video Merger in your browser
Open Video Merger →

What each flag does

-iInput file. Can be a video, audio, or image. Repeat for multiple inputs.
-c copyStream-copy: no re-encoding. Output is bit-identical between cut points. Fastest possible.
-yOverwrite output file without confirmation.
-f concatUse the concat demuxer (file-list-driven concatenation).
-safe 0Allow absolute paths in the list file.

Notes & gotchas

  • All inputs must share codec, resolution, frame rate, and audio settings for -c copy. Mismatch → garbled output.
  • For mismatched inputs, use the concat filter: -filter_complex "[0:v][0:a][1:v][1:a]concat=n=2:v=1:a=1[v][a]" with re-encoding.

Check it worked

ffprobe -v error -show_entries format=duration -of csv=p=0 output.mp4

The sum of the input durations, give or take a frame.

What to change

concat demuxer needs matching streamsSame codec, resolution, frame rate and audio layout. Mismatch is why the second clip turns to garbage rather than erroring.
Use the concat filter for mismatched filesIt re-encodes and accepts anything, at the cost of time and one generation of quality.
-safe 0 for absolute pathsWithout it the demuxer refuses paths outside the working directory, with an error that does not say so.

If it fails

Unsafe file name, or the concat demuxer refuses to start.

Why: The list file contains absolute paths, which the demuxer rejects by default.

Fix: Add -safe 0, or use paths relative to the list file.

The second clip is garbled, or audio drops after the join.

Why: Concat with stream copy requires identical codecs, resolution, frame rate and audio parameters in every input.

Fix: Normalise the inputs first by re-encoding them to matching settings, or use the concat filter, which re-encodes and tolerates differences.

Related recipes