Skip to content

fix(player): keep foreground service alive across track swaps - #10

Open
Dollarius wants to merge 1 commit into
maxrave-dev:multiplatformfrom
Dollarius:fix/2233-keep-fgs-across-track-swaps
Open

fix(player): keep foreground service alive across track swaps#10
Dollarius wants to merge 1 commit into
maxrave-dev:multiplatformfrom
Dollarius:fix/2233-keep-fgs-across-track-swaps

Conversation

@Dollarius

Copy link
Copy Markdown

This fixes music randomly stopping between tracks after a few songs on Android (maxrave-dev/SimpMusic#2233), the cause that remained after the audio-focus fix from maxrave-dev/SimpMusic#2022.

During a track swap, loadAndPlayTrackInternal let MediaSession observe the promoted precached player with playWhenReady=false before play() ran. Media3 samples that as user disengagement and arms its 10-minute foreground-service timeout, which never gets cancelled: the service is demoted mid-playback, Android stops it as idle, cuts the app's network, and playback starves at the next track (evidence in the issue).

  • loadAndPlayTrackInternal: start the new player before swapDelegate() / notifyMediaItemChanged() (the crossfade path already does this).
  • SimpleMediaService.onUpdateNotification: keep the service in the foreground while the player is actually playing, self-healing any wrong demotion.

Tested on a Galaxy S23 (Android 16): 1h+ of background playback across 14 track changes with isForeground=true throughout, where 1.5.1 stopped within ~15 minutes.

Fixes maxrave-dev/SimpMusic#2233

Track swaps in loadAndPlayTrackInternal exposed the promoted precached
player to MediaSession with playWhenReady=false before play() was
called. Media3 samples that as user disengagement and arms its
user-engaged foreground-service timeout; the timer is never cancelled,
so the service is demoted 10 minutes later while music is still
playing. Android then stops the idle service, cuts the app's network,
and playback starves at the next track boundary.

Apply settings and start the new player before swapping the delegate,
so the session never observes a paused player mid-transition. Also
trust the actual player state in SimpleMediaService.onUpdateNotification
and keep the service in the foreground whenever it is really playing,
which self-heals any stale demotion.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant