The honest answer to why your MP4 won’t play is that the .mp4 on the end of the filename was never the problem. That extension describes the box the video came in. It tells you almost nothing about the thing inside the box — and the thing inside the box is what your player choked on.
This is the single most common misconception in all of digital media, and it survives because the naming convention actively encourages it. We say “an MP4” the way we’d say “a JPEG,” as though the file format and the compression were the same fact. They are not, they were never designed to be, and every confusing playback failure you have ever had traces back to that one collapsed distinction.

Get the distinction right and the whole subject stops being mysterious. You can diagnose a broken file in about four seconds with one command, you can tell instantly whether the fix takes one second or forty minutes, and you will never again try to fix a video by renaming it.
A Container Is a Box; a Codec Is the Compression Inside It
Two completely separate things are happening in any video file.
A container — also called a wrapper format — is a file structure that holds one or more encoded streams, plus timestamps, metadata, and usually a seek index so a player can jump to minute 45 without reading everything before it. MP4, MKV, WebM, MOV, and AVI are containers. A container says nothing whatsoever about how the video was compressed.
A codec (coder/decoder) is the compression scheme itself — the algorithm that turned an impossible pile of raw pixels into something that fits on a phone. H.264, HEVC (H.265), AV1, and VP9 are video codecs. AAC, Opus, MP3, and AC-3 are audio codecs.
You don’t have to take a blogger’s word for the split. The Matroska project states it about as plainly as a specification can, describing its own format as “an audiovisual data container format,” “an envelope in which there can be many audio, video, and subtitles streams,” and adding explicitly that “it is NOT a video or audio compression format (codec)” (Matroska Basics).
FFmpeg — the library set that does the actual decoding inside a startling proportion of the world’s media software — enforces the same split structurally. Containers are handled by libavformat (“demuxers and muxers for multimedia container formats”); compression is handled by libavcodec (“decoders and encoders for audio/video codecs”). They are two different libraries with two different jobs (ffmpeg.org — About FFmpeg). The architecture of the tool that plays your file already agrees with the distinction; only the filename doesn’t.

One quick disambiguation before we go further, because the word is overloaded: this is not the Docker sense of “container”, which packages software rather than media streams. Same word, unrelated idea. Media people were using it first, and neither camp is giving it up.
The reason any of this compression exists at all is worth one paragraph of arithmetic. One second of uncompressed 1920×1080 video at 4:2:0 chroma subsampling and 8 bits per sample runs about 3.1 MB per frame; at 30 frames per second that’s roughly 746 Mbit/s, or on the order of 336 GB for a single hour. Against that, YouTube’s published upload target for 1080p30 SDR is 8 Mbps (YouTube Help — Recommended upload encoding settings) — very roughly 90-to-1, for that specific resolution, frame rate, chroma format, and bitrate target, not as a universal constant. Video is not a format that happens to be compressed. It is a format that could not exist as a consumer medium without compression, which is why there are so many competing codecs, and why the one your device is missing is the one your file used. (If bitrate figures are a foreign language, the bandwidth explainer covers the units.)
What .mp4 Actually Tells You (Almost Nothing)
MP4 is the common name for a file conforming to the ISO Base Media File Format, standardized as ISO/IEC 14496-12 and published in February 2004. It was, per its own history, “directly based on Apple’s QuickTime container format” (ISO/IEC 14496-12 catalog entry); the first MP4 specification was built on the QuickTime format specification published in 2001. That single family tree has since been extended into MP4, 3GP, 3G2, .f4v, and even HEIF, the format your phone probably saves photos in.
So .mp4 tells you: this file is laid out as a sequence of ISO BMFF boxes, with tracks, a duration, and an index. That’s it. The bytes inside those tracks could be H.264 from 2003, HEVC from 2013, or AV1 from 2018, and the extension would be identical in all three cases.
You can watch this lineage surface in real output. When FFmpeg’s tools open your .mp4, the demuxer that handles it announces itself as mov,mp4,m4a,3gp,3g2,mj2 — one demuxer for the whole ISO BMFF family — with a long name of “QuickTime / MOV.” Your MP4 and a Mac screen recording’s .mov are close enough relatives that the same code reads both.

