FFmpeg - Concatenate MP4 Files: Difference between revisions

From PiRho Knowledgebase
Jump to navigationJump to search
Dex (talk | contribs)
No edit summary
Dex (talk | contribs)
No edit summary
 
Line 1: Line 1:
[[Category:FFmpeg]]
[[Category:FFmpeg]]
[[Category:MP4]]
[[Category:MP4]]
Concatenating video files in FFmpeg can be achieved in several ways, depending on your input formats, codecs, and whether you want to avoid re‑encoding. This article explains the three official FFmpeg concatenation methods, when to use each one, and common pitfalls.
Concatenating MP4 files in FFmpeg can be done using three official methods. Each method behaves differently, has different requirements, and supports different levels of compatibility. This article explains when to use each method, how they work, and common pitfalls to avoid—especially when working with MP4, which is strict about matching codecs and container metadata.


== 1. concat Video Filter ==
== 1. concat Video Filter ==
Use this method when:
The concat filter works at the decoded‑frame level. FFmpeg fully decodes each input, merges the streams, and then re‑encodes the result.
* Your inputs do not share the same properties (resolution, frame rate, codec).
* You want to apply filters, scaling, or other transformations.
* You are comfortable with a full re‑encode of all inputs.


Because the filter merges decoded streams, FFmpeg must re‑encode everything.
=== Use this method when: ===
* Your input files do not match (resolution, codec, bitrate, frame rate, audio layout).
* You need to apply filters, scaling, overlays, trimming, or processing.
* A full re‑encode is acceptable or required.
 
Because the filter merges raw audio and video frames, re‑encoding is mandatory.


=== Example: Concatenating Three Clips ===
=== Example: Concatenating Three Clips ===
<pre>
```
ffmpeg -i opening.mkv -i episode.mkv -i ending.mkv -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]" output.mkv
ffmpeg -i opening.mkv -i episode.mkv -i ending.mkv -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]" output.mkv
</pre>
```


== Notes ==
=== Notes ===
* Ideal for complicated workflows or mismatched sources.
* Most flexible method; works with mismatched or problematic sources.
* If you want to avoid full re‑encode, pre‑normalise the odd inputs first, then use the concat demuxer.
* If you want to avoid re‑encode, normalise the inputs first, then use the concat demuxer.


== 2. concat Demuxer ==
== 2. concat Demuxer ==
Use this method when you want to avoid re‑encoding and your formats support stream copying. This is the recommended method for MP4 as long as the files are perfectly matching (same codec, profile, level, frame rate, resolution, audio layout).
The concat demuxer is the recommended MP4 method when files are perfectly matching. It concatenates at the container level while rewriting metadata, allowing stream copying (-c copy) for a lossless, fast result.
 
=== Use this method when: ===
* All inputs are identical in codec, profile, level, frame rate, resolution, pixel format, audio codec, and channel layout.
* You want to avoid re‑encoding.
* You're joining MP4 files exported from the same device or encoder.


=== Create a List File ===
=== Create a List File ===
<pre>
```
file '/path/to/file1'
file '/path/to/file1.mp4'
file '/path/to/file2'
file '/path/to/file2.mp4'
file '/path/to/file3'
file '/path/to/file3.mp4'
</pre>
```


=== Concatenate Without Re‑Encoding ===
=== Concatenate Without Re‑Encoding ===
<code>
```
ffmpeg -f concat -i mylist.txt -c copy output.mp4
ffmpeg -f concat -i mylist.txt -c copy output.mp4
</code>
```


=== Windows Examples ===
=== Windows Examples ===
==== Manual list: ====
==== Manual list: ====
<pre>
```
(echo file 'first file.mp4' & echo file 'second file.mp4') > list.txt
(echo file 'first file.mp4' & echo file 'second file.mp4') > list.txt
ffmpeg -safe 0 -f concat -i list.txt -c copy output.mp4
ffmpeg -safe 0 -f concat -i list.txt -c copy output.mp4
</pre>
```


==== Automatically list all MP4 files: ====
==== Automatically list all MP4 files: ====
<pre>
```
(for %i in (*.mp4) do @echo file '%i') > list.txt
(for %i in (*.mp4) do @echo file '%i') > list.txt
ffmpeg -safe 0 -f concat -i list.txt -c copy output.mp4
ffmpeg -safe 0 -f concat -i list.txt -c copy output.mp4
</pre>
```


== Notes ==
=== Notes ===
* All parameters must match. Even slight differences can break stream copy.
* All technical parameters must match, or FFmpeg cannot stream copy.
* Safest method for MP4 when conditions are met.
* Safest method for MP4.
* -safe 0 allows absolute or unusual paths.
* Use UTF‑8 list files for international filenames.


== 3. concat Protocol ==
== 3. concat Protocol ==
Use this only when formats support raw file‑level concatenation (MPEG‑1, MPEG‑2 PS, DV). Do not use this for MP4.
This is a raw byte-level concatenation method used only for formats that can be joined without adjusting metadata.
 
