Every "convert MOV to MP4" tutorial on the first page of search results says the same thing: run ffmpeg -i input.mov -c copy output.mp4. Most of them don't tell you when that command silently drops streams, when it refuses to run at all, or how to check that nothing was lost. I ran the cases on FFmpeg 9 to see what actually happens, and this post is the record — the good path first, then the three traps.
Remuxing is not converting
A QuickTime MOV file and an MP4 file are both containers. The video and audio inside them — usually H.264 and AAC — are just bits wrapped in a different box. Re-encoding those streams to "convert" them is like photocopying a document to move it between binders: it always loses a little quality, it takes as long as playing the file, and it's unnecessary. Remuxing (-c copy) moves the streams between containers byte-for-byte:
ffmpeg -i input.mov -c copy output.mp4
On my test file — H.264 video, AAC audio — the input was 217,295 bytes and the output was 217,244 bytes. A 51-byte difference is container overhead, not quality. That's what a correct remux looks like: the sizes should be within a few kilobytes of each other. If your output is clearly smaller, something inside it got dropped — see the next section.
For files you're uploading to the web rather than keeping locally, add -movflags +faststart. Normally MP4 players need the index (the moov atom) that FFmpeg writes at the end of the file, which forces a full download before playback starts. faststart moves that index to the front as a second pass, so browsers can start playing while the rest downloads. YouTube-style platforms handle either layout, but direct links and <video> tags behave better with it.
Trap 1: -c copy does not mean "copy everything"
This is the one that bites people with multi-track files. FFmpeg's default behavior is stream selection: it picks one video stream and one audio stream, and ignores the rest. -c copy only means "don't re-encode what you picked" — it does not mean "take all the streams." A MOV file with two audio languages, a commentary track, or a timed-text track will come out of the default command with only one audio track, and FFmpeg exits 0 with no warning.
The fix is -map 0, which pulls in every stream from the input:
ffmpeg -i input.mov -map 0 -c copy output.mp4
I've seen forum arguments about this where the confident answer is "you don't need -map 0 if you have -c copy" — that's wrong, and it's checkable in one line: run ffprobe input.mov and ffprobe output.mp4 and count the streams before and after. That comparison should be part of every remux you care about. (Subtitles are a related but deeper trap: SRT-style subtitle tracks cannot be copied into MP4 at all — the container doesn't carry them the way Matroska does — and FFmpeg drops them silently unless you convert them explicitly with -c:s mov_text.)
Trap 2: some codecs are simply not allowed in MP4
If your MOV file holds ProRes video — common for anything out of Final Cut Pro or a pro camera — the remux fails outright:
Could not find tag for codec prores in stream #0, codec not currently supported in container
FFmpeg refuses, exits nonzero, and may leave a zero-byte output.mp4 behind as a souvenir. This isn't a bug and there's no flag past it: MP4's spec has no slot for ProRes in the way your file carries it. Your options are to keep the MOV, wrap into a container that accepts it, or actually re-encode. For that last resort, the standard one-liner is:
ffmpeg -i input.mov -c:v libx264 -crf 23 -c:a aac output.mp4
-crf 23 is the default quality level; lower numbers are bigger and better. This re-encodes, so it's the lossy path — use it only when the remux is impossible.
Trap 3: trust sizes, not exit codes
The sanity check that catches both traps above is comparing byte sizes. A remux that copied everything lands within a few KB of the original. A file that came out at 60% of the original size had streams dropped — usually the second audio or the subtitle track — and the default command will still have exited 0. Check the size, then ffprobe the stream list, and only then delete your original.
Wrap up
The whole decision in one paragraph: H.264/AAC in, -map 0 -c copy with +faststart out, verify sizes match; ProRes in, no remux exists — re-encode or keep MOV. I keep a longer write-up with the command outputs for each case (including the subtitle behavior and a batch variant for whole folders) here: FFmpeg: Convert MOV to MP4 Without Losing Quality.
Disclosure: this post links to a site I run; some links there are affiliate links.
Top comments (0)