Free browser-based media tool
How to Merge MP4 Files Without Re-encoding
Joining MP4 clips does not have to re-encode them. Here is when a stream-copy join works, which parameters have to match, and what to do when the clips differ.
How to Merge MP4 Files Without Re-encoding
Joining MP4 clips does not have to re-encode them. Here is when a stream-copy join works, which parameters have to match, and what to do when the clips differ.
What 'merge without re-encoding' actually means
An MP4 file is a container wrapping two compressed streams: one video, one audio. 'Merging without re-encoding' means the join copies the already-compressed packets from the end of clip A to the start of clip B and writes new container metadata around them. No frame is decoded, so no frame is re-compressed.
This is what FFmpeg calls stream copy, and it is the difference between a join that mostly moves bytes around and a join that has to decode and encode every frame again. The second one always costs more CPU time and always costs some quality, because H.264 and H.265 encoding are lossy processes.
The five parameters that have to match
- Video codec and profile: H.264 High profile at 1080p behaves differently from H.265 Main at 4K, and the packets cannot simply be placed next to each other.
- Resolution: a mix of 1920x1080 and 1280x720 clips breaks the assumption that every frame has the same geometry.
- Frame rate: 30fps and 60fps footage produce different timestamp intervals, which is where stuttering and duration drift come from.
- Audio codec, sample rate and channel count: AAC at 44.1kHz stereo and AAC at 48kHz mono are not interchangeable in a raw packet join.
- Sample aspect ratio: phone footage is often stored with non-square pixels, so the same pixel count can display at a different aspect ratio.
A sensible order of operations
- 1. Queue the clips in the order you want them and check that order, because the join follows the list exactly.
- 2. Start with fast join. If every clip came from the same phone, the same camera or the same export preset, this path usually succeeds and barely touches your CPU.
- 3. Do not treat a finished job as proof that stream copy was valid. When the clips differ, ffmpeg sometimes exits with a success code and still writes a broken file: the muxer refuses to accept timestamps that go backwards, so the later clips' frames get dropped even though the container keeps reporting the first clip's resolution. If in doubt, switch to unified re-encode — it scales, pads and re-times every clip to the first one, which is the expensive part but also the reason it succeeds where stream copy cannot.
- 4. Check the exported file on the device you actually care about, and check the join points rather than only the opening seconds.