MPV: Handle resolution switch (#635)

## Description
When switching resolution (and possibly refresh rate less frequently),
the initial surface is not always valid. This means, the MPV playback
treated it as detaching the surface and would never update.

This PR instead subscribes to the `SurfaceHolder`'s callbacks which will
provide a new, valid surface once the switch is ready. Then the surface
is attached and queued commands execute to start playback.

Also temporarily disables content scale options for MPV since the
compose implementation conflicts with MPV rendering.

### Related issues
Fixes #626
This commit is contained in:
Ray 2026-01-05 15:38:36 -05:00 committed by GitHub
parent 4f1c730736
commit 356a93310f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 99 additions and 26 deletions

View file

@ -46,6 +46,7 @@ data class PlaybackSettings(
@Composable
fun PlaybackDialog(
enableSubtitleDelay: Boolean,
enableVideoScale: Boolean,
type: PlaybackDialogType,
settings: PlaybackSettings,
onDismissRequest: () -> Unit,
@ -117,7 +118,9 @@ fun PlaybackDialog(
buildList {
add(stringResource(R.string.audio))
add(stringResource(R.string.playback_speed))
add(stringResource(R.string.video_scale))
if (enableVideoScale) {
add(stringResource(R.string.video_scale))
}
if (enableSubtitleDelay) {
add(stringResource(R.string.subtitle_delay))
}

View file

@ -40,6 +40,7 @@ import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.input.key.onKeyEvent
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.intl.Locale
@ -152,7 +153,7 @@ fun PlaybackPage(
var playbackDialog by remember { mutableStateOf<PlaybackDialogType?>(null) }
OneTimeLaunchedEffect {
if (prefs.playerBackend == PlayerBackend.MPV) {
scope.launch(Dispatchers.Main + ExceptionHandler()) {
scope.launch(Dispatchers.IO + ExceptionHandler()) {
preferences.appPreferences.interfacePreferences.subtitlesPreferences.applyToMpv(
configuration,
density,
@ -161,7 +162,15 @@ fun PlaybackPage(
}
}
AmbientPlayerListener(player)
var contentScale by remember { mutableStateOf(prefs.globalContentScale.scale) }
var contentScale by remember {
mutableStateOf(
if (prefs.playerBackend == PlayerBackend.MPV) {
ContentScale.FillBounds
} else {
prefs.globalContentScale.scale
},
)
}
var playbackSpeed by remember { mutableFloatStateOf(1.0f) }
LaunchedEffect(playbackSpeed) { player.setPlaybackSpeed(playbackSpeed) }
@ -572,6 +581,7 @@ fun PlaybackPage(
onPlaybackActionClick = onPlaybackActionClick,
onChangeSubtitleDelay = { viewModel.updateSubtitleDelay(it) },
enableSubtitleDelay = player is MpvPlayer,
enableVideoScale = player !is MpvPlayer,
)
}
}