The audio codec list sent to Jellyfin comes from MediaCodecList, which
describes ExoPlayer — but video does not play through ExoPlayer. Android
force-renders every video in the webview <video> element (the interim
override in VideoPlayer.svelte) and Linux always has, and Chromium/WebKit
decode a far narrower set than the platform does.
A motorola edge 30 ships /vendor/etc/media_codecs_dolby_audio.xml, so it
reported ac3,eac3; the server direct-played an E-AC-3 track with
static=true and the webview built a video decoder and no audio decoder at
all — full picture, no sound. The defect is triggered by capability rather
than the lack of it, which is why a Fairphone and an Honor tablet play the
same file on the same build: without the Dolby decoder they never claim the
codec, so the server transcodes to AAC. Confirmed by A/B on the failing
device — hevc+eac3 silent, hevc+aac audible, same session, same profile,
same direct-play path, audio codec the only variable.
video_audio_codecs narrows the platform list to the webview-decodable set
for the video direct-play profile only. Audio-only playback really is the
native player's, so that profile keeps the full list rather than
transcoding music that plays perfectly well. A list with nothing decodable
still claims aac, since a profile claiming nothing invites the server to
give up instead of transcoding. The video codec list is deliberately
untouched: HEVC direct-plays through the webview correctly, so the
constraint is specific to audio.
Test-first: the tests failed against the old behaviour before the filter
existed, including the case built from the phone's real codec list. The
requirement-count assertion in extract-traces.test.ts moves 280 -> 281 for
the added DR, which is the deliberate edit that test exists to force.
Not yet verified on device — the 0.4.7 APK was still building.
Minor bump rather than patch: Android gains working equalizer, volume
normalization and gapless playback, which are new user-facing capabilities.
CHANGELOG entry written by hand rather than from `bun run release:notes`. The
generated draft lists "Crossfade between audio tracks (UR-031)" as a feature of
this release, which is false — the trace graph cannot distinguish code that
plumbs a setting (settings.rs clamping, the backend.rs trait method, both
legitimately tagged DR-034) from code that implements it, and crossfade is
implemented nowhere. The release-notes tool documents its output as a reviewed
draft; this is a concrete case of why.
v0.1.3-v0.1.5 have no CHANGELOG entries; noted in the file rather than
backfilled.