feat(app-phone): трекбар-таймлайн в пульте (seek на любую позицию)
- MediaCommand.SEEK (абсолютный seek на seekMs, поле в протоколе уже было) - MovieController (очки): SEEK → player.seekTo(seekMs.clamp(0,duration)); чистая seekTargetMs - GlassesScreen (пульт): material3 Slider под статус-карточкой (виден при durationMs>0), локальный стейт драга — время под слайдером следует за пальцем (sliderValue ?: positionMs), после отпускания цель держится до подтверждения позиции от очков (±2.5с, таймаут 10с), звук: SEEK → audio.seekTo(seekMs) - Тесты 70/0 phone, 37/0 glasses (MovieControllerSeekTest, сериализация SEEK)
This commit is contained in:
@@ -13,6 +13,14 @@ import pw.binom.viewmate.core.MediaCommand
|
||||
import pw.binom.viewmate.core.protocol.PlayVideo
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Абсолютная цель seek-а: [seekMs] зажимается в [0, durationMs].
|
||||
* durationMs ≤ 0 (ещё не известно / нет контента) → зажимаем только снизу.
|
||||
* Чистая функция — покрыта unit-тестами без Android.
|
||||
*/
|
||||
internal fun seekTargetMs(seekMs: Long, durationMs: Long): Long =
|
||||
seekMs.coerceIn(0L, durationMs.coerceAtLeast(0L))
|
||||
|
||||
/**
|
||||
* Держатель плеера фильма: создаёт/освобождает SimpleExoPlayer,
|
||||
* выполняет команды из WS-протокола. Сам плеер создаётся только по PlayVideo.
|
||||
@@ -81,6 +89,11 @@ class MovieController(private val context: Context) {
|
||||
player.seekTo(target)
|
||||
}
|
||||
|
||||
MediaCommand.SEEK -> {
|
||||
val target = seekTargetMs(seekMs, player.duration)
|
||||
player.seekTo(target)
|
||||
}
|
||||
|
||||
// Звук — на телефоне, переключение аудио-дорожек очкам не нужно.
|
||||
MediaCommand.NEXT_AUDIO, MediaCommand.PREV_AUDIO -> {
|
||||
log("glasses", "MediaCommand $command игнорируется (звук на телефоне)")
|
||||
|
||||
Reference in New Issue
Block a user