Skip to content

fix(studio): the thumbnail capture page loads media near the playhead like the preview - #6146

Merged
miguel-heygen merged 1 commit into
mainfrom
fix/capture-page-loads-media-near-playhead
Oct 23, 2026
Merged

miguel-heygen merged 1 commit into
mainfrom
fix/capture-page-loads-media-near-playhead

Conversation

@miguel-heygen

Copy link
Copy Markdown
Collaborator

What

The hidden page Studio uses to screenshot thumbnails and posters now loads video and audio near the playhead, as the live preview does. A 163-clip film cut from one source needs 1.35 GB and 140 threads to make its thumbnails instead of 6.2 GB and 737, and the thumbnails are byte-identical.

Why

The live preview page already defers media: only clips on screen or about to start load, the rest stay at preload="none". The capture page (/preview?hf-capture=1, loaded by the thumbnail route) got no preview mark, so none of that applied and the runtime's eager pass set preload="auto" on and loaded every clip. Chrome keeps one decoder per element, so a film cut into many pieces mounts them all at once.

Measured on the devbox, headless Chrome, a project of 163 timed pieces cut from one 1080p source:

Videos loaded Renderer memory Renderer threads
Live preview page 7 of 163 ~400 MB 36
Capture page, before 163 of 163 5.6 GB 661

Whole thumbnail server (browser, renderers, node), three thumbnails at 0.5 s, 20.3 s and 45.1 s, peak:

Memory Threads First thumbnail
before 6.2 GB 737 6.1 s
after 1.35 GB 140 1.9 s

The three PNGs have the same md5 before and after.

Related work

#4682 and #5716 added the preview's near-playhead load. #6142 is the render-side equivalent and does not touch this path.

How

One mark, one owner of "this is a Studio preview page": the page keeps meta[name=hyperframes-studio-preview] and the capture page now carries it with content="capture".

  • routes/preview.ts: the capture page gets the mark (still without lazy images, so its screenshot has every image).
  • timedClipHide.ts: defersMedia() is true under the mark; the hidden-image skip stays off in capture mode. preloadMedia.ts and init.ts use defersMedia() for media, and keep skipsHiddenImages() for images.
  • The thumbnail seek already waits for video frames at the target time (__hfWaitForSeekCompletion), so a clip that is only loaded once the seek lands on it is ready before the screenshot.

Test plan

  • Failing first: init.test.ts "loads media near the playhead" (a preview mark and a capture-mode mark hold the clips off the playhead at preload="none"; no mark keeps today's eager load) and preview.test.ts (the capture page carries the capture-mode mark and no lazy images). Both fail on main and pass; core runtime 2342/2342 and the preview route file 114/114, three runs in a row.
  • Studio-server 1364 passed, cli server and capture 740 passed; tsc --noEmit clean in core and studio-server; oxfmt, oxlint, comment checks clean.
  • Captured frame: thumbnails at 0.5 s, 20.3 s and 45.1 s on the 163-clip project are byte-identical before and after.
  • Seek and scrub on the live preview page are untouched by this change; the preview-mark path is the same code with the same mark.
  • Comments follow CONTRIBUTING.md "Comments"

@miguel-heygen
miguel-heygen force-pushed the fix/capture-page-loads-media-near-playhead branch from 3e0ae5b to ba5b5a3 Compare October 23, 2026 16:05
@github-actions

Copy link
Copy Markdown
Contributor

Edit accuracy: accurate 271 (base branch 271), smooth 159 of those

The gate passes.
Smoothness is reported in the artifact, not gated. A case fails only if it fails 2 of 3 runs.

Quarantined, measured but not gated (0)

Unstable (2)

  • seqplainkeys-none-px-r0-root-z100: tracking 0.06, pressJump 0, drop 0, reload 0, render 0.03, renderKey -, undo false, teleport true / tracking 0.06, pressJump 0, drop 0, reload 0, render 0.03, renderKey -, undo true, teleport true / tracking 0.06, pressJump 0, drop 0, reload 0, render 0.03, renderKey -, undo true, teleport true
  • seqplainkeys-none-pct-r0-root-z100: tracking 0.06, pressJump 0, drop 0, reload 0, render 0.03, renderKey -, undo false, teleport true / tracking 0.06, pressJump 0, drop 0, reload 0, render 0.03, renderKey -, undo true, teleport true / tracking 0.06, pressJump 0, drop 0, reload 0, render 0.03, renderKey -, undo true, teleport true

@heygengenesis heygengenesis Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: APPROVE · 0 blocker · 0 important · 0 nits · head ba5b5a3d

Only timedClipHide and compositionReadiness read the preview mark, so adding it to the capture page has no other effect. The capture page still loads every image. Once a forward seek on a reused page shows a clip at preload="none", media sync arms it and holds the seek barrier, and that is the path your 0.5 s → 20.3 s → 45.1 s md5 check runs through.

Scope / CI
  • Audited: the whole diff, all readers of STUDIO_PREVIEW_MARK_META, the thumbnail route and its page reuse (thumbnailPages.ts, studioServer.generateThumbnail), holdSeekBarrierUntilVideoLands, and scanPendingCompositionAssets.
  • Ran locally: init.test.ts passes 249/249. The new preview-mark and capture-mark cases fail on the base runtime and pass on this head. I did not run preview.test.ts locally because it needs a workspace build; CI covers it.
  • CI: the optional Studio: timeline viewport gate fails on a perf-ratchet decrease (the index.html t=3.00 thumbnail is no longer requested: 14→13 renders, 15→14 requests). #6142, which does not touch the capture path, fails the same way at the same time. It is not a required check. The required checks have no failures so far; some are still running.

@miguel-heygen
miguel-heygen added this pull request to the merge queue Oct 23, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 23, 2026
@miguel-heygen
miguel-heygen added this pull request to the merge queue Oct 23, 2026
Merged via the queue into main with commit 28ac4d7 Oct 23, 2026
79 of 80 checks passed
@miguel-heygen
miguel-heygen deleted the fix/capture-page-loads-media-near-playhead branch October 23, 2026 19:41
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