Skip to content

Show video frame preview when hovering/dragging the progress slider#3140

Merged
Him188 merged 2 commits into
mainfrom
him188/seek-preview-frames
Jul 11, 2026
Merged

Show video frame preview when hovering/dragging the progress slider#3140
Him188 merged 2 commits into
mainfrom
him188/seek-preview-frames

Conversation

@Him188

@Him188 Him188 commented Jul 10, 2026

Copy link
Copy Markdown
Member

What

长按拖动进度条(触摸)/ 鼠标悬浮进度条(PC)时,原来只显示 "15:23" 的浮窗扩展为一张固定尺寸的卡片,在时间上方显示该位置的视频预览帧。

Built on the new mediamp FramePreview feature (open-ani/mediamp#39) — implemented for mpv, VLC and ExoPlayer; backends without it (AVKit/iOS) gracefully fall back to the time-only popup.

Screenshots

Hovering at ~48% while playing at 02:04 — the popup shows the frame at 11:05 (mpv backend, LocalTorrent media):

hover 48%

Moving to ~25% updates the frame (05:24):

hover 25%

While the frame is loading, the popup keeps its final fixed size with a placeholder area — no size jumping:

loading placeholder

How

  • MediaProgressFramePreviewState (video-player commonMain):
    • requests aligned to a 2s grid — extraction is keyframe-snapped anyway, finer granularity buys nothing;
    • LRU cache of 8 frames (~80 KB each at 192×108 ARGB, ~650 KB total) so scrubbing back over the recent trail hits instantly;
    • 50ms debounce, collectLatest semantics (newest position wins);
    • prewarm: the preview decoder is warmed at the current playback position when media loads, so the first hover doesn't pay the ~1.5s decoder startup.
  • MediaProgressSlider renders the frame in both the hover popup and the drag (thumb) popup; the frame area is a fixed 160×90dp box with a placeholder background.
  • BT sources: only positions whose pieces are DONE (from cacheProgressInfoFlow) are requested, so preview seeks never steal piece-deadline priority from the playback position. Non-BT sources are unrestricted.
  • Platform pixel conversion via expect/actual (androidMain Bitmap / skikoMain installPixels).

Verification

  • 7 new desktop Compose tests: hover shows frame, drag requests the dragged position, uncached-position gating, no-feature fallback, pixel conversion, and a screenshot-based regression test asserting the frame stays inside the popup.
  • End-to-end in the packaged desktop app on both mpv and VLC backends with cached LocalTorrent media (frames match the requested positions across both backends). Measured: first hover < 0.8s, new position < 0.6s, scrub-back (cache hit) < 0.35s.

Notes

🤖 Generated with Claude Code

…s slider

Extend the progress slider's time popup ("15:23") into a fixed-size card that
also shows a decoded video frame of the hovered (desktop) or dragged (touch)
position, using the new mediamp FramePreview feature (implemented for mpv, VLC
and ExoPlayer backends; backends without it gracefully fall back to the
time-only popup).

- MediaProgressFramePreviewState: requests are aligned to a 2s grid (finer
  makes no sense with keyframe-snapped extraction), recent frames are LRU
  cached (8 frames, ~650 KB) so scrubbing back is instant, 50ms debounce, and
  the decoder is prewarmed at the current playback position when media loads
  so the first hover doesn't wait for decoder startup.
- The popup keeps a fixed 160x90dp frame area with a placeholder background
  while loading, so its size never jumps.
- For BT sources only positions whose pieces are downloaded are requested, to
  avoid stealing piece-deadline priority from the playback position.

Verified end-to-end in the packaged desktop app on both mpv and VLC backends:
first hover < 0.8s, moving to a new position < 0.6s, scrub-back < 0.35s.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Him188 Him188 marked this pull request as ready for review July 11, 2026 15:39
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Him188 Him188 merged commit f8d059e into main Jul 11, 2026
22 checks passed
@Him188 Him188 deleted the him188/seek-preview-frames branch July 11, 2026 16:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant