How to merge multiple mp4 files locally
- Step 1Open the merger and add at least two MP4s — Drop your clips onto the video-merger tool. The merger needs at least two files — it throws
Pick at least two clips to mergeon a single input. Accepted inputs are.mp4,.mov,.mkv,.webm,.avi,.m4v, and.ts. - Step 2Add clips in playback order — Files merge in the order they appear in the list — first added plays first. There is no drag-to-reorder control, so add (or drop) them in the sequence you want. To fix the order, remove a clip with its trash button and re-add it in position with Add more.
- Step 3Confirm you're on Pro or higher — The Free tier caps batch jobs at one file, so it can't merge. Pro allows 5 files, Pro + Media 50, Developer is unlimited. Per-file size caps are 1 GB (Free, irrelevant here), 10 GB (Pro), and 100 GB (Pro + Media / Developer).
- Step 4Let the merger pick the path automatically — There are no options to set — the merger first tries stream-copy concat; if the codecs/resolutions don't match it re-encodes. You don't choose the mode. If the stage label flips to 'Codecs differ — re-encoding for clean concat', your clips weren't identical.
- Step 5Wait for the merge — Stream-copy completes in seconds (it copies bytes, not pixels). A re-encode runs at roughly real-time-to-several-times-real-time depending on resolution and whether your CPU has spare cores — a 4-minute 1080p mixed-source merge typically takes a few minutes.
- Step 6Download or stream the merged file — On Free/Pro the result downloads as a blob named
<firstclip>-merged.<ext>. On Pro + Media you can pick a destination folder up front and the bytes stream straight to disk, which is what lets multi-GB merges complete without exhausting browser memory.
Which path your merge takes
The merger has no mode switch — it tries stream-copy first and only re-encodes if that fails. This table shows what triggers each path and what you get.
| Your clips | Path taken | FFmpeg command | Quality | Speed |
|---|---|---|---|---|
| All identical codec, resolution, fps, audio format | Stream-copy (concat demuxer) | -f concat -safe 0 -i list.txt -c copy out.<ext> | Lossless — streams copied byte-for-byte | Seconds (no decode/encode) |
| Mixed codec (e.g. H.264 + H.265) | Re-encode (concat filter) | -filter_complex concat ... -c:v libx264 -crf 20 -c:a aac -b:a 192k | Re-encoded to a clean H.264/AAC baseline | Roughly real-time to a few × real-time |
| Mixed resolution (e.g. 1080p + 720p) | Re-encode (concat filter) | Same as above — concat filter normalises the streams | Re-encoded; output dimensions follow the filter | Depends on resolution |
| Mixed frame rate (30 fps + 60 fps) | Re-encode (concat filter) | Same as above | Re-encoded to a uniform timeline | Depends on length |
Output container and codec by path
The stream-copy path preserves the container of the LAST file you added; the re-encode fallback always writes MP4. Verified against the merge processor.
| Path | Output container | Video codec | Audio codec | Extras |
|---|---|---|---|---|
| Stream-copy | Extension of the last clip added (e.g. .mp4, .mkv) | Whatever the source clips already use (copied) | Source audio (copied) | Bit-identical streams; no +faststart flag applied |
| Re-encode fallback | Always .mp4 | H.264 (libx264 -preset medium -crf 20, yuv420p) | AAC at 192 kbps | +faststart written for instant web playback |
Tier limits for merging
Merging needs at least 2 files, so the single-file Free tier cannot run it. Real numbers from the video tier table.
| Tier | Files per merge | Max size per file | Can merge? |
|---|---|---|---|
| Free | 1 | 1 GB | No — needs ≥ 2 files |
| Pro | 5 | 10 GB | Yes |
| Pro + Media | 50 | 100 GB (streamed) | Yes |
| Developer | Unlimited | 100 GB (streamed) | Yes |
Cookbook
Concrete merge scenarios with the path each one takes and the exact behaviour you'll see. Stage labels shown are the ones the tool surfaces while running.
Three same-camera MP4s — instant lossless join
Three 4-minute clips off the same phone, all H.264 1080p30 AAC. Because every stream matches, the concat demuxer copies them with -c copy and finishes in seconds. The output is bit-identical to the sources.
Inputs (added in this order): clip-A.mp4 H.264 1920x1080 30fps AAC 142 MB clip-B.mp4 H.264 1920x1080 30fps AAC 138 MB clip-C.mp4 H.264 1920x1080 30fps AAC 151 MB Merger: -f concat -safe 0 -i list.txt -c copy out.mp4 Stage: (no re-encode warning shown) Output: clip-A-merged.mp4 ~431 MB, lossless, done in ~4s
Wrong order — fix by remove + re-add
There is no drag handle. If clip C ended up second, you can't drag it down. Remove it and re-add it last with Add more. The list order IS the merge order.
List as added: A, C, B ← C is in the wrong slot Desired order: A, B, C Fix: 1. Click the trash icon on C -> list is A, B 2. Click 'Add more' and re-select C -> list is A, B, C 3. Run There is no reorder/drag UI — order = add order.
H.264 clip + H.265 clip — automatic re-encode
An iPhone HEVC (H.265) clip dropped in next to an H.264 export. The concat demuxer can't stitch different codecs, so pass 1 fails and the merger transparently re-encodes both through the concat filter to one H.264/AAC MP4.
Inputs: intro.mp4 H.264 1080p AAC body.mov H.265/HEVC AAC (iPhone) Pass 1 (stream-copy) -> fails (codec mismatch) Stage flips to: 'Codecs differ — re-encoding for clean concat' Pass 2 (concat filter): -filter_complex '[0:v:0][0:a:0?][1:v:0][1:a:0?]concat=n=2:v=1:a=1[outv][outa]' -c:v libx264 -preset medium -crf 20 -pix_fmt yuv420p -c:a aac -b:a 192k -movflags +faststart out.mp4 Output: intro-merged.mp4 (re-encoded, always .mp4)
Mixed container output surprise
On the stream-copy path the output container follows the LAST file added — the merger overwrites its target extension with each input as it loops. If you add two MKVs then one MP4, a successful stream-copy writes .mp4. If it has to re-encode, the output is always .mp4 regardless.
Added: a.mkv, b.mkv, c.mp4 (all same codec/res/fps) Stream-copy succeeds -> output extension = .mp4 (last file) Added: a.mkv, b.mkv, c.mkv Stream-copy succeeds -> output extension = .mkv Any re-encode fallback -> always .mp4
Single file dropped — rejected
The merger is a multi-file tool. Dropping one clip throws immediately with a clear message. Use the trimmer or transcoder for single-file jobs.
Input: one_clip.mp4 Error: 'Pick at least two clips to merge.' For a single file: - trim it -> /video-tools/lossless-trimmer - convert it -> /video-tools/video-transcoder
Edge cases and what actually happens
Only one file added
RejectedThe merger throws Pick at least two clips to merge when fewer than two files are present. It is strictly a join tool. For single-clip jobs use lossless-trimmer or video-transcoder.
Free tier tries to merge
Blocked by tierThe Free tier caps batch jobs at one file, and the merger needs at least two — so Free can't run it. Pro raises the batch limit to 5 files, Pro + Media to 50, Developer to unlimited. This is a hard limit in the tier table, not a soft prompt.
Wrong clip order
By designClips merge in the order they appear in the file list, which is the order you added them. There is no drag-to-reorder handle in the UI. To reorder, remove a clip (trash icon) and re-add it in the right position with Add more, then run.
Codecs differ between clips
Preserved (auto re-encode)When the stream-copy concat demuxer fails — usually because clips have different codecs, resolutions, or frame rates — the merger does NOT error out. It automatically re-encodes everything through the concat filter to H.264/AAC and shows the stage 'Codecs differ — re-encoding for clean concat'. You get a file either way.
Output container isn't what you expected
ExpectedOn a successful stream-copy, the output container is taken from the LAST file you added (the loop overwrites the target extension on each input). The re-encode fallback always writes .mp4. If you need a specific container, run the merged file through video-transcoder afterward.
A clip is larger than your tier's per-file cap
RejectedEach input is checked against your tier's per-file byte limit before processing (1 GB Free, 10 GB Pro, 100 GB Pro + Media / Developer). An over-limit file is rejected by name with its size and your tier's allowance. Shrink it with discord-compressor or trim it first.
Slight stutter at a join on the stream-copy path
ExpectedStream-copy preserves each clip's original timing and keyframe layout, so if clips have different GOP structures you can see a brief non-smooth transition at the seam. This is inherent to copying streams without re-encoding. A re-encode (which happens automatically for mismatched clips) produces a uniform timeline and removes it.
Browser runs out of memory on a huge merge (Free/Pro)
Out of memoryWithout a chosen destination folder, the merged bytes are held in a blob in browser memory. Very large totals can exhaust the heap. Pro + Media streams output straight to disk via a destination handle, which is the supported path for multi-GB merges.
Mixing audio-only or no-audio clips
HandledThe re-encode concat filter maps audio optionally ([i:a:0?]), so a clip with no audio track won't crash the filter graph. On the stream-copy path, however, a missing audio stream in one clip can cause the demuxer to fail and trigger the re-encode fallback.
Unsupported file extension dropped
RejectedThe dropzone only accepts .mp4, .mov, .mkv, .webm, .avi, .m4v, and .ts (or files with a video/* MIME type). Anything else is filtered out with a 'No video files in the drop' message before the merge runs.
Frequently asked questions
Are my MP4 files uploaded anywhere?
No. The merger runs entirely in your browser on FFmpeg compiled to WebAssembly. Your clips are read into local memory (or streamed to a folder you pick on Pro + Media) and never sent to a server. This is why it works offline once the page has loaded.
Does merging re-encode my MP4s and lose quality?
Only if it has to. When all your clips share the same codec, resolution, frame rate, and audio format, the merger uses -c copy to copy the encoded streams byte-for-byte — that's truly lossless. It re-encodes (to H.264 CRF 20 / AAC 192k) only when the clips differ and can't be stitched as-is.
Can I drag clips to reorder them before merging?
No — there is no drag-to-reorder control. Clips merge in the order they appear in the list, which is the order you added them. To change the order, remove a clip with its trash button and re-add it in the position you want using Add more.
How many MP4s can I merge at once?
At least two (it's a join tool). The upper bound is your tier's batch limit: Pro allows 5 files, Pro + Media 50, Developer unlimited. The Free tier is capped at a single file, so it can't merge at all.
Why can't I merge on the Free tier?
The Free tier's batch limit is one file, and merging requires at least two. Upgrading to Pro raises the limit to 5 files (and 10 GB per file), which is enough for most merges. Pro + Media goes to 50 files at 100 GB each.
What container does the merged file use?
On the lossless stream-copy path, the output container is taken from the last file you added. On the re-encode fallback, the output is always .mp4 with +faststart. If you need a specific container, convert the result afterward with the video-transcoder.
What input formats can I merge?
MP4, MOV, MKV, WebM, AVI, M4V, and TS — plus anything the browser reports with a video/* MIME type. You can mix containers and codecs; the merger re-encodes them to a common baseline if they don't match for a clean stream-copy.
Why is there a stutter at the point where two clips join?
On the stream-copy path the merger keeps each clip's original timing and keyframe layout, so clips with different GOP structures can show a brief hitch at the seam. If you let it re-encode (by mixing codecs/resolutions), it builds a uniform timeline and the seam smooths out. There's no manual transcode toggle — the path is chosen automatically.
Can I set the output bitrate, resolution, or CRF for the merge?
No. The merger has no options panel — it either copies streams losslessly or re-encodes to a fixed H.264 CRF 20 / AAC 192k baseline. For full control over codec, container, and CRF, merge first and then run the output through the video-transcoder.
Do I need an account to merge files?
You need a Pro (or higher) subscription because merging requires the multi-file batch limit that Free doesn't have. There's no separate per-merge account step beyond being signed in on a qualifying tier; the actual processing still happens locally in your browser.
How fast is a merge?
A stream-copy merge takes seconds because no pixels are decoded — it copies bytes. A re-encode runs roughly real-time to a few times real-time depending on resolution and your CPU's spare cores; a few-minute 1080p mixed-source merge usually finishes in a few minutes.
My clips are the same resolution but it still re-encoded — why?
Stream-copy needs more than matching resolution: the codec, frame rate, pixel format, and audio format must also line up, and the timestamps must be concatenable. A difference in any of those (e.g. one clip at 29.97 fps and another at 30 fps, or different audio sample rates) causes the demuxer to fail and the merger to fall back to a clean re-encode.
Privacy first
Every JAD Video tool runs entirely in your browser via WebCodecs and FFmpeg (WebAssembly). Your video files never leave your device — verified by zero outbound network requests during processing.