The Five Containers You’ll Actually Meet
| Container | Extensions | What it actually is | Commonly holds | Where you meet it |
|---|---|---|---|---|
| MP4 | .mp4, .m4v, .m4a | ISO Base Media File Format (ISO/IEC 14496-12, Feb 2004), derived from Apple’s QuickTime format | Video: H.264, HEVC, AV1, VP9. Audio: AAC, MP3, FLAC, Opus | Phones, cameras, every streaming service, every <video> element |
| MKV (Matroska) | .mkv, .mka | An open, deliberately unrestricted container — “an envelope in which there can be many audio, video, and subtitles streams” | Effectively anything, plus multiple audio tracks, chapters, font attachments, and both text and bitmap subtitles | Archives, film and anime releases, anything multi-track |
| WebM | .webm | Matroska with a deliberately restricted codec list | Video: VP8, VP9, AV1. Audio: Vorbis, Opus | The open web; browser-native playback |
| MOV | .mov | Apple’s QuickTime File Format — the ancestor ISO BMFF was derived from | H.264, HEVC, ProRes and other production codecs; AAC, uncompressed PCM | macOS and iOS screen recordings, cameras, editing timelines |
| AVI | .avi | A RIFF-based Microsoft format introduced 10 November 1992 with Video for Windows | Legacy codecs — MPEG-4 Part 2 (DivX/Xvid era), MJPEG, MP3, PCM | Old downloads, old camcorders, legacy archives |
WebM is the clearest proof that container and codec are independent, because it’s the one container that deliberately fuses them. The WebM Project describes its file structure as “based on the Matroska container,” restricted to “video streams compressed with the VP8 or VP9 video codecs and audio streams compressed with the Vorbis or Opus audio codecs” (About WebM). Everywhere else the two vary freely; WebM pins one to the other specifically to remove ambiguity. That restriction is a design choice, not a property of containers in general.
AVI is the interesting failure case at the other end, because it’s the container that genuinely does constrain what you can put in it. AVI “was not intended to contain video using any compression technique that requires access to future video frame data beyond the current frame (B-frame)” — and B-frames, which predict a picture from frames both before and after it, are fundamental to every modern codec. AVI also “does not provide a standardized way to encode aspect ratio information” (the later OpenDML/AVI 2.0 extension, from February 1996, does), and “AVI files cannot contain attachments such as fonts and subtitles. Consequently, subtitles must be distributed in a separate file or hardcoded into the video stream” (Wikipedia — Audio Video Interleave, an analyst source rather than a specification). If you have ever wondered why old AVI downloads came with a separate .srt file, that’s why.

MOV deserves a note too, because it’s the container most people produce without realizing it. Every macOS and iOS screen recording lands as a .mov, and screen recordings are one of the most common file types that plays perfectly on the machine that made it and mysteriously fails everywhere else. If you record your desktop regularly, the screencast guide covers the capture side; this article covers what to do when the resulting file won’t open on someone else’s computer.
Diagnosing It Properly: ffprobe on the File That Won’t Play
Guessing is unnecessary. ffprobe, one of the three command-line tools that ship with FFmpeg, exists specifically to “gather information from multimedia streams and print it in human- and machine-readable fashion” (ffprobe documentation). It does not decode anything or convert anything. It opens the file, reads the container’s structure, identifies each stream, and prints what it found. Everything below was checked against FFmpeg 8.1 “Hoare,” released 2026-03-16 (ffmpeg.org/download, checked 2026-08-14).
The short form takes no options at all:
ffprobe -hide_banner holiday-clip.mp4For a file exhibiting the classic failure — a perfectly valid container holding compression your player can’t handle — the output looks like this:
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'holiday-clip.mp4': Metadata: major_brand : mp42 minor_version : 512 compatible_brands: mp42iso2mp41 Duration: 00:24:07.83, start: 0.000000, bitrate: 4187 kb/s Stream #0:0[0x1](und): Video: hevc (Main 10) (hvc1 / 0x31637668), yuv420p10le(tv, bt2020nc/bt2020/smpte2084), 3840x2160, 3789 kb/s, 23.98 fps Stream #0:1[0x2](eng): Audio: ac3 (ac-3 / 0x332D6361), 48000 Hz, 5.1(side), fltp, 384 kb/sRead line by line, that output has already solved the case. Line 1: the container parsed cleanly — FFmpeg opened it, identified it as ISO BMFF, and read its structure without complaint. There is nothing wrong with the box. Duration is populated, so the index is intact. Then the two streams: the video is hevc, and the audio is ac3. Both are perfectly legitimate. Both are things a large number of players cannot decode.
For anything scripted, ask for JSON instead — that machine-readable output is why media pipelines shell out to ffprobe before trusting a file at all:
ffprobe -v error -show_streams -show_format -of json holiday-clip.mp4{ "streams": [ { "index": 0, "codec_name": "hevc", "codec_long_name": "H.265 / HEVC (High Efficiency Video Coding)", "profile": "Main 10", "codec_type": "video", "codec_tag_string": "hvc1", "codec_tag": "0x31637668", "width": 3840, "height": 2160, "pix_fmt": "yuv420p10le", "color_space": "bt2020nc", "color_transfer": "smpte2084", "r_frame_rate": "24000/1001", "bit_rate": "3789172" }, { "index": 1, "codec_name": "ac3", "codec_long_name": "ATSC A/52A (AC-3)", "codec_type": "audio", "codec_tag_string": "ac-3", "sample_fmt": "fltp", "sample_rate": "48000", "channels": 6, "channel_layout": "5.1(side)", "bit_rate": "384000" } ], "format": { "filename": "holiday-clip.mp4", "nb_streams": 2, "format_name": "mov,mp4,m4a,3gp,3g2,mj2", "format_long_name": "QuickTime / MOV", "duration": "1447.833000", "bit_rate": "4187193" }}
Three fields carry the whole diagnosis, and it’s worth knowing exactly which:
format_nameis the container. Here it’s the ISO BMFF family. This field is almost never the problem.codec_nameon each stream is the codec. Here:hevcfor video,ac3for audio. This field is almost always the problem.codec_typetells you whether a failing stream is video, audio, subtitle, or data — which is how you decide whether you’re fixing a black screen or silent sound.
Notice that ffprobe reports codec_name (hevc) and codec_tag_string (hvc1) as two separate fields. That isn’t redundancy. The codec name is what the compression actually is; the tag is the four-character label the container uses to announce that stream. They’re two different layers describing the same data, and a player can, in rare cases, understand the compression while rejecting the label. That is one of the genuinely container-level playback failures — and it’s rare enough that you should exhaust the codec explanation first.
Why Renaming the File Extension Never Works
The instinct is universal: the file won’t play, the extension looks wrong, so rename movie.mkv to movie.mp4 and try again. It never works, and understanding why makes the whole model click.
A file extension is a hint to your operating system about which application to launch. It is not stored inside the file, it is not read by the decoder, and changing it modifies exactly zero bytes of actual content. A Matroska file renamed to .mp4 is still a Matroska file, byte for byte. Real media software doesn’t trust the extension anyway — it opens the file, reads the leading bytes, and identifies the format from its actual structure. That’s why ffprobe correctly identified our example file regardless of what it was called.

Renaming can actively make things worse in two ways. First, it can turn a clear error into a confusing one: a program that would have said “I don’t support Matroska” now hands the bytes to an MP4 parser, which fails deeper in with something less helpful — a crash, a hang, or a garbled first frame. Second, it destroys your own diagnostic trail. Six months later that file’s name asserts something false about it, and the next person to open it starts from a wrong premise.
There is a real operation that does what renaming pretends to do — it’s called remuxing, and it’s covered below. It takes about a second and changes nothing but the box.
The Codec Support Reality: HEVC and AV1
Almost all of the “won’t play” pain in circulation right now comes from two codecs: HEVC (H.265) and AV1. Both are genuinely better at compression than H.264. Neither is anywhere near as universally decodable, and the reasons are as much legal and economic as technical.
Support figures move, so this table is explicitly a snapshot. All rows below were checked on 2026-08-14 against MDN’s web video codec guide and caniuse; re-check before relying on any of it, because these numbers change with browser releases and silicon generations.
| Video codec | Chrome | Edge | Firefox | Safari |
|---|---|---|---|---|
| H.264 / AVC | All versions | All versions | All versions (uses the operating system’s own decoder) | All versions |
| VP9 | All versions | All versions | All versions | All versions (no alpha transparency) |
| AV1 | 70+ | 121+ | 67+ | 17+, but only on devices with a hardware decoder — M3 and later Macs, iPhone 15 Pro, iPhone 16 and later |
| HEVC / H.265 | 107+, on devices with hardware support on Windows 8+, Linux and ChromeOS; all devices on macOS Big Sur 11+ and Android 5.0+ | On devices with hardware support, Windows 10 1709+, with the HEVC video extension from the Microsoft Store installed | 134+ on Windows (hardware, or a paid software extension), 136+ on macOS, 137+ on Linux and Android (hardware only) | 13+ on desktop, iOS 11+ |
Read the AV1 and HEVC rows carefully, because they say something more interesting than “mostly supported.” Support for both is frequently conditional on the device having a hardware decoder — a dedicated block of silicon that decodes that specific codec. Availability of that silicon, not compression efficiency, is usually the real gate on whether a codec spreads. A codec can be measurably better and still be commercially irrelevant for years because the chips in people’s pockets can’t decode it without melting the battery.

