Why Your Video Won't Play — Containers vs Codecs Explained

You have two files. Both end in .mp4, both are about the same size, both came from the same camera. One plays everywhere and the other refuses to open. The extension is telling you almost nothing useful — and once you understand why, video playback problems become straightforward to diagnose.

The distinction

The container is the box: MP4, MKV, MOV, WebM. The codec is what is inside it: H.264, H.265, AV1, VP9. The file extension names only the box. A player must support both, and it is nearly always the codec that fails.

What is actually in a video file

A video file is a container holding several independent streams, each compressed with its own codec, plus an index telling the player where everything is.

example.mp4 ← the container ├── Video stream — H.264, 1920×1080, 30fps ├── Audio stream — AAC, stereo, 128kbps ├── Audio stream — AC-3, 5.1 surround ← optional second track ├── Subtitle stream — SRT, English └── Metadata — title, chapters, timing index

The player decodes each stream separately. That independence is why a file can play with no sound: the video decoder found a codec it knows and the audio decoder did not.

ContainerExtensionTypical contentsBrowser support
MP4.mp4 .m4vH.264/H.265/AV1 + AACUniversal
WebM.webmVP8/VP9/AV1 + Opus/VorbisAll modern browsers
Matroska.mkvAnything at allNone
QuickTime.movH.264, ProResPartial
AVI.aviLegacy codecsNone
MPEG-TS.tsH.264 + AAC/AC-3Via HLS only

Matroska deserves a note because it is genuinely the best-designed container here — it supports any codec, unlimited tracks, chapters and rich subtitles. It is also supported by no browser at all, which is why it dominates archiving and appears nowhere on the web.

Video codecs and where they work

CodecAlso calledEfficiencySupport
H.264AVC, MPEG-4 Part 10BaselineEverywhere — the safe choice
H.265HEVC~50% betterApple yes; Chrome/Firefox limited
VP9~50% betterAll browsers; not all hardware
AV1~30% better than VP9All modern browsers; newer hardware
MPEG-2PoorDVD and broadcast only
ProResEditing codec, huge filesEditing software only

💡 Why H.265 is missing from browsers

H.265 is technically excellent and encumbered by patents held across several competing pools, with royalties owed per device and sometimes per stream. That is unworkable for a browser distributed free to billions of users, and the licensing situation was messy enough that even paying was legally uncertain.

The industry's answer was to build AV1 — developed by an alliance including Google, Amazon, Netflix, Microsoft and Mozilla, explicitly royalty-free. It now has comparable efficiency and universal browser support. H.265 remains dominant in Apple's ecosystem and in broadcast, and is largely absent from the open web.

Audio codecs — the quiet failure

CodecUsed forBrowser support
AACThe web and mobile standardUniversal
OpusWebM, calls, streamingAll modern browsers
MP3LegacyUniversal
AC-3DVD, Blu-ray, broadcastPoor
DTSBlu-rayNone
FLACLossless archivingMost browsers
PCMUncompressed, editingVaries

AC-3 and DTS are the usual culprits behind silent playback. They are the standards for physical media surround sound and are essentially absent from web and mobile support. A file ripped from a Blu-ray will very often have perfectly playable H.264 video and completely unplayable DTS audio.

Finding out what is really in the file

# ffprobe — the definitive answer ffprobe -v error -show_entries \ stream=index,codec_type,codec_name,profile,width,height \ -of default=noprint_wrappers=1 video.mp4 # Compact summary of every stream ffprobe -hide_banner video.mp4 # Just the video codec ffprobe -v error -select_streams v:0 \ -show_entries stream=codec_name -of csv=p=0 video.mp4

MediaInfo is the graphical equivalent and reports the same information plus bitrates, colour space and encoder details. Either is worth installing — guessing from the extension is what produced the problem in the first place.

✅ Read the browser's own error

The HTML video element reports why it failed, and the code tells you which layer broke:

video.addEventListener('error', () => { const e = video.error; console.log(e.code, e.message); // 1 ABORTED — the user stopped it // 2 NETWORK — the download failed // 3 DECODE — corrupt data, or an unsupported profile // 4 SRC_NOT_SUPPORTED — container or codec unsupported }); // Test support before loading anything video.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"'); // "probably" | "maybe" | ""

Code 4 means the format is wrong. Code 3 means the format is right and the data is damaged — a completely different investigation.

Remuxing — the fix that takes seconds

This is the single most useful thing in this article.

If the codecs are supported but the container is not — an MKV holding H.264 and AAC, for instance — you do not need to convert anything. You can copy the existing compressed streams into a new container. Nothing is decoded, nothing is re-encoded, no quality is lost, and it completes in seconds because it is essentially a file copy.

# MKV → MP4, lossless, near-instant ffmpeg -i input.mkv -c copy output.mp4 # Keep the video, re-encode only the incompatible audio ffmpeg -i input.mkv -c:v copy -c:a aac -b:a 192k output.mp4 # Pick specific streams — first video, second audio ffmpeg -i input.mkv -map 0:v:0 -map 0:a:1 -c copy output.mp4 # Move the index to the front so it streams before # fully downloading — essential for web video ffmpeg -i input.mp4 -c copy -movflags +faststart output.mp4
Remux (-c copy)Re-encode
SpeedSecondsMinutes to hours
QualityIdenticalAlways some loss
CPUAlmost noneHeavy
ChangesContainer onlyResolution, bitrate, codec
Use whenCodecs supported, container is notCodec itself is unsupported

Always try -c copy first. A surprising proportion of "this video will not play" problems are solved by it, and it costs nothing to attempt — if the streams are incompatible with the target container, ffmpeg says so immediately.

The faststart flag

An MP4 stores its index — the moov atom — wherever the encoder happened to put it, which is usually at the end. A browser cannot begin playback until it has that index, so it downloads the entire file first. On a large video over a slow connection, that looks exactly like the video is broken.

-movflags +faststart moves the index to the front. Playback then begins after a few hundred kilobytes. It costs one extra pass over the file and is essential for anything served on the web.

When you genuinely must re-encode

# The safe universal target: H.264 + AAC in MP4 ffmpeg -i input.mkv \ -c:v libx264 -preset slow -crf 22 \ -c:a aac -b:a 192k \ -movflags +faststart \ output.mp4 # CRF controls quality — lower is better and larger # 18 visually lossless # 22 a good default # 28 noticeably degraded # Preset trades encoding time for compression efficiency # Ensure maximum device compatibility ffmpeg -i input.mkv \ -c:v libx264 -profile:v high -level 4.0 -pix_fmt yuv420p \ -c:a aac -b:a 192k -movflags +faststart output.mp4

⚠️ The pix_fmt trap

Video encoded with 4:2:2 or 4:4:4 chroma subsampling, or in 10-bit colour, will not play on a great deal of hardware even though the codec is nominally H.264. Phones, televisions and older browsers expect yuv420p — 8-bit, 4:2:0.

This is a common and baffling failure with footage from professional cameras or screen recorders: the codec is right, the container is right, and it still refuses to play. Adding -pix_fmt yuv420p fixes it.

Hardware decoding

Modern devices decode video in dedicated silicon rather than on the CPU, which is dramatically more efficient. But that hardware supports a fixed list of codecs, fixed to whenever the chip was designed.

When a codec is not in that list, playback falls back to software decoding — which works, and on a phone or laptop means high CPU use, heat, fan noise and rapid battery drain. A 4K AV1 stream on a device without AV1 hardware may drop frames despite the format being fully "supported".

SymptomLikely cause
Plays smoothly, low CPUHardware decode
Plays, CPU at 60–100%Software decode
Stutters, drops framesSoftware decode of too high a resolution
Audio fine, video frozenDecoder failure mid-stream
Black screen with soundUnsupported pixel format or colour space

Serving video reliably on the web

<video controls preload="metadata" poster="poster.jpg"> <!-- Best first; the browser picks the first it can play --> <source src="video.webm" type='video/webm; codecs="av01.0.05M.08, opus"'> <source src="video.mp4" type='video/mp4; codecs="avc1.640028, mp4a.40.2"'> <track kind="captions" src="captions.vtt" srclang="en" default> <p>Your browser cannot play this video. <a href="video.mp4">Download it</a>.</p> </video>

Specifying full codec strings in the type attribute lets the browser choose without downloading anything. With a bare type="video/mp4" it must fetch part of the file to find out whether it can decode it, and if it cannot, that bandwidth is wasted.

Two server-side requirements are easy to miss: the correct MIME type must be configured (video/mp4, video/webm), and the server must support range requests. Without ranges, seeking does not work — the user can only play from the start, because the browser cannot request an arbitrary byte offset.

Diagnostic order

  1. Identify the streams. ffprobe or MediaInfo. Never guess from the extension.
  2. Check video and audio separately. Silent playback means only the audio codec is wrong.
  3. Try remuxing. ffmpeg -i in.mkv -c copy out.mp4 — seconds, lossless, frequently sufficient.
  4. Check the pixel format. Anything other than yuv420p limits compatibility sharply.
  5. Add faststart for anything served over the web.
  6. Re-encode only as a last resort, targeting H.264 + AAC in MP4.
  7. Verify server configuration — MIME type and range request support.

Working with other media formats?

Convert images, compress files and handle PDFs entirely in your browser — nothing is uploaded to a server.

Browse all tools →

Summary

  • The extension names the container, not the codec. Two .mp4 files can be entirely different.
  • H.264 + AAC in MP4 plays everywhere. It remains the safe target.
  • No browser supports MKV — but remuxing to MP4 takes seconds.
  • Silent video means an unsupported audio codec, usually AC-3 or DTS.
  • H.265 is absent from browsers because of patent licensing. AV1 exists to solve that.
  • Try -c copy first. Lossless, instant, and often enough.
  • Use -pix_fmt yuv420p for maximum device compatibility.
  • +faststart is mandatory for web video.

Frequently Asked Questions

What is the difference between a container and a codec?

The container is the file format that packages everything together — MP4, MKV, MOV, WebM. The codec is the compression used for the actual video and audio inside it — H.264, H.265, AV1, AAC. The extension tells you the container only, which is why two .mp4 files can behave completely differently.

Why does my video play but with no sound?

The video codec is supported and the audio codec is not. This is common with files ripped from Blu-ray, which often carry AC-3 or DTS audio that browsers and many mobile devices cannot decode. The picture plays normally because the two streams are decoded independently.

Why won't MKV files play in my browser?

No browser supports the Matroska container. MKV is technically excellent and widely used for archiving, but browsers only implement MP4 and WebM. If the streams inside are H.264 and AAC, you can repackage into MP4 in seconds without re-encoding anything.

What is remuxing and how is it different from converting?

Remuxing copies the existing compressed streams into a different container without decoding them. It takes seconds, is completely lossless, and works whenever the codecs are supported but the container is not. Converting re-encodes the video, which takes minutes or hours and always loses some quality.

Why does H.265 not play in Chrome?

Patent licensing. H.265 requires royalty payments to several patent pools, which is incompatible with a browser given away free at enormous scale. This is precisely why the industry created AV1 — a royalty-free codec with comparable efficiency, now supported across all major browsers.

P

Written by Paras

We build free, browser-based file tools and write the reference material we wish existed when we were looking things up. Spotted an error? Tell us and we will fix it.