fix: Fix cross-fade not working when the app was cleared from background
This commit is contained in:
parent
36f15ffe9e
commit
bf165c7eff
6 changed files with 33 additions and 14 deletions
|
@ -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()) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue