mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-09 08:01:20 +02:00
Fix duplicate commands from key presses/MediaSession (#663)
## Description Fixes duplicate play/pause commands from a remote button press and `MediaSession`. This ended up being a bit complicated because Wholphin overrides the default play/pause behavior for the skip back setting and to show the controller on pause. This means using a forwarding player which meant implementing more functionality into `MpvPlayer`. ### Related issues Fixes #653
This commit is contained in:
parent
2cd34692e9
commit
ee73e7d723
4 changed files with 167 additions and 43 deletions
|
|
@ -0,0 +1,27 @@
|
|||
package com.github.damontecres.wholphin.ui.playback
|
||||
|
||||
import androidx.media3.common.ForwardingSimpleBasePlayer
|
||||
import androidx.media3.common.Player
|
||||
import com.github.damontecres.wholphin.preferences.PlaybackPreferences
|
||||
import com.github.damontecres.wholphin.preferences.skipBackOnResume
|
||||
import com.github.damontecres.wholphin.ui.seekBack
|
||||
import com.google.common.util.concurrent.ListenableFuture
|
||||
import timber.log.Timber
|
||||
|
||||
class MediaSessionPlayer(
|
||||
player: Player,
|
||||
private val controllerViewState: ControllerViewState,
|
||||
private val playbackPreferences: PlaybackPreferences,
|
||||
) : ForwardingSimpleBasePlayer(player) {
|
||||
override fun handleSetPlayWhenReady(playWhenReady: Boolean): ListenableFuture<*> {
|
||||
Timber.v("handleSetPlayWhenReady: playWhenReady=$playWhenReady")
|
||||
if (!playWhenReady && player.isPlaying) {
|
||||
controllerViewState.showControls()
|
||||
} else if (playWhenReady) {
|
||||
playbackPreferences.skipBackOnResume?.let {
|
||||
player.seekBack(it)
|
||||
}
|
||||
}
|
||||
return super.handleSetPlayWhenReady(playWhenReady)
|
||||
}
|
||||
}
|
||||
|
|
@ -61,27 +61,8 @@ class PlaybackKeyHandler(
|
|||
}
|
||||
} else if (isMedia(it)) {
|
||||
when (it.key) {
|
||||
Key.MediaPlay -> {
|
||||
Util.handlePlayButtonAction(player)
|
||||
skipBackOnResume?.let {
|
||||
player.seekBack(it)
|
||||
}
|
||||
}
|
||||
|
||||
Key.MediaPause -> {
|
||||
Util.handlePauseButtonAction(player)
|
||||
controllerViewState.showControls()
|
||||
}
|
||||
|
||||
Key.MediaPlayPause -> {
|
||||
Util.handlePlayPauseButtonAction(player)
|
||||
if (!player.isPlaying) {
|
||||
controllerViewState.showControls()
|
||||
} else {
|
||||
skipBackOnResume?.let {
|
||||
player.seekBack(it)
|
||||
}
|
||||
}
|
||||
Key.MediaPlay, Key.MediaPause, Key.MediaPlayPause -> {
|
||||
// no-op, MediaSession will handle
|
||||
}
|
||||
|
||||
Key.MediaFastForward, Key.MediaSkipForward -> {
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ class PlaybackViewModel
|
|||
val player by lazy {
|
||||
playerFactory.createVideoPlayer()
|
||||
}
|
||||
private val mediaSession: MediaSession
|
||||
private var mediaSession: MediaSession? = null
|
||||
internal val mutex = Mutex()
|
||||
|
||||
val controllerViewState =
|
||||
|
|
@ -179,15 +179,11 @@ class PlaybackViewModel
|
|||
}
|
||||
jobs.forEach { it.cancel() }
|
||||
player.release()
|
||||
mediaSession.release()
|
||||
mediaSession?.release()
|
||||
}
|
||||
viewModelScope.launch(ExceptionHandler()) { controllerViewState.observe() }
|
||||
player.addListener(this)
|
||||
(player as? ExoPlayer)?.addAnalyticsListener(this)
|
||||
mediaSession =
|
||||
MediaSession
|
||||
.Builder(context, player)
|
||||
.build()
|
||||
jobs.add(subscribe())
|
||||
jobs.add(listenForTranscodeReason())
|
||||
}
|
||||
|
|
@ -284,6 +280,18 @@ class PlaybackViewModel
|
|||
} else {
|
||||
throw IllegalArgumentException("Item is not playable and not PlaybackList: ${queriedItem.type}")
|
||||
}
|
||||
|
||||
val sessionPlayer =
|
||||
MediaSessionPlayer(
|
||||
player,
|
||||
controllerViewState,
|
||||
preferences.appPreferences.playbackPreferences,
|
||||
)
|
||||
mediaSession =
|
||||
MediaSession
|
||||
.Builder(context, sessionPlayer)
|
||||
.build()
|
||||
|
||||
val item = BaseItem.from(base, api)
|
||||
|
||||
val played =
|
||||
|
|
@ -1058,7 +1066,7 @@ class PlaybackViewModel
|
|||
Timber.v("release")
|
||||
activityListener?.release()
|
||||
player.release()
|
||||
mediaSession.release()
|
||||
mediaSession?.release()
|
||||
activityListener = null
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue