mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 15:50:16 +02:00
Add setting for subtitle outline size (#375)
Adds a settings allowing for adjusting the thickness of unstyled subtitle outlines, if outline is enabled. This is applied for both ExoPlayer & MPV Closes #179  Dev note: the ExoPlayer implementation is bad code, don't write code like this. It works though
This commit is contained in:
parent
a197f6911b
commit
ac10517028
9 changed files with 116 additions and 0 deletions
|
|
@ -170,4 +170,5 @@ fun SubtitlePreferences.Builder.resetSubtitles() {
|
|||
backgroundOpacity = SubtitleSettings.BackgroundOpacity.defaultValue.toInt()
|
||||
backgroundStyle = SubtitleSettings.BackgroundStylePref.defaultValue
|
||||
margin = SubtitleSettings.Margin.defaultValue.toInt()
|
||||
edgeThickness = SubtitleSettings.EdgeThickness.defaultValue.toInt()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -163,4 +163,14 @@ suspend fun upgradeApp(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (previous.isEqualOrBefore(Version.fromString("0.3.5-0-g0"))) {
|
||||
appPreferences.updateData {
|
||||
it.updateSubtitlePreferences {
|
||||
if (edgeThickness < 1) {
|
||||
edgeThickness = SubtitleSettings.EdgeThickness.defaultValue.toInt()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,12 +73,14 @@ 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.calculateEdgeSize
|
||||
import com.github.damontecres.wholphin.ui.preferences.subtitle.SubtitleSettings.toSubtitleStyle
|
||||
import com.github.damontecres.wholphin.ui.seasonEpisode
|
||||
import com.github.damontecres.wholphin.ui.skipStringRes
|
||||
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.Media3SubtitleOverride
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -329,6 +331,10 @@ fun PlaybackPage(
|
|||
},
|
||||
update = {
|
||||
it.setCues(cues)
|
||||
Media3SubtitleOverride(
|
||||
preferences.appPreferences.interfacePreferences.subtitlesPreferences
|
||||
.calculateEdgeSize(density),
|
||||
).apply(it)
|
||||
},
|
||||
onReset = {
|
||||
it.setCues(null)
|
||||
|
|
|
|||
|
|
@ -140,6 +140,23 @@ object SubtitleSettings {
|
|||
},
|
||||
)
|
||||
|
||||
val EdgeThickness =
|
||||
AppSliderPreference<AppPreferences>(
|
||||
title = R.string.edge_size,
|
||||
defaultValue = 4,
|
||||
min = 1,
|
||||
max = 32,
|
||||
interval = 1,
|
||||
getter = {
|
||||
it.interfacePreferences.subtitlesPreferences.edgeThickness
|
||||
.toLong()
|
||||
},
|
||||
setter = { prefs, value ->
|
||||
prefs.updateSubtitlePreferences { edgeThickness = value.toInt() }
|
||||
},
|
||||
summarizer = { value -> value?.let { "${it / 2.0}" } },
|
||||
)
|
||||
|
||||
val BackgroundColor =
|
||||
AppChoicePreference<AppPreferences, Color>(
|
||||
title = R.string.background_color,
|
||||
|
|
@ -230,6 +247,7 @@ object SubtitleSettings {
|
|||
listOf(
|
||||
EdgeStylePref,
|
||||
EdgeColor,
|
||||
EdgeThickness,
|
||||
),
|
||||
),
|
||||
PreferenceGroup(
|
||||
|
|
@ -278,6 +296,8 @@ object SubtitleSettings {
|
|||
)
|
||||
}
|
||||
|
||||
fun SubtitlePreferences.calculateEdgeSize(density: Density): Float = with(density) { (edgeThickness / 2f).dp.toPx() }
|
||||
|
||||
fun SubtitlePreferences.applyToMpv(
|
||||
configuration: Configuration,
|
||||
density: Density,
|
||||
|
|
@ -316,6 +336,8 @@ object SubtitleSettings {
|
|||
MPVLib.setPropertyDouble("sub-outline-size", 0.0)
|
||||
}
|
||||
}
|
||||
val outlineSizePx = calculateEdgeSize(density) * .8
|
||||
MPVLib.setPropertyDouble("sub-outline-size", outlineSizePx)
|
||||
|
||||
// if (fontBold) {
|
||||
// MPVLib.setPropertyString("sub-font", "Roboto Bold")
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import androidx.compose.runtime.setValue
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
|
|
@ -32,7 +33,9 @@ import com.github.damontecres.wholphin.preferences.AppPreferences
|
|||
import com.github.damontecres.wholphin.ui.preferences.PreferenceScreenOption
|
||||
import com.github.damontecres.wholphin.ui.preferences.PreferencesContent
|
||||
import com.github.damontecres.wholphin.ui.preferences.PreferencesViewModel
|
||||
import com.github.damontecres.wholphin.ui.preferences.subtitle.SubtitleSettings.calculateEdgeSize
|
||||
import com.github.damontecres.wholphin.ui.preferences.subtitle.SubtitleSettings.toSubtitleStyle
|
||||
import com.github.damontecres.wholphin.util.Media3SubtitleOverride
|
||||
|
||||
@OptIn(UnstableApi::class)
|
||||
@Composable
|
||||
|
|
@ -41,6 +44,7 @@ fun SubtitleStylePage(
|
|||
modifier: Modifier = Modifier,
|
||||
viewModel: PreferencesViewModel = hiltViewModel(),
|
||||
) {
|
||||
val density = LocalDensity.current
|
||||
var preferences by remember { mutableStateOf(initialPreferences) }
|
||||
LaunchedEffect(Unit) {
|
||||
viewModel.preferenceDataStore.data.collect {
|
||||
|
|
@ -95,6 +99,7 @@ fun SubtitleStylePage(
|
|||
Cue.Builder().setText(text).build(),
|
||||
),
|
||||
)
|
||||
Media3SubtitleOverride(prefs.calculateEdgeSize(density)).apply(it)
|
||||
},
|
||||
modifier =
|
||||
Modifier
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
package com.github.damontecres.wholphin.util
|
||||
|
||||
import androidx.media3.ui.SubtitleView
|
||||
import timber.log.Timber
|
||||
import java.lang.reflect.Field
|
||||
|
||||
/**
|
||||
* Utility class to override private fields in media3's [SubtitleView]
|
||||
*/
|
||||
class Media3SubtitleOverride(
|
||||
val outlineThicknessPx: Float,
|
||||
) {
|
||||
companion object {
|
||||
private lateinit var outputField: Field
|
||||
private lateinit var classCanvasSubtitleOutput: Class<*>
|
||||
private lateinit var paintersField: Field
|
||||
private lateinit var classSubtitlePainter: Class<*>
|
||||
private lateinit var outlineWidthField: Field
|
||||
|
||||
var initialized: Boolean
|
||||
private set
|
||||
|
||||
init {
|
||||
try {
|
||||
// This is bad times
|
||||
outputField = SubtitleView::class.java.getDeclaredField("output")
|
||||
classCanvasSubtitleOutput = Class.forName("androidx.media3.ui.CanvasSubtitleOutput")
|
||||
paintersField = classCanvasSubtitleOutput.getDeclaredField("painters")
|
||||
classSubtitlePainter = Class.forName("androidx.media3.ui.SubtitlePainter")
|
||||
outlineWidthField = classSubtitlePainter.getDeclaredField("outlineWidth")
|
||||
outputField.isAccessible = true
|
||||
outlineWidthField.isAccessible = true
|
||||
paintersField.isAccessible = true
|
||||
initialized = true
|
||||
} catch (ex: Exception) {
|
||||
Timber.w(ex, "Error initializing")
|
||||
initialized = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun apply(subtitleView: SubtitleView) {
|
||||
try {
|
||||
if (initialized) {
|
||||
// Basically hijack the field that controls the subtitle outline size
|
||||
val canvasSubtitleOutput = outputField.get(subtitleView)
|
||||
val painters = paintersField.get(canvasSubtitleOutput) as List<*>
|
||||
painters.forEach { painter ->
|
||||
outlineWidthField.set(painter, outlineThicknessPx)
|
||||
}
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
Timber.w(ex, "Failed to apply")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -121,6 +121,7 @@ message SubtitlePreferences{
|
|||
bool font_bold = 9;
|
||||
bool font_italic = 10;
|
||||
int32 margin = 11;
|
||||
int32 edge_thickness = 12;
|
||||
}
|
||||
|
||||
message InterfacePreferences {
|
||||
|
|
|
|||
|
|
@ -349,6 +349,7 @@
|
|||
<string name="image_type">Image type</string>
|
||||
<string name="cast_and_crew"><![CDATA[Cast & Crew]]></string>
|
||||
<string name="guest_stars">Guest stars</string>
|
||||
<string name="edge_size">Edge size</string>
|
||||
|
||||
|
||||
<string-array name="theme_song_volume">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
package com.github.damontecres.wholphin.test
|
||||
|
||||
import com.github.damontecres.wholphin.util.Media3SubtitleOverride
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
|
||||
class TestMedia3SubtitleOverride {
|
||||
@Test
|
||||
fun test() {
|
||||
// This tests whether the class and field names exist
|
||||
Media3SubtitleOverride(2f)
|
||||
Assert.assertTrue(Media3SubtitleOverride.Companion.initialized)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue