MpegFlowBlogBack to home
← Recipes·Concatenate videos·video operations

Concatenate video files with FFmpeg: concat demuxer, concat filter, and the right choice

Join multiple video files into one. The concat demuxer for matched files (no re-encoding), the concat filter for mismatched ones, and the file-list discipline that prevents the most common bug.

ByMpegFlow Engineering Team·FFmpeg recipe
·3 variants·May 9, 2026

When to use this

You concatenate videos when joining episodic content, stitching ad-inserted segments into a single asset, recombining multi-take recordings, or assembling a master from production deliverables. The right method depends on whether the input files match in codec, container, resolution, and framerate — matched files concat in seconds via stream-copy; mismatched files require re-encoding. Always inspect before deciding.

Command variants

Concat demuxer (matched files, no re-encoding — preferred)
# Create a file list:
cat > files.txt << EOF
file 'part1.mp4'
file 'part2.mp4'
file 'part3.mp4'
EOF

# Concat:
ffmpeg -f concat -safe 0 -i files.txt -c copy output.mp4

Near-instant when files match. The default for most concat use cases.

Concat filter (mismatched files, re-encodes)
ffmpeg -i part1.mp4 -i part2.mp4 -i part3.mp4 \
  -filter_complex "[0:v][0:a][1:v][1:a][2:v][2:a]concat=n=3:v=1:a=1[v][a]" \
  -map "[v]" -map "[a]" \
  -c:v libx264 -preset medium -crf 21 \
  -c:a aac -b:a 192k \
  output.mp4

Use when files differ in codec, resolution, or framerate. Re-encodes everything.

Verify before concat
for f in part*.mp4; do
  ffprobe -v error -select_streams v:0 \
    -show_entries stream=codec_name,width,height,r_frame_rate \
    -of csv=p=0 "$f"
done

Run this first to confirm all files have the same codec, resolution, and framerate. If they match → use concat demuxer. If they don't → use concat filter.

What each parameter does

  • -f concat

    Tells FFmpeg the input is a concat demuxer file list, not a single video file.

  • -safe 0

    Allows file paths in the list to use any filename. Required for absolute paths or filenames with special characters.

  • -c copy

    Stream-copy everything. Works only when files match exactly in codec/format. The reason concat demuxer is fast.

  • concat=n=3:v=1:a=1

    Concat filter with n inputs, 1 video stream each, 1 audio stream each. Forces re-encoding.

  • filter_complex

    Routes each input's video + audio streams into the concat filter and emits combined streams.

What this outputs

A single video file containing all input files joined end-to-end. Concat demuxer produces output identical to the inputs (just glued together); concat filter re-encodes and produces a new file at the encoder settings you specify.

Pitfalls

  1. The MOST common bug: concat demuxer with mismatched files succeeds but produces broken output (audio/video drift, frozen frames, no audio after part 2). Always verify the codec/resolution/framerate before stream-copy concat.
  2. File path issues in files.txt: paths must be relative to the file list location, OR you use absolute paths with -safe 0. Mixing is unreliable.
  3. Single quotes around filenames are required if filenames contain spaces. Double quotes won't work.
  4. Audio/video stream count mismatches: if part1.mp4 has stereo audio and part2.mp4 has 5.1, concat filter fails. Pre-process to a uniform format first.
  5. Concat filter with many inputs (>10) gets slow and memory-hungry. For long lists, use intermediate concat passes (5 → 1, then 5 → 1, then 2 → 1 final).
  6. GOP boundaries: concat demuxer with VBR codecs (most modern codecs) sometimes produces a brief audio/video glitch at the join point. The fix: use closed GOPs and segment-aligned splits.

At production scale

Concat demuxer is essentially free at scale (I/O-bound). Concat filter is libx264-bound and roughly 2× the cost of single-file encoding because it must process every frame of every input. At production scale, structure pipelines so files arrive already matched (uniform encoder, uniform format) so concat demuxer is the default. Re-encoding concat should be the exception, not the rule.

How MpegFlow handles this

MpegFlow models concat as a dedicated DAG stage that probes inputs first, picks demuxer or filter mode based on actual codec/format match, and reports the choice in the audit log. This avoids the silent-broken-output failure mode that surprises teams using FFmpeg directly.

Topics
  • FFmpeg
  • concat
  • video-operations
  • editing
See also
  • Recipe
    Extract Audio From Video
  • Recipe
    H264 To Hevc Transcoding
Running this at scale?

Get the orchestration layer for free.

The concatenate videos command above is the easy part. The queue, retries, audit trail, encoder-version pinning, and multi-tenant security around it are what every video team rebuilds from scratch. We did the rebuild — design partners run it free during beta.

Apply More recipes
© 2026 MpegFlow, Inc. · Trust & complianceAll systems nominal·StatusPrivacy