[feat] Video system optimization2

This commit is contained in:
acite
2025-09-20 03:18:25 +08:00
parent 947ffc4599
commit 55ea2e1ae3
4 changed files with 245 additions and 39 deletions

View File

@@ -5,6 +5,7 @@ import android.content.Context
import android.content.pm.ActivityInfo
import android.content.res.Configuration
import android.media.AudioManager
import android.view.View
import androidx.activity.compose.BackHandler
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
@@ -46,6 +47,7 @@ import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
@@ -85,6 +87,7 @@ import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Shadow
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
import androidx.compose.ui.input.nestedscroll.nestedScroll
@@ -93,9 +96,16 @@ import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.sp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.media3.common.text.Cue
import androidx.media3.common.util.UnstableApi
import coil3.ImageLoader
import coil3.compose.AsyncImage
import coil3.request.ImageRequest
@@ -207,6 +217,64 @@ fun BiliMiniSlider(
)
}
@Composable
fun SubtitleOverlay(
cues: List<Cue>,
modifier: Modifier = Modifier,
maxLines: Int = 2,
textSize: TextUnit = 14.sp,
backgroundAlpha: Float = 0.6f,
horizontalMargin: Dp = 16.dp,
bottomMargin: Dp = 14.dp,
contentPadding: Dp = 6.dp,
cornerRadius: Dp = 6.dp,
textColor: Color = Color.White
) {
val raw = if (cues.isEmpty()) "" else cues.joinToString(separator = "\n") { it.text?.toString() ?: "" }.trim()
if (raw.isEmpty()) return
val textAlign = when (cues.firstOrNull()?.textAlignment) {
android.text.Layout.Alignment.ALIGN_CENTER -> TextAlign.Center
android.text.Layout.Alignment.ALIGN_OPPOSITE -> TextAlign.End
android.text.Layout.Alignment.ALIGN_NORMAL -> TextAlign.Start
else -> TextAlign.Center
}
val blurPx = with(LocalDensity.current) { (2.dp).toPx() }
Box(
modifier = modifier,
contentAlignment = Alignment.BottomCenter
) {
Box(
modifier = Modifier
.padding(start = horizontalMargin, end = horizontalMargin, bottom = bottomMargin)
.wrapContentWidth(Alignment.CenterHorizontally)
.clip(RoundedCornerShape(cornerRadius))
.background(Color.Black.copy(alpha = backgroundAlpha))
.padding(horizontal = 12.dp, vertical = contentPadding)
) {
Text(
text = raw,
maxLines = maxLines,
overflow = TextOverflow.Ellipsis,
style = TextStyle(
color = textColor,
fontSize = textSize,
shadow = Shadow(
color = Color.Black.copy(alpha = 0.85f),
offset = Offset(0f, 0f),
blurRadius = blurPx
)
),
textAlign = textAlign,
modifier = Modifier
)
}
}
}
@Composable
fun VideoPlayer(
videoPlayerViewModel: VideoPlayerViewModel = hiltViewModel<VideoPlayerViewModel>(),
@@ -227,6 +295,7 @@ fun VideoPlayer(
}
}
@androidx.annotation.OptIn(UnstableApi::class)
@Composable
fun PortalCorePlayer(modifier: Modifier, videoPlayerViewModel: VideoPlayerViewModel, cover: Float)
{
@@ -255,6 +324,9 @@ fun PortalCorePlayer(modifier: Modifier, videoPlayerViewModel: VideoPlayerViewMo
).apply {
player = exoPlayer
useController = false
subtitleView?.let { sv ->
sv.visibility = View.GONE
}
}
},
modifier = Modifier
@@ -555,6 +627,11 @@ fun PortalCorePlayer(modifier: Modifier, videoPlayerViewModel: VideoPlayerViewMo
}
}
}
SubtitleOverlay(
cues = videoPlayerViewModel.cues,
modifier = Modifier.matchParentSize()
)
}
}
@@ -829,6 +906,7 @@ fun SingleImageItem(img: KeyImage, imageLoader: ImageLoader) {
)
}
@androidx.annotation.OptIn(UnstableApi::class)
@Composable
fun VideoPlayerLandscape(videoPlayerViewModel: VideoPlayerViewModel)
{
@@ -867,6 +945,9 @@ fun VideoPlayerLandscape(videoPlayerViewModel: VideoPlayerViewModel)
).apply {
player = exoPlayer
useController = false
subtitleView?.let { sv ->
sv.visibility = View.GONE
}
}
},
modifier = Modifier
@@ -1106,8 +1187,6 @@ fun VideoPlayerLandscape(videoPlayerViewModel: VideoPlayerViewModel)
}
}
AnimatedVisibility(
visible = videoPlayerViewModel.planeVisibility,
enter = slideInVertically(initialOffsetY = { fullHeight -> fullHeight }),
@@ -1170,6 +1249,11 @@ fun VideoPlayerLandscape(videoPlayerViewModel: VideoPlayerViewModel)
}
}
}
SubtitleOverlay(
cues = videoPlayerViewModel.cues,
modifier = Modifier.matchParentSize()
)
}
}
}