From ae85428065bd8a97b6ade68fb2939733d5572e10 Mon Sep 17 00:00:00 2001 From: 4gray Date: Thu, 3 Sep 2026 20:57:45 +0200 Subject: [PATCH] fix(playback): seek Embedded MPV steps relative to mpv's own position MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 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 --- .changes/playback-embedded-mpv-seek-steps.md | 10 ++++ CLAUDE.md | 2 +- .../native/helper/mpv_frame_helper.cpp | 11 ++++ .../native/src/embedded_mpv.mm | 45 +++++++++++++++++ .../native/src/embedded_mpv_wid_common.h | 50 +++++++++++++++++++ .../src/app/api/main.preload.ts | 5 ++ .../src/app/events/embedded-mpv.events.ts | 7 +++ .../embedded-mpv-frame-copy.adapter.spec.ts | 13 +++++ .../embedded-mpv-frame-copy.adapter.ts | 4 ++ .../embedded-mpv-native.service.spec.ts | 41 +++++++++++++++ .../services/embedded-mpv-native.service.ts | 31 ++++++++++++ docs/architecture/embedded-mpv-native.md | 4 +- docs/architecture/player-controls-contract.md | 4 +- .../src/lib/electron-api.interface.ts | 13 +++++ .../shared/interfaces/src/lib/ipc-commands.ts | 1 + .../embedded-mpv-command-runner.spec.ts | 33 +++++++++++- .../embedded-mpv-command-runner.ts | 21 +++++++- .../embedded-mpv-session-controller.spec.ts | 12 ++++- 18 files changed, 300 insertions(+), 7 deletions(-) create mode 100644 .changes/playback-embedded-mpv-seek-steps.md diff --git a/.changes/playback-embedded-mpv-seek-steps.md b/.changes/playback-embedded-mpv-seek-steps.md new file mode 100644 index 000000000..d8dd4bb7e --- /dev/null +++ b/.changes/playback-embedded-mpv-seek-steps.md @@ -0,0 +1,10 @@ +--- +type: fix +area: playback +--- + +Arrow keys and the ±10 s buttons in the Embedded MPV player now move by their +full step every time. Pressing an arrow repeatedly, or holding it, used to +advance only about a second per press because each step was computed from a +stale position; steps are now relative seeks executed by mpv itself, so rapid +presses add up. diff --git a/CLAUDE.md b/CLAUDE.md index e0fc47973..420d4ab9a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -996,7 +996,7 @@ app as a real argument, so it is not an option. API. Radio's `