Skip to content

Commit

Permalink
fix: episode progress draw & progress save loop
Browse files Browse the repository at this point in the history
  • Loading branch information
muedsa committed Nov 13, 2023
1 parent 7237d86 commit d504d06
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package com.muedsa.agetv.ui.features.detail

import androidx.activity.compose.BackHandler
import androidx.compose.foundation.focusable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.collectIsFocusedAsState
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
Expand All @@ -18,12 +20,13 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.draw.drawWithCache
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.clipRect
import androidx.compose.ui.graphics.drawscope.scale
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.tv.foundation.lazy.list.TvLazyRow
Expand All @@ -35,6 +38,7 @@ import androidx.tv.material3.WideButton
import com.muedsa.agetv.model.dandanplay.DanEpisode
import com.muedsa.agetv.room.model.EpisodeProgressModel
import com.muedsa.compose.tv.theme.ImageCardRowCardPadding
import kotlin.math.max

const val EpisodePageSize = 20
val EpisodeProgressStrokeWidth = 12.dp
Expand Down Expand Up @@ -109,30 +113,44 @@ fun EpisodeListWidget(
items = currentPartEpisodeList,
key = { _, item -> item[1] }
) { episodePartIndex, episode ->
val interactionSource = remember { MutableInteractionSource() }
val focusedState = interactionSource.collectIsFocusedAsState()
WideButton(
modifier = Modifier
.padding(end = 12.dp)
.drawBehind {
.drawWithCache {
// 进度条
episodeProgressMap[episode[0]]?.let { model ->
val strokeWidthPx = EpisodeProgressStrokeWidth.toPx()
val wideButtonCornerRadiusPx = WideButtonCornerRadius.toPx()
val width = size.width * model.progress / model.duration
val height = strokeWidthPx / 2
clipRect(
right = width,
bottom = height
) {
drawRoundRect(
color = Color.Red,
cornerRadius = CornerRadius(
wideButtonCornerRadiusPx,
wideButtonCornerRadiusPx
)
)
val model = episodeProgressMap[episode[0]]
val strokeWidthPx = EpisodeProgressStrokeWidth.toPx()
val wideButtonCornerRadiusPx = WideButtonCornerRadius.toPx()
val width = if (model != null) {
val progressRatio =
model.progress.toFloat() / model.duration
size.width * max(progressRatio, 0.1f)
} else 0f
val height = strokeWidthPx / 2
val cornerRadius = CornerRadius(
wideButtonCornerRadiusPx,
wideButtonCornerRadiusPx
)
onDrawWithContent {
drawContent()
if (width > 0) {
scale(if (focusedState.value) 1.1f else 1f) {
clipRect(
right = width,
bottom = height
) {
drawRoundRect(
color = Color.Red,
cornerRadius = cornerRadius
)
}
}
}
}
},
interactionSource = interactionSource,
title = {
Text(text = episode[0], overflow = TextOverflow.Ellipsis)
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ fun PlaybackScreen(
if (playerEnd) {
if (episodeProgress.aid == aid && exoplayerHolder != null) {
val exoPlayer = exoplayerHolder!!
episodeProgress.progress = exoPlayer.duration
episodeProgress.duration = exoPlayer.duration
episodeProgress.updateAt = System.currentTimeMillis()
playbackViewModel.saveEpisodeProgress(episodeProgress)
Expand All @@ -77,15 +78,17 @@ fun PlaybackScreen(
LaunchedEffect(key1 = exoplayerHolder) {
if (exoplayerHolder != null) {
val exoPlayer = exoplayerHolder!!
delay(10_000)
if (episodeProgress.aid == aid) {
episodeProgress.progress = exoPlayer.currentPosition
episodeProgress.duration = exoPlayer.duration
if (episodeProgress.progress + 5_000 > episodeProgress.duration) {
episodeProgress.progress = max(episodeProgress.duration - 5_000, 0)
while (exoplayerHolder != null) {
delay(10_000)
if (episodeProgress.aid == aid) {
episodeProgress.progress = exoPlayer.currentPosition
episodeProgress.duration = exoPlayer.duration
if (episodeProgress.progress + 5_000 > episodeProgress.duration) {
episodeProgress.progress = max(episodeProgress.duration - 5_000, 0)
}
episodeProgress.updateAt = System.currentTimeMillis()
playbackViewModel.saveEpisodeProgress(episodeProgress)
}
episodeProgress.updateAt = System.currentTimeMillis()
playbackViewModel.saveEpisodeProgress(episodeProgress)
}
}
}
Expand Down Expand Up @@ -119,18 +122,30 @@ fun PlaybackScreen(
if (exoplayerHolder == null) {
exoplayerHolder = this@DanmakuVideoPlayer
if (episodeProgress.progress > 0) {
seekTo(episodeProgress.progress)
val progressStr = episodeProgress.progress
.toDuration(DurationUnit.MILLISECONDS)
.toComponents { hours, minutes, seconds, _ ->
String.format(
"%02d:%02d:%02d",
hours,
minutes,
seconds,
)
val position =
if (episodeProgress.progress == episodeProgress.duration) {
// 如果上次已经播放完成则不跳转 从头播放
0
} else if (episodeProgress.duration > 5_000 && episodeProgress.progress > episodeProgress.duration - 5_000) {
// 如果太过接近结束的位置
episodeProgress.duration - 5_000
} else {
episodeProgress.progress
}
errorMsgBoxState.error("跳转到上次播放位置: $progressStr")
if (position > 0) {
seekTo(position)
val positionStr = position
.toDuration(DurationUnit.MILLISECONDS)
.toComponents { hours, minutes, seconds, _ ->
String.format(
"%02d:%02d:%02d",
hours,
minutes,
seconds,
)
}
errorMsgBoxState.error("跳转到上次播放位置: $positionStr")
}
}
}
}
Expand Down

0 comments on commit d504d06

Please sign in to comment.