HEVC’s other problem is licensing, and it’s a big enough problem to have shaped the modern web. MDN’s own codec documentation flags HEVC as “Proprietary; confirm your compliance with the licensing requirements. Note that multiple patent pools may apply.” That plural is the whole story: multiple competing pools, plus patent holders affiliated with none of them, means a company shipping HEVC cannot easily compute what it owes or to whom. That uncomputable-cost problem, rather than any technical shortcoming, is the best available explanation for why the open web largely skipped HEVC. This is a licensing landscape, not legal advice — if you’re shipping a product, that’s a conversation for a lawyer, not a blog.
AV1 was designed by the Alliance for Open Media to sidestep exactly that. AOMedia’s position is that AV1 is royalty-free, and MDN records it as “Royalty-free, open standard.” That position is contested: Sisvel operates a rival patent pool claiming royalties on AV1, and there is live 2026 litigation involving AV1-related patent claims. Both positions exist, neither has been settled, and nobody honest declares a winner yet. Worth knowing before you standardize a workflow on it.
The one genuinely boring answer: H.264 in an MP4 container, with AAC audio, plays essentially everywhere. It compresses less efficiently than either of the above. It also never generates a support ticket. For anything you’re sending to a person whose device you don’t control, that trade is usually correct.
When the Video Plays but There’s No Sound
The audio side of this produces the most confusing symptom in the whole category, because it fails partially. The picture is fine. The timeline scrubs. There is simply no sound, and no error message explaining why, because from the player’s point of view nothing went wrong — it just had nothing to do with a stream it couldn’t decode.
Our example file is the textbook case. codec_name: "ac3" is Dolby Digital, the standard audio format for DVDs, Blu-ray, and broadcast television. It’s completely normal in a video file and completely absent from the web platform. MDN’s media container formats reference lists MP4’s browser-supported audio codecs as AAC, FLAC, MP3, and Opus — AC-3 does not appear. So a browser handed that MP4 will show you 4K video in perfect silence, and technically nothing has failed.

Opus is the mirror-image trap, and it catches more technical users. Opus is an excellent modern audio codec, and it can live in MP4 — there is a published specification for exactly that, “Encapsulation of Opus in ISO Base Media File Format” (opus-codec.org), version 0.6.8, last updated 28 April 2016, and still marked incomplete. MDN lists Opus among the audio codecs browsers support inside MP4. But Opus grew up in WebM and Ogg, and plenty of hardware players, older TVs, and editing tools that read MP4 perfectly well have simply never implemented Opus in that container. A specification existing and every device implementing it are separate facts, and the gap between them is exactly where silent playback lives.
The useful consequence: audio-only failures are the cheapest possible fix. You do not need to touch the video. Re-encoding just the audio track takes seconds even on a large file, because the expensive part of the pipeline — decoding and re-encoding video — never runs.
The Fix: Remux When You Can, Transcode Only When You Must
This is the takeaway worth keeping even if you forget everything else in this article.
FFmpeg’s processing model has five stages: demux → decode → filter → encode → mux. Demuxers pull elementary streams out of a container; decoders turn compressed packets into raw frames; filters transform raw frames; encoders compress frames back into packets; muxers write packets into an output container (ffmpeg documentation). Two named data types cross those boundaries: compressed packets and raw frames. They never blur together.
That separation is what makes the cheap fix possible. When you pass -c copy, the documentation is precise about what happens: “the stream is not to be re-encoded.” Decode, filter, and encode are skipped entirely. Compressed packets travel from the demuxer straight to the muxer, unopened. Same bits, new box.
Remux (-c copy) | Transcode (re-encode) | |
|---|---|---|
| What changes | The container only | The compressed data itself |
| Pipeline stages used | demux → mux | demux → decode → filter → encode → mux |
| Quality cost | None. The video bits are bit-identical | Lossy, every time. Repeat it and generation loss compounds |
| Speed | Bounded by disk I/O — seconds on a multi-gigabyte file | Bounded by CPU or GPU — minutes to hours |
| Fixes | A container the player can’t read | A codec the player can’t decode |
| Cannot fix | A codec the player can’t decode | — (but you pay for it in time and quality) |
| Typical command | ffmpeg -i in.mkv -c copy out.mp4 | ffmpeg -i in.mp4 -c:v libx264 -crf 20 -preset slow -c:a aac -b:a 192k out.mp4 |

So the decision is a single question: is the codec supported, or isn’t it?
If the codec is fine and only the container is wrong — H.264 inside an MKV that Safari won’t open, say — remux:
ffmpeg -i movie.mkv -c copy movie.mp4That finishes in about the time it takes to read and write the file. Nothing is re-compressed. Two caveats: the target container has to be able to hold those streams (you cannot remux HEVC into AVI, for the B-frame reason above), and subtitle formats often don’t survive the trip, since MKV’s text and bitmap subtitle types have no direct MP4 equivalent.
If only the audio is unsupported, transcode the audio and copy the video:
ffmpeg -i movie.mp4 -c:v copy -c:a aac -b:a 192k movie-fixed.mp4This is the highest-value command in the article. The video — the expensive 95% of the file — is passed through untouched and unharmed. Only the small audio stream is rebuilt. On a 4K film this typically completes in well under a minute.
If the video codec genuinely isn’t supported, you have to re-encode, and it will cost you both time and a measure of quality:
ffmpeg -i movie.mp4 -c:v libx264 -crf 20 -preset slow \ -c:a aac -b:a 192k -movflags +faststart movie-h264.mp4A few notes on that command. libx264 is an encoder implementing the H.264 standard — the two are not synonyms, and the same distinction holds for x265/HEVC and SVT-AV1/AV1. -crf 20 sets the quality target; CRF values are an internal scale and do not transfer between encoders, so a CRF of 20 in x264 does not mean what a CRF of 20 means in x265. -preset slow trades encoding time for compression efficiency — at the same CRF, a slower preset produces a smaller file at equivalent quality, not a better-looking one. And -movflags +faststart runs a second pass moving the MP4 index to the front of the file, which is what stops a web-hosted video from stalling before it starts.
One more honest note before the summary table: if a file plays but stutters, that is not a support problem at all — the decoder works, it just can’t keep up, usually because it’s decoding 4K HEVC or AV1 in software with no hardware assist. That’s a performance question, and the fix is a lower resolution or a codec the machine decodes in hardware, not a remux.
Symptom → Diagnosis → Fix
| Symptom | What ffprobe shows | What it actually is | The fix |
|---|---|---|---|
| Won’t open at all; “unsupported format” or a black frame | codec_name is hevc, av1, or vp9 on the video stream | Codec problem | Transcode to H.264, or use a player that carries its own decoders (VLC, mpv) |
| Video plays, no sound | codec_name is ac3, eac3, dts, or opus on the audio stream | Codec problem, audio side only | -c:v copy -c:a aac -b:a 192k — seconds, video untouched |
| Plays in VLC but not in a browser, TV, or editor | Ordinary codecs inside matroska,webm | Container problem — the genuinely rare one | Remux: ffmpeg -i in.mkv -c copy out.mp4 |
| Long pause before a web-hosted file starts | Container parses fine, index sits at the end | Container layout problem | Remux with -movflags +faststart |
| Plays but stutters or drops frames | High-resolution HEVC or AV1, no hardware decoder present | Performance, not support | Lower the resolution/bitrate, or move to a hardware-decoded codec |
Renaming .mkv to .mp4 made things worse | format_name still reads matroska,webm | Self-inflicted | Rename it back, then remux properly |
| Audio only, no picture | nb_streams is 1, or no stream has codec_type: "video" | Depends — the file may genuinely have no video | ffprobe has already told you which |

