mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-10 18:36:15 -08:00
fix(playback): seek Embedded MPV steps relative to mpv's own position
Arrow keys and the ±10 s buttons in the Embedded MPV player advanced only about a second per press when pressed repeatedly or held. The shortcuts already asked for 5 s steps, but `EmbeddedMpvCommandRunner.seekBy` turned each step into an absolute `seek` computed from `session.positionSeconds`, which is floored to whole seconds, polled every 500 ms (helper snapshots at most every 250 ms) and not refreshed by the seek reply. Every press inside that window therefore landed on the same target. Steps now go through a new `EMBEDDED_MPV_SEEK_BY` IPC / `seekEmbeddedMpvBy` bridge method that every backend forwards as mpv `seek <delta> relative+exact`: `seekBy` exports in the macOS addon and the Windows/Linux `wid` addon (Linux over its JSON IPC socket), and a `seek-by` stdin command in the frame-copy helper. mpv resolves the delta against its own position and merges queued relative seeks, so presses accumulate as in mpv itself. The absolute form survives only as a fallback for a preload without the method or an addon binary without `seekBy`; the timeline scrub still commits an absolute target. Validated with a real mpv 0.39 IPC probe: three relative seeks in a burst advance +15 s, three absolute seeks from one stale base advance +5 s. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
078bd07d94
commit
ae85428065
18 files changed
+300
-7
No files matched your search
@@ -166,7 +166,7 @@ The renderer never gets direct native-module access. It can only call the preloa
|
||||
- load playback
|
||||
- set bounds
|
||||
- play/pause
|
||||
- seek
|
||||
- seek (absolute target) and seek by (relative step)
|
||||
- set volume
|
||||
- set audio track
|
||||
- start/stop live stream recording
|
||||
@@ -476,6 +476,8 @@ VOD and episode payloads carry `contentInfo` and are treated as non-live unless
|
||||
|
||||
Live catchup is different: the catchup URL already encodes the archive window, so live catchup playback must not pass an absolute Unix timestamp as `startTime`.
|
||||
|
||||
Seeking has two IPC shapes. The timeline scrub commits one absolute target (`seekEmbeddedMpv` → mpv `seek <t> absolute`). Arrow-key and ±10 s button steps go through `seekEmbeddedMpvBy`, which every backend forwards as a relative mpv seek (`seek <delta> relative+exact`): the macOS and Windows addons via their `seekBy` export, the frame-copy helper via the `seek-by\tseconds=<delta>` stdin command, and Linux over the MPV JSON IPC socket. The renderer must never derive an absolute target for a step from `session.positionSeconds`: that value is floored to whole seconds and refreshed at most every 500 ms (the helper emits snapshots at most every 250 ms), and a seek reply does not carry the new position yet, so every press inside that window landed on the same target and a burst of presses advanced by roughly one second each. mpv resolves relative seeks against its own position and merges the ones still queued, so presses accumulate exactly as they do in mpv itself. `EmbeddedMpvNativeService.seekBy` keeps an absolute fallback computed from the addon's own snapshot only for an addon binary built before `seekBy` existed, and `EmbeddedMpvCommandRunner.seekBy` keeps the same fallback for a preload without `seekEmbeddedMpvBy`.
|
||||
|
||||
Audio tracks are discovered from MPV's `track-list` property. The selected track is controlled through MPV's `aid` property. Switching tracks must not reload the stream.
|
||||
|
||||
Subtitle tracks mirror the audio-track contract: same `track-list` source, same parsing pipeline, but selected through MPV's `sid` property. A `trackId` of `-1` from the renderer is interpreted as "disable subtitles" and translated to `sid=no` at the addon boundary. Playback speed is observed and set through MPV's `speed` property, clamped at the addon to `[0.25, 4.0]`. Aspect override uses MPV's `video-aspect-override` property as a passthrough string ("no", "16:9", "4:3", "21:9", "2.35:1"). All four properties (`sid`, `speed`, `video-aspect-override`, plus `aid`) are observed at session init so renderer state stays in sync with the native side without needing extra round-trips.
|
||||
|
||||
@@ -215,7 +215,9 @@ owner.
|
||||
`PlayerControlsCommands` is an imperative, fire-and-forget surface:
|
||||
|
||||
- `togglePlay`
|
||||
- `seekTo` / `seekBy`
|
||||
- `seekTo` / `seekBy` — `seekBy` is a relative command; Embedded MPV forwards
|
||||
the delta to mpv itself instead of adding it to the snapshot position (see
|
||||
`embedded-mpv-native.md`, "Resume And Track Handling")
|
||||
- `setVolume`
|
||||
- `setAudioTrack` / `setSubtitleTrack`
|
||||
- `addExternalSubtitleFile` / `setSubtitleDelay` / `setSubtitleStyle`
|
||||
|
||||
Reference in new issue
Block a user