Very Good FFmpeg
How it worksPricingDocsBlog

Published Jun 10, 2026

FFmpeg Formats Documentation: MP4, Matroska (MKV), WebM, and MOV Explained

How to convert between video containers with FFmpeg, lose zero quality with stream copy, and when to re-encode

What is a video container format?

A video container is a file format that holds video streams, audio streams, subtitles, metadata, and chapter information inside a single file. Think of it as a zip file for media: the container bundles everything together, while the codec determines how the video and audio data is actually compressed.

FFmpeg supports over 100 container formats through its libavformat library. The four most common ones developers encounter are MP4, Matroska (MKV), WebM, and MOV. Each has different strengths, codec support, and compatibility characteristics.

TL;DR: Key Takeaways

  • Containers are not codecs. MP4, MKV, WebM, and MOV are wrappers. H.264, AAC, VP9, and Opus are the compression formats inside them. You cannot just change the file extension and expect it to work.
  • Stream copy (-c copy) is fast and lossless but only works when the target container supports your source codecs. If it fails, you need to re-encode the incompatible streams.
  • Re-encoding is slow and causes generation loss. Every re-encode degrades quality slightly. Only re-encode when stream copy is impossible.
  • MP4 is the most compatible format but restricts which codecs you can use. H.264 + AAC in MP4 plays everywhere.
  • MKV accepts almost any codec but has less universal device support outside VLC, mpv, and modern browsers.
  • WebM is royalty-free with 96.11% browser support (caniuse, May 2026) but only allows VP8/VP9/AV1 video and Vorbis/Opus audio. No H.264.
  • MOV shares MP4's ISO base structure but adds ProRes, Animation, and DNxHD support used in professional video production.

What is the difference between a container and a codec?

This is the most common point of confusion. The container is the file wrapper (the .mp4 or .mkv extension). The codec is the compression algorithm used on the video or audio data inside (H.264, AAC, VP9, Opus, FLAC, and so on).

A single container can hold many different codec types. An MP4 file might contain H.264 video with AAC audio, or H.265 video with Opus audio. The container format defines which codecs are allowed inside it. This is why you cannot always just change the file extension and expect it to work.

The consequence of mixing up containers and codecs is visible in one common Stack Overflow scenario: a user converted an MP4 file to MKV and noticed the file size dropped by 15%. They assumed MKV was somehow more efficient. In reality, running ffmpeg -i input.mp4 output.mkv without -c copy caused FFmpeg to re-encode both video and audio, introducing generation loss. The correct command is ffmpeg -i input.mp4 -c copy output.mkv, which copies the streams without any quality change (Stack Overflow, 65525078).

Why can't I just stream copy everything?

Each container format defines a list of acceptable codecs. When you attempt a stream copy to a container that does not support the source codec, FFmpeg returns an error like "codec not supported in container."

MP4 is the most restrictive mainstream container. MKV is the most permissive. WebM is deliberately restricted for royalty-free web delivery. MOV is similar to MP4 but adds Apple ProRes and animation codecs.

Common container codec compatibility:

CodecMP4MKVWebMMOV
H.264/AVCYesYesNoYes
H.265/HEVCYesYesNoYes
VP9NoYesYesNo
AV1YesYesYesNo
ProResNoYesNoYes
AACYesYesNoYes
OpusYes (experimental)YesYesNo
FLACYesYesNoNo
DTSNoYesNoNo
PGS subtitlesNoYesNoNo

When should you use stream copy instead of re-encoding?

Stream copy (-c copy) copies the raw compressed data without decoding or encoding. It is extremely fast and produces zero quality loss. Re-encoding decodes then recompresses, which is computationally expensive and degrades quality.

ScenarioStream copyRe-encode
MOV to MP4, same codecsUse thisOnly if needed
MKV to MP4, H.264+AACUse thisOnly if needed
MKV to MP4, VP9+OpusFailsRequired
WebM to MP4ImpossibleRequired
Adding filters or scalingImpossibleRequired
Reducing file sizeImpossibleUse CRF + preset

