| Component name | media_codecs |
|---|---|
| In the visitorId | yes |
| structuredId group | browser (engine and build) |
| Hashing | always a digest (first 128 bits of SHA-256) |
| Excluded under | no browser class |
| Inner timeout | 1000 ms |
| Added in | signalsVersion 1 |
Browsers support different audio and video formats, depending on the browser, its build and the operating system’s media libraries. WhiskerJS asks the browser, for 20 common formats, “could you play this?”, and hashes the answers. It never loads, downloads or plays any media.
What it reads
For each of 8 audio and 12 video MIME types:
- the answer of
canPlayType(type)on a new<audio>or<video>element:probably,maybeor an empty string (written asno); - the answer of
MediaSource.isTypeSupported(type), written1or0.
The audio types include audio/mp4; codecs="mp4a.40.2", audio/mpeg;, Vorbis in WebM and Ogg, WAV, Speex, FLAC and AMR in 3GPP. The video types include five H.264 profiles in MP4, two MPEG-4 Part 2 forms, VP8 in WebM, Theora and Dirac in Ogg, MPEG-4 in 3GPP and Theora in Matroska.
How the technique works
- One
<audio>and one<video>element are created withdocument.createElement. They are never given a source and never attached, so the browser loads nothing. - For each type,
canPlayTypeis called on the matching element, andMediaSource.isTypeSupportedis called if MediaSource exists. A missing method gives-, a throw gives!. - Each answer is written
type=<play>/<source>, joined with;, and always hashed (SHA-256, first 128 bits).
The two MIME lists are adapted from fpscanner 1.0.8 (MIT), with the notice kept.
Why it helps
The answers follow the browser’s media stack: which decoders it ships, which it gets from the operating system, and how confidently it answers (maybe against probably). Chromium, Firefox and WebKit differ, and so can builds of one browser on different systems. MediaSource support adds a second, independent view.
Stability
Stable between visits. It changes when the browser or operating system gains or drops a codec, which happens with updates. That moves the visitorId and the browser part of the structuredId.
Browser support and what blocks it
All current browsers answer canPlayType. Where MediaSource is missing, the source half of each answer is - and the component is still ok. See the browser pages and the support matrix. No browser class excludes it.
Privacy
The value describes the browser build’s media support, which is shared by everyone with the same browser and system. It is reported only as a digest. No media is fetched, so there is no network trace.
How WhiskerJS handles noise and failures
| Status | ruleId | When |
|---|---|---|
ok |
digest of the 20 answers | |
unavailable |
no_document |
no document or no createElement |
unavailable |
no_api |
neither canPlayType nor MediaSource.isTypeSupported answered for any type (every entry -/-) |
unavailable |
no_digest |
no crypto.subtle, so it cannot be hashed |
blocked |
threw, security_error |
creating an element throws |
excluded |
caller_excluded |
you excluded it |
timed_out |
timeout, aborted |
budget or abort |
Single failing calls become ! inside the value instead of failing the component.
Example value
In the container test, headless Chromium gave dcdbcc9c150c1b84d9741e38cfcc6ddf, Firefox a20d8637fc821657c25051d9329cfb27 and WebKit 1e05ba5e0df74709cab1f47e421950b5: three engines, three different answers.
Questions and answers
Does media_codecs download or play anything?
No. It creates an audio and a video element that never get a source and are never attached to the page, and asks them canPlayType(). MediaSource.isTypeSupported() is a pure question too.
Why does it change after a browser update?
Browsers add and drop codec support over time, and canPlayType answers can move between maybe and probably. Any change in the 20 answers changes the digest.
Where do the MIME types come from?
The two lists are adapted from fpscanner 1.0.8 under the MIT licence, with the notice kept. The probing code is WhiskerJS's own.