What You Will Learn
- The difference between containers and codecs (essential knowledge before converting)
- When stream copy (
-c copy) works instantly — and when it fails - Practical commands for MKV→MP4, MP4→WebM, MOV→MP4, AVI→MP4, and MP4→MKV
- How to verify codecs before and after conversion using ffprobe
Tested version: Verified with FFmpeg 6.1 (ubuntu-latest / CI-validated) Target OS: Windows / macOS / Linux
About filenames: This article uses placeholder filenames such as
input.mkvandinput.mp4. Replace them with the actual file paths you want to process.
Containers vs. Codecs
The most common source of confusion when working with video files is the distinction between containers and codecs.
| Concept | Description | Examples |
|---|---|---|
| Container (extension) | A “wrapper” that holds video, audio, subtitles, etc. | .mp4, .mkv, .webm, .mov, .avi |
| Video codec | Compression format for video data | H.264, H.265, VP9, AV1 |
| Audio codec | Compression format for audio data | AAC, MP3, Opus, Vorbis |
Simply renaming the file extension does not convert it. For example, if an .avi file contains H.264+AAC video, you only need to “repack” it into an MP4 container (stream copy). On the other hand, converting a WebM file with VP9 video to MOV may require re-encoding the codec.
Checking Codecs (ffprobe)
Checking codecs before conversion helps you choose the right approach.
ffprobe -v error -show_streams -select_streams v:0 input.mp4
ffprobe -v error -show_entries stream=codec_name,codec_type -of default=noprint_wrappers=1 input.mkv
Commands that use only
-hide_banneror-show_streamswithout an output file are shown intextblocks.
When to Use Stream Copy (-c copy)
If you only need to change the container (keeping the codec as-is), -c copy is the fastest option.
ffmpeg -i input.mkv -c copy output.mp4
Benefits:
- Completes without re-encoding (seconds to tens of seconds)
- Zero degradation in video or audio quality
Caveats and failure cases:
- Will fail if the output container does not support the input codec
- Example: Trying to convert an MKV with VP9 video to MP4 using
-c copywill error because MP4 does not support VP9 - If
-c copyfails, switch to re-encoding
Common Conversion Commands
MKV → MP4 (Stream Copy)
If the MKV contains H.264+AAC, a single command converts it instantly.
ffmpeg -i input.mkv -c copy output.mp4
If the content uses a different codec and stream copy fails, re-encode instead.
ffmpeg -i input.mkv -c:v libx264 -crf 23 -c:a aac output.mp4
MOV → MP4 (iPhone / Mac Video Conversion)
MOV files recorded on iPhone or Mac almost always contain H.264/HEVC, so stream copy often works.
ffmpeg -i input.mov -c copy output.mp4
If the file contains HEVC (H.265) video and you need broad compatibility, re-encode:
ffmpeg -i input.mov -c:v libx264 -crf 22 -c:a aac output.mp4
AVI → MP4 (Converting from Legacy Format)
AVI files use a wide variety of codecs, so re-encoding is recommended for safety.
ffmpeg -i input.avi -c:v libx264 -crf 23 -c:a aac output.mp4
MP4 → MKV (Container-Only Conversion)
MKV can hold virtually any codec, so stream copy works reliably here.
ffmpeg -i input.mp4 -c copy output.mkv
MP4 → WebM (For Web Delivery)
WebM uses VP8/VP9 video and Vorbis/Opus audio as its standard. Well-suited for browser delivery.
ffmpeg -i input.mp4 -c:v libvpx-vp9 -crf 30 -b:v 0 -c:a libopus output.webm
| Option | Meaning |
|---|---|
-c:v libvpx-vp9 | Use VP9 encoder |
-crf 30 -b:v 0 | Constant quality mode (CRF mode) |
-c:a libopus | Use Opus encoder (recommended audio for WebM) |
How Automatic Codec Selection Works
Simply specifying the output container causes FFmpeg to auto-select default codecs.
ffmpeg -i input.avi output.mp4
This command automatically selects libx264 (video) and aac (audio) — the defaults for the MP4 container. However, since you have no quality control, it is recommended to explicitly specify options like -crf.
Supported Codecs by Container
| Container | Common Video Codecs | Common Audio Codecs |
|---|---|---|
| MP4 | H.264, H.265 | AAC, MP3 |
| MKV | H.264, H.265, VP9, AV1, etc. | AAC, MP3, Opus, FLAC, etc. |
| WebM | VP8, VP9, AV1 | Vorbis, Opus |
| MOV | H.264, H.265, ProRes | AAC, PCM |
| AVI | H.264, DivX, Xvid, etc. | MP3, PCM, etc. |
Common Errors and Solutions
Could not write header for output file Error
This is a codec/container compatibility problem. Switch from -c copy to -c:v libx264 -c:a aac.
Encoder not found Error
The FFmpeg build you installed does not include that codec. Reinstall a full-featured build from the official site or gyan.dev (Windows).
WebM Conversion Is Extremely Slow
VP9 encoding is time-consuming. Add -cpu-used 4 to prioritize speed.
Related Articles
- FFmpeg Basic Syntax and Options
- What is FFmpeg? Overview and Use Cases
- Converting Video to MP4 with FFmpeg
Tested with: ffmpeg 6.1.1 / Ubuntu 24.04 (GitHub Actions runner) Primary sources: ffmpeg.org/ffmpeg.html / ffmpeg.org/ffmpeg-formats.html / trac.ffmpeg.org/wiki/Encode/H.264