fileformer
search⌘KtranslateENexpand_moreupload_fileConvert
Converters8 file families · 44 direct conversions
What changes in a conversionarrow_forward
home / video / mkv · webm

.mkv/.webm

1A 45 DF A3 · Matroska, written in EBML

WebM is Matroska with a shorter codec list. Both are trees of EBML elements, each written as an ID, a variable-length size and a payload. A recorder that streams as it goes can mark sizes as “unknown” and leave out the duration and the seek index. That is why WebM files saved by browsers often show no length and can’t be scrubbed. Below, this page records such a file with MediaRecorder, walks every element, then rebuilds it with sizes, Duration, SeekHead and Cues, without re-encoding, and asks your browser to play both versions.

folder_openOpen .mkv / .webmradio_button_checkedRecord a 4 s sampleAs loadedRebuilt copy
Recording a 4 s WebM sample with MediaRecorder…
showing: mediarecorder.webmtop-level elements to scale · hover for detail
EBML element tree33 elements · blocks summarised
movie
Track 1 · video · V_VP9640×360 · 121 blocks (2 key) · 108.3 KB ≈ 215 kb/sno CodecPrivate (none needed)
rebuild lab · no re-encoding

Making a streamed WebM seekable

The rebuilt copy keeps every block byte for byte. Only the wrapper changes: Segment and Cluster get real sizes, Info gets a Duration worked out from the last block’s timestamp, a SeekHead at the front points to Info, Tracks and Cues, and Cues lists the first keyframe of every cluster. Then both files are loaded into a hidden video element, and each is seeked to its midpoint.

propertyas loadedrebuilt copy
downloadDownload rebuilt copyDownload as loaded2 cue points written · rebuilt in this tab
as loaded
rebuilt copy
VINT lab

Every size is a variable-length integer

The number of leading zero bits, plus one, gives the length: 1xxxxxxx is one byte, 01xxxxxx xxxxxxxx is two, and so on up to eight. The remaining bits hold the value. If every value bit is 1, the size is “unknown”, which is how a live recorder says “I don’t know yet”. Element IDs use the same scheme but keep the marker bits, so the Cluster ID is written as 1F 43 B6 75, marker and all.

12716,3832^53 − 1unknown sizeClustersize 127 (2 B)
as an ID1A 45 DF A3 → 4-byte ID, EBML
then a size01 FF FF FF FF FF FF FF → 8-byte VINT = unknown (all ones)
whole as VINT4 bytes, value 172,351,395
widthbits (marker · value)hex
1 B11111111all value bits 1: means “unknown size”, not 127FF
2 B01000000 01111111shortest form40 7F
3 B00100000 00000000 01111111also legal: writers pad sizes so they can be patched later20 00 7F
4 B00010000 00000000 00000000 01111111also legal: writers pad sizes so they can be patched later10 00 00 7F
5 B00001000 00000000 00000000 00000000 01111111also legal: writers pad sizes so they can be patched later08 00 00 00 7F
6 B00000100 00000000 00000000 00000000 00000000 01111111also legal: writers pad sizes so they can be patched later04 00 00 00 00 7F
7 B00000010 00000000 00000000 00000000 00000000 00000000 01111111also legal: writers pad sizes so they can be patched later02 00 00 00 00 00 7F
8 B00000001 00000000 00000000 00000000 00000000 00000000 00000000 01111111also legal: writers pad sizes so they can be patched later01 00 00 00 00 00 00 7F

Reference

top-level IDelementwhat it holdshere
1A 45 DF A3EBMLheader: EBML version, DocType “matroska” or “webm”. The file’s magic bytes.-
18 53 80 67Segmenteverything else; one per file (more = chained segments)-
11 4D 9B 74SeekHeadbyte positions of the other level-1 elements-
15 49 A9 66InfoTimestampScale, Duration, MuxingApp, WritingApp, DateUTC-
16 54 AE 6BTracksone TrackEntry per stream: CodecID, CodecPrivate, size, rate-
1F 43 B6 75Clustera Timestamp plus SimpleBlocks / BlockGroups of frames-
1C 53 BB 6BCuesseek index: CueTime → cluster position, per track-
10 43 A7 70Chapterseditions and chapter atoms with start times and names-
12 54 C3 67TagsSimpleTag name/value pairs aimed at targets-
19 41 A4 69Attachmentsfiles such as fonts for ASS subtitles or cover art-
CodecIDWebMCodecPrivate holdsbrowser
V_VP8yesnothingyes (MSE)
V_VP9yesoptional VP9 profile/level featuresyes (MSE)
V_AV1yesav1C (sequence header)yes (MSE)
V_MPEG4/ISO/AVCnoavcC (SPS/PPS)probably
V_MPEGH/ISO/HEVCnohvcCno
A_OPUSyesOpusHead (19+ bytes)yes (MSE)
A_VORBISyes3 Vorbis headers, Xiph-lacedyes (MSE)
A_AACnoAudioSpecificConfigprobably
A_FLACnofLaC + metadata blocksprobably
A_AC3nonothingno
S_TEXT/UTF8nonothing (SRT-style text)-
D_WEBVTT/SUBTITLESyesWebVTT header block-
MIME typesvideo/webm, audio/webm; video/matroska, audio/matroska (RFC 9559), often seen as video/x-matroska
Extensions.mkv video, .mka audio, .mks subtitles, .mk3d stereo 3D, .webm
Magic bytes1A 45 DF A3 at offset 0, then DocType “matroska” or “webm” inside the EBML header
VINT sizes1-8 bytes; leading zeros + 1 = length; all value bits 1 = unknown size (only Segment and Cluster may use it)
Element IDs1-4 bytes, marker bits kept (EBMLMaxIDLength 4); unknown IDs can be skipped by size
TimestampsCluster Timestamp + signed 16-bit block offset, in TimestampScale ticks (default 1,000,000 ns)
KeyframesSimpleBlock flag 0x80; in a BlockGroup, a block with no ReferenceBlock
Lacingseveral frames per block: Xiph, EBML or fixed-size lacing, flags bits 1-2
CRC-32optional first child of a master element: IEEE CRC-32, little-endian, over the rest of that parent
StandardsRFC 8794 (EBML, 2020), RFC 9559 (Matroska, 2024), WebM Container Guidelines
2002MatroskaSteve Lhomme starts Matroska, a fork of the Multimedia Container Format, built on his EBML.
2010WebMGoogle launches WebM: a Matroska subset holding VP8 video and Vorbis audio, royalty-free.
2013VP9 + OpusWebM adds VP9 and Opus, now the usual pair in browser recordings.
2018AV1AV1 1.0 ships, and the Matroska/WebM mapping follows for the new codec.
2020RFC 8794EBML itself becomes an IETF standard.
2024RFC 9559The Matroska container is published as an IETF standard.

Working with Matroska and WebM