Skip to content

Commit 279584e

Browse files
committed
feat(subtitle): Optimize the display of subtitles when switching subtitles or skipping progress
1 parent a257376 commit 279584e

File tree

2 files changed

+27
-15
lines changed

2 files changed

+27
-15
lines changed

composeApp/src/commonMain/kotlin/com/jankinwu/fntv/client/ui/screen/PlayerScreen.kt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ fun PlayerOverlay(
446446
}
447447

448448
LaunchedEffect(hlsSubtitleUtil, externalSubtitleUtil) {
449-
hlsSubtitleUtil?.initialize()
449+
hlsSubtitleUtil?.initialize(mediaPlayer.getCurrentPositionMillis())
450450
externalSubtitleUtil?.initialize()
451451
}
452452

@@ -513,7 +513,7 @@ fun PlayerOverlay(
513513
// Check if it's an internal subtitle
514514
if (subtitleStream != null && subtitleStream.isExternal == 0) {
515515
// Reload HLS subtitle repository to fetch new segments
516-
hlsSubtitleUtil?.reload()
516+
// hlsSubtitleUtil?.reload() // Removed reload() to avoid re-initialization conflict
517517
// Don't restart playback for internal subtitles
518518
if (cache.previousSubtitle?.isExternal == 0) {
519519
shouldStartPlayback = false
@@ -1022,6 +1022,13 @@ fun PlayerOverlay(
10221022
val seekPosition = (newProgress * totalDuration).toLong()
10231023
mediaPlayer.seekTo(seekPosition)
10241024
logger.i("Seek to: ${newProgress * 100}%")
1025+
1026+
// Force update subtitle on seek
1027+
if (hlsSubtitleUtil != null) {
1028+
kotlinx.coroutines.CoroutineScope(kotlinx.coroutines.Dispatchers.IO).launch {
1029+
hlsSubtitleUtil.update(seekPosition)
1030+
}
1031+
}
10251032

10261033
callPlayRecord(
10271034
ts = (seekPosition / 1000).toInt(),

composeApp/src/commonMain/kotlin/com/jankinwu/fntv/client/utils/HlsSubtitleUtil.kt

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@ import com.jankinwu.fntv.client.data.model.response.SubtitleStream
77
import com.jankinwu.fntv.client.data.store.AccountDataCache
88
import io.ktor.client.HttpClient
99
import io.ktor.client.request.get
10-
import io.ktor.client.request.header
1110
import io.ktor.client.statement.bodyAsText
12-
import kotlinx.coroutines.delay
1311
import kotlinx.coroutines.Dispatchers
12+
import kotlinx.coroutines.delay
1413
import kotlinx.coroutines.sync.Mutex
1514
import kotlinx.coroutines.sync.withLock
1615
import kotlinx.coroutines.withContext
@@ -103,9 +102,11 @@ class HlsSubtitleUtil(
103102
}
104103
}
105104

106-
suspend fun initialize() {
105+
suspend fun initialize(startPositionMs: Long) {
106+
mutex.withLock {
107+
if (isInitialized) return
108+
}
107109
withContext(Dispatchers.IO) {
108-
if (isInitialized) return@withContext
109110
try {
110111
baseUrl = playLink.substringBeforeLast("/")
111112
val fullPlayLink = constructFullUrl(playLink)
@@ -127,17 +128,21 @@ class HlsSubtitleUtil(
127128
val playlistContent = fetchWithAuth(subtitlePlaylistUrl)
128129

129130
// 4. Parse segments with duration
130-
parseSegments(playlistContent)
131-
132-
isInitialized = true
131+
mutex.withLock {
132+
parseSegments(playlistContent)
133+
isInitialized = true
134+
}
133135
logger.i { "Initialized HLS subtitle repository with ${segments.size} segments" }
136+
137+
// 5. Immediately update for the current position
138+
update(startPositionMs)
134139
} catch (e: Exception) {
135140
logger.e(e) { "Failed to initialize HlsSubtitleRepository" }
136141
}
137142
}
138143
}
139144

140-
suspend fun reload() {
145+
suspend fun reload(startPositionMs: Long = 0L) {
141146
mutex.withLock {
142147
segments.clear()
143148
cues.clear()
@@ -146,7 +151,7 @@ class HlsSubtitleUtil(
146151
lastUpdateCheckTime = 0L
147152
lastProcessedPositionSec = -1.0
148153
}
149-
initialize()
154+
initialize(startPositionMs)
150155
}
151156

152157
suspend fun update(currentPositionMs: Long) = withContext(Dispatchers.IO) {
@@ -335,10 +340,10 @@ class HlsSubtitleUtil(
335340

336341
private suspend fun fetchWithAuth(url: String): String {
337342
return client.get(url) {
338-
if (AccountDataCache.cookieState.isNotBlank()) {
339-
header("cookie", AccountDataCache.cookieState)
340-
header("Authorization", AccountDataCache.authorization)
341-
}
343+
// if (AccountDataCache.cookieState.isNotBlank()) {
344+
// header("cookie", AccountDataCache.cookieState)
345+
// header("Authorization", AccountDataCache.authorization)
346+
// }
342347
}.bodyAsText()
343348
}
344349

0 commit comments

Comments
 (0)