Signal · signalsVersion 5

media_codecs

Which of 8 audio and 12 video formats the browser says it can play, asked of a media element and of MediaSource. Nothing is loaded or played.

media_codecs at a glance (from the library code, signalsVersion 5)
Component namemedia_codecs
In the visitorIdyes
structuredId groupbrowser (engine and build)
Hashingalways a digest (first 128 bits of SHA-256)
Excluded underno browser class
Inner timeout1000 ms
Added insignalsVersion 1
In plain words

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, maybe or an empty string (written as no);
  • the answer of MediaSource.isTypeSupported(type), written 1 or 0.

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

  1. One <audio> and one <video> element are created with document.createElement. They are never given a source and never attached, so the browser loads nothing.
  2. For each type, canPlayType is called on the matching element, and MediaSource.isTypeSupported is called if MediaSource exists. A missing method gives -, a throw gives !.
  3. 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.