Signal · signalsVersion 14

video_decoding

navigator.mediaCapabilities.decodingInfo() for four codecs at 1080p and 2160p: supported, smooth and powerEfficient for each. Reported, not in either id.

video_decoding at a glance (from the library code, signalsVersion 14)
Component namevideo_decoding
In the visitorIdno (reported, kept out of both ids)
structuredId groupnone
Hashingplain value; a digest only when longer than 128 characters or not printable ASCII
Excluded underno browser class
Inner timeout1000 ms
Added insignalsVersion 14
Collector revision2 (reported as revision with every result)
In plain words

Browsers can tell a page whether a video format would play, play without stutter, and play on a hardware decoder that saves battery. Which formats get a hardware decoder depends on the graphics chip, the operating system and the browser build. WhiskerJS asks about four common video formats at two sizes and keeps only the yes or no answers.

What it reads

navigator.mediaCapabilities.decodingInfo() for eight plain-file configurations (type: 'file', 30 frames per second), and from each answer only supported, smooth and powerEfficient:

Key Codec Codecs string Size Bitrate
h264_1080 H.264 High avc1.640028 (MP4) 1920 x 1080 8 Mbit/s
h264_2160 H.264 High avc1.640033 (MP4) 3840 x 2160 30 Mbit/s
vp9_1080 VP9 profile 0 vp09.00.40.08 (WebM) 1920 x 1080 6 Mbit/s
vp9_2160 VP9 profile 0 vp09.00.51.08 (WebM) 3840 x 2160 20 Mbit/s
av1_1080 AV1 Main av01.0.08M.08 (MP4) 1920 x 1080 5 Mbit/s
av1_2160 AV1 Main av01.0.12M.08 (MP4) 3840 x 2160 16 Mbit/s
hevc_1080 HEVC Main hvc1.1.6.L120.90 (MP4) 1920 x 1080 6 Mbit/s
hevc_2160 HEVC Main hvc1.1.6.L153.90 (MP4) 3840 x 2160 20 Mbit/s

No key system is named, so no DRM machinery starts; no media element is created, nothing is fetched and nothing prompts.

How the technique works

Step What happens Value
1 ask all eight at once; wait up to 650 ms three digits per key: supported, smooth, powerEfficient (1 or 0); ! when the call failed, ? when it did not answer in time
2 ask all eight again; wait up to 250 ms (the media stack is warm now)
3 both rounds answered everything and differ noisy / read_varies
4 otherwise the first round’s answers

The first round gets more time because the first decodingInfo() of a page can wait for the browser’s media stack to start: in one CI run Firefox gave no answer within 400 ms on a first page load (library PR #41 raised the first round from 400 to 650 ms; the component’s revision went to 2).

Why it helps

Hardware decoders differ between graphics chips, operating systems and builds: licensed codecs (H.264 in some builds, HEVC on many systems) and AV1 decode support on newer chips. powerEfficient says whether a hardware decoder would be used. On a desktop the answers mostly follow the GPU and the browser build; they say little alone but add context to webgl_renderer and the platform.

Stability

Expected to be the same from load to load on one device, but smooth and powerEfficient can follow load, power state and driver updates, so it is reported outside both ids until it is measured on real devices. Added in library PR #40 (2026-10-28) at signalsVersion 14; it is outside both ids, so no version moved and no id changed.

Browser support and what blocks it

In the self-hosted CI browser matrix (23 browsers and channels on Linux without a GPU; load, reload and a new context; Browsers runs 40635322566 and 40635905144) every browser reported ok and the same value in all three collections. No browser reported a power-efficient decoder there, since the runner has no GPU:

Browsers H.264 VP9 AV1 HEVC
Chrome (stable, beta, dev, canary), Chromium, Edge (stable, beta, dev), Brave (stable, beta), Playwright’s Chromium 110 110 110 000
Opera (stable, beta, developer) 000 110 110 000
Firefox stable and ESR, Playwright’s Firefox (default and fingerprinting protection) 110 110 110 111
Firefox beta and nightly, Playwright’s Firefox with resistFingerprinting 110 110 110 110
Playwright’s WebKit 110 110 110 110

Each cell is the same at 1080p and 2160p. Opera’s Linux build has no H.264 decoder. One earlier run caught Playwright’s Firefox with a display giving no answer within 400 ms on its first page load (unavailable / no_value there, the usual value on the reload); PR #41 gave the first round more time. Time taken: 100 to 400 ms in Firefox, about 26 ms in Brave, under about 100 ms in the other browsers.

  • unavailable / no_api without navigator.mediaCapabilities (Safari before 13, Firefox before 63, Chrome before 66).
  • No browser class excludes it.

Privacy

It asks the browser eight fixed questions about described files and keeps eight three-digit answers; no media is created or fetched, no DRM query is made and nothing prompts. Leave it out with collect({ exclude: ['video_decoding'] }) if you do not need it; no id changes.

How WhiskerJS handles noise and failures

Status ruleId When
ok the answers, for example h264_1080=110,...,hevc_2160=000
unavailable no_api no navigator.mediaCapabilities.decodingInfo
unavailable no_value no answer within the first round
blocked threw, security_error every call failed
noisy read_varies two rounds in a row gave different answers
excluded caller_excluded you excluded it
timed_out timeout, aborted budget or abort

Example value

"video_decoding": { "status": "ok", "value": "h264_1080=110,h264_2160=110,vp9_1080=110,vp9_2160=110,av1_1080=110,av1_2160=110,hevc_1080=000,hevc_2160=000", "hashed": false, "durationMs": 31.2, "revision": 2 }

Questions and answers

Does video_decoding query DRM or key systems?

No. It never passes a keySystemConfiguration, so no Encrypted Media Extensions code starts. DRM key system queries are on the roadmap's Not doing list because they can show browser UI or leak a client id.

Does it play or download a video?

No. decodingInfo() is a question about a described file (codec, size, bitrate, frame rate); no media is created, fetched or decoded, and nothing prompts.

Why is it not in the visitorId?

smooth and powerEfficient can change with load, power state and driver updates, and the component is new and not yet measured on real devices. It is reported outside both ids.