Support subtitle style from #177

This commit is contained in:
Damontecres 2025-11-08 20:34:07 -05:00
parent 6d585a2a99
commit e546f7a074
No known key found for this signature in database
3 changed files with 64 additions and 11 deletions

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.platform.LocalDensity
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.intl.Locale
import androidx.compose.ui.unit.dp
@ -65,18 +66,21 @@ import androidx.tv.material3.surfaceColorAtElevation
import com.github.damontecres.wholphin.R
import com.github.damontecres.wholphin.data.model.ItemPlayback
import com.github.damontecres.wholphin.data.model.Playlist
import com.github.damontecres.wholphin.preferences.PlayerBackend
import com.github.damontecres.wholphin.preferences.UserPreferences
import com.github.damontecres.wholphin.preferences.skipBackOnResume
import com.github.damontecres.wholphin.ui.OneTimeLaunchedEffect
import com.github.damontecres.wholphin.ui.components.ErrorMessage
import com.github.damontecres.wholphin.ui.components.LoadingPage
import com.github.damontecres.wholphin.ui.nav.Destination
import com.github.damontecres.wholphin.ui.preferences.subtitle.SubtitleSettings.applyToMpv
import com.github.damontecres.wholphin.ui.preferences.subtitle.SubtitleSettings.toSubtitleStyle
import com.github.damontecres.wholphin.ui.tryRequestFocus
import com.github.damontecres.wholphin.util.ExceptionHandler
import com.github.damontecres.wholphin.util.LoadingState
import com.github.damontecres.wholphin.util.seasonEpisode
import com.github.damontecres.wholphin.util.stringRes
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.jellyfin.sdk.model.api.DeviceProfile
@ -116,6 +120,7 @@ fun PlaybackPage(
LoadingState.Success -> {
val prefs = preferences.appPreferences.playbackPreferences
val scope = rememberCoroutineScope()
val density = LocalDensity.current
val player = viewModel.player
val title by viewModel.title.observeAsState(null)
@ -156,6 +161,13 @@ fun PlaybackPage(
OneTimeLaunchedEffect {
player.addListener(cueListener)
if (prefs.playerBackend == PlayerBackend.MPV) {
scope.launch(Dispatchers.Main + ExceptionHandler()) {
preferences.appPreferences.interfacePreferences.subtitlesPreferences.applyToMpv(
density,
)
}
}
}
DisposableEffect(Unit) {
onDispose { player.removeListener(cueListener) }

View file

@ -4,6 +4,8 @@ import android.graphics.Typeface
import androidx.annotation.OptIn
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.sp
import androidx.media3.common.util.UnstableApi
import androidx.media3.ui.CaptionStyleCompat
import com.github.damontecres.wholphin.R
@ -17,6 +19,8 @@ import com.github.damontecres.wholphin.preferences.SubtitlePreferences
import com.github.damontecres.wholphin.preferences.updateSubtitlePreferences
import com.github.damontecres.wholphin.ui.indexOfFirstOrNull
import com.github.damontecres.wholphin.ui.preferences.PreferenceGroup
import com.github.damontecres.wholphin.util.mpv.MPVLib
import com.github.damontecres.wholphin.util.mpv.setPropertyColor
object SubtitleSettings {
val FontSize =
@ -245,4 +249,51 @@ object SubtitleSettings {
},
)
}
fun SubtitlePreferences.applyToMpv(density: Density) {
val fo = (fontOpacity / 100.0 * 255).toInt().shl(24)
val fc = Color(fo.or(fontColor))
val bg = Color((backgroundOpacity / 100.0 * 255).toInt().shl(24).or(backgroundColor))
val edge = Color(fo.or(edgeColor))
// TODO weird, but seems to get the size to be very close to matching sizes between renderers
val fontSizePx = with(density) { fontSize.sp.toPx() * .8 }.toInt()
MPVLib.setPropertyInt("sub-font-size", fontSizePx)
MPVLib.setPropertyColor("sub-color", fc)
MPVLib.setPropertyColor("sub-outline-color", edge)
when (edgeStyle) {
EdgeStyle.EDGE_NONE,
EdgeStyle.UNRECOGNIZED,
-> {
MPVLib.setPropertyInt("sub-shadow-offset", 0)
MPVLib.setPropertyDouble("sub-outline-size", 0.0)
}
EdgeStyle.EDGE_SOLID -> {
MPVLib.setPropertyInt("sub-shadow-offset", 0)
MPVLib.setPropertyDouble("sub-outline-size", 1.15)
}
EdgeStyle.EDGE_SHADOW -> {
MPVLib.setPropertyInt("sub-shadow-offset", 4)
MPVLib.setPropertyDouble("sub-outline-size", 0.0)
}
}
MPVLib.setPropertyBoolean("sub-bold", fontBold)
MPVLib.setPropertyBoolean("sub-italic", fontItalic)
MPVLib.setPropertyColor("sub-back-color", bg)
val borderStyle =
when (backgroundStyle) {
BackgroundStyle.UNRECOGNIZED,
BackgroundStyle.BG_NONE,
-> "outline-and-shadow"
BackgroundStyle.BG_WRAP -> "opaque-box"
BackgroundStyle.BG_BOXED -> "background-box"
}
MPVLib.setPropertyString("sub-border-style", borderStyle)
}
}

View file

@ -105,16 +105,6 @@ class MpvPlayer(
MPVLib.setOptionString("demuxer-max-bytes", "${cacheMegs * 1024 * 1024}")
MPVLib.setOptionString("demuxer-max-back-bytes", "${cacheMegs * 1024 * 1024}")
// TODO make configurable
// Subtitle styling
MPVLib.setPropertyInt("sub-font-size", 56)
MPVLib.setPropertyColor("sub-color", Color.White)
MPVLib.setPropertyColor("sub-outline-color", Color.Black)
MPVLib.setPropertyDouble("sub-outline-size", 1.65)
// sub-back-color
// sub-border-style
MPVLib.init()
MPVLib.setOptionString("force-window", "no")
@ -752,7 +742,7 @@ class MpvPlayer(
set(value) = MPVLib.setPropertyDouble("sub-delay", value)
}
private fun MPVLib.setPropertyColor(
fun MPVLib.setPropertyColor(
property: String,
color: Color,
) = MPVLib.setPropertyString(property, color.mpvFormat)