The rule is simple: try -c copy first. If FFmpeg errors, identify the incompatible streams and re-encode only those.

When should you use MP4?

MP4 (formally MPEG-4 Part 14) is the most widely supported video container format. It is based on the ISO Base Media File Format (ISO/IEC 14496-12), which was itself derived from Apple's QuickTime File Format. MP4 is patent-encumbered but universally supported across browsers, devices, TVs, and streaming platforms.

Supported codecs in MP4:

  • Video: H.264/AVC, H.265/HEVC, AV1, MPEG-4 Visual
  • Audio: AAC, MP3, AC-3, FLAC, Opus (recently added), ALAC
  • Subtitles: MPEG-4 Timed Text (tx3g)

The moov atom problem: MP4 files store critical metadata (resolution, frame rate, orientation) in a section called the moov atom. By default, FFmpeg writes the moov atom at the end of the file. This means playback cannot start until the entire file is downloaded. The fix is -movflags faststart, which moves the moov atom to the beginning. Without faststart, truncated or partially-downloaded MP4 files become unplayable.

Very Good FFmpeg handles moov atom placement automatically when serving MP4 output, so you never deal with corrupted progressive downloads.

Use MP4 when you need widest compatibility: uploading to social media, sending to clients, serving video on a website, or playing on a TV or game console.

What makes Matroska (MKV) the most flexible container?

Matroska is an open-standard container format based on EBML (a binary XML format). It was announced in December 2002 as a fork of the Multimedia Container Format. In October 2024, Matroska was published as RFC 9559, formalising it as an internet standard. It is royalty-free and licensed under LGPL/BSD.

What makes Matroska special:

  • Unlimited video, audio, picture, or subtitle tracks in a single file
  • Support for virtually any codec: H.264, H.265, VP8, VP9, AV1, MPEG-2, MPEG-4 Visual, Theora, ProRes, DNxHD, AAC, MP3, AC-3, DTS, TrueHD, FLAC, Opus, Vorbis, WMA, PGS subtitles, ASS/SSA subtitles
  • Chapters, attachments (fonts for subtitles), variable frame rate, variable bitrate
  • Extensions: .mkv (video), .mk3d (stereoscopic 3D), .mka (audio only), .mks (subtitles only)

Matroska is the format of choice for archiving and high-quality video because there are no meaningful codec restrictions. If FFmpeg can decode it, Matroska can hold it. Native support is available in Windows 10+, VLC, mpv, Chrome, Firefox, and OBS Studio.

Very Good FFmpeg accepts MKV inputs and automatically detects which streams can be stream-copied versus which need re-encoding when converting to other containers.

Use MKV when archiving video, storing multiple audio tracks (director commentary, alternate languages), or keeping subtitle files embedded.

Is WebM good enough for production video?

WebM is a restricted subset of Matroska, announced by Google in 2010 specifically for royalty-free HTML5 video. The container is identical to Matroska at the structural level, but the codec set is deliberately limited.

WebM codec restrictions:

  • Video: VP8, VP9, or AV1 only
  • Audio: Vorbis or Opus only

The tradeoff for royalty-free licensing is narrow codec support. You cannot put H.264 or AAC inside a WebM file. This makes WebM excellent for web delivery but impractical for professional production workflows.

Browser support: WebM has 96.11% global browser support as of May 2026 (caniuse). Native support in Chrome since v25, Firefox since v28, Opera since v16, Safari since v14.1 (full support from iOS 17.4), and Edge since v79. PlayStation 5 captures gameplay footage in WebM. The FSF has endorsed WebM as a free format.

Very Good FFmpeg can serve WebM output from any input format, handling the required VP9 or AV1 re-encode automatically.

Use WebM when you need royalty-free video delivery on the web and your target audience uses modern browsers.

When is MOV still the right format?

MOV is Apple's proprietary container format. It shares the same underlying ISO Base Media File Format structure as MP4, which means direct stream copy between MOV and MP4 is often possible.

What MOV adds over MP4:

  • ProRes, Animation, and DNxHD codec support
  • Chapter markers and edit lists
  • Timecode tracks for professional editing workflows

MOV is the standard format in Apple ecosystem production pipelines. Most video editing software exports to MOV with ProRes as the intermediate codec. If you receive video files from a Final Cut Pro or DaVinci Resolve workflow, they will almost certainly be MOV files.

Very Good FFmpeg handles MOV inputs with automatic stream copy detection, flagging incompatible streams like PCM audio or ProRes video when converting to MP4.

Use MOV when working in Apple ecosystem production, editing in Final Cut Pro or DaVinci Resolve, or exchanging ProRes or DNxHD files in a post-production pipeline.

How do I convert MOV to MP4 with FFmpeg?

MOV and MP4 share the same underlying file structure, so this is the easiest conversion. When both files contain H.264 video and AAC audio, stream copy works perfectly:

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

This command copies all streams without re-encoding. The conversion takes seconds regardless of file size because no decoding or encoding happens.

When stream copy fails for MOV to MP4:

  • If the MOV contains Apple ProRes video (not supported in MP4)
  • If the MOV contains PCM audio (needs re-encoding to AAC)
  • QuickTime edit lists may not translate correctly

In these cases, re-encode the incompatible stream:

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

How do I convert MKV to MP4 with FFmpeg?

MKV to MP4 is the most common conversion request, and also the most likely to fail with stream copy. The reason is codec compatibility.

When stream copy works (MKV to MP4):

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

This works when all streams use codecs that MP4 supports: H.264/H.265/AV1 video, AAC/MP3 audio, and no complex subtitles.

When stream copy fails:

  • VP9 or AV1 video in the MKV (not supported in MP4)
  • DTS, TrueHD, FLAC, Vorbis, or Opus audio (not supported in MP4)
  • PGS or ASS/SSA subtitles (not supported in MP4)

One common pitfall: a user on Stack Overflow (91k views) ran ffmpeg -i input.mkv -vcodec copy output.mp4 and was confused why FFmpeg re-encoded their audio. The -vcodec copy flag only copies video. FFmpeg still selects an audio encoder if not told to copy audio. The fix is to use -c copy which copies all stream types, or explicitly specify both -vcodec copy -acodec copy (Stack Overflow, 40077681).

Another frequent error: MKV files with Opus audio will fail when stream-copying to MP4 with the message "opus in MP4 support is experimental, add '-strict -2' if you want to use it." The recommended fix is to re-encode Opus to AAC rather than using experimental support:

plaintext
ffmpeg -i input.mkv -c:v copy -c:a aac output.mp4

This keeps the video lossless (stream copy) and only re-encodes the audio (Stack Overflow, 63664953).

FFmpeg will error out with a message like "codec not supported in container" when codecs are incompatible. The solution is to re-encode the incompatible streams while stream-copying the compatible ones:

plaintext
ffmpeg -i input.mkv -c:v libx264 -c:a aac -sn output.mp4

The -sn flag drops subtitles entirely. You can also convert subtitles to MP4-compatible timed text with -c:s mov_text.

How do I convert WebM to MP4 with FFmpeg?

WebM always requires re-encoding to convert to MP4. VP8, VP9, and AV1 are not supported in the MP4 container, so stream copy is not possible.

plaintext
ffmpeg -i input.webm -c:v libx264 -c:a aac output.mp4
WebM codecMP4 targetNotes
VP8 videoH.264 (libx264)Good quality, slower encode
VP9 videoH.265 (libx265) or H.264H.265 gives smaller files
AV1 videoH.265 or H.264AV1 to H.264 is a heavy encode
Vorbis audioAACStandard web audio conversion
Opus audioAACOpus to AAC, minor quality shift

How do I convert MP4 to MKV or MOV?

These are reverse directions and almost always work with stream copy because MKV and MOV accept virtually any codec that MP4 does:

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

What is the moov atom and why does it matter?

The moov atom is a metadata section in MP4 files that contains the seek index, track information, and sample tables. Without it, a media player cannot start playback.

By default, FFmpeg places the moov atom at the end of the MP4 file. This is fine for local files but causes problems for web delivery: the browser must download the entire file before starting playback.

Fix with faststart:

plaintext
ffmpeg -i input.mp4 -c copy -movflags faststart output.mp4

The -movflags faststart option moves the moov atom to the beginning of the file. This enables progressive download and streaming playback. Always use faststart for MP4 files served over the web.

What container format should I use for web video?

For broad browser compatibility, MP4 with H.264 video and AAC audio is the safest choice. Every browser, device, and platform supports it.

For royalty-free web delivery, use WebM with VP9 or AV1 video and Opus audio. WebM support is now universal across modern browsers.

Browser container support:

BrowserMP4WebMMKV
ChromeYesYesPartial
FirefoxYesYesPartial
SafariYesYes (14.1+)No
EdgeYesYesPartial

Can I run FFmpeg format conversions without installing FFmpeg?

Yes. Very Good FFmpeg is a hosted REST API that runs your exact FFmpeg commands on cloud infrastructure. You send the file URL and FFmpeg command, and it returns the output.

Instead of installing FFmpeg locally and running:

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

You send the same command to the API:

plaintext
curl -X POST https://verygoodffmpeg.com/api/ffmpeg \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input_files": {
      "input.mov": "https://your-bucket.s3.amazonaws.com/input.mov"
    },
    "output_files": ["output.mp4"],
    "ffmpeg_commands": ["-i {{input.mov}} -c copy {{output.mp4}}"]
  }'

The API handles format conversion the same way local FFmpeg does. It supports all the same flags, codecs, and filter graphs. This is useful when you need to run conversions at scale, in serverless functions that cannot install FFmpeg, or in CI/CD pipelines.

Very Good FFmpeg gives you 16 dedicated CPU cores, up to 6-hour job runtimes, and Nvidia GPU support for accelerated encoding. You pay per GB processed with volume discounts that kick in automatically.

Verdict: which container should you use for what?

Use caseRecommended containerReason
Widest device compatibilityMP4 (H.264 + AAC)Supported on every browser, TV, phone, and console
Archiving and backupsMKVNo codec restrictions, chapters, attachments, multiple tracks
Web video (royalty-free)WebM (VP9 + Opus)96.11% browser support, no patent fees
Apple/ProRes production pipelineMOVProfessional codec support, edit lists, timecode
No CLI or no serverVery Good FFmpeg APISingle curl for any container conversion

The choice comes down to your audience. If you need the broadest possible playback, MP4 is the answer. If you are preserving source material, MKV gives you maximum flexibility. If you are building a web-first application and want to avoid patent licensing, WebM covers 96% of browsers. And if you are in post-production, MOV is the standard for a reason.

For teams that need to handle all four containers without installing FFmpeg on every machine, Very Good FFmpeg provides a single API endpoint that accepts any input format, detects codecs automatically, and produces the correct output format with appropriate stream copy or re-encoding.

FAQ

How do I check which streams are in a video file?

Use ffprobe: ffprobe input.mkv. It shows every video, audio, and subtitle stream with codec information.

I converted MP4 to MKV and the file got smaller. Did MKV compress it?

No. You accidentally re-encoded. Run ffmpeg -i input.mp4 -c copy output.mkv to preserve quality (Stack Overflow, 65525078).

I used -vcodec copy but FFmpeg is still encoding my audio. Why?

You specified video copy only. Use -c copy to copy all streams, or add -acodec copy to copy audio separately (Stack Overflow, 40077681).

Why do I get "opus in MP4 support is experimental" when converting MKV to MP4?

Opus audio in MP4 was experimental in older FFmpeg releases. Upgrade to FFmpeg 4.3+ or re-encode the audio to AAC: ffmpeg -i input.mkv -c:v copy -c:a aac output.mp4 (Stack Overflow, 63664953).

