Replace example filenames such as input.mkv and input.mp4 with the paths of your own files.

Containers vs. Codecs

A video file has a container and codecs, and the two are easy to mix up.

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

Renaming the file extension does not convert the file. If an .avi file contains H.264+AAC video, you only need to repack the streams into an MP4 container (a stream copy). A WebM file with VP9 video, on the other hand, may need re-encoding to become a MOV.

Checking Codecs (ffprobe)

Check the codecs before you convert. They tell you whether a stream copy can work or you need to re-encode.

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

When to Use Stream Copy (-c copy)

If you only need to change the container and can keep the codecs, -c copy is the fastest option.

ffmpeg -i input.mkv -c copy output.mp4

Benefits:

  • No re-encoding, so it finishes in seconds to tens of seconds
  • No loss of video or audio quality

When it fails:

  • It fails if the output container does not support the input codec
  • Example: converting an MKV with ASS subtitles to MP4 with -map 0 -c copy (keep every stream) fails, because MP4 cannot store ASS subtitles
  • If -c copy fails, re-encode instead

Common Conversion Commands

MKV → MP4 (Stream Copy)

If the MKV contains H.264+AAC, one command converts it in seconds.

ffmpeg -i input.mkv -c copy output.mp4

If it uses other codecs and the 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 an iPhone or Mac almost always contain H.264 or HEVC, so a stream copy often works.

ffmpeg -i input.mov -c copy output.mp4

If the file has HEVC (H.265) video and must play on more devices, re-encode:

ffmpeg -i input.mov -c:v libx264 -crf 22 -c:a aac output.mp4

AVI → MP4 (Converting from Legacy Format)

AVI files can contain many different codecs, so re-encoding is the safe choice.

ffmpeg -i input.avi -c:v libx264 -crf 23 -c:a aac output.mp4

MP4 → MKV (Container-Only Conversion)

MKV can hold almost any video and audio codec, so a stream copy usually works. The exception is a text subtitle in the MP4 (mov_text): FFmpeg cannot copy it into MKV, so add -c:s srt to convert it.

ffmpeg -i input.mp4 -c copy output.mkv

MP4 → WebM (For Web Delivery)

WebM uses VP8/VP9 video and Vorbis/Opus audio. It suits video that is played in web browsers.

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

If you give only the output file name, FFmpeg picks the default codecs for that container.

ffmpeg -i input.avi output.mp4

For MP4, the defaults are libx264 for video and aac for audio. This leaves the quality to the defaults, so set options such as -crf yourself.

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 (incorrect codec parameters ?) Error

The output container does not support one of the codecs. Replace -c copy with -c:v libx264 -c:a aac.

Encoder not found Error

Your FFmpeg build does not include that codec. Install a full build, for example from gyan.dev (Windows) or from your package manager.

WebM Conversion Is Extremely Slow

VP9 encoding is slow. Add -cpu-used 4 to make it faster.