feat(android): play the original file — decode Dolby/DTS audio with FFmpeg

Android ships no AC-3, E-AC-3, DTS or TrueHD decoders; they are licensed
codecs, present only where a vendor paid for them. The ROD2-W09 tablet has a
vendor DTS decoder and no AC-3/E-AC-3 at all. So every film with Dolby audio
was re-encoded by the server, for streaming and for download alike, and a
transcoded download has no Content-Length and ignores Range: ~1 MB/s,
restarting from byte zero on every network blip.

ExoPlayer now carries Jellyfin's media3 FFmpeg audio decoder in extension
mode ON (platform decoders first, FFmpeg for what they lack), and
CodecDetector reports its codecs so the device profile and the download
policy agree with what actually decodes. The download policy judges audio
against the renderer that will play the file (renderer_can_decode_audio)
instead of the webview's list, so Android downloads are always the direct
copy — a 910 MB E-AC-3 5.1 episode downloaded in 94 s and played offline.

The webview video path is removed on Android: it decodes none of these
codecs, so a stored "native video off" would play every original-file
download silent. Rust reports webview_video_fallback (false on Android, true
only beside mpv native video on Linux); Settings offers the switch and the
player honours it only then. Linux keeps the fallback and, with it, the
server transcode for undecodable audio.

The decoder is GPL-3.0; the distributed APK carries its terms and the source
stays MIT (THIRD_PARTY_NOTICES.md). The on-device remux spec this replaces is
folded into 05-platform-backends.md and deleted.

DR-293, UT-259, UT-262.
This commit is contained in:
2026-09-22 22:22:05 -04:00
parent bb7d5dc01a
commit bed1030443
19 changed files with 339 additions and 382 deletions
+10
View File
@@ -172,6 +172,16 @@ dependencies {
// itself: without a view to hand them to, a selected subtitle track renders
// nowhere. See JellyTauPlayer.onCues. (DR-260)
implementation("androidx.media3:media3-ui:1.5.0")
// Software audio decoders for what Android does not ship: AC-3, E-AC-3,
// DTS and TrueHD are licensed codecs, present only where a vendor paid for
// them (the ROD2-W09 tablet has DTS but no AC-3/E-AC-3 at all). With this,
// ExoPlayer plays the source file as-is, so neither a download nor a stream
// needs the server to re-encode its audio (DR-293). Jellyfin's own build of
// the media3 FFmpeg extension, versioned to match media3 above — keep the
// two in step. Licence: GPL-3.0 — the distributed APK carries its terms,
// the source stays MIT; see THIRD_PARTY_NOTICES.md and
// docs/architecture/05-platform-backends.md.
implementation("org.jellyfin.media3:media3-ffmpeg-decoder:1.5.0+1")
implementation("com.google.guava:guava:33.0.0-android")
// Media library for VolumeProviderCompat (remote volume control)