mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-07-26 22:42:17 +00:00
fix: improve resume position handling in player and trakt progress logic
This commit is contained in:
parent
f7071e1fc2
commit
b1d9e2dc93
3 changed files with 23 additions and 21 deletions
|
|
@ -507,15 +507,8 @@ fun PlayerScreen(
|
|||
fun switchToSource(stream: StreamItem) {
|
||||
val url = stream.directPlaybackUrl ?: return
|
||||
if (url == activeSourceUrl) return
|
||||
val currentPositionMs = playbackSnapshot.positionMs.coerceAtLeast(0L)
|
||||
flushWatchProgress()
|
||||
val resumeVideoId = buildPlaybackVideoId(
|
||||
parentMetaId = parentMetaId,
|
||||
seasonNumber = activeSeasonNumber,
|
||||
episodeNumber = activeEpisodeNumber,
|
||||
fallbackVideoId = activeVideoId,
|
||||
)
|
||||
val entry = WatchProgressRepository.progressForVideo(resumeVideoId)
|
||||
val resumePositionMs = entry?.lastPositionMs?.takeIf { it > 0L } ?: 0L
|
||||
if (playerSettingsUiState.streamReuseLastLinkEnabled && activeVideoId != null) {
|
||||
val cacheKey = StreamLinkCacheRepository.contentKey(
|
||||
contentType ?: parentMetaType,
|
||||
|
|
@ -538,7 +531,7 @@ fun PlayerScreen(
|
|||
activeStreamSubtitle = stream.streamSubtitle
|
||||
activeProviderName = stream.addonName
|
||||
activeProviderAddonId = stream.addonId
|
||||
activeInitialPositionMs = resumePositionMs
|
||||
activeInitialPositionMs = currentPositionMs
|
||||
activeInitialProgressFraction = null
|
||||
showSourcesPanel = false
|
||||
controlsVisible = true
|
||||
|
|
@ -564,9 +557,11 @@ fun PlayerScreen(
|
|||
fallbackVideoId = epVideoId,
|
||||
)
|
||||
val epEntry = WatchProgressRepository.progressForVideo(epResumeVideoId)
|
||||
val epResumePositionMs = epEntry
|
||||
?.takeIf { !it.isCompleted }
|
||||
?.lastPositionMs?.takeIf { it > 0L } ?: 0L
|
||||
val epResumeFraction = epEntry?.progressPercent
|
||||
?.takeIf { it > 0f }
|
||||
?.let { (it / 100f).coerceIn(0f, 1f) }
|
||||
val epResumePositionMs = epEntry?.lastPositionMs?.takeIf { it > 0L } ?: 0L
|
||||
if (playerSettingsUiState.streamReuseLastLinkEnabled) {
|
||||
val cacheKey = StreamLinkCacheRepository.contentKey(
|
||||
contentType ?: parentMetaType,
|
||||
|
|
@ -595,7 +590,7 @@ fun PlayerScreen(
|
|||
activeEpisodeThumbnail = episode.thumbnail
|
||||
activeVideoId = episode.id
|
||||
activeInitialPositionMs = epResumePositionMs
|
||||
activeInitialProgressFraction = null
|
||||
activeInitialProgressFraction = epResumeFraction
|
||||
controlsVisible = true
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ import kotlinx.serialization.decodeFromString
|
|||
import kotlinx.serialization.json.Json
|
||||
|
||||
private const val BASE_URL = "https://api.trakt.tv"
|
||||
private const val PLAYBACK_SYNTHETIC_DURATION_MS = 100_000L
|
||||
private const val HISTORY_LIMIT = 250
|
||||
private const val METADATA_FETCH_TIMEOUT_MS = 3_500L
|
||||
private const val METADATA_FETCH_CONCURRENCY = 5
|
||||
|
|
@ -356,8 +355,6 @@ object TraktProgressRepository {
|
|||
|
||||
val progressPercent = normalizeTraktProgressPercent(item.progress) ?: return null
|
||||
if (progressPercent <= 0f) return null
|
||||
val progressFraction = progressPercent / 100f
|
||||
val positionMs = (PLAYBACK_SYNTHETIC_DURATION_MS * progressFraction).toLong()
|
||||
|
||||
return WatchProgressEntry(
|
||||
contentType = "movie",
|
||||
|
|
@ -365,8 +362,8 @@ object TraktProgressRepository {
|
|||
parentMetaType = "movie",
|
||||
videoId = parentMetaId,
|
||||
title = movie.title ?: parentMetaId,
|
||||
lastPositionMs = positionMs,
|
||||
durationMs = PLAYBACK_SYNTHETIC_DURATION_MS,
|
||||
lastPositionMs = 0L,
|
||||
durationMs = 0L,
|
||||
lastUpdatedEpochMs = rankedTimestamp(item.pausedAt, fallbackIndex),
|
||||
isCompleted = false,
|
||||
progressPercent = progressPercent,
|
||||
|
|
@ -384,8 +381,6 @@ object TraktProgressRepository {
|
|||
|
||||
val progressPercent = normalizeTraktProgressPercent(item.progress) ?: return null
|
||||
if (progressPercent <= 0f) return null
|
||||
val progressFraction = progressPercent / 100f
|
||||
val positionMs = (PLAYBACK_SYNTHETIC_DURATION_MS * progressFraction).toLong()
|
||||
|
||||
return WatchProgressEntry(
|
||||
contentType = "series",
|
||||
|
|
@ -401,8 +396,8 @@ object TraktProgressRepository {
|
|||
seasonNumber = season,
|
||||
episodeNumber = number,
|
||||
episodeTitle = episode.title,
|
||||
lastPositionMs = positionMs,
|
||||
durationMs = PLAYBACK_SYNTHETIC_DURATION_MS,
|
||||
lastPositionMs = 0L,
|
||||
durationMs = 0L,
|
||||
lastUpdatedEpochMs = rankedTimestamp(item.pausedAt, fallbackIndex),
|
||||
isCompleted = false,
|
||||
progressPercent = progressPercent,
|
||||
|
|
|
|||
|
|
@ -53,6 +53,18 @@ data class WatchProgressEntry(
|
|||
|
||||
val isResumable: Boolean
|
||||
get() = !isCompleted
|
||||
|
||||
fun resolveResumePosition(actualDurationMs: Long): Long {
|
||||
if (actualDurationMs <= 0L) return lastPositionMs.coerceAtLeast(0L)
|
||||
if (durationMs > 0L && lastPositionMs > 0L) {
|
||||
return lastPositionMs.coerceIn(0L, actualDurationMs)
|
||||
}
|
||||
progressPercent?.let { percent ->
|
||||
val fraction = (percent / 100f).coerceIn(0f, 1f)
|
||||
return (actualDurationMs * fraction).toLong()
|
||||
}
|
||||
return lastPositionMs.coerceAtLeast(0L)
|
||||
}
|
||||
}
|
||||
|
||||
data class WatchProgressUiState(
|
||||
|
|
|
|||
Loading…
Reference in a new issue