Skip to content

Instant video-bite hover playback + unified <Video> SSOT (preload policy, rendition cap, poster/fit props)#1493

Merged
michaelassraf merged 2 commits into
mainfrom
claude/video-playback-optimization-396be0
Jul 17, 2026
Merged

Instant video-bite hover playback + unified <Video> SSOT (preload policy, rendition cap, poster/fit props)#1493
michaelassraf merged 2 commits into
mainfrom
claude/video-playback-optimization-396be0

Conversation

@michaelassraf

@michaelassraf michaelassraf commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

What changed

Fast-start / instant hover playback (video bites):

  • Explicit preload policy in video.tsx: every <Video kind="file"> now passes an explicit preload — default metadata (playback-core loads the manifest immediately and clamps buffering to maxBufferLength=1: manifest + ~1 segment, then idle), downgraded to none on Save-Data connections. play() restores full buffering automatically, so hover start rides an already-warm buffer. Public preload prop added for deliberate overrides.
  • toMuxPreviewUrl() (mux-origins.ts, server-safe): appends ?max_resolution=720p to public Mux HLS URLs for the ~234px bite hover cards — the only Safari-side rendition cap (native HLS ignores hls.js's capLevelToPlayerSize; MuxPlayer's maxResolution prop needs playbackId, we use src). Signed (?token=) and non-Mux URLs pass through untouched. Verified live: variant count drops 4→3.
  • saveDataEnabled() extracted as the ONE Save-Data source of truth (exported from use-video-warmup.ts; its inline check refactored to consume it).
  • Dev hover→playing metric in startHoverPlayback (always in dev, prod opt-in via localStorage.VIDEO_PERF_DEBUG). Measured 16 ms hover→playing on a mounted card.
  • NEAR_VIEWPORT_ROOT_MARGIN exported from use-near-viewport.ts — SSOT for all three '500px' mount-gate literals (hook default, cards-strip per-index gate, bite-card standalone gate).
  • Bites strip: capped previewUrl used by BOTH the first-frame facade and the hover player (shared HTTP cache across original + marquee clone); poster-layer invariant documented.

Why

Bite hover playback must start instantly with zero visible loading, and all video playback must run through one implementation. The preload default + early mount gate means each near-viewport card holds manifest + first segment before the pointer ever arrives.

Reviewer notes

  • Breaking lib API: VideoSourceSelector's resolveVideoUrl prop is REMOVED (zero hub call sites — all pass VideoPreviewComponent). Consumers passing it get a compile error on upgrade.
  • firstFrameOnly facade now honors poster and the new fit="cover" (--media-object-fit) and inherits the preload default (Save-Data aware).
  • simple-markdown-renderer: 'video' dropped from SAFE_HTML_TAGS — chat strips the tag server-side already; a stray tag now renders as escaped text instead of a native player.
  • Companion hub PR (flamingo-stack/multi-platform-hub) consumes the new props after this releases; hub pin bump follows the normal release flow.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Unified video playback across galleries, release media, highlights, video bites, source selection, and Markdown content.
    • Improved video previews with consistent sizing, poster images, and display modes.
    • Mux video previews now support capped playback resolutions.
  • Performance
    • Media loads as content approaches the viewport.
    • Video preloading now respects browser Save-Data preferences.
  • Bug Fixes
    • Improved handling of embedded and invalid video content in Markdown.

…x_resolution cap, poster/fit props, admin+markdown surfaces on <Video>) [preview:none]
@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9fa6c25c-a25d-48f4-bf1c-da95022b1755

📥 Commits

Reviewing files that changed from the base of the PR and between afd4fc2 and e43c7f2.

📒 Files selected for processing (12)
  • openframe-frontend-core/src/components/features/cards-strip.tsx
  • openframe-frontend-core/src/components/features/highlight-video-section.tsx
  • openframe-frontend-core/src/components/features/media-gallery-manager.tsx
  • openframe-frontend-core/src/components/features/mux-origins.ts
  • openframe-frontend-core/src/components/features/release-media-manager.tsx
  • openframe-frontend-core/src/components/features/use-video-warmup.ts
  • openframe-frontend-core/src/components/features/video-bites-strip.tsx
  • openframe-frontend-core/src/components/features/video-source-selector.tsx
  • openframe-frontend-core/src/components/features/video.tsx
  • openframe-frontend-core/src/components/ui/rich-markdown-renderer.tsx
  • openframe-frontend-core/src/components/ui/simple-markdown-renderer.tsx
  • openframe-frontend-core/src/hooks/use-near-viewport.ts

📝 Walkthrough

Walkthrough

Changes

The PR centralizes video playback through the shared Video component, adds Mux preview URL resolution and Save-Data-aware preload behavior, instruments hover playback latency, standardizes near-viewport margins, and updates feature and Markdown renderers.

Video playback pipeline

Layer / File(s) Summary
Video playback contracts and policies
openframe-frontend-core/src/components/features/mux-origins.ts, openframe-frontend-core/src/components/features/use-video-warmup.ts, openframe-frontend-core/src/components/features/video.tsx
Video props now support preload and fit policies, Save-Data affects default preloading, Mux HLS URLs can receive resolution caps, and optional hover latency logging is available.
Feature video preview migration
openframe-frontend-core/src/components/features/highlight-video-section.tsx, openframe-frontend-core/src/components/features/media-gallery-manager.tsx, openframe-frontend-core/src/components/features/release-media-manager.tsx, openframe-frontend-core/src/components/features/video-source-selector.tsx
Feature previews use the shared Video component instead of native video elements or asynchronous URL resolution.
Video bites and viewport mounting
openframe-frontend-core/src/hooks/use-near-viewport.ts, openframe-frontend-core/src/components/features/cards-strip.tsx, openframe-frontend-core/src/components/features/video-bites-strip.tsx
A shared 500px viewport margin is used by card and video-bite mounting observers, while video bites use capped preview URLs for playback.
Markdown video rendering and escaping
openframe-frontend-core/src/components/ui/rich-markdown-renderer.tsx, openframe-frontend-core/src/components/ui/simple-markdown-renderer.tsx
Rich Markdown renders valid raw video tags through Video, while simple Markdown escapes video tags before raw HTML processing.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant VideoBiteCard
  participant Video
  participant FilePlayer
  participant MuxPlayer
  VideoBiteCard->>Video: provide capped preview URL
  Video->>FilePlayer: pass preload and fit
  FilePlayer->>MuxPlayer: render playback surface
  VideoBiteCard->>Video: activate hover playback
  MuxPlayer-->>FilePlayer: emit playing event
Loading

Possibly related PRs

Suggested reviewers: pavlo-flamingo

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main change: instant hover playback and unifying video handling via the shared Video SSOT with related playback settings.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/video-playback-optimization-396be0

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@michaelassraf
michaelassraf merged commit f006954 into main Jul 17, 2026
6 of 7 checks passed
@michaelassraf
michaelassraf deleted the claude/video-playback-optimization-396be0 branch July 17, 2026 21:46
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