=== Use this only for: ===
* MPEG‑1
* MPEG‑2 Program Streams
* DV


=== Example ===
=== Example ===
<code>
```
ffmpeg -i "concat:input1|input2" -codec copy output.mkv
ffmpeg -i "concat:input1|input2" -codec copy output.mkv
</code>
```


== Why This Fails for MP4 ==
== Why This Fails for MP4 ==
The concat protocol performs raw joining without rewriting container metadata. MP4 requires regenerated moov atoms and indices, so raw concatenation corrupts the container.
The concat protocol does not rewrite container metadata. MP4 containers require updated moov atoms, index tables, durations, and sample tables. Raw concatenation usually corrupts playback, causes wrong durations, broken seeking, or player failures.


== Summary ==
== Summary ==
{| class="wikitable"
{| class="wikitable"
! Method !! Re-Encode? !! MP4 Support !! Best Use Case
! Method !! Re‑Encode? !! MP4 Support !! Best Use Case
|-
|-
| concat filter || Yes || Yes || Mismatched sources, filtering
| concat filter || Yes || Yes || Mismatched sources, filtering, full control
|-
|-
| concat demuxer || No || Yes (if identical) || Safe MP4 joining
| concat demuxer || No || Yes (if identical) || Safe MP4 joining with stream copy
|-
|-
| concat protocol || No || No || MPEG‑1 / MPEG‑2 PS / DV
| concat protocol || No || No || MPEG‑1 / MPEG‑2 PS / DV only
|}
|}


== Reference ==
== Reference ==
* https://stackoverflow.com/questions/7333232/how-to-concatenate-two-mp4-files-using-ffmpeg
* https://stackoverflow.com/questions/7333232/how-to-concatenate-two-mp4-files-using-ffmpeg

Latest revision as of 14:36, 14 March 2026

Concatenating MP4 files in FFmpeg can be done using three official methods. Each method behaves differently, has different requirements, and supports different levels of compatibility. This article explains when to use each method, how they work, and common pitfalls to avoid—especially when working with MP4, which is strict about matching codecs and container metadata.

1. concat Video Filter

The concat filter works at the decoded‑frame level. FFmpeg fully decodes each input, merges the streams, and then re‑encodes the result.

Use this method when:

  • Your input files do not match (resolution, codec, bitrate, frame rate, audio layout).
  • You need to apply filters, scaling, overlays, trimming, or processing.
  • A full re‑encode is acceptable or required.

Because the filter merges raw audio and video frames, re‑encoding is mandatory.

Example: Concatenating Three Clips

``` ffmpeg -i opening.mkv -i episode.mkv -i ending.mkv -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]" output.mkv ```

Notes

  • Most flexible method; works with mismatched or problematic sources.
  • If you want to avoid re‑encode, normalise the inputs first, then use the concat demuxer.

2. concat Demuxer

The concat demuxer is the recommended MP4 method when files are perfectly matching. It concatenates at the container level while rewriting metadata, allowing stream copying (-c copy) for a lossless, fast result.

Use this method when:

  • All inputs are identical in codec, profile, level, frame rate, resolution, pixel format, audio codec, and channel layout.
  • You want to avoid re‑encoding.
  • You're joining MP4 files exported from the same device or encoder.

Create a List File

``` file '/path/to/file1.mp4' file '/path/to/file2.mp4' file '/path/to/file3.mp4' ```

Concatenate Without Re‑Encoding

``` ffmpeg -f concat -i mylist.txt -c copy output.mp4 ```

Windows Examples

Manual list:

``` (echo file 'first file.mp4' & echo file 'second file.mp4') > list.txt ffmpeg -safe 0 -f concat -i list.txt -c copy output.mp4 ```

Automatically list all MP4 files:

``` (for %i in (*.mp4) do @echo file '%i') > list.txt ffmpeg -safe 0 -f concat -i list.txt -c copy output.mp4 ```

Notes

  • All technical parameters must match, or FFmpeg cannot stream copy.
  • Safest method for MP4.
  • -safe 0 allows absolute or unusual paths.
  • Use UTF‑8 list files for international filenames.

3. concat Protocol

This is a raw byte-level concatenation method used only for formats that can be joined without adjusting metadata.

Use this only for:

  • MPEG‑1
  • MPEG‑2 Program Streams
  • DV

Example

``` ffmpeg -i "concat:input1|input2" -codec copy output.mkv ```

Why This Fails for MP4

The concat protocol does not rewrite container metadata. MP4 containers require updated moov atoms, index tables, durations, and sample tables. Raw concatenation usually corrupts playback, causes wrong durations, broken seeking, or player failures.

Summary

Method Re‑Encode? MP4 Support Best Use Case
concat filter Yes Yes Mismatched sources, filtering, full control
concat demuxer No Yes (if identical) Safe MP4 joining with stream copy
concat protocol No No MPEG‑1 / MPEG‑2 PS / DV only

Reference