1. Summary
navigator.mediaCapabilities.decodingInfo() throws / rejects with a TypeError for valid MediaDecodingConfiguration objects whose audio contentType uses a short codec id such as "ac3", "eac3", or "ac-3". The implementation appears to route every codec string through an AV1 codec-id parser (parseAV1CodecId), which fails with Invalid number of fields 1 whenever the string isn’t a dotted AV1 string. The same configurations return true from MediaSource.isTypeSupported(...).
This breaks Shaka Player’s variant filter: any HLS variant declaring AC‑3 audio is rejected before playback starts with MANIFEST_CONTENT_UNSUPPORTED_BY_BROWSER (Shaka error 4032).
- App Name:
Tablo
Bug Severity: Impacts operation of app (without a polyfill, no playback at all for any HLS variant declaring AC‑3 audio)
2. Steps to Reproduce
-
On Vega 0.22, in any RN app linking
@amazon-devices/react-native-w3cmedia, run:await navigator.mediaCapabilities.decodingInfo({ type: 'media-source', audio: { contentType: 'audio/mp4; codecs="ac3"', channels: '2', bitrate: 192000, samplerate: 48000, }, }); -
Observe the call rejects/throws.
-
Compare with
MediaSource.isTypeSupported('audio/mp4; codecs="ac3"')which returnstrue. -
Same behavior is seen for
codecs="eac3"andcodecs="ac-3".
3. Observed Behavior
decodingInfo rejects. Console output:
ERROR parseAV1CodecId: Invalid number of fields 1
ERROR invalid audio mime type audio/mp4; codecs="ac3"
ERROR isValidMediaConfigurationForDecoding failed
ERROR decodingInfoImpl invalid config
Downstream effect when Shaka Player is the consumer: variants with AC‑3 audio are filtered out and HLS playback never starts (Shaka Error 4032 — MANIFEST_CONTENT_UNSUPPORTED_BY_BROWSER).
4. Expected Behavior
decodingInfo({ type: 'media-source', audio: { contentType: 'audio/mp4; codecs="ac3"', … } }) should resolve to { supported: true, smooth: true, powerEfficient: …, … }, consistent with MediaSource.isTypeSupported('audio/mp4; codecs="ac3"') returning true. At minimum, the AV1 parser should not be applied to non-AV1 codec strings.
4.a Possible Root Cause & Temporary Workaround
Suspected root cause: the decodingInfoImpl validator unconditionally invokes the AV1 codec-id parser on every codec string. Any codec id that isn’t dot-segmented in the AV1 shape errors out, the validator interprets that as “invalid config” and rejects the whole call.
Workaround we shipped: monkey-patch decodingInfo to fall back to MediaSource.isTypeSupported when the underlying call throws.
const original = navigator.mediaCapabilities.decodingInfo
.bind(navigator.mediaCapabilities);
navigator.mediaCapabilities.decodingInfo = async (config) => {
try {
return await original(config);
} catch {
const types = [config?.video?.contentType, config?.audio?.contentType]
.filter(Boolean);
const supported = types.length > 0 && types.every(t => {
try { return MediaSource.isTypeSupported(t); } catch { return false; }
});
return {
supported,
smooth: supported,
powerEfficient: supported,
keySystemAccess: null,
configuration: config,
};
}
};
This unblocks variant selection but is obviously not a real fix.
5. Logs or Crash Report
# Filtered RN/Vega console capture demonstrating
# navigator.mediaCapabilities.decodingInfo() throwing on a valid
# `audio/mp4; codecs="ac3"` configuration.
#
# Device : Fire TV Stick 4K Max (arm)
# Vega : 0.22
# RN : 0.72 (system-bundled)
# Player : Shaka Player 4.x (mp2vshaka build)
# Stream : HLS, master playlist injects CODECS="avc1.4D401F,ac3"
# media playlist serves muxed MPEG-TS segments
# (1× H.264 PID, 1× AC-3 PID)
#
# All log lines below are real, copied verbatim from a single playback
# attempt. The "MediaCapabilitiesPolyfill" lines are NOT present in the
# reference run that demonstrates the bug — they are shown to
# illustrate the workaround we are forced to ship.
# ---------------------------------------------------------------------
# (1) ----- Shaka loads master + media playlist, then runs its variant
# filter. As part of that filter, Shaka calls MediaSource.isTypeSupported
# AND MediaCapabilities.decodingInfo for every (video, audio) codec pair
# in the variants. We see the isTypeSupported probes succeed:
INFO MediaSource: isTypeSupported video/mp4; codecs="avc1.4D401F"
DEBUG js queryMediaCapabilities: [ { decoderFeaturesCapabilities: { decryptionSupported: true },
mediaCodecFeaturesCapabilities: { hardwareBacked: true },
videoFormatCapabilities: { resolutions: [Array], colorFormats: [Array] },
… },
… 7 entries total … ]
DEBUG result length: 7
INFO avc1.4D401F is supported
INFO MediaSource: isTypeSupported audio/mp4; codecs="ac3"
DEBUG js queryMediaCapabilities: [ { decoderFeaturesCapabilities: { decryptionSupported: true },
mediaCodecFeaturesCapabilities: { hardwareBacked: false },
… },
… 8 entries total … ]
DEBUG result length: 8
INFO ac3 is supported # <-- isTypeSupported says YES for "ac3" in audio/mp4
# (2) ----- Shaka now calls MediaCapabilities.decodingInfo({ type: 'media-source',
# audio: { contentType: 'audio/mp4; codecs="ac3"', channels: '2',
# bitrate: 192000, samplerate: 48000 }, … })
# for the same codec, and Vega's decodingInfo implementation throws.
# The four ERROR lines below are emitted by the platform synchronously,
# from inside decodingInfo:
ERROR parseAV1CodecId: Invalid number of fields 1
ERROR invalid audio mime type audio/mp4; codecs="ac3"
ERROR isValidMediaConfigurationForDecoding failed
ERROR decodingInfoImpl invalid config
# ^^^ THIS IS THE BUG.
# Vega routes "ac3" through an AV1 codec-id parser. The parser
# splits "ac3" on '.', sees one field, and fails. The whole
# decodingInfo call rejects with a TypeError.
#
# Spec-wise, decodingInfo(...) should resolve with
# { supported: true, smooth: true, powerEfficient: …,
# keySystemAccess: null, configuration: …passed-in config… }
# given that MediaSource.isTypeSupported('audio/mp4; codecs="ac3"')
# returns true on the same device (see logs immediately above).
# (3) ----- The same throw fires for `eac3`. Sample from a different run
# with the same device / stream:
INFO MediaSource: isTypeSupported audio/mp4; codecs="eac3"
DEBUG result length: 8
INFO eac3 is supported
ERROR parseAV1CodecId: Invalid number of fields 1
ERROR invalid audio mime type audio/mp4; codecs="eac3"
ERROR isValidMediaConfigurationForDecoding failed
ERROR decodingInfoImpl invalid config
# (4) ----- Downstream Shaka behavior WITHOUT the workaround
# (this is what users hit by default):
#
# Shaka's variant filter treats the rejected decodingInfo() call as
# "platform doesn't support this audio codec", drops the only variant
# in the master playlist, and surfaces:
ERROR [ShakaVideoPlayerBase - handleErrorEvent]
Critical Error: MANIFEST_CONTENT_UNSUPPORTED_BY_BROWSER
{ code: 4032, category: 4, severity: 2,
message: "Shaka Error 4032",
data: [ "audio/mp4; codecs=\"ac3\"" ] }
# Playback never starts. End of run.
# (5) ----- Downstream behavior WITH our MediaCapabilitiesPolyfill
# installed. We monkey-patch navigator.mediaCapabilities.decodingInfo
# to catch the throw and fall back to MediaSource.isTypeSupported:
INFO MediaSource: isTypeSupported audio/mp4; codecs="ac3"
INFO ac3 is supported
ERROR parseAV1CodecId: Invalid number of fields 1
ERROR invalid audio mime type audio/mp4; codecs="ac3"
ERROR isValidMediaConfigurationForDecoding failed
ERROR decodingInfoImpl invalid config
LOG [MediaCapabilitiesPolyfill] decodingInfo threw, falling back to
isTypeSupported for: audio/mp4; codecs="ac3" -> supported=true
# After the polyfill, Shaka accepts the variant and proceeds to source
# buffer setup (which then exposes Bug 2 / Bug 3 — filed separately).
# ---------------------------------------------------------------------
# REPRO MINIMIZED TO ~10 LINES OF JS:
# ---------------------------------------------------------------------
# const cfg = {
# type: 'media-source',
# audio: {
# contentType: 'audio/mp4; codecs="ac3"',
# channels: '2',
# bitrate: 192000,
# samplerate: 48000,
# },
# };
# console.log('isTypeSupported:',
# MediaSource.isTypeSupported(cfg.audio.contentType)); // true
# try {
# const info = await navigator.mediaCapabilities.decodingInfo(cfg);
# console.log('decodingInfo:', info); // never reached
# } catch (e) {
# console.error('decodingInfo threw:', e); // hit, with above log
# }
# ---------------------------------------------------------------------
6. Environment
-
SDK Version: 0.22.5600
-
App State: Foreground
-
OS Information:
NAME="OS" OE_VERSION="4.0.0" OS_MAJOR_VERSION="1" OS_MINOR_VERSION="1" RELEASE_ID="14" OS_VERSION="1.1" BRANCH_CODE="TV Ship day60" BUILD_DESC="OS 1.1 (TV Ship day60/99)" BUILD_FINGERPRINT="4.0.227617.0(3072cab629675a74)/99N:user-external/release-keys" BUILD_VARIANT="user-external" BUILD_TAGS="release-keys" BUILD_DATE="Tue Feb 17 22:57:51 UTC 2026" BUILD_TIMESTAMP="1771369071" VERSION_NUMBER="1401010009950" -
Device:
Fire TV Stick 4K Select -
React Native: system-bundled (Vega 0.22 / RN 0.72)
-
Player SDK: Shaka Player 4.8.5 (from the docs)
7. Example Code Snippet
await navigator.mediaCapabilities.decodingInfo({
type: 'media-source',
audio: {
contentType: 'audio/mp4; codecs="ac3"',
channels: '2',
bitrate: 192000,
samplerate: 48000,
},
});
Playback Issues
-
Player SDK: Shaka Player
-
Player SDK Version: 4.8.5
-
Audio Codecs: AC‑3 (also reproducible with E‑AC‑3 /
eac3) -
Video Codecs: H.264 (codec under test for this bug is audio-only)
-
Manifest Types: HLS (m3u8)
Additional Context
The polyfilled state lets us discover bugs 2 and 3 (filed separately).