FFmpeg
Video Editing
MP4 Files
File Concatenation
Multimedia Processing

How to concatenate two MP4 files using FFmpeg?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

With FFmpeg, concatenating MP4 files can be either fast and lossless or slower and more flexible. The right method depends on whether the input files are actually compatible. If the codec, resolution, frame rate, or audio layout differ, the simple copy-based method is likely to fail or produce broken playback.

Method 1: Concat Demuxer With No Re-encoding

Use the concat demuxer when the files already match.

Create a list file:

text
file 'part1.mp4'
file 'part2.mp4'

Then run:

bash
ffmpeg -f concat -safe 0 -i files.txt -c copy output.mp4

This is the preferred method when it works because:

  • it is fast
  • it avoids quality loss
  • it keeps CPU use low

The catch is that the streams must be compatible.

Check Compatibility First

Before assuming -c copy will work, inspect the inputs.

bash
ffprobe -v error -show_streams -select_streams v:0 part1.mp4
ffprobe -v error -show_streams -select_streams v:0 part2.mp4

Compare at least:

  • video codec
  • resolution
  • frame rate
  • pixel format
  • audio codec
  • audio sample rate

If those differ, copy-based concatenation is the wrong tool.

Method 2: Concat Filter With Re-encoding

When the files differ, use the concat filter and encode a new output.

bash
1ffmpeg -i part1.mp4 -i part2.mp4 \
2-filter_complex "[0:v:0][0:a:0][1:v:0][1:a:0]concat=n=2:v=1:a=1[v][a]" \
3-map "[v]" -map "[a]" \
4-c:v libx264 -crf 18 -preset medium \
5-c:a aac -b:a 192k \
6output.mp4

This is slower, but it handles mismatched inputs more safely because you are explicitly generating a new unified output stream.

Normalize Inputs When Needed

If one file has a different size or frame rate, normalize both first.

bash
ffmpeg -i part1.mp4 -vf "scale=1280:720,fps=30" -c:v libx264 -c:a aac part1_norm.mp4
ffmpeg -i part2.mp4 -vf "scale=1280:720,fps=30" -c:v libx264 -c:a aac part2_norm.mp4

Then concatenate the normalized outputs.

This sounds like extra work, but it is often the cleanest way to avoid sync problems.

Watch Out for Missing Audio

If one clip has no audio track and the other does, concat commands that expect both audio streams can fail. In that case, either:

  • add silent audio to the clip that lacks it
  • or build a filter graph that matches the actual stream layout

Ignoring the mismatch is a common reason the command fails even when the video portion looks compatible.

Validate the Output

Do not assume success just because FFmpeg produced a file. Check duration and playback around the join.

bash
ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1 output.mp4

Then test the boundary between clips in a media player. Seek there and verify:

  • audio stays continuous
  • there are no timestamp jumps
  • the player does not freeze at the join

If the output is meant for web playback, you may also want a final remux step with -movflags +faststart so MP4 metadata is placed earlier in the file for progressive loading.

Common Pitfalls

  • Using -c copy on incompatible files and expecting FFmpeg to fix them automatically.
  • Forgetting to create the concat list file with the correct file 'name' syntax.
  • Ignoring audio stream mismatches.
  • Re-encoding with default settings and accidentally lowering output quality.

Summary

  • Use the concat demuxer plus -c copy when the MP4 files are genuinely compatible.
  • Use the concat filter and re-encode when the inputs differ.
  • Check stream properties with ffprobe before choosing the method.
  • Normalize inputs when needed instead of fighting mismatched streams.
  • Always validate playback at the join point after concatenation.

Course illustration
Course illustration

All Rights Reserved.