mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-07-26 22:42:17 +00:00
feat: enhance subtitle styling with adjustable font size and improved iOS bridge integration
This commit is contained in:
parent
0ab26a1ac2
commit
ead49a200b
6 changed files with 43 additions and 75 deletions
|
|
@ -2,6 +2,7 @@ package com.nuvio.app.features.player
|
|||
|
||||
import android.net.Uri
|
||||
import android.util.Log
|
||||
import android.util.TypedValue
|
||||
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
|
|
@ -379,7 +380,7 @@ private fun PlayerView.applySubtitleStyle(style: SubtitleStyleState) {
|
|||
null,
|
||||
)
|
||||
)
|
||||
setFractionalTextSize(SubtitleView.DEFAULT_TEXT_SIZE_FRACTION)
|
||||
setFixedTextSize(TypedValue.COMPLEX_UNIT_SP, style.fontSizeSp.toFloat())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,8 @@ enum class SubtitleTab {
|
|||
data class SubtitleStyleState(
|
||||
val textColor: Color = Color.White,
|
||||
val outlineEnabled: Boolean = false,
|
||||
val bottomOffset: Int = 50,
|
||||
val fontSizeSp: Int = 18,
|
||||
val bottomOffset: Int = 20,
|
||||
) {
|
||||
companion object {
|
||||
val DEFAULT = SubtitleStyleState()
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import androidx.compose.foundation.layout.Box
|
|||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.widthIn
|
||||
|
|
@ -19,7 +18,7 @@ import androidx.compose.material.icons.rounded.KeyboardArrowDown
|
|||
import androidx.compose.material.icons.rounded.KeyboardArrowUp
|
||||
import androidx.compose.material.icons.rounded.Remove
|
||||
import androidx.compose.material.icons.rounded.Tune
|
||||
import androidx.compose.material.icons.rounded.Visibility
|
||||
import androidx.compose.material.icons.rounded.FormatSize
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
|
|
@ -27,13 +26,9 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.Shadow
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import kotlin.math.min
|
||||
|
||||
@Composable
|
||||
fun SubtitleStylePanel(
|
||||
|
|
@ -48,13 +43,6 @@ fun SubtitleStylePanel(
|
|||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(gap),
|
||||
) {
|
||||
LivePreviewCard(
|
||||
style = style,
|
||||
isCompact = isCompact,
|
||||
sectionPadding = sectionPadding,
|
||||
colorScheme = colorScheme,
|
||||
)
|
||||
|
||||
StyleControlsCard(
|
||||
style = style,
|
||||
isCompact = isCompact,
|
||||
|
|
@ -65,64 +53,6 @@ fun SubtitleStylePanel(
|
|||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun LivePreviewCard(
|
||||
style: SubtitleStyleState,
|
||||
isCompact: Boolean,
|
||||
sectionPadding: androidx.compose.ui.unit.Dp,
|
||||
colorScheme: androidx.compose.material3.ColorScheme,
|
||||
) {
|
||||
val previewHeight = if (isCompact) 90.dp else 120.dp
|
||||
val previewFontSize = if (isCompact) 18.sp else 22.sp
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(16.dp))
|
||||
.background(colorScheme.surfaceVariant.copy(alpha = 0.45f))
|
||||
.padding(sectionPadding),
|
||||
) {
|
||||
SectionHeader(
|
||||
icon = Icons.Rounded.Visibility,
|
||||
label = "Preview",
|
||||
)
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(previewHeight)
|
||||
.clip(RoundedCornerShape(8.dp))
|
||||
.background(Color.Black),
|
||||
contentAlignment = Alignment.BottomCenter,
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.padding(bottom = min(80, style.bottomOffset).dp, start = 10.dp, end = 10.dp),
|
||||
) {
|
||||
if (style.outlineEnabled) {
|
||||
Text(
|
||||
text = "The quick brown fox jumps over the lazy dog.",
|
||||
color = Color.Black,
|
||||
fontSize = previewFontSize,
|
||||
style = TextStyle(
|
||||
shadow = Shadow(
|
||||
color = Color.Black,
|
||||
blurRadius = 6f,
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
Text(
|
||||
text = "The quick brown fox jumps over the lazy dog.",
|
||||
color = style.textColor,
|
||||
fontSize = previewFontSize,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun StyleControlsCard(
|
||||
style: SubtitleStyleState,
|
||||
|
|
@ -147,6 +77,33 @@ private fun StyleControlsCard(
|
|||
label = "Style",
|
||||
)
|
||||
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text(
|
||||
text = "Font Size",
|
||||
color = colorScheme.onSurfaceVariant,
|
||||
fontSize = 14.sp,
|
||||
fontWeight = FontWeight.Medium,
|
||||
)
|
||||
StepperControl(
|
||||
value = "${style.fontSizeSp}sp",
|
||||
onMinus = {
|
||||
onStyleChanged(style.copy(fontSizeSp = (style.fontSizeSp - 2).coerceAtLeast(12)))
|
||||
},
|
||||
onPlus = {
|
||||
onStyleChanged(style.copy(fontSizeSp = (style.fontSizeSp + 2).coerceAtMost(40)))
|
||||
},
|
||||
buttonSize = btnSize,
|
||||
buttonRadius = btnRadius,
|
||||
minWidth = 58.dp,
|
||||
minusIcon = Icons.Rounded.Remove,
|
||||
plusIcon = Icons.Rounded.FormatSize,
|
||||
)
|
||||
}
|
||||
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ interface NuvioPlayerBridge {
|
|||
fun applySubtitleStyle(
|
||||
textColor: String,
|
||||
outlineSize: Float,
|
||||
fontSize: Float,
|
||||
subPos: Int,
|
||||
)
|
||||
fun getIsLoading(): Boolean
|
||||
|
|
|
|||
|
|
@ -194,6 +194,7 @@ actual fun PlatformPlayerSurface(
|
|||
bridge.applySubtitleStyle(
|
||||
textColor = style.textColor.toMpvColorString(),
|
||||
outlineSize = if (style.outlineEnabled) 1.65f else 0f,
|
||||
fontSize = style.toMpvSubtitleFontSize(),
|
||||
subPos = style.toMpvSubtitlePosition(),
|
||||
)
|
||||
}
|
||||
|
|
@ -280,6 +281,9 @@ private fun Color.toMpvColorString(): String {
|
|||
private fun SubtitleStyleState.toMpvSubtitlePosition(): Int =
|
||||
(100 - (bottomOffset / 2)).coerceIn(0, 150)
|
||||
|
||||
private fun SubtitleStyleState.toMpvSubtitleFontSize(): Float =
|
||||
(fontSizeSp * 3f).coerceIn(24f, 96f)
|
||||
|
||||
private fun Int.toHexByte(): String {
|
||||
val digits = "0123456789ABCDEF"
|
||||
val value = coerceIn(0, 255)
|
||||
|
|
|
|||
|
|
@ -75,10 +75,11 @@ final class MPVPlayerBridgeImpl: NSObject, NuvioPlayerBridge {
|
|||
func setSubtitleUrl(url: String) { playerVC?.addSubtitleUrl(url) }
|
||||
func clearExternalSubtitle() { playerVC?.removeExternalSubtitles() }
|
||||
func clearExternalSubtitleAndSelect(trackId: Int32) { playerVC?.removeExternalSubtitlesAndSelect(Int(trackId)) }
|
||||
func applySubtitleStyle(textColor: String, outlineSize: Float, subPos: Int32) {
|
||||
func applySubtitleStyle(textColor: String, outlineSize: Float, fontSize: Float, subPos: Int32) {
|
||||
playerVC?.applySubtitleStyle(
|
||||
textColor: textColor,
|
||||
outlineSize: outlineSize,
|
||||
fontSize: fontSize,
|
||||
subPos: Int(subPos)
|
||||
)
|
||||
}
|
||||
|
|
@ -337,7 +338,7 @@ final class MPVPlayerViewController: UIViewController {
|
|||
}
|
||||
}
|
||||
|
||||
func applySubtitleStyle(textColor: String, outlineSize: Float, subPos: Int) {
|
||||
func applySubtitleStyle(textColor: String, outlineSize: Float, fontSize: Float, subPos: Int) {
|
||||
guard mpv != nil else { return }
|
||||
|
||||
checkError(mpv_set_property_string(mpv, "sub-ass-override", "force"))
|
||||
|
|
@ -347,6 +348,9 @@ final class MPVPlayerViewController: UIViewController {
|
|||
var outline = Double(outlineSize)
|
||||
checkError(mpv_set_property(mpv, "sub-outline-size", MPV_FORMAT_DOUBLE, &outline))
|
||||
|
||||
var size = Double(fontSize)
|
||||
checkError(mpv_set_property(mpv, "sub-font-size", MPV_FORMAT_DOUBLE, &size))
|
||||
|
||||
var position = Int64(subPos)
|
||||
checkError(mpv_set_property(mpv, "sub-pos", MPV_FORMAT_INT64, &position))
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue