mirror of
https://github.com/bbara04/Purefin.git
synced 2026-07-23 19:26:50 +00:00
feat(player): batch relative seek requests
This commit is contained in:
@@ -49,6 +49,9 @@ class PlayerViewModel @Inject constructor(
|
||||
val controlsVisible: StateFlow<Boolean> = _controlsVisible.asStateFlow()
|
||||
|
||||
private val controlsAutoHidePolicy = ControlsAutoHidePolicy(DEFAULT_CONTROLS_AUTO_HIDE_MS)
|
||||
private val seekByCollector = SeekByCollector(viewModelScope) { deltaMs ->
|
||||
playerManager.seekBy(deltaMs)
|
||||
}
|
||||
private var autoHideJob: Job? = null
|
||||
private var dataErrorMessage: String? = null
|
||||
|
||||
@@ -191,18 +194,21 @@ class PlayerViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
fun seekTo(positionMs: Long) {
|
||||
seekByCollector.clear()
|
||||
playerManager.seekTo(positionMs)
|
||||
}
|
||||
|
||||
fun seekBy(deltaMs: Long) {
|
||||
playerManager.seekBy(deltaMs)
|
||||
seekByCollector.seekBySoon(deltaMs)
|
||||
}
|
||||
|
||||
fun seekToLiveEdge() {
|
||||
seekByCollector.clear()
|
||||
playerManager.seekToLiveEdge()
|
||||
}
|
||||
|
||||
fun skipActiveSegment() {
|
||||
seekByCollector.clear()
|
||||
playerManager.skipActiveSegment()
|
||||
}
|
||||
|
||||
@@ -240,11 +246,13 @@ class PlayerViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
fun next(autoHideDelayMs: Long = DEFAULT_CONTROLS_AUTO_HIDE_MS) {
|
||||
seekByCollector.clear()
|
||||
playerManager.next()
|
||||
showControls(autoHideDelayMs)
|
||||
}
|
||||
|
||||
fun previous(autoHideDelayMs: Long = DEFAULT_CONTROLS_AUTO_HIDE_MS) {
|
||||
seekByCollector.clear()
|
||||
playerManager.previous()
|
||||
showControls(autoHideDelayMs)
|
||||
}
|
||||
@@ -258,6 +266,7 @@ class PlayerViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
fun playQueueItem(id: String) {
|
||||
seekByCollector.clear()
|
||||
playerManager.play(id.toUuidOrNull() ?: return)
|
||||
showControls()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package hu.bbara.purefin.player.viewmodel
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class SeekByCollector(
|
||||
private val scope: CoroutineScope,
|
||||
private val intervalMs: Long = 120,
|
||||
private val seekBy: (Long) -> Unit,
|
||||
) {
|
||||
private var pendingSeekMs = 0L
|
||||
private var flushJob: Job? = null
|
||||
|
||||
fun seekBySoon(deltaMs: Long) {
|
||||
pendingSeekMs += deltaMs
|
||||
if (flushJob?.isActive != true) {
|
||||
scheduleFlush()
|
||||
}
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
pendingSeekMs = 0
|
||||
flushJob?.cancel()
|
||||
flushJob = null
|
||||
}
|
||||
|
||||
private fun scheduleFlush() {
|
||||
flushJob = scope.launch {
|
||||
delay(intervalMs)
|
||||
flush()
|
||||
}
|
||||
}
|
||||
|
||||
private fun flush() {
|
||||
val deltaMs = pendingSeekMs
|
||||
pendingSeekMs = 0
|
||||
if (deltaMs != 0L) {
|
||||
seekBy(deltaMs)
|
||||
}
|
||||
if (pendingSeekMs != 0L) {
|
||||
scheduleFlush()
|
||||
} else {
|
||||
flushJob = null
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user