Skip to content

Commit

Permalink
新增进度条装扮显示
Browse files Browse the repository at this point in the history
  • Loading branch information
aaa1115910 committed Jun 10, 2024
1 parent b154506 commit c721fc5
Show file tree
Hide file tree
Showing 15 changed files with 421 additions and 112 deletions.
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ dependencies {
implementation(libs.ktor.server.cio)
implementation(libs.ktor.server.core)
implementation(libs.logging)
implementation(libs.lottie)
implementation(libs.material)
implementation(libs.qrcode)
implementation(libs.rememberPreference)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ class RemoteControllerPanelDemoActivity : ComponentActivity() {
epid: Int? = null,
seasonId: Int? = null,
isVerticalVideo: Boolean = false,
proxyArea: ProxyArea = ProxyArea.MainLand
proxyArea: ProxyArea = ProxyArea.MainLand,
playerIconIdle: String = "",
playerIconMoving: String = ""
) {
context.startActivity(
Intent(context, RemoteControllerPanelDemoActivity::class.java).apply {
Expand All @@ -44,6 +46,8 @@ class RemoteControllerPanelDemoActivity : ComponentActivity() {
putExtra("seasonId", seasonId)
putExtra("isVerticalVideo", isVerticalVideo)
putExtra("proxy_area", proxyArea.ordinal)
putExtra("playerIconIdle", playerIconIdle)
putExtra("playerIconMoving", playerIconMoving)
}
)
}
Expand Down Expand Up @@ -80,7 +84,9 @@ fun RemoteControllerPanelDemoScreen(
epid = intent.getIntExtra("epid", 0),
seasonId = intent.getIntExtra("seasonId", 0),
isVerticalVideo = intent.getBooleanExtra("isVerticalVideo", false),
proxyArea = ProxyArea.entries[intent.getIntExtra("proxy_area", 0)]
proxyArea = ProxyArea.entries[intent.getIntExtra("proxy_area", 0)],
playerIconIdle = intent.getStringExtra("playerIconIdle") ?: "",
playerIconMoving = intent.getStringExtra("playerIconMoving") ?: ""
)
context.finish()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ class VideoPlayerV3Activity : ComponentActivity() {
epid: Int? = null,
seasonId: Int? = null,
isVerticalVideo: Boolean = false,
proxyArea: ProxyArea = ProxyArea.MainLand
proxyArea: ProxyArea = ProxyArea.MainLand,
playerIconIdle: String = "",
playerIconMoving: String = ""
) {
context.startActivity(
Intent(context, VideoPlayerV3Activity::class.java).apply {
Expand All @@ -50,6 +52,8 @@ class VideoPlayerV3Activity : ComponentActivity() {
putExtra("seasonId", seasonId)
putExtra("isVerticalVideo", isVerticalVideo)
putExtra("proxy_area", proxyArea.ordinal)
putExtra("playerIconIdle", playerIconIdle)
putExtra("playerIconMoving", playerIconMoving)
}
)
}
Expand Down Expand Up @@ -117,6 +121,8 @@ class VideoPlayerV3Activity : ComponentActivity() {
val seasonId = intent.getIntExtra("seasonId", 0)
val isVerticalVideo = intent.getBooleanExtra("isVerticalVideo", false)
val proxyArea = ProxyArea.entries[intent.getIntExtra("proxy_area", 0)]
val playerIconIdle = intent.getStringExtra("playerIconIdle") ?: ""
val playerIconMoving = intent.getStringExtra("playerIconMoving") ?: ""
logger.fInfo { "Launch parameter: [aid=$aid, cid=$cid]" }
playerViewModel.apply {
loadPlayUrl(
Expand All @@ -133,6 +139,8 @@ class VideoPlayerV3Activity : ComponentActivity() {
this.seasonId = seasonId
this.isVerticalVideo = isVerticalVideo
this.proxyArea = proxyArea
this.playerIconIdle = playerIconIdle
this.playerIconMoving = playerIconMoving
}
} else {
logger.fInfo { "Null launch parameter" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ fun ControllerVideoInfo(
title: String,
secondTitle: String,
clock: Triple<Int, Int, Int>,
idleIcon: String,
movingIcon: String,
onHideInfo: () -> Unit
) {
var seekHideTimer: CountDownTimer? by remember { mutableStateOf(null) }
Expand Down Expand Up @@ -93,7 +95,9 @@ fun ControllerVideoInfo(
) {
ControllerVideoInfoBottom(
infoData = infoData,
partTitle = secondTitle
partTitle = secondTitle,
idleIcon = idleIcon,
movingIcon = movingIcon
)
}
}
Expand Down Expand Up @@ -140,7 +144,9 @@ fun ControllerVideoInfoTop(
fun ControllerVideoInfoBottom(
modifier: Modifier = Modifier,
partTitle: String,
infoData: VideoPlayerInfoData
infoData: VideoPlayerInfoData,
idleIcon: String,
movingIcon: String
) {
Column(
modifier = modifier
Expand Down Expand Up @@ -184,7 +190,10 @@ fun ControllerVideoInfoBottom(
.padding(horizontal = 24.dp),
duration = infoData.totalDuration,
position = infoData.currentTime,
bufferedPercentage = infoData.bufferedPercentage
bufferedPercentage = infoData.bufferedPercentage,
moveState = SeekMoveState.Idle,
idleIcon = idleIcon,
movingIcon = movingIcon
)
}
}
Expand Down Expand Up @@ -257,7 +266,9 @@ private fun ControllerVideoInfoPreview() {
title = "【A320】民航史上最佳逆袭!A320的前世今生!民航史上最佳逆袭!A320的前世今生!",
secondTitle = "2023车队车手介绍分析预测",
clock = Triple(12, 30, 30),
onHideInfo = {}
onHideInfo = {},
idleIcon = "",
movingIcon = ""
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package dev.aaa1115910.bv.component.controllers2

import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.tv.material3.Surface
import com.airbnb.lottie.compose.LottieAnimation
import com.airbnb.lottie.compose.LottieCompositionSpec
import com.airbnb.lottie.compose.rememberLottieComposition

@Composable
fun ProgressSeekThumb(
modifier: Modifier = Modifier,
state: SeekMoveState,
idleJsonUrl: String,
movingJsonUrl: String
) {
val idleComposition by rememberLottieComposition(
spec = LottieCompositionSpec.Url(idleJsonUrl)
)
val movingComposition by rememberLottieComposition(
spec = LottieCompositionSpec.Url(movingJsonUrl)
)

val idleProgress by animateFloatAsState(
targetValue = when (state) {
SeekMoveState.Idle -> 1f
else -> 0f
},
animationSpec = when (state) {
SeekMoveState.Idle -> tween(800)
else -> tween(0)
},
label = "idle progress"
)

val movingProgress by animateFloatAsState(
targetValue = when (state) {
SeekMoveState.Backward -> 0f
SeekMoveState.Forward -> 1f
else -> 0.5f
},
animationSpec = when (state) {
SeekMoveState.Backward -> tween(800)
SeekMoveState.Forward -> tween(800)
else -> tween(0)
},
label = "moving progress"
)

LottieAnimation(
modifier = modifier
.size(48.dp),
composition = when (state) {
SeekMoveState.Backward -> movingComposition
SeekMoveState.Forward -> movingComposition
SeekMoveState.Idle -> idleComposition
},
progress = {
when (state) {
SeekMoveState.Backward -> movingProgress
SeekMoveState.Forward -> movingProgress
SeekMoveState.Idle -> idleProgress
}
}
)
}

enum class SeekMoveState {
Backward,
Forward,
Idle
}

@Preview
@Composable
private fun ProgressSeekThumbPreview() {
var state by remember { mutableStateOf(SeekMoveState.Idle) }
Surface {
Column {
ProgressSeekThumb(
state = state,
idleJsonUrl = "https://i0.hdslb.com/bfs/garb/item/df917f079cd8175cc851cd1e19a197d810a1c6b7.json",
movingJsonUrl = "https://i0.hdslb.com/bfs/garb/item/b61bb387a4c895ef165798102ef322c631a9e4e1.json"
)
Button(onClick = { state = SeekMoveState.Idle }) { Text(text = "idle") }
Button(onClick = { state = SeekMoveState.Backward }) { Text(text = "backward") }
Button(onClick = { state = SeekMoveState.Forward }) { Text(text = "forward") }
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,10 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowDropDown
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
Expand All @@ -25,19 +20,19 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import androidx.compose.ui.unit.dp
import androidx.tv.material3.Icon
import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.Text
import dev.aaa1115910.bv.component.controllers.info.VideoPlayerInfoData
import dev.aaa1115910.bv.ui.theme.BVTheme
import dev.aaa1115910.bv.util.formatMinSec

@Composable
fun SeekController(
modifier: Modifier = Modifier,
show: Boolean,
infoData: VideoPlayerInfoData,
goTime: Long
goTime: Long,
moveState: SeekMoveState,
idleIcon: String,
movingIcon: String
) {
Box(
modifier = modifier.fillMaxSize()
Expand All @@ -51,7 +46,10 @@ fun SeekController(
) {
SeekController(
duration = infoData.totalDuration,
position = goTime
position = goTime,
moveState = moveState,
idleIcon = idleIcon,
movingIcon = movingIcon
)
}
}
Expand All @@ -61,7 +59,10 @@ fun SeekController(
private fun SeekController(
modifier: Modifier = Modifier,
duration: Long,
position: Long
position: Long,
moveState: SeekMoveState,
idleIcon: String,
movingIcon: String
) {
Box {
Column(
Expand All @@ -77,58 +78,29 @@ private fun SeekController(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 24.dp)
.offset(y = 12.dp),
.padding(top = 8.dp),
duration = duration,
position = position,
bufferedPercentage = 0
bufferedPercentage = 1,
moveState = moveState,
idleIcon = idleIcon,
movingIcon = movingIcon,
showPosition = true
)
}
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = (12.5).dp)
.offset(y = (-6).dp),
horizontalArrangement = Arrangement.End
) {
CurrentPositionTip(position = position)
Spacer(
// 避免在开始播放前,获取到总长度为 0 时导致崩溃
modifier = Modifier.fillMaxWidth((duration - position) / (duration + 1).toFloat())
)
}
}
}

@Composable
private fun CurrentPositionTip(
modifier: Modifier = Modifier,
position: Long
) {
Column(
modifier = modifier,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
modifier = Modifier.offset(y = 8.dp),
text = position.formatMinSec()
)
Icon(imageVector = Icons.Default.ArrowDropDown, contentDescription = null)
}
}

@Preview
@Composable
private fun CurrentPositionTipPreview() {
CurrentPositionTip(position = 234_000)
}

@Preview(device = "id:tv_1080p")
@Composable
private fun VideoProgressSeekPreview(@PreviewParameter(VideoProgressProvider::class) data: Pair<Long, Long>) {
BVTheme {
SeekController(
duration = data.first,
position = data.second
position = data.second,
moveState = SeekMoveState.Idle,
idleIcon = "",
movingIcon = ""
)
}
}
Expand Down
Loading

0 comments on commit c721fc5

Please sign in to comment.