From c545ddf75ad8ac937a967968e4f7b1075f4874bf Mon Sep 17 00:00:00 2001 From: Damontecres Date: Wed, 5 Nov 2025 23:21:51 -0500 Subject: [PATCH] WIP --- .../wholphin/ui/playback/PlaybackViewModel.kt | 10 ++++-- .../wholphin/util/mpv/MpvPlayer.kt | 33 ++++++++++++++----- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/playback/PlaybackViewModel.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/playback/PlaybackViewModel.kt index 7d25e7aa..4d89eeae 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/playback/PlaybackViewModel.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/playback/PlaybackViewModel.kt @@ -437,7 +437,7 @@ class PlaybackViewModel "changeStreams: userInitiated=$userInitiated, audioIndex=$audioIndex, subtitleIndex=$subtitleIndex, " + "enableDirectPlay=$enableDirectPlay, enableDirectStream=$enableDirectStream", ) - + val playerBackend = preferences.appPreferences.playbackPreferences.playerBackend // TODO if the new audio or subtitle index is already in the streams (eg direct play), should toggle in the player instead val maxBitrate = preferences.appPreferences.playbackPreferences.maxBitrate @@ -448,7 +448,12 @@ class PlaybackViewModel itemId, PlaybackInfoDto( startTimeTicks = null, - deviceProfile = deviceProfile, + deviceProfile = + if (playerBackend == PlayerBackend.EXO_PLAYER) { + deviceProfile + } else { + null + }, maxAudioChannels = null, audioStreamIndex = audioIndex, subtitleStreamIndex = subtitleIndex, @@ -491,6 +496,7 @@ class PlaybackViewModel } val transcodeType = when { + playerBackend == PlayerBackend.MPV -> PlayMethod.DIRECT_PLAY source.supportsDirectPlay -> PlayMethod.DIRECT_PLAY source.supportsDirectStream -> PlayMethod.DIRECT_STREAM source.supportsTranscoding -> PlayMethod.TRANSCODE diff --git a/app/src/main/java/com/github/damontecres/wholphin/util/mpv/MpvPlayer.kt b/app/src/main/java/com/github/damontecres/wholphin/util/mpv/MpvPlayer.kt index 7bec827c..07973004 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/util/mpv/MpvPlayer.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/util/mpv/MpvPlayer.kt @@ -31,6 +31,7 @@ import androidx.media3.common.util.ListenerSet import androidx.media3.common.util.Size import androidx.media3.common.util.UnstableApi import androidx.media3.common.util.Util +import com.github.damontecres.wholphin.util.mpv.MPVLib.MpvEvent.MPV_EVENT_END_FILE import com.github.damontecres.wholphin.util.mpv.MPVLib.MpvEvent.MPV_EVENT_FILE_LOADED import timber.log.Timber import kotlin.concurrent.atomics.ExperimentalAtomicApi @@ -68,6 +69,7 @@ class MpvPlayer( private var startPositionMs: Long = 0L private var durationMs: Long = 0L private var positionMs: Long = 0L + private var playbackState: Int = STATE_READY var isReleased = false private set @@ -144,6 +146,9 @@ class MpvPlayer( mediaItems.firstOrNull()?.let { mediaItem = it } + if (surface != null) { + loadFile() + } } override fun setMediaItems( @@ -188,8 +193,7 @@ class MpvPlayer( override fun getPlaybackState(): Int { if (DEBUG) Timber.v("getPlaybackState") - val state = STATE_READY - return state + return playbackState } override fun getPlaybackSuppressionReason(): Int = Player.PLAYBACK_SUPPRESSION_REASON_NONE @@ -206,6 +210,12 @@ class MpvPlayer( } else { MPVLib.setPropertyBoolean("pause", true) } + notifyListeners(EVENT_PLAY_WHEN_READY_CHANGED) { + onPlayWhenReadyChanged( + playWhenReady, + PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST, + ) + } } override fun getPlayWhenReady(): Boolean { @@ -377,19 +387,13 @@ class MpvPlayer( throwIfReleased() if (DEBUG) Timber.v("setVideoSurfaceView") val surface = surfaceView?.holder?.surface - val newSurfaceSize = if (surface == null) 0 else C.LENGTH_UNSET - this.surfaceSize = if (surface == null) Size(0, 0) else Size.UNKNOWN if (surface != null) { this.surface = surface Timber.v("Queued attach") MPVLib.attachSurface(surface) MPVLib.setOptionString("force-window", "yes") Timber.d("Attached surface") - - val url = mediaItem!!.localConfiguration?.uri.toString() - MPVLib.command(arrayOf("loadfile", url)) - MPVLib.setPropertyString("vo", "gpu") - Timber.d("Called loadfile") + loadFile() } else { clearVideoSurfaceView(null) } @@ -558,9 +562,20 @@ class MpvPlayer( notifyListeners(EVENT_TRACKS_CHANGED) { onTracksChanged(it) } } } + MPV_EVENT_END_FILE -> { + playbackState = STATE_ENDED + notifyListeners(EVENT_PLAYBACK_STATE_CHANGED) { onPlaybackStateChanged(STATE_ENDED) } + } } } + private fun loadFile() { + val url = mediaItem!!.localConfiguration?.uri.toString() + MPVLib.command(arrayOf("loadfile", url)) + MPVLib.setPropertyString("vo", "gpu") + Timber.d("Called loadfile") + } + private fun throwIfReleased() { if (isReleased) { throw IllegalStateException("Cannot access MpvPlayer after it is released")