WebM Format: The Complete Technical Guide
WebM is an open, royalty-free multimedia container format developed by Google and released in 2010 as part of the WebM Project. It is a restricted subset of the Matroska (MKV) container, supporting only specific open codecs: VP8, VP9, or AV1 for video, and Vorbis or Opus for audio. WebM was designed specifically for web video delivery — it is the native format for HTML5 <video> element with open codecs in Chrome, Firefox, and Edge, and is the delivery format for YouTube's VP9 and AV1 streams.
Design Philosophy and History
When Google acquired On2 Technologies in 2010 (makers of VP8), they open-sourced VP8 and created WebM to package it. The motivation was providing a patent-unencumbered alternative to H.264/MP4 for the HTML5 video specification. The W3C and browser vendors were deadlocked on whether H.264 (Cisco, Apple) or Theora/Ogg (Mozilla, Opera) should be the baseline for <video>. Google's release of VP8 and WebM broke the deadlock by providing a technically competitive codec with a clean patent pledge from Google.
WebM uses the Matroska container's EBML (Extensible Binary Meta Language) infrastructure but defines a strict codec subset and mandatory element set, ensuring interoperability without the full complexity of MKV.
WebM vs MKV: The Relationship
| Feature | WebM | MKV (Matroska) |
|---|---|---|
| Container format | Restricted MKV | Full Matroska EBML |
| Video codecs allowed | VP8, VP9, AV1 only | Any codec (H.264, H.265, AV1, etc.) |
| Audio codecs allowed | Vorbis, Opus only | Any codec (AAC, MP3, FLAC, etc.) |
| Subtitle formats | WebVTT only | ASS, SSA, SRT, PGS, DVBSUB, etc. |
| Chapters | No | Yes |
| Attachments | No | Yes (fonts, cover art) |
| Use case | Web streaming | General media archival |
| File extension | .webm |
.mkv |
A WebM file is a valid MKV file (Matroska players can open WebM), but not all MKV files are valid WebM.
EBML Container Structure
WebM inherits Matroska's EBML encoding:
- Each element has a Variable-Length Integer (VINT) ID and size
- The document starts with the
EBMLelement (ID 0x1A45DFA3) declaring EBML version and doctype (webm)
Key WebM/Matroska elements:
Segment: Root container for all actual content
SeekHead: Index of top-level elements (Tracks, Chapters, Cues) with byte offsets, enabling O(1) random access without full parsing
Info: Duration, timestamp scale (typically 1,000,000 ns = 1 ms granularity), muxing application, writing application, title
Tracks: One TrackEntry per media track:
TrackType: 1 (video) or 2 (audio)CodecID:V_VP8,V_VP9,V_AV1,A_VORBIS,A_OPUSVideoelement:PixelWidth,PixelHeight,DisplayWidth,DisplayHeight,FrameRate,ColourSpaceAudioelement:SamplingFrequency,Channels,BitDepthCodecPrivate: Codec-specific initialization data (VP9 codec feature ID, AV1 configOBU)
Cues: Keyframe index — CuePoint elements each with CueTime and CueTrackPositions (byte offset of keyframe cluster). Required for efficient random access in WebM.
Cluster: Time-stamped group of blocks. A cluster typically starts at a keyframe and covers a fixed time range (1–4 seconds). Each cluster has:
Timecode: Cluster start time in msSimpleBlockelements: Compressed audio/video data with relative timestamps and flags (keyframe, invisible, lacing)
VP8 and VP9 in WebM
VP8 (2010): Similar architecture to H.264 Baseline. Intra-frame (I-frame) with intra prediction, inter-frame (P/B-frames) with motion compensation. 16×16 macroblocks. Entropy coding with Boolean coder (similar to CABAC). Largely superseded by VP9.
VP9 (2013): Major redesign. Superblock structure (64×64 superblocks subdivided into 4×4 to 64×64 transform blocks). Spatial and temporal intra prediction modes (H.264-compatible plus additional). Asymmetric Discrete Sine Transform (ADST), 8-point DCT, recursive Walsh-Hadamard transform. Compound prediction, loop filters, tile-based parallel encoding. VP9 profiles:
- Profile 0: 8-bit 4:2:0 (most common, universal support)
- Profile 1: 8-bit 4:2:2 or 4:4:4
- Profile 2: 10-bit or 12-bit 4:2:0 (HDR video)
- Profile 3: 10-bit or 12-bit 4:2:2 or 4:4:4
YouTube uses VP9 for HD streams (360p–4K) on Chrome and Firefox. A 1080p YouTube stream is typically VP9 at 2–5 Mbps.
AV1 in WebM
AV1 (2018) is the successor to VP9, developed by the Alliance for Open Media (AOM). AV1 in WebM provides:
- 30–50% better compression than VP9/H.264 at equal quality
- Hardware decode support: on chips from 2020+ (Apple M1, NVIDIA Ampere, Intel Tiger Lake)
- YouTube uses AV1 for 4K+ content on supported clients since 2019
CodecID:V_AV1,CodecPrivatecontains AV1CodecConfigurationRecord
Transparency and Alpha Channel
VP8 and VP9 support alpha channel in WebM via a separate alpha track:
- The main track contains RGB data
- An additional
BlockAdditionselement stores the alpha channel as a separate VP8/VP9 bitstream - This enables WebM to replace animated GIFs with transparent animation, much smaller
- Chrome supports
<video>with alpha channel from WebM since Chrome 62 (2017)
Adaptive Streaming with WebM
WebM is used in DASH (Dynamic Adaptive Streaming over HTTP) as an alternative to MP4 DASH:
- Multiple WebM files at different bitrates/resolutions
- MPD (Media Presentation Description) XML manifest lists available representations
- Player selects bitrate based on bandwidth estimation
- YouTube's DASH delivery uses both MP4 (H.264) and WebM (VP9/AV1) segments
Encoding Commands
# VP9 in WebM (2-pass, high quality)
ffmpeg -i input.mp4 -c:v libvpx-vp9 -b:v 0 -crf 30 -pass 1 -an -f null /dev/null
ffmpeg -i input.mp4 -c:v libvpx-vp9 -b:v 0 -crf 30 -pass 2 -c:a libopus -b:a 128k output.webm
# VP9 single-pass (faster, slightly lower quality)
ffmpeg -i input.mp4 -c:v libvpx-vp9 -crf 33 -b:v 0 -c:a libopus -b:a 128k output.webm
# AV1 in WebM (libaom-av1, slow but best quality)
ffmpeg -i input.mp4 -c:v libaom-av1 -crf 30 -b:v 0 -c:a libopus -b:a 128k output.webm
# AV1 with SVT-AV1 (faster encoder)
ffmpeg -i input.mp4 -c:v libsvtav1 -crf 35 -preset 6 -c:a libopus -b:a 128k output.webm
# WebM with alpha channel (transparent video)
ffmpeg -i rgb_input.mp4 -i alpha_mask.mp4 -filter_complex "[0:v][1:v]alphamerge" \
-c:v libvpx-vp9 -b:v 0 -crf 30 output.webm
# Convert WebM to MP4 H.264 for maximum compatibility
ffmpeg -i input.webm -c:v libx264 -crf 22 -c:a aac -b:a 192k output.mp4
# Extract audio from WebM to Opus
ffmpeg -i input.webm -vn -c:a copy output.opus
# Batch convert MP4 to WebM VP9
for f in *.mp4; do
ffmpeg -i "$f" -c:v libvpx-vp9 -crf 33 -b:v 0 -c:a libopus -b:a 128k "${f%.mp4}.webm"
done
Browser Support
| Browser | VP8 | VP9 | AV1 |
|---|---|---|---|
| Chrome | ✓ | ✓ | ✓ (Chrome 70+) |
| Firefox | ✓ | ✓ | ✓ (Firefox 67+) |
| Edge (Chromium) | ✓ | ✓ | ✓ |
| Safari | ✗ | ✗ | ✓ (Safari 17+, macOS Sonoma) |
| iOS Safari | ✗ | ✗ | Partial (iOS 17+) |
The lack of VP8/VP9 support in Safari has historically been WebM's main weakness. AV1 support in Safari 17 (2023) changes the picture for AV1-in-WebM but VP8/VP9 remain unsupported in all Safari versions.
Use Cases
- HTML5 video without royalties: WebM VP9 or AV1 for
<video>content on websites - YouTube streaming: VP9 and AV1 DASH segments for Chrome/Firefox/Edge
- WebRTC video: VP8 is mandatory in WebRTC; VP9 and AV1 are supported in modern implementations
- Transparent web animation: VP9 alpha channel as an alternative to animated GIFs or APNG
- Discord, Telegram: Animated stickers in VP8/VP9 WebM format
Related conversions
Common video conversions that pair well with this guide: