Why the codec matrix tracks the build, not the engine
Codec support is not purely a function of the rendering engine. It is a function of what the person who compiled the browser was licensed and willing to ship. H.264 video and AAC audio are covered by patent licensing, so official vendor builds include the decoders while open-source builds compiled from the same source frequently do not, or defer to whatever the operating system provides.
This produces a reliable structural signal. A browser presenting a Chrome User-Agent implies an official build, and an official build implies the licensed codec set. A request claiming Chrome that reports no H.264 and no AAC support is far more likely to be an open build of Chromium wearing a Chrome identity, since a genuine Chrome installation that cannot decode the most common video format on the web is close to nonexistent.
A second layer comes from the operating system. Some containers and codecs are decoded by platform frameworks rather than by the browser, so the supported matrix shifts with the OS and even with which media packs are installed. That makes the codec list a weak but genuine platform oracle, corroborating the stronger ones described in engine and OS oracle fingerprinting. Related digital-rights capabilities behave the same way: the presence and baseline behaviour of the encrypted-media stack is another build-level property that branded and open builds do not share.
Three APIs that must give one answer
The browser exposes codec capability through several APIs that were added at different times, which makes the surface a natural cross-API coherence target.
canPlayType()- the oldest, returning the empty string,maybe, orprobably. Critically it is specified to be element-agnostic: avideoelement and anaudioelement must return the same answer for the same MIME type, because the question is about the browser, not the element. A browser where the two disagree is answering from something other than a real codec table.MediaSource.isTypeSupported()- used for streaming, returning a strict boolean. AnythingcanPlayTypereports asprobablyshould generally be supported here too.MediaCapabilities.decodingInfo()- the modern API, returning not just support but whether decoding is smooth and power-efficient. Itssupportedflag must agree with the other two.
There is also a parser check that needs no reference data at all. Codec strings follow a defined syntax, so a browser should reject malformed ones and handle valid but obscure ones correctly. A capability table that answers optimistically to strings a real parser rejects was not produced by a parser - a straightforward spec invariant violation.
What this means in practice
Codec fingerprinting will not identify an individual. Its entropy is low, it groups visitors into broad buckets, and those buckets shift slowly. What it does well is test whether a declared browser identity is backed by the build characteristics that identity implies - which is why it appears in detection scripts far more often than its entropy would justify.
The practical consequence for anyone running browsers at scale is that the choice of build matters more than the User-Agent string attached to it. Running an open-source build compiled without licensed decoders while presenting a branded identity creates a contradiction that no header change addresses, because the decoders are either compiled in or they are not. Matching the claim to the binary - or simply presenting the build you are actually running - avoids the entire issue.
For teams whose goal is public web data rather than browser engineering, this is one more argument for not assembling the stack by hand. A managed web data API runs complete, conventional browser builds, so the codec matrix matches the identity presented without anyone auditing a capability table.