playback: improve mediasession reliability
Fix some issues with PlaybackSessionConnector that resulted in the position being stuck when a new song was played, alongside simplifying the connector code to an extent.
This commit is contained in:
parent
ab28fb6323
commit
58eee7a891
4 changed files with 27 additions and 36 deletions
|
@ -91,8 +91,7 @@ dependencies {
|
|||
// --- THIRD PARTY ---
|
||||
|
||||
// ExoPlayer
|
||||
def exoplayer_version = "2.14.0"
|
||||
implementation "com.google.android.exoplayer:exoplayer-core:$exoplayer_version"
|
||||
implementation "com.google.android.exoplayer:exoplayer-core:2.14.0"
|
||||
|
||||
// Image loading
|
||||
implementation "io.coil-kt:coil:1.2.1"
|
||||
|
|
|
@ -234,8 +234,8 @@ class PlaybackStateManager private constructor() {
|
|||
private fun updatePlayback(song: Song, shouldPlay: Boolean = true) {
|
||||
mIsInUserQueue = false
|
||||
|
||||
mSong = song
|
||||
mPosition = 0
|
||||
mSong = song
|
||||
|
||||
setPlaying(shouldPlay)
|
||||
}
|
||||
|
|
|
@ -204,12 +204,6 @@ class PlaybackService : Service(), Player.Listener, PlaybackStateManager.Callbac
|
|||
playbackManager.next()
|
||||
}
|
||||
|
||||
override fun onPositionDiscontinuity(reason: Int) {
|
||||
if (reason == Player.DISCONTINUITY_REASON_SEEK) {
|
||||
playbackManager.setPosition(player.currentPosition)
|
||||
}
|
||||
}
|
||||
|
||||
// --- PLAYBACK STATE CALLBACK OVERRIDES ---
|
||||
|
||||
override fun onSongUpdate(song: Song?) {
|
||||
|
|
|
@ -16,12 +16,7 @@ class PlaybackSessionConnector(
|
|||
private val mediaSession: MediaSessionCompat
|
||||
) : PlaybackStateManager.Callback, MediaSessionCompat.Callback() {
|
||||
private val playbackManager = PlaybackStateManager.getInstance()
|
||||
|
||||
private val emptyMetadata = MediaMetadataCompat.Builder().build()
|
||||
private val state = PlaybackStateCompat.Builder()
|
||||
.setActions(ACTIONS)
|
||||
|
||||
private var playerState = PlaybackStateCompat.STATE_NONE
|
||||
|
||||
init {
|
||||
mediaSession.setCallback(this)
|
||||
|
@ -29,7 +24,6 @@ class PlaybackSessionConnector(
|
|||
|
||||
onSongUpdate(playbackManager.song)
|
||||
onPlayingUpdate(playbackManager.isPlaying)
|
||||
onPositionUpdate(playbackManager.position)
|
||||
}
|
||||
|
||||
fun release() {
|
||||
|
@ -55,11 +49,7 @@ class PlaybackSessionConnector(
|
|||
}
|
||||
|
||||
override fun onSeekTo(position: Long) {
|
||||
// Set the state to buffering to prevent weird delays on the duration counter when seeking.
|
||||
// And yes, STATE_PAUSED is the only state that works with this code. Because of course it is.
|
||||
setPlayerState(PlaybackStateCompat.STATE_PAUSED)
|
||||
playbackManager.seekTo(position)
|
||||
setPlayerState(getPlayerState())
|
||||
}
|
||||
|
||||
override fun onRewind() {
|
||||
|
@ -93,9 +83,10 @@ class PlaybackSessionConnector(
|
|||
// --- PLAYBACKSTATEMANAGER CALLBACKS ---
|
||||
|
||||
override fun onSongUpdate(song: Song?) {
|
||||
invalidateSessionState()
|
||||
|
||||
if (song == null) {
|
||||
mediaSession.setMetadata(emptyMetadata)
|
||||
setPlayerState(PlaybackStateCompat.STATE_STOPPED)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -116,24 +107,36 @@ class PlaybackSessionConnector(
|
|||
}
|
||||
|
||||
override fun onPlayingUpdate(isPlaying: Boolean) {
|
||||
setPlayerState(
|
||||
if (playbackManager.isPlaying) {
|
||||
PlaybackStateCompat.STATE_PLAYING
|
||||
} else {
|
||||
PlaybackStateCompat.STATE_PAUSED
|
||||
}
|
||||
)
|
||||
invalidateSessionState()
|
||||
}
|
||||
|
||||
override fun onSeek(position: Long) {
|
||||
updateState()
|
||||
invalidateSessionState()
|
||||
}
|
||||
|
||||
// --- MISC ---
|
||||
|
||||
private fun setPlayerState(state: Int) {
|
||||
playerState = state
|
||||
updateState()
|
||||
private fun invalidateSessionState() {
|
||||
// Position updates arrive faster when you upload STATE_PAUSED for some inane reason.
|
||||
val state = PlaybackStateCompat.Builder()
|
||||
.setActions(ACTIONS)
|
||||
.setState(
|
||||
PlaybackStateCompat.STATE_PAUSED,
|
||||
playbackManager.position,
|
||||
1.0f,
|
||||
SystemClock.elapsedRealtime()
|
||||
)
|
||||
|
||||
mediaSession.setPlaybackState(state.build())
|
||||
|
||||
state.setState(
|
||||
getPlayerState(),
|
||||
playbackManager.position,
|
||||
1.0f,
|
||||
SystemClock.elapsedRealtime()
|
||||
)
|
||||
|
||||
mediaSession.setPlaybackState(state.build())
|
||||
}
|
||||
|
||||
private fun getPlayerState(): Int {
|
||||
|
@ -148,11 +151,6 @@ class PlaybackSessionConnector(
|
|||
}
|
||||
}
|
||||
|
||||
private fun updateState() {
|
||||
state.setState(playerState, playbackManager.position, 1.0f, SystemClock.elapsedRealtime())
|
||||
mediaSession.setPlaybackState(state.build())
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val ACTIONS = PlaybackStateCompat.ACTION_PLAY or
|
||||
PlaybackStateCompat.ACTION_PAUSE or
|
||||
|
|
Loading…
Reference in a new issue