Skip to content

fix: use beginFrame for headless recording capture - #1

Closed
carlesandres wants to merge 1 commit into
mainfrom
fix-recording-quality
Closed

fix: use beginFrame for headless recording capture#1
carlesandres wants to merge 1 commit into
mainfrom
fix-recording-quality

Conversation

@carlesandres

@carlesandres carlesandres commented Jun 5, 2026

Copy link
Copy Markdown
Owner

Summary

This PR narrows the core headless recording fix from vercel-labs#12.

Credit to @sld0Ant for the earlier investigation and implementation work that identified the correct fix direction. This PR keeps only the begin-frame-control capture-path fix, the aligned PNG source-frame update, and focused test coverage so it is easier to review independently.

If you have time, I’d also welcome feedback from @sld0Ant on whether this captures the intended minimal version of the earlier fix.

Problem

webreel already launches headless Chrome with --enable-begin-frame-control, but the recorder still captures frames with:

  • Page.captureScreenshot()
  • JPEG q60 source frames

That creates two problems:

  1. Page.captureScreenshot() is the wrong capture API for begin-frame-control mode
  2. JPEG source frames introduce visible artifacting before the final video encode

Changes

This PR makes the narrowest recording-path fix I could extract from vercel-labs#12:

  • add HeadlessExperimental to the CDP client type
  • call HeadlessExperimental.enable() during recording setup
  • add a pre-record frame pump while the page is loading in begin-frame-control mode
  • stop that pre-record frame pump both before Recorder.start() and during failure cleanup
  • replace Page.captureScreenshot() with HeadlessExperimental.beginFrame()
  • switch source capture from JPEG to PNG with optimizeForSpeed
  • save debug frames as .png

Why this helps

This fixes the headless capture path for begin-frame-control mode and improves source-frame quality for final exports.

The scope here is intentionally narrow. This PR is not claiming full 4k support or universal high-resolution throughput. It is only claiming:

  • the correct headless capture API for begin-frame-control mode
  • cleaner PNG source frames instead of JPEG q60
  • reduced JPEG artifacting in final exports

Tests

Added focused coverage for:

  • recorder using HeadlessExperimental.beginFrame() with PNG screenshots
  • debug frames being written as .png
  • HeadlessExperimental.enable() happening before Recorder.start()
  • pre-record frame pump cleanup when setup fails before recording starts

The small vitest.config.ts alias change is test-only plumbing for that runner coverage. It lets Vitest resolve the workspace @webreel/core package from source instead of requiring a built dist output first.

Verification run locally:

  • pnpm --filter @webreel/core test
  • pnpm --filter webreel test
  • pnpm type-check

Docs

Updated the user-facing --frames wording to match current behavior:

  • CLI help now says raw frames are saved as PNGs
  • README and skill docs now describe .webreel/frames/ as PNG source frames in headless recording mode

Non-goals

This PR intentionally does not include:

@carlesandres
carlesandres force-pushed the fix-recording-quality branch 2 times, most recently from b0ece26 to 77c6de8 Compare June 5, 2026 15:03
@carlesandres
carlesandres force-pushed the fix-recording-quality branch from 77c6de8 to 087aaea Compare June 5, 2026 19:25
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