# Video codec support in browsers and devices

Canonical URL: https://encode.wiki/reference/video-codec-support/
Content version: ca42e61ede0a24f789d7287a0001244ad22f4abf
Status: current
License: CC BY-SA 4.0
Checksum (SHA-256): 1d36808335534a2f642209bc3f441a149decadb9033d5fcffe705227b3dd3ae6

Checking a codec name is not enough. A file plays only if the browser handles the whole
combination: codec, profile, level or tier, bit depth, chroma, container and audio codec, through the
playback API you use.

## Native browser playback

| Format                              | Native browser playback                                                                                                                                                                                                                                                                                   | Check on your targets                                                                      |
| ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| [AVC / H.264](/codecs/video/avc/)   | All major browsers. Chromium builds without proprietary codecs lack it.                                                                                                                                                                                                                                   | Profile, level and MP4 setup                                                               |
| [HEVC / H.265](/codecs/video/hevc/) | Safari. Chrome only with a hardware decoder. Mozilla lists Firefox support as limited.                                                                                                                                                                                                                    | Hardware and OS availability, `hvc1` versus `hev1`, depth, chroma and HDR display behavior |
| [VP8](/codecs/video/vp8/)           | Chrome and Firefox. Safari on macOS since 14.1, on iOS and iPadOS since 17.4.                                                                                                                                                                                                                             | File playback versus WebRTC, audio track and WebM/MSE path                                 |
| [VP9](/codecs/video/vp9/)           | Chrome and Firefox. Safari on macOS since 14.1, on iOS and iPadOS since 17.4.                                                                                                                                                                                                                             | Profile 0 versus 2, 8/10/12-bit, chroma, HDR and hardware decode                           |
| [AV1](/codecs/video/av1/)           | Chrome and Firefox. Safari 17+ only on devices with hardware AV1 decoding.                                                                                                                                                                                                                                | Device, profile, depth, level, software decode speed and container                         |
| [Theora](/codecs/video/theora/)     | Legacy. Firefox disabled it by default in 126, and Chromium no longer lists it.                                                                                                                                                                                                                           | Not a web fallback any more                                                                |
| Everything else                     | None: [VVC](/codecs/video/vvc/), [AV2](/codecs/video/av2/), [AVS3](/codecs/video/avs3/), [VC-1](/codecs/video/vc-1/), [FFV1](/codecs/video/ffv1/), [ProRes](/codecs/video/prores/), [Ut Video](/codecs/video/utvideo/), [DSV](/codecs/video/dsv/), [DSV2](/codecs/video/dsv2/), [ECM](/codecs/video/ecm/) | Ship a web rendition in one of the codecs above, or bring your own application decoder     |

