Use custom player in VideoDetails with deep-link start time#1663
Conversation
…ions' into horatiu-lig-9805-import-activitynet-style-event-annotations-3
…ent-annotations-3
…ent-annotations-3
Previously, filtering and counting video annotations only considered annotations attached to a video's frames. Videos can also carry annotations directly (e.g. ActivityNet-style event/classification labels on the whole video). This makes both the video filter and the annotation counter consider these direct video annotations in addition to frame annotations.
…ions-3' into horatiu-lig-9806-filter-videos-by-event-metadata
Mirrors a <video> element's playback state into reactive fields and exposes intent callbacks (seek, play/pause, mute, fullscreen) for a custom control bar. Listening via native events keeps it composable with handlers on the element. Covered by a harness-driven unit test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Compose useVideoPlayback + VideoControls, forcing native <video controls> off so the full-width scrubber can host aligned timeline overlays. Adds a startTimeS prop (null waits for a deep-link timestamp) and a region ref for fullscreen. Updates tests and stories accordingly. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Hand the deep-linked frame's timestamp to VideoPlayer via startTimeS instead of seeking after load, and remount on frame-number change with a composite #key. Align the annotation overlay to the <video> box and fix min-h-0 layout so the player fills its card. Adds a VideoDetails test covering the frame-load branch and deep-link handoff. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Full-width scrubber + transport buttons that own no playback state and call back on user intent. Includes helpers (formatTime, clampPercent, timeFromClientX) and unit tests. Exported from the components barrel. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughVideoDetails now supports frame-based deep-link playback, positions annotations over the measured video element, and stops frame synchronization on unmount. The video route remounts on frame changes, while tests validate loading and resolved playback start times. ChangesVideo frame navigation
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant VideoPage
participant VideoDetails
participant useVideoFrames
participant VideoPlayer
VideoPage->>VideoDetails: remount for sample_id and frameNumber
VideoDetails->>useVideoFrames: load initial or deep-linked frame
useVideoFrames-->>VideoDetails: provide current frame
VideoDetails->>VideoPlayer: pass startTimeS
VideoDetails->>VideoDetails: measure video and position annotation overlay
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Interactive Playground plus paused / near-end states, on a dark backdrop matching how the bar overlays a video. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Hand the deep-linked frame's timestamp to VideoPlayer via startTimeS instead of seeking after load, and remount on frame-number change with a composite #key. Align the annotation overlay to the <video> box and fix min-h-0 layout so the player fills its card. Adds a VideoDetails test covering the frame-load branch and deep-link handoff. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Compose useVideoPlayback + VideoControls, forcing native <video controls> off so the full-width scrubber can host aligned timeline overlays. Adds a startTimeS prop (null waits for a deep-link timestamp) and a region ref for fullscreen. Updates tests and stories accordingly. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mirrors a <video> element's playback state into reactive fields and exposes intent callbacks (seek, play/pause, mute, fullscreen) for a custom control bar. Listening via native events keeps it composable with handlers on the element. Covered by a harness-driven unit test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Interactive Playground plus paused / near-end states, on a dark backdrop matching how the bar overlays a video.
5a07a5b to
7dede03
Compare
…github.com:lightly-ai/lightly-studio into horatiu-lig-9807-show-event-bars-on-the-timeline.d
…o horatiu-lig-9807-show-event-bars-on-the-timeline.d
|
/review |
…o horatiu-lig-9807-show-event-bars-on-the-timeline.b
…o horatiu-lig-9807-show-event-bars-on-the-timeline.c
…o horatiu-lig-9807-show-event-bars-on-the-timeline.d
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
lightly_studio_view/src/lib/components/VideoDetails/VideoDetails.svelte (1)
117-136: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueScope the
ResizeObservertightly within the effect.
resizeObserveris declared at the component level but is only utilized inside the$effect. Moving its declaration inside the effect prevents potential reference leaks or stale closure issues during cleanup, keeping the component state clean.♻️ Proposed refactor
- let resizeObserver: ResizeObserver; - // Align the annotation overlay to the <video> box, not the full player chrome. $effect(() => { if (!videoEl || !videoFrameContainerEl) return; const updateOverlaySize = () => { if (!videoEl || !videoFrameContainerEl) return; const videoRect = videoEl.getBoundingClientRect(); const containerRect = videoFrameContainerEl.getBoundingClientRect(); overlayLeft = videoRect.left - containerRect.left; overlayTop = videoRect.top - containerRect.top; videoWidth = videoRect.width; videoHeight = videoRect.height; }; updateOverlaySize(); - resizeObserver = new ResizeObserver(updateOverlaySize); - resizeObserver.observe(videoEl); - resizeObserver.observe(videoFrameContainerEl); + const resizeObserver = new ResizeObserver(updateOverlaySize); + resizeObserver.observe(videoEl); + resizeObserver.observe(videoFrameContainerEl); return () => resizeObserver.disconnect(); });🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@lightly_studio_view/src/lib/components/VideoDetails/VideoDetails.svelte` around lines 117 - 136, Move the ResizeObserver declaration from component scope into the $effect callback alongside its creation and observation logic, while preserving the existing updateOverlaySize behavior and cleanup handling.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@lightly_studio_view/src/routes/datasets/`[dataset_id]/[collection_type]/[collection_id]/videos/[sample_id]/+page.svelte:
- Line 19: Update the frameNumber derivation to parse data.frameNumber with an
explicit base-10 radix and convert any NaN result to undefined before passing it
to VideoDetails, preserving undefined for absent values.
---
Nitpick comments:
In `@lightly_studio_view/src/lib/components/VideoDetails/VideoDetails.svelte`:
- Around line 117-136: Move the ResizeObserver declaration from component scope
into the $effect callback alongside its creation and observation logic, while
preserving the existing updateOverlaySize behavior and cleanup handling.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 439cb8d7-7cf3-4c93-86f3-d4a52c08789e
📒 Files selected for processing (4)
lightly_studio_view/src/lib/components/VideoDetails/VideoDetails.stub.sveltelightly_studio_view/src/lib/components/VideoDetails/VideoDetails.sveltelightly_studio_view/src/lib/components/VideoDetails/VideoDetails.test.tslightly_studio_view/src/routes/datasets/[dataset_id]/[collection_type]/[collection_id]/videos/[sample_id]/+page.svelte
What has changed and why?
Last of 4 PRs splitting #1649.
Switches
VideoDetailsto the custom player: instead of seeking after load,it hands the deep-linked frame's timestamp to
VideoPlayerviastartTimeS,and remounts on frame-number change via a composite
#key. Aligns theannotation overlay to the
<video>box (not the full player chrome) andfixes
min-h-0layout so the player fills its card.How has it been tested?
New
VideoDetailsunit tests covering the on-mount frame-load branch(deep-link vs. playback-time) and the deep-link
startTimeShandoff. Plusmanual testing.
Did you update CHANGELOG.md?
Summary by CodeRabbit