Add experimental MPV player backend (#161)

Experimental MPV player backend

Related to #14, #22, & #85

You can switch to MPV in advanced settings and toggle using hardware
decoding or not.

This uses code and buildscripts from
https://github.com/mpv-android/mpv-android, plus other third party
libraries to build MPV
This commit is contained in:
damontecres 2025-11-16 18:46:25 -05:00 committed by GitHub
parent d7b333e519
commit 6be2662d4e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
84 changed files with 3987 additions and 289 deletions

View file

@ -8,6 +8,7 @@ import androidx.preference.PreferenceManager
import com.github.damontecres.wholphin.R
import com.github.damontecres.wholphin.WholphinApplication
import com.github.damontecres.wholphin.ui.nav.Destination
import com.github.damontecres.wholphin.ui.preferences.ConditionalPreferences
import com.github.damontecres.wholphin.ui.preferences.PreferenceGroup
import com.github.damontecres.wholphin.ui.preferences.PreferenceScreenOption
import com.github.damontecres.wholphin.ui.preferences.PreferenceValidation
@ -672,6 +673,30 @@ sealed interface AppPreference<T> {
title = R.string.subtitle_style,
destination = Destination.Settings(PreferenceScreenOption.SUBTITLES),
)
val PlayerBackendPref =
AppChoicePreference<PlayerBackend>(
title = R.string.player_backend,
defaultValue = PlayerBackend.EXO_PLAYER,
getter = { it.playbackPreferences.playerBackend },
setter = { prefs, value ->
prefs.updatePlaybackPreferences { playerBackend = value }
},
displayValues = R.array.player_backend_options,
indexToValue = { PlayerBackend.forNumber(it) },
valueToIndex = { it.number },
)
val MpvHardwareDecoding =
AppSwitchPreference(
title = R.string.mpv_hardware_decoding,
defaultValue = true,
getter = { it.playbackPreferences.mpvOptions.enableHardwareDecoding },
setter = { prefs, value ->
prefs.updateMpvOptions { enableHardwareDecoding = value }
},
summary = R.string.disable_if_crash,
)
}
}
@ -752,6 +777,7 @@ val advancedPreferences =
preferences =
listOf(
AppPreference.OneClickPause,
AppPreference.GlobalContentScale,
AppPreference.SkipIntros,
AppPreference.SkipOutros,
AppPreference.SkipCommercials,
@ -762,15 +788,24 @@ val advancedPreferences =
),
),
PreferenceGroup(
title = R.string.playback_overrides,
preferences =
title = R.string.player_backend,
preferences = listOf(AppPreference.PlayerBackendPref),
conditionalPreferences =
listOf(
AppPreference.GlobalContentScale,
AppPreference.DownMixStereo,
AppPreference.Ac3Supported,
AppPreference.DirectPlayAss,
AppPreference.DirectPlayPgs,
AppPreference.FfmpegPreference,
ConditionalPreferences(
{ it.playbackPreferences.playerBackend == PlayerBackend.EXO_PLAYER },
listOf(
AppPreference.FfmpegPreference,
AppPreference.DownMixStereo,
AppPreference.Ac3Supported,
AppPreference.DirectPlayAss,
AppPreference.DirectPlayPgs,
),
),
ConditionalPreferences(
{ it.playbackPreferences.playerBackend == PlayerBackend.MPV },
listOf(AppPreference.MpvHardwareDecoding),
),
),
),
PreferenceGroup(

View file

@ -46,6 +46,7 @@ class AppPreferencesSerializer
passOutProtectionMs =
AppPreference.PassOutProtection.defaultValue.hours.inWholeMilliseconds
showNextUpWhen = AppPreference.ShowNextUpTiming.defaultValue
playerBackend = AppPreference.PlayerBackendPref.defaultValue
overrides =
PlaybackOverrides
@ -58,6 +59,14 @@ class AppPreferencesSerializer
mediaExtensionsEnabled =
AppPreference.FfmpegPreference.defaultValue
}.build()
mpvOptions =
MpvOptions
.newBuilder()
.apply {
enableHardwareDecoding =
AppPreference.MpvHardwareDecoding.defaultValue
}.build()
}.build()
homePagePreferences =
HomePagePreferences
@ -112,6 +121,11 @@ inline fun AppPreferences.updatePlaybackOverrides(block: PlaybackOverrides.Build
overrides = overrides.toBuilder().apply(block).build()
}
inline fun AppPreferences.updateMpvOptions(block: MpvOptions.Builder.() -> Unit): AppPreferences =
updatePlaybackPreferences {
mpvOptions = mpvOptions.toBuilder().apply(block).build()
}
inline fun AppPreferences.updateHomePagePreferences(block: HomePagePreferences.Builder.() -> Unit): AppPreferences =
update {
homePagePreferences = homePagePreferences.toBuilder().apply(block).build()