Why VLC Plays Everything
The reason one particular player seems immune to all of this is worth being precise about, because it’s usually explained wrongly.
VLC ships its own decoders. Specifically, it links libavcodec — the FFmpeg library that holds decoders and encoders for an enormous range of codecs — while using mainly its own muxers and demuxers for container handling. That is not the same as being “a GUI for FFmpeg,” and the distinction matters: FFmpeg is a set of libraries that many programs link, and the ffmpeg command is just one tool built on those same libraries.

Browsers make the contrast sharp. Chromium, the open-source project behind Chrome, Edge, Brave, and others, carries its own fork of FFmpeg — its README.chromium states plainly that “Chromium’s copy of FFmpeg is a fork of the upstream git repository,” maintained with Chromium-specific patches. Yet browsers still refuse codecs that VLC plays without complaint, because a browser’s codec list is constrained by patent licensing, security posture, and platform policy — not by whether the decoding code exists. VLC, a desktop application from a nonprofit, sits under very different constraints than a browser shipping to billions of devices.
So “just use VLC” is genuinely good advice for watching a file once. It is not a fix, because it doesn’t change the file, and the next device — a TV, a phone, a video editor, someone else’s browser — will fail on it exactly as before.
Further Reading
- ffprobe documentation — every option behind the diagnosis above:
-show_streams,-show_format,-show_chapters, and thejson/xml/csv/flatoutput writers. - ffmpeg documentation — the demux → decode → filter → encode → mux pipeline,
-c copysemantics, stream selection, and-map. - Matroska Basics and About WebM — the container/codec split stated by the specifications themselves.
- MDN — Media container formats and MDN — Web video codec guide — the maintained reference for which codec plays in which browser, with the licensing notes.
- Digital Video Introduction — Leandro Moreira’s free, extensively illustrated guide to how video compression actually works, and the best next step if this article left you curious rather than satisfied.
❓ Frequently Asked Questions
Why won’t my MP4 play on my TV but plays fine on my laptop?
Because your laptop has a decoder your TV doesn’t. Run ffprobe on the file and look at codec_name for the video stream — if it says hevc or av1, that’s the answer. TVs decode in fixed-function hardware, so their codec list is frozen at manufacture and will never grow. Laptops decode in software when hardware support is missing, which is slower but far more permissive. Transcode to H.264 if the file needs to work on the TV.
Does renaming .mkv to .mp4 convert the file?
No. It changes nothing inside the file at all. An extension is a hint to your operating system about which program to open; media software identifies formats by reading the file’s actual structure, not its name. What you want is a remux: ffmpeg -i movie.mkv -c copy movie.mp4. That genuinely rewrites the container while leaving the compressed video and audio bit-for-bit identical, and it usually takes seconds.
Is MKV better than MP4?
They’re built for different jobs. MKV holds essentially any codec plus unlimited audio tracks, chapters, font attachments, and both text and bitmap subtitles — which makes it excellent for archiving. MP4 holds a narrower set but is the format phones, browsers, TVs, and editors all read without argument. Archive in MKV; distribute in MP4. Neither choice affects picture quality, because the container isn’t what compresses the video.
Will remuxing lose quality?
No — that’s the entire point of it. -c copy skips the decode and encode stages completely, so the compressed video and audio packets are copied unchanged from one container to the other. The output is bit-identical to the input on the stream level. Transcoding is the operation that costs quality, and it costs it every single time you do it, which is why repeatedly re-encoding the same file visibly degrades it.
Which codec should I use if I just need it to play everywhere?
H.264 video with AAC audio, in an MP4 container. It compresses less efficiently than HEVC or AV1, so the file is bigger at the same quality, but it plays on effectively every browser, phone, TV, console, and editor in circulation. When you control the playback device, newer codecs are worth it. When you’re emailing a file to someone whose setup you can’t see, they aren’t.
How do I tell whether my problem is the video or the audio?
ffprobe -v error -show_streams -of json yourfile.mp4 and read codec_type on each stream. If the black-screen failure is total, look at the video entry’s codec_name. If the picture is fine but there’s no sound, look at the audio entry. That distinction determines the cost of the fix: an audio-only problem is repaired in seconds with -c:v copy, while a video codec problem means a full re-encode.
📚 Recommended Resources
Disclosure: some links below are Amazon affiliate links. If you buy through them, I earn a small commission — at no extra cost to you — which helps keep this site running.
Start with the free tier. This is one of the few subjects where the best material costs nothing and is more current than most of the printed shelf. Read these before you buy anything:
- Digital Video Introduction — Leandro Moreira’s free, heavily illustrated walk through frames, redundancy, motion compensation, and what a codec is actually doing to your pixels. It is the single best answer to “why does the compression matter more than the file extension,” it treats AV1 as a first-class citizen, and it is translated into several languages. Free, and the correct next step after this article.
- ffprobe and ffmpeg documentation — regenerated from the source tree, so they describe the version you actually have rather than the version someone blogged about in 2019. Every flag in this article is documented there in full, including the output writers (
json,xml,csv,flat) and the exact semantics of-c copy. - MDN’s media container formats and web video codec guide — the maintained reference for which codec plays in which browser, complete with the licensing notes. If you only bookmark one page from this whole article, make it one of these two.
- The specifications themselves — Matroska Basics, About WebM, and the AOMedia AV1 spec are free to read and unambiguous about the container/codec split. No AV1 or VVC book worth recommending exists yet; the spec is the literature.
The books below are for the layer underneath — the compression theory, the codec standards, and the color science that the free guides summarize rather than derive. Buy one only if you want the deeper version.
Coding Video: A Practical Guide to HEVC and Beyond
Iain E. Richardson · Wiley, 1st ed., Sept 30 2024 · Hardcover, 448 pp
HEVC is the codec behind most of the “won’t play” failures in this article, and Richardson is the standard author on it. This is the current, HEVC-centric title in his catalogue — the one to read if you want to know what hevc (Main 10) in that ffprobe output is actually doing to your frames, rather than just that your TV can’t decode it. One honest caveat: despite the “and Beyond” in the title, the book’s own description makes no substantive AV1 or VVC claim, so don’t buy it expecting coverage of either.
The H.264 Advanced Video Compression Standard (2nd ed.)
Iain E. Richardson · Wiley, Aug 16 2010 · Hardcover, 352 pp
H.264 is the boring, correct answer whenever a file has to play on a device you don’t control, and this is the book-length treatment of the standard behind that answer. Useful precisely because H.264 has stopped changing: a 2010 text on a 2003 standard is still accurate in a way no book about AV1 could be. Note that Richardson’s earlier H.264 and MPEG-4 Video Compression (2003, ASIN 0470848375) is the superseded first-generation text — Amazon’s own listing points at this 2nd edition instead. Default here unless you specifically want the 2003 book.
Introduction to Data Compression (5th ed.)
Khalid Sayood · Morgan Kaufmann, Nov 6 2017 · Paperback, 790 pp
The article’s raw-video arithmetic — roughly 746 Mbit/s for uncompressed 1080p30, about 336 GB an hour — is the reason every one of these codecs exists. This is the general theory behind why that number can be cut by two orders of magnitude at all: entropy coding, quantization, transform coding, and the precise point where “lossless” ends and “lossy” begins. It is compression theory rather than a video book, so pair it with one of the Richardson titles above rather than treating it as a substitute.
Digital Video and HD: Algorithms and Interfaces (2nd ed.)
Charles Poynton · Morgan Kaufmann, Feb 2012 · Hardcover, 752 pp
The reference for the other half of that ffprobe output — yuv420p10le, bt2020nc, smpte2084. Those fields are color space, transfer function, and bit depth, and they are the reason a file can decode perfectly and still look wrong: washed out, too dark, or oddly saturated on a different display. Poynton is the standard text on chroma subsampling, gamma, and color encoding. Be clear about what it is not: roughly one part in six covers compression, and it has no HEVC or AV1 content at all.
Video Demystified: A Handbook for the Digital Engineer (5th ed.)
Keith Jack · Newnes, May 14 2007 · Paperback, 944 pp
A broad hardware-side handbook covering video signals, interfaces, and formats end to end — the perspective of an engineer building the device rather than debugging a file on one. Worth knowing that it predates HEVC and AV1 entirely, so treat it as reference material on the signal and interface layer, not as a guide to any modern codec.
One more free resource with no Amazon listing at all: Werner Robitza’s CRF guide, and FFmpeg’s own ffmpeg-all manual, together explain the -crf and -preset values in the transcode command above far more precisely than any book in print. If the transcoding section is where you want to go deeper, start there rather than with a purchase.