Commit Graph
284 Commits
Author SHA1 Message Date
edde746 ae331b217c fix(android): keep the FFmpeg audio decoder through R8
Flutter enables minification for every release build, and nothing but a
keep rule reaches androidx.media3.decoder.ffmpeg. DefaultRenderersFactory
instantiates FfmpegAudioRenderer with Class.forName, media3's consumer
rules only -keepclassmembers its constructor, and this project had no
proguard-rules.pro at all, so R8 shrank the renderer out of the shipped
dex and the reflective lookup failed with ClassNotFoundException. The
same pass dropped FfmpegAudioDecoder.growOutputBuffer, which ffmpeg_jni
resolves in JNI_OnLoad and whose absence fails the whole
System.loadLibrary("ffmpegJNI") call.

Release builds therefore lost every codec that decoder adds. TrueHD and
DTS-HD fell through to MediaCodecAudioRenderer, which has no decoder for
them, so a 4K Dolby Vision file died with NO_SUITABLE_DECODER_ERROR and
handed off to the mpv fallback — losing ExoPlayer's Profile 7 to 8.1
conversion on hardware that could have direct-played it. Only debug
builds, where R8 never runs, exercised the working path.

Keep the package and the type named in the JNI callback descriptor, and
guard the invariant so it cannot silently rot again: check_shrinker_rules
fails when an app class in a reflected namespace, a FindClass target, a
native callback member, or a descriptor type has no keep covering it.
Also record the built audio renderers, because whether the extension
loaded is otherwise indistinguishable in an uploaded log.

close #1703
2026-07-28 19:44:04 +02:00
edde746 ad3af474e9 fix(android): emit playback-restart after every seek
Separate the playback-restart signal from the one-shot decoder-hang latch. A
seek flushes the codec without re-initializing it, so the claimed latch
swallowed the post-seek first frame and Watch Together guests sat in
correcting for the full settle timeout.
2026-07-27 17:44:52 +02:00
edde746 5f77da93d1 fix(android): keep fixed endpoints on system certificate authorities
Scope user-installed CA trust to the user-entered server hosts that need it
and pin the hard-coded first-party hosts to system anchors. The base config
applied user CAs to every host, including plex.tv token exchange and the
OAuth proxy.
2026-07-27 17:44:52 +02:00
edde746 fcda012468 style(android): apply ktlint's wrapping to the player sources
scripts/format_native.sh --check reported eight class-signature,
function-signature and wrapping violations. Applies --fix; no behaviour
changes.
2026-07-26 23:05:17 +02:00
edde746 a56b9a3dfb Merge the deduplication and dead-code removal pass
Consolidates duplicated logic behind shared implementations — paginated
grid tabs, focus chrome, cached remote stores, sheet selection columns,
the server artifact store and a test fixture layer — and removes code
that had become unreachable. Net reduction of about 5,500 lines with no
behaviour change.

Where a fix had landed separately in code that moved into a shared
helper, the fix was re-applied inside the helper rather than left behind
in the copy that went away.
2026-07-26 19:41:23 +02:00
edde746 ecc55d9b36 fix(android): retry ExoPlayer after decoder loss
close #1540
2026-07-26 14:58:21 +02:00
edde746 352b88109b refactor: extract shared mixins and helpers, drop dead abstractions
Introduces shared seams for paginated views, D-pad reorder, media control
routing, async singletons and the device method channel, then points the
open-coded copies at them.

Also removes unused models and duplicated provider/server plumbing, folds
the twice-implemented artifact store in the server, and factors the
repeated Flutter toolchain prologue in CI into a composite action.
2026-07-26 06:09:48 +02:00
edde746 3b1e71b3fa feat(player): support playback speeds up to 8x
close #1545
2026-07-26 04:24:55 +02:00
edde746 e251273322 feat(downloads): warn about Android background restrictions 2026-07-26 04:24:55 +02:00
edde746 6710c87892 fix(android): accept denied audio-focus resumes 2026-07-25 17:38:09 +02:00
edde746 5c221468d6 perf(android): use Skia on 32-bit Android TVs 2026-07-25 16:45:59 +02:00
edde746 f8f366a513 fix(native): harden player teardown and shelf recovery 2026-07-25 16:16:24 +02:00
edde746 9a6f48a4cb fix(android): use Skia on 32-bit TCL TVs 2026-07-25 08:33:06 +02:00
edde746 2b3853a882 fix(player): preserve transcoded subtitles at high speed
close #1622
2026-07-25 04:21:37 +02:00
edde746 0643787fbe fix(android): prevent ghost playback after autoplay failures
close #1673
2026-07-25 04:12:54 +02:00
edde746 d6b24c3e07 fix(android): prevent Dolby Vision seek crashes 2026-07-24 19:10:38 +02:00
edde746 4cc9a35b2e fix(android): use OpenGLES on 32-bit TCL TVs 2026-07-24 12:22:58 +02:00
edde746 40833e65ec fix(ci): align toolchains and isolate platform tests 2026-07-24 10:06:50 +02:00
edde746 54a002f9b7 fix(android): consolidate native media decoders 2026-07-24 03:56:40 +02:00
edde746 fb45ff44f3 fix(android): persist startup and runtime exit diagnostics 2026-07-24 03:56:40 +02:00
edde746 9f2e050797 fix(native): bound cross-platform lifecycle ownership 2026-07-24 03:56:40 +02:00
edde746 e0bf66eea8 fix(runtime): harden application service boundaries 2026-07-24 03:46:46 +02:00
edde746 658da37b48 build: make toolchain inputs reproducible 2026-07-24 03:40:06 +02:00
edde746 0707d4d9b1 fix(live-tv): stabilize HLS playback 2026-07-18 20:04:09 +02:00
edde746 a1b6a89714 fix(player): load subtitle sidecars with media
close #1583
2026-07-17 23:09:07 +02:00
edde746 d86e820a16 fix(android): trust user-installed CAs 2026-07-14 00:24:54 +02:00
edde746 822657972d fix(android): enforce minSdk compatibility 2026-07-13 17:00:50 +02:00
edde746 ae71b7bc64 fix(android): guard API 29 codec query
close #1553
2026-07-13 17:00:49 +02:00
edde746 e6e7d8cdfd test: remove redundant coverage and shorten timers 2026-07-13 02:15:03 +02:00
edde746 e03edad824 fix: prevent async state and platform regressions 2026-07-13 00:03:52 +02:00
edde746 b676ef6c56 refactor(android): harden and share player integration 2026-07-12 17:31:15 +02:00
edde746 0135318ded fix(android): include mpv end-file diagnostics 2026-07-12 08:42:22 +02:00
edde746 5876a602c3 fix(android): surface mpv command failures 2026-07-12 08:42:22 +02:00
edde746 02a032d287 fix(android): reconnect Flutter texture after TV standby 2026-07-11 01:01:08 +02:00
edde746 03651d6c73 fix(exoplayer): unwrap AAC-LATM (LOAS) audio in MKV direct streams
close #1521
2026-07-10 23:23:44 +02:00
edde746 5867809560 fix: resolve Jellyfin, logout, playback, and Android regressions 2026-07-09 17:14:45 +02:00
edde746andClaude Fable 5 73be8ab1c8 fix(music): convert SAF content:// downloads for gapless arming
setNext() appended raw content:// URIs that mpv cannot open, stalling
playback at the SD-card-download track boundary. Convert to fdclose://
like open(), track the armed fd, and reclaim it via a new closeContentFd
method when the entry is dropped unplayed (close only when provably
unconsumed — playlist-pos 0 before and after the remove; leak on doubt).
The playlist-pos pre-check also keeps the clear path from removing the
playing entry when mpv rolls into the armed track mid-clear.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 15:26:59 +02:00
edde746 422db75b5b feat(music): mpv audio playback engine with gapless queue service
Audio-only mpv core on every platform (dedicated
com.plezy/mpv_audio_player channels): parameterized android/windows/
linux mpv plugins and a new apple MpvAudioPlayerCore, all skipping
video/window paths (vid=no, audio-display=no, gapless-audio=weak).
MusicPlaybackService drives an in-memory queue with shuffle/repeat,
file-loaded-event gapless arming (property edges coalesce and the
android bridge drops them), per-track progress reporting, OS media
controls, audio focus, sleep timer, and error auto-skip.
PlaybackCoordinator enforces one live native player: starting video
disposes the audio core first.
2026-07-05 19:26:28 +02:00
edde746 c87a9060f9 chore: tidy formatting and local ignores 2026-07-05 14:32:21 +02:00
edde746 90c4fe5458 feat(audio): add Kodi-style stereo downmix with center channel boost 2026-07-05 14:29:57 +02:00
edde746 0fb0c7fb4c perf(android): cap engine memory pools on low-RAM devices
Flutter's imageCache budget only bounds decoded CPU bitmaps: Skia's GPU
resource cache is sized from the surface area (hundreds of MB on a
4K-composited TV) and the Dart old gen defaults to a large fraction of
physical RAM. Both drive LMK kills on 2GB boxes. Cap them via engine
shell args on hardware matching the reduced-tier triple.

Ref #1349
2026-07-05 09:10:27 +02:00
edde746 4a43ae2771 fix(android): auto-recover frozen video after pause/resume on stalling decoders
Some TV SoCs (Amlogic Mi Box class) stall the MediaCodec output path
after pause/resume: audio and the clock keep advancing but the picture
freezes until a seek flushes the codec. Arm a watchdog on every
transition to playing with a warm decoder; if rendered frames stop
advancing while the position moves, recover with a 250ms seek-back
(same-position seeks are short-circuited without a codec flush),
capped per session and logged for field diagnosis.

close #1454
2026-07-05 09:08:29 +02:00
edde746 7b1c150e18 feat(android): enable impeller on capable TV devices
Impeller was blanket-disabled on TV in e759dafa as a precaution when the
Tensor/NVIDIA fallbacks landed, and #749 (API 30 Fire TV Cube freezing
until the Skia build) validated it. Flutter has since deprecated the
Impeller opt-out, so start walking the disable back where the hardware
can take it: TV devices on Android 12+ with a Vulkan 1.1 driver use
Impeller, while Fire OS (modern API levels on GPUs whose drivers can't
back it up), pre-12 boxes, and the existing NVIDIA/Huawei/e-waste quirks
stay on Skia. Tag Sentry events with the active renderer so TV
regressions are attributable while this rolls out.
2026-07-05 02:28:51 +02:00
edde746 8fe66f6e36 fix(android): keep the activity alive when a BT keyboard connects
close #1455
2026-07-04 19:54:19 +02:00
edde746 dd09e421bf fix(android): force codec re-init on TV surface changes to recover video after screensaver
close #1481
2026-07-04 19:25:56 +02:00
edde746 50261398bf fix(android): serialize mpv writes to restore fallback ordering
close #1482
2026-07-04 19:15:34 +02:00
edde746 28e6e349b3 fix(android): restore ExoPlayer audio for tunneled decoded PCM 2026-06-30 18:58:08 +02:00
edde746 ea86ce5a4b fix(android): preserve bitmap subtitle aspect
close #1444
2026-06-30 02:31:18 +02:00
edde746 79b75483bd style: fix CI formatting 2026-06-27 10:36:21 +02:00
edde746 c3ca6e4c49 fix: clear subtitle overlays when disabling subtitles
close #1387
2026-06-26 10:09:45 +02:00