Files
hyperframes/packages
James 77ce7eede4 fix(producer): inline base64 frames in injector to unblock video-heavy renders
The URL-served frame path (PR #596) hands each injected `<img>` a fileServer URL
instead of a base64 data URI, on the theory that shipping a short URL through
`page.evaluate` beats shipping a multi-MB base64 string per frame. That holds
when the fileServer is otherwise idle.

But on video-heavy compositions, the same fileServer also serves every
`<video>.src`. The runtime's drift-recovery branch (`runtime/media.ts:294-302`)
issues `el.load()` on the underlying `<video>` during seeks, kicking off
full-file downloads that occupy the fileServer's single Node event loop (it
uses `readFileSync` and offers no `Accept-Ranges`). The injector's
`<img>.decode()` then queues behind those video fetches and is never serviced
before puppeteer's protocol timeout fires, surfacing as
`Runtime.callFunctionOn timed out` in `capture_streaming`.

Reproducer (30 × 32 MB videos / 90 s comp / 8-core / 30 GB host):

  baseline (broken corpus)            537 s   render fails
  baseline (corpus-fixed)             428 s   render fails
  this fix (drop frameSrcResolver)    121 s   render succeeds, 69 MB MP4

Control corpus (30 × 1.6 MB / 60 s) shows no regression: 137 s with this
change vs ~135 s on \`main\`. The \`createCompiledFrameSrcResolver\` builder and
the \`frameSrcResolver\` option stay in the codebase, just unused for now —
re-enabling them behind a proper gate ("only use URL-served frames when the
page has zero fileServer-bound \`<video>.src\` traffic") is a follow-up. The
cache memory ceiling (\`frameDataUriCacheBytesLimitMb\`, default 1500 MB above
8 GB hosts) already bounds the cost of base64 inlining.

— Jerrai
2026-06-22 00:34:47 +00:00
..
2026-06-21 17:59:01 -04:00
2026-06-21 17:59:01 -04:00
2026-06-21 17:59:01 -04:00
2026-06-21 17:59:01 -04:00
2026-06-21 17:59:01 -04:00
2026-06-16 13:16:09 -04:00
2026-06-21 17:59:01 -04:00