From bf165c7eff3eeaf4e896d60fb62a742efcb6c70e Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Mon, 20 Mar 2023 00:33:55 +0530 Subject: [PATCH] fix: Fix cross-fade not working when the app was cleared from background --- .../retromusic/service/CrossFadePlayer.kt | 31 +++++++++++++++---- .../monkey/retromusic/service/MultiPlayer.kt | 2 +- .../monkey/retromusic/service/MusicService.kt | 8 ++--- .../retromusic/service/PlaybackManager.kt | 2 +- .../retromusic/service/playback/Playback.kt | 2 +- .../monkey/retromusic/service/CastPlayer.kt | 2 +- 6 files changed, 33 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/code/name/monkey/retromusic/service/CrossFadePlayer.kt b/app/src/main/java/code/name/monkey/retromusic/service/CrossFadePlayer.kt index dea5c7e6f..dfea2c408 100644 --- a/app/src/main/java/code/name/monkey/retromusic/service/CrossFadePlayer.kt +++ b/app/src/main/java/code/name/monkey/retromusic/service/CrossFadePlayer.kt @@ -34,6 +34,7 @@ class CrossFadePlayer(context: Context) : LocalPlayback(context) { private var durationListener = DurationListener() private var mIsInitialized = false private var hasDataSource: Boolean = false /* Whether first player has DataSource */ + private var nextDataSource:String? = null private var crossFadeAnimator: Animator? = null override var callbacks: PlaybackCallbacks? = null private var crossFadeDuration = PreferenceUtil.crossFadeDuration @@ -92,8 +93,10 @@ class CrossFadePlayer(context: Context) : LocalPlayback(context) { return true } - override fun seek(whereto: Int): Int { - endFade() + override fun seek(whereto: Int, force: Boolean): Int { + if (force) { + endFade() + } getNextPlayer()?.stop() return try { getCurrentPlayer()?.seekTo(whereto) @@ -143,7 +146,12 @@ class CrossFadePlayer(context: Context) : LocalPlayback(context) { } } - override fun setNextDataSource(path: String?) {} + override fun setNextDataSource(path: String?) { + // Store the next song path in nextDataSource, we'll need this just in case + // if the user closes the app, then we can't get the nextSong from musicService + // As MusicPlayerRemote won't have access to the musicService + nextDataSource = path + } override fun setAudioSessionId(sessionId: Int): Boolean { return try { @@ -281,7 +289,7 @@ class CrossFadePlayer(context: Context) : LocalPlayback(context) { fun start() { job?.cancel() job = launch { - while (true) { + while (isActive) { delay(250) onDurationUpdated(position(), duration()) } @@ -298,10 +306,21 @@ class CrossFadePlayer(context: Context) : LocalPlayback(context) { getNextPlayer()?.let { player -> val nextSong = MusicPlayerRemote.nextSong // Switch to other player (Crossfade) only if next song exists - if (nextSong != null) { + // If we get an empty song it's can be because the app was cleared from background + // And MusicPlayerRemote don't have access to MusicService + if (nextSong != null && nextSong != Song.emptySong) { + nextDataSource = null setDataSourceImpl(player, nextSong.uri.toString()) { success -> if (success) switchPlayer() } + + } + // So we have to use the previously stored nextDataSource value + else if (!nextDataSource.isNullOrEmpty()) { + setDataSourceImpl(player, nextDataSource!!) { success -> + if (success) switchPlayer() + nextDataSource = null + } } } } @@ -335,7 +354,7 @@ class CrossFadePlayer(context: Context) : LocalPlayback(context) { } } -internal fun crossFadeScope(): CoroutineScope = CoroutineScope(Job() + Dispatchers.Main) +internal fun crossFadeScope(): CoroutineScope = CoroutineScope(Job() + Dispatchers.Default) fun MediaPlayer.setPlaybackSpeedPitch(speed: Float, pitch: Float) { if (hasMarshmallow()) { diff --git a/app/src/main/java/code/name/monkey/retromusic/service/MultiPlayer.kt b/app/src/main/java/code/name/monkey/retromusic/service/MultiPlayer.kt index 6ad5c6bbc..a29122a68 100644 --- a/app/src/main/java/code/name/monkey/retromusic/service/MultiPlayer.kt +++ b/app/src/main/java/code/name/monkey/retromusic/service/MultiPlayer.kt @@ -200,7 +200,7 @@ class MultiPlayer(context: Context) : LocalPlayback(context) { * @param whereto The offset in milliseconds from the start to seek to * @return The offset in milliseconds from the start to seek to */ - override fun seek(whereto: Int): Int { + override fun seek(whereto: Int, force: Boolean): Int { return try { mCurrentMediaPlayer.seekTo(whereto) whereto diff --git a/app/src/main/java/code/name/monkey/retromusic/service/MusicService.kt b/app/src/main/java/code/name/monkey/retromusic/service/MusicService.kt index a800f5322..fb04d57c0 100644 --- a/app/src/main/java/code/name/monkey/retromusic/service/MusicService.kt +++ b/app/src/main/java/code/name/monkey/retromusic/service/MusicService.kt @@ -707,7 +707,7 @@ class MusicService : MediaBrowserServiceCompat(), || repeatMode == REPEAT_MODE_NONE && isLastTrack ) { notifyChange(PLAY_STATE_CHANGED) - seek(0) + seek(0, false) if (pendingQuit) { pendingQuit = false quit() @@ -727,7 +727,7 @@ class MusicService : MediaBrowserServiceCompat(), if (pendingQuit || repeatMode == REPEAT_MODE_NONE && isLastTrack) { playbackManager.setNextDataSource(null) pause(false) - seek(0) + seek(0, false) if (pendingQuit) { pendingQuit = false quit() @@ -974,9 +974,9 @@ class MusicService : MediaBrowserServiceCompat(), } @Synchronized - fun seek(millis: Int): Int { + fun seek(millis: Int, force: Boolean = true): Int { return try { - val newPosition = playbackManager.seek(millis) + val newPosition = playbackManager.seek(millis, force) throttledSeekHandler?.notifySeek() newPosition } catch (e: Exception) { diff --git a/app/src/main/java/code/name/monkey/retromusic/service/PlaybackManager.kt b/app/src/main/java/code/name/monkey/retromusic/service/PlaybackManager.kt index d38c80d2d..f57e1505c 100644 --- a/app/src/main/java/code/name/monkey/retromusic/service/PlaybackManager.kt +++ b/app/src/main/java/code/name/monkey/retromusic/service/PlaybackManager.kt @@ -78,7 +78,7 @@ class PlaybackManager(val context: Context) { } } - fun seek(millis: Int): Int = playback!!.seek(millis) + fun seek(millis: Int, force: Boolean): Int = playback!!.seek(millis, force) fun setDataSource( song: Song, diff --git a/app/src/main/java/code/name/monkey/retromusic/service/playback/Playback.kt b/app/src/main/java/code/name/monkey/retromusic/service/playback/Playback.kt index 3795e7634..fdcae6b55 100644 --- a/app/src/main/java/code/name/monkey/retromusic/service/playback/Playback.kt +++ b/app/src/main/java/code/name/monkey/retromusic/service/playback/Playback.kt @@ -45,7 +45,7 @@ interface Playback { fun position(): Int - fun seek(whereto: Int): Int + fun seek(whereto: Int, force: Boolean): Int fun setVolume(vol: Float): Boolean diff --git a/app/src/normal/java/code/name/monkey/retromusic/service/CastPlayer.kt b/app/src/normal/java/code/name/monkey/retromusic/service/CastPlayer.kt index 514612e33..34c61c3ae 100644 --- a/app/src/normal/java/code/name/monkey/retromusic/service/CastPlayer.kt +++ b/app/src/normal/java/code/name/monkey/retromusic/service/CastPlayer.kt @@ -79,7 +79,7 @@ class CastPlayer(castSession: CastSession) : Playback, RemoteMediaClient.Callbac return remoteMediaClient?.approximateStreamPosition?.toInt() ?: 0 } - override fun seek(whereto: Int): Int { + override fun seek(whereto: Int, force: Boolean): Int { remoteMediaClient?.seek(MediaSeekOptions.Builder().setPosition(whereto.toLong()).build()) return whereto }