Sources: [Chromium's codec list](https://www.chromium.org/audio-video/),
[Mozilla's supported-format table](https://support.mozilla.org/en-US/kb/audio-and-video-firefox),
[Firefox 126 release notes](https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/126), and
WebKit's [Safari 17.0](https://webkit.org/blog/14445/webkit-features-in-safari-17-0/) and
[Safari 17.4](https://webkit.org/blog/15063/webkit-features-in-safari-17-4/) notes. Edge and other
Chromium browsers follow Chrome, except where the vendor removes proprietary codecs.

## Four playback paths

| Path                           | Appropriate check                                                    | What a positive result leaves unresolved                                    |
| ------------------------------ | -------------------------------------------------------------------- | --------------------------------------------------------------------------- |
| Native file / HTML video       | `HTMLMediaElement.canPlayType()` and an actual file                  | Decode rate, seeking, timestamps, audio, HDR and display correctness        |
| Media Source Extensions (MSE)  | `MediaSource.isTypeSupported()` for the intended byte-stream type    | Segmentation, initialization data, append boundaries and adaptive switching |
| WebCodecs                      | `VideoDecoder.isConfigSupported()` for the exact codec configuration | Demuxing, timestamps, audio synchronization and frame rendering             |
| JavaScript / WebAssembly codec | Application-specific decode test                                     | Integration, CPU and memory budget, battery cost and renderer correctness   |

The same browser can give different answers for each path. A WebCodecs decoder does not demux MP4 or
play audio by itself, and a software WASM decoder does not add to the browser's native codec list. The
[WebCodecs specification](https://www.w3.org/TR/webcodecs/) defines the configuration queries and the
encode and decode model.

## Probe a concrete rendition

Run this in the target page's browser console. The configurations are examples. Derive the real codec
string, dimensions, bitrate and frame rate from your encoded file, and use its container's MIME type.

```js
const candidates = [
  { name: 'AVC High 8-bit', contentType: 'video/mp4; codecs="avc1.640028"' },
  { name: 'HEVC Main 10', contentType: 'video/mp4; codecs="hvc1.2.4.L120.B0"' },
  { name: 'VP9 profile 0', contentType: 'video/webm; codecs="vp09.00.40.08"' },
  { name: 'VP9 profile 2', contentType: 'video/webm; codecs="vp09.02.40.10"' },
  { name: 'AV1 Main 10-bit', contentType: 'video/mp4; codecs="av01.0.08M.10"' },
];
const element = document.createElement('video');
for (const candidate of candidates) {
  const result = {
    name: candidate.name,
    canPlayType: element.canPlayType(candidate.contentType),
    mse: globalThis.MediaSource?.isTypeSupported(candidate.contentType) ?? null,
  };
  if (navigator.mediaCapabilities?.decodingInfo) {
    try {
      result.mediaCapabilities = await navigator.mediaCapabilities.decodingInfo({
        type: 'file',
        video: {
          contentType: candidate.contentType,
          width: 1920,
          height: 1080,
          bitrate: 6_000_000,
          framerate: 30,
        },
      });
    } catch (error) {
      result.error = String(error);
    }
  }
  console.log(result);
}
```

`canPlayType()` returns an empty string, `maybe` or `probably`. [Media Capabilities](https://www.w3.org/TR/media-capabilities/)
adds `supported`, `smooth` and `powerEfficient` estimates. These can be unavailable, and they do not
certify an HDR display, a specific decoder, or every frame of a file. For MSE, query with
`type: 'media-source'` and your real configuration.

A WebCodecs check uses the same idea with an AV1 configuration:

```js
if (globalThis.VideoDecoder?.isConfigSupported) {
  const result = await VideoDecoder.isConfigSupported({
    codec: 'av01.0.08M.10',
    codedWidth: 1920,
    codedHeight: 1080,
    hardwareAcceleration: 'prefer-hardware',
  });
  console.log(result);
}
```

`prefer-hardware` is a preference: a `supported: true` result can still mean software decoding. For AVC,
supply the AVC configuration data when your input needs it. The [AVC registration](https://www.w3.org/TR/webcodecs-avc-codec-registration/)
distinguishes AVC-format input from Annex B, and the [AV1 registration](https://www.w3.org/TR/webcodecs-av1-codec-registration/)
defines AV1 codec strings and chunk expectations. Handle unsupported configurations and decode errors
in code rather than choosing a codec from a user-agent string.

## Hardware and device validation

Hardware encoding and decoding are separate capabilities. Check the GPU or SoC model, OS, driver,
application backend, profile, depth, chroma, resolution and frame-rate limit. The
[vendor matrix](https://developer.nvidia.com/video-encode-and-decode-gpu-support-matrix-new) lists encode and decode
support per sample format, and a newer chip in a product family is not evidence for an older one.

For each rendition you deliver:

1. Inspect the final file with `ffprobe -show_streams -show_format`, and note the codec, profile, pixel
   format, dimensions, frame rate and color metadata.
2. Run a full decode with an independent software decoder to catch stream errors before device testing.
3. Play the exact file on representative browsers and devices, including low-power and older supported
   targets. Check startup, seeking, audio sync, captions, adaptive switching and dropped frames.
4. Compare SDR range and matrix, and HDR output, against a known-good source and display path. A picture
   on screen does not confirm color or tone mapping.

Keep a fallback rendition, and handle playback errors without breaking the page.

For preservation and editing codecs, keep the original or a lossless master, and encode delivery
renditions separately. For AV2, ECM or custom codecs, use the matching decoder revision and state the
research or deployment constraints of the output.
