Fix unreliable small custom seek steps (e.g. 1 ms) on single key press (#12027)#12033
Merged
Merged
Conversation
SubtitleEdit#12027) Custom video seek shortcuts re-read vp.Position on every press and add the delta. While playing or in frame mode the player reports the live time-pos, which lags an in-flight seek, so consecutive small steps compute from the same stale base and are lost. A 1 ms custom seek then "sometimes works, mostly doesn't" on single presses yet works while the key is held (auto-repeat accumulates enough to land on a new frame). Track the intended position across successive relative seeks so each press moves exactly its delta. The tracker resyncs to the real position whenever playback is running or the player diverges by more than half a second (the user played, clicked the waveform, or jumped to a cue), and SetVideoPositionSeconds clears it for any non-relative position change.
This was referenced Jul 1, 2026
pull Bot
pushed a commit
to matrixer2306/subtitleedit
that referenced
this pull request
Jul 1, 2026
…llow-up) The waveform playhead is a smoothed estimate that extrapolates on a wall clock during playback. On pause it kept gliding until mpv's IsPlaying flipped ~100 ms later, then snapped to mpv's still-lagging reported position - so the cursor didn't stop on the keypress and jittered backward. Freeze the estimate the instant a pause is requested (Pause / TogglePlayPause set _pauseRequested, which the estimator honors before IsPlaying flips), and hold it for a short settle window instead of snapping to the stale reported position; release on a large gap (real seek) or once mpv settles. Play paths clear the flag, and it auto-clears if the pause doesn't take, so the cursor can't wedge. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fix unreliable small custom seek steps on single key press
Fixes #12027.
Problem
When a custom video seek shortcut is set to a very small value (the reporter used 1 ms on "D" / "A"), a single key press usually does nothing, but holding the key works. It used to work in older 4.x builds.
Root cause is in the relative seek path.
MoveVideoPositionMsre-readsvp.Positionon every press and adds the delta:While the player is playing or running in frame mode, the libmpv backend's
Positiongetter returns the livetime-pos, which lags an in-flight (async) seek rather than the value just requested. So two quick presses both read the same not-yet-updated base position and each computesbase + 1 ms, and the second press is effectively lost. With a tiny step this means single presses "sometimes work, mostly don't", while holding the key (auto-repeat) fires fast enough to accumulate across a frame boundary and appears to work.(When paused and not in frame mode the backend already caches the last seek target, so that specific case was reliable; playing and frame mode were not.)
Fix
Track the intended position across successive relative seeks so every press moves exactly its delta instead of re-reading a possibly stale position:
MoveVideoPositionMsaccumulates from a tracked target while playback is paused and the player still agrees with that target (within half a second).SetVideoPositionSeconds, the shared choke point for every position change, clears the tracker, andMoveVideoPositionMsre-arms it right after, so only chained relative steps accumulate.Behaviour for the normal larger steps (500 ms, 1 s, etc.) is unchanged; they already exceeded a frame, and they still resync correctly.
Files
src/ui/Features/Main/MainViewModel.csNote on sub-frame steps
A step well below one frame (1 ms versus roughly 33 to 40 ms per frame) still cannot change the displayed video frame on a single press, but the timecode and waveform cursor now advance by exactly the configured amount each press, which is what fine subtitle timing relies on.