From bed10304431aafc193177420ae2c269095c958ba Mon Sep 17 00:00:00 2001
From: Duncan Tourolle
Date: Tue, 22 Sep 2026 22:22:05 -0400
Subject: [PATCH] =?UTF-8?q?feat(android):=20play=20the=20original=20file?=
=?UTF-8?q?=20=E2=80=94=20decode=20Dolby/DTS=20audio=20with=20FFmpeg?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
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.
---
THIRD_PARTY_NOTICES.md | 21 ++
docs/architecture/05-platform-backends.md | 49 ++-
docs/requirements.md | 13 +-
docs/specs/README.md | 8 +-
docs/specs/on-device-audio-remux.md | 327 ------------------
src-tauri/android/app/build.gradle.kts | 10 +
.../jellytau/player/CodecDetector.kt | 42 +++
.../jellytau/player/JellyTauPlayer.kt | 13 +
src-tauri/src/commands/player/mod.rs | 55 +++
src-tauri/src/repository/device_profile.rs | 23 +-
src-tauri/src/repository/online.rs | 56 +--
src/lib/api/bindings.ts | 8 +-
.../VideoPlayer.scrubRegression.test.ts | 12 +
src/lib/components/player/VideoPlayer.svelte | 12 +-
.../player/VideoPlayer.touchScrub.test.ts | 12 +
src/lib/services/playbackCapabilities.ts | 8 +
src/lib/stores/nativeVideo.ts | 17 +
src/lib/stores/nativeVideo.wanted.test.ts | 17 +
src/routes/settings/+page.svelte | 18 +-
19 files changed, 339 insertions(+), 382 deletions(-)
create mode 100644 THIRD_PARTY_NOTICES.md
delete mode 100644 docs/specs/on-device-audio-remux.md
create mode 100644 src/lib/stores/nativeVideo.wanted.test.ts
diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md
new file mode 100644
index 000000000..c0854ae4c
--- /dev/null
+++ b/THIRD_PARTY_NOTICES.md
@@ -0,0 +1,21 @@
+# Third-party notices
+
+JellyTau's own source code is licensed under the MIT License (see `LICENSE`).
+Some builds bundle third-party components under other licences, listed here.
+
+## Android: FFmpeg audio decoder (GPL-3.0)
+
+The Android app bundles **`org.jellyfin.media3:media3-ffmpeg-decoder`**, the
+Jellyfin project's build of the media3 FFmpeg extension, which contains FFmpeg.
+It lets the player decode AC-3, E-AC-3, DTS and TrueHD audio, which Android does
+not ship.
+
+- Licence: **GNU General Public License v3.0**
+- Source: (build of
+ ), with FFmpeg from
+
+Because this component is GPL-3.0, **the Android APK as distributed is subject
+to the terms of the GPL-3.0**. The complete corresponding source for JellyTau is
+available in this repository; JellyTau's own code remains available under MIT.
+
+Desktop builds do not include this component.
diff --git a/docs/architecture/05-platform-backends.md b/docs/architecture/05-platform-backends.md
index bcee2598b..5b69f9549 100644
--- a/docs/architecture/05-platform-backends.md
+++ b/docs/architecture/05-platform-backends.md
@@ -95,8 +95,9 @@ flowchart LR
**Location**: `src/lib/player/html5Adapter.ts`, `src/lib/player/index.ts`, report commands in
`src-tauri/src/commands/player/timers.rs`
-Video on desktop (Linux WebKitGTK) — and, per current interim behavior, Android — is rendered by an
-HTML5 `
-
- {#if supportsNativeVideo}
+
+ {#if offerNativeVideoSwitch}