Can I convert AVI to MP4 with FFmpeg?

Yes. ffmpeg -i input.avi -c copy output.mp4 works if the codecs are compatible. Otherwise re-encode with -c:v libx264 -c:a aac.

Why does my MP4 file not play in a browser?

The moov atom is likely at the end of the file. Re-encode with -movflags faststart to move it to the beginning.

Does converting between containers reduce quality?

Stream copy (-c copy) preserves quality perfectly because no re-encoding happens. Re-encoding always reduces quality to some degree, which you control with the CRF value.

What is the best container for archiving video?

Matroska (MKV) is the best choice for archiving. It supports all codecs, attachments, chapters, and has no patent restrictions.

Can MKV contain H.264 and AAC?

Yes. MKV supports H.264 and AAC natively. You can stream copy an MP4 file with these codecs directly into MKV.

Why does FFmpeg say "codec not supported in container"?

The source codec is not in the target container's allow list. Use ffprobe to check what codecs are in the file, then re-encode incompatible streams.

Can I stream copy MKV with VP9 video to MP4?

No. MP4 does not support VP9. You must re-encode to H.264 or H.265.

What is the difference between MP4 and M4A?

M4A is MP4 with audio-only content. The extension tells media players that the file contains only audio. The underlying format is identical.

Does Very Good FFmpeg handle all these conversions?

Yes. Submit your file, pick target format, and VGF handles codec detection, stream copy, or re-encode automatically.

References

  • FFmpeg formats documentation
  • FFmpeg stream copy documentation
  • Wikipedia: Comparison of video container formats
  • Wikipedia: Matroska
  • Matroska RFC 9559
  • Wikipedia: WebM
  • Wikipedia: MPEG-4 Part 14
  • Super User: Convert MOV to MP4 without re-encoding
  • Stack Overflow: MKV to MP4 without losing quality
  • Stack Overflow: Opus in MP4 experimental error
  • Stack Overflow: Missing audio codec spec during MKV to MP4 conversion
  • Stack Overflow: Generation loss when converting MP4 to MKV
  • Stack Overflow: MKV to H.264 re-encode
  • caniuse: WebM browser support
  • Very Good FFmpeg

Related reading

  • Jun 10, 2026

    Hosted FFmpeg REST API: 2026 Pricing and Comparison Guide

    Compare the top hosted FFmpeg REST APIs for video transcoding in 2026. Transparent pricing, hidden costs, and use-case recommendations across Mux, Bitmovin, AWS, Coconut, Rendi, FetchMedia, and Very Good FFmpeg.

  • Jun 10, 2026

    FFmpeg Extract Audio From Video: Command for WAV, MP3, AAC With Codec, Channel, and Sample Rate Control

    Extract audio from video with ffmpeg using exact commands for wav mono 16khz, high-quality mp3, and aac stream copy. Covers -ac, -ar, -acodec flags and scaling with a hosted FFmpeg API.

  • Jun 10, 2026

    FFmpeg documentation: thumbnail filter, select filter, and frame extraction commands

    How to extract thumbnails from video with FFmpeg using -ss, thumbnail filter, select filter, fps filter, and contact sheets

  • Jun 10, 2026

    api.video Pricing, Video API Transcoding Docs 2026

    Compare api.video pricing for video API transcoding, docs, and how a full-stack video platform differs from a hosted FFmpeg API like Very Good FFmpeg.

Very Good FFmpegChecking status...
Product
  • How it works
  • Pricing
  • Comparison
  • FAQ
  • Blog
Developers
  • Documentation
  • API Reference
  • MCP Server
  • TypeScript SDK
  • Python SDK
Company
  • Contact
  • Sign in
  • Sign up
  • Terms
  • Privacy
As Seen On
  • G2
  • Product Hunt
  • GitHub
  • PyPI
  • NPM
  • Smithery
  • MCP.so
  • AlternativeTo
  • Make
© 2026 Very Good FFmpeg