Almost every FFmpeg task comes down to one fundamental decision: do you copy the existing streams or re-encode them? Choosing right can mean the difference between a one-second lossless operation and a ten-minute lossy one. This guide explains what each path does, when to use it, and the one caveat that trips people up — container compatibility. Once this clicks, most other FFmpeg commands make sense. Estimated time: 6 minutes.
Tested with: FFmpeg 8.1
What You’ll Learn
- What stream copy (
-c copy) actually does - What re-encoding does and why it costs more
- A side-by-side comparison
- The container compatibility caveat
- When to copy and when to re-encode
- Copying or re-encoding individual streams
- Troubleshooting and FAQ
1. Stream Copy (-c copy)
Stream copy moves the already-compressed audio and video packets from the input straight into a new container, without decoding or re-compressing them. The basic command:
ffmpeg -i input.mp4 -c copy output.mp4
-c copy… copy all streams as-is (shorthand for-c:v copy -c:a copy ...).
Because nothing is decoded, stream copy is:
- Lossless — not a single bit of the media is altered.
- Fast — typically finishes in seconds, limited mostly by disk speed.
- Light — almost no CPU usage.
It’s the right tool for changing containers (remuxing), cutting on keyframes, or merging streams — anything that doesn’t need to alter the actual picture or sound.
2. Re-encoding
Re-encoding decodes each frame back to raw form and then compresses it again with a chosen encoder. The basic command:
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -c:a aac output.mp4
-c:v libx264… re-encode video to H.264.-crf 23… quality target (lower = better quality, larger file).-c:a aac… re-encode audio to AAC.
Re-encoding is:
- Lossy — recompression discards some detail (for lossy codecs). Quality never improves.
- Slow — every frame is decoded and encoded; this is CPU-heavy.
- Flexible — you can change codec, resolution, bitrate, frame rate, filters, and more.
It’s required whenever you need to actually change the media: compress it, resize it, convert to an incompatible codec, or apply filters.
3. Side by Side
-c copy (stream copy) | Re-encode | |
|---|---|---|
| Quality | Lossless (identical) | Lossy (some loss) |
| Speed | Seconds | Minutes (CPU-bound) |
| CPU usage | Minimal | High |
| File size | ~Same as source | Controllable |
| Change codec? | No | Yes |
| Resize / filter? | No | Yes |
| Change container? | Yes | Yes |
| Cut anywhere? | Keyframes only | Any frame |
The rule of thumb: copy when you can, re-encode when you must.
4. The Container Compatibility Caveat
Stream copy fails if the source codec isn’t allowed inside the target container. Each container accepts only certain codecs. For example:
- MP4 accepts H.264, HEVC, AAC — but not PCM or ProRes.
- WebM accepts VP9/AV1 + Opus/Vorbis — but not H.264 or AAC.
So this can fail even though no quality change is intended:
ffmpeg -i input.mp4 -c copy output.mp4
If FFmpeg prints Could not find tag for codec ... in stream, the codec doesn’t fit the chosen container. Your options are to pick a compatible container, or re-encode just the offending stream to a codec the container accepts (Section 6).
| Source codec | Target container | Copy works? |
|---|---|---|
| H.264 + AAC | MP4 / MKV | Yes |
| HEVC + AAC | MP4 (add -tag:v hvc1) | Yes |
| VP9 + Opus | WebM / MKV | Yes |
| VP9 + Opus | MP4 | No (re-encode) |
| PCM audio | MP4 | No (re-encode audio) |
| Almost anything | MKV | Usually yes |
MKV is the most permissive container, which is why stream copy “just works” into MKV far more often than into MP4.
5. When to Copy and When to Re-encode
Use -c copy when:
- Changing only the container (e.g., MKV to MP4, MOV to MP4).
- Trimming at keyframe boundaries.
- Merging or splitting without altering the media.
- The streams are already compatible with the target.
Re-encode when:
- Compressing to reduce file size.
- Changing resolution, frame rate, or pixel format.
- Converting to a codec the container or device requires.
- Applying filters (scale, crop, overlay, subtitles burn-in, color).
- Cutting frame-accurately between keyframes.
6. Per-stream Choices
You don’t have to treat every stream the same. A common pattern is to copy the video (the expensive part to encode) while re-encoding only the audio into a compatible codec:
ffmpeg -i input.mp4 -c:v copy -c:a aac -b:a 192k output.mp4
Here the video is untouched and instant, and only the audio is re-encoded — far faster than a full re-encode while solving an audio-codec incompatibility. The reverse (re-encode video, copy audio) works too:
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -c:a copy output.mp4
7. Troubleshooting
Error 1: Could not find tag for codec ... in stream
Cause: The source codec isn’t allowed in the target container during a copy. Fix: Choose a compatible container (MKV is most permissive) or re-encode that stream (Section 6).
Error 2: The trimmed copy starts with a frozen frame or black gap
Cause: Stream copy can only cut on keyframes, so the cut snaps to the nearest one. Fix: Re-encode for frame-accurate cuts, or accept the keyframe boundary. See the trimming workflow in related guides.
Error 3: Re-encoding made the file bigger, not smaller
Cause: Your -crf (or bitrate) is set higher quality than the source warrants.
Fix: Raise the CRF number (e.g., 23 to 26) to compress more, and confirm you actually need to re-encode at all.
Error 4: Copy succeeds but the file won’t play in a browser
Cause: The moov atom is at the end of the MP4.
Fix: Add -movflags +faststart. See the faststart guide.
FAQ
Q1. Does -c copy ever change quality?
A. No. It copies compressed packets verbatim — the media is bit-for-bit identical. Only re-encoding can change quality.
Q2. Why is re-encoding so much slower? A. It decodes every frame to raw pixels and compresses them again. Copy just moves existing packets, which is orders of magnitude less work.
Q3. Can I re-encode without losing quality?
A. Only with lossless encoders (e.g. FFV1, or -qp 0 for libx264), which produce huge files. Normal lossy re-encoding always discards some detail.
Q4. How do I know which codecs my file uses?
A. Run ffprobe input.mp4 and read the stream lines, or use ffprobe -show_streams. Then check the table in Section 4 for copy compatibility.
Q5. Should I default to copy or re-encode?
A. Default to -c copy. Only re-encode when you actually need to change the media (size, resolution, codec, filters) or when copy fails due to container incompatibility.
Related Articles
- Converting MKV to MP4 — Lossless Remux
- Converting MOV to MP4 — Copy and Re-encode
- Compressing Video Without Wrecking Quality
- Fixing Web Playback with faststart
Tested with FFmpeg 8.1 — verified with our command-check script Primary sources: ffmpeg.org/ffmpeg.html / ffmpeg.org/ffmpeg-codecs.html