Skip to content

[Feature]: Use new Page.startScreenRecording for Chromium video capture #43999

Open

Description

@paulirish

🚀 Feature Request

Hey fellas. I saw the recent screencast work in #42752 and #42929, so figured I'd put this on y'all's radar (cuz I didn't see it mentioned yet).

Rudenko landed Page.startScreenRecording a bit ago. Frames straight from Viz into a media encoding utility process. AV1 + optional Opus audio into a .mp4.

My agent also wanted to point out that ..

Since it gets real compositor presentation timestamps from Viz, it sidesteps the delivery-timestamp jitter from crbug.com/562567707. And since screencast.showActions() injects its annotations into the page's utility context, those show up in the recording automatically.

Cool story.

I "built" a small wrapper + benchmark suite to kick the tires on it (paulirish/chrome-capture) and did a 1280x800 comparison on my M4 Max:

Playwright recordVideo Page.startScreenRecording
Output 25fps VP8/VP9 .webm 60fps AV1 .mp4
Total wall-clock 21.2s 11.6s
Stop + finalize 3,825ms 17ms (91ms at 4K)
WebSocket traffic 10.5 MB 449 KB
Final file size 484 KB 331 KB
PSNR vs. lossless screenshot 32.3 dB 34.8 dB
Tab audio none optional (48kHz Opus)

On my 120Hz ProMotion in headed mode, it holds a locked 1080p@120fps and 4K@120fps (119.9 unique fps verified via in-canvas binary barcode counter):

barcode-1920x1080-120fps.mp4

Anyway.. Curious what y'all think! :)

Example

No response

Motivation

no slow ffmpeg teardown. faster overall. no frame drops. only tradeoff is bitrate (but that's arguable)

(also, damn, issue # was soo close to my age × 1000! )

Activity

  1. github-actions commented on Nov 9, 2026

    @github-actions
  2. microsoft-playwright-automation commented on Nov 9, 2026

    @microsoft-playwright-automation
    Contributor

    Hi, I'm the Playwright bot. I checked the native recorder on Linux.

    Native AV1/MP4 recording works, but adopting it is not a transparent replacement for the current recorder. On Playwright 1.66.0-next (51328259d100b64f5e51ec025668dfe22532ac3b), Chromium 158.0.8127.18 produced playable MP4 through context.newCDPSession(page), in headless shell, full headless Chromium and headed Chromium.

    The compatibility question is the recording format: Playwright currently produces VP9/WebM, and the test runner saves .webm attachments as video/webm. Also, Chromium rejects native recording and JPEG screencasting in the same CDP session. I verified that a separate session allows native recording alongside Playwright's JPEG callbacks and existing WebM recorder; those JPEG frames are still needed by tracing and onFrame.

    My recommendation is opt-in native MP4 recording, keeping existing WebM output unchanged. That needs a public format/API design, including the behavior on other browsers, rather than a backend-only change. No API or default change is proposed in this run.

    One correction to the motivation: 562567707 is already fixed by Chromium change 8426459. The tested Chromium version uses compositor reference_time for ordinary screencast timestamps too.

    What I checked

    The first-principles test used a 320×240 page, requested 60 fps, displayed action annotations, clicked a button and animated the background for 60 animation frames. It recorded through these commands, while separately running page.screencast.start({ path: 'current.webm', fps: 60, onFrame }):

    const cdp = await context.newCDPSession(page);
    const { stream } = await cdp.send('Page.startScreenRecording', {
      maxWidth: 320, maxHeight: 240, frameRate: 60,
    });
    // Perform the page actions.
    await cdp.send('Page.stopScreenRecording');
    const chunks = [];
    for (;;) {
      const { data, base64Encoded, eof } =
        await cdp.send('IO.read', { handle: stream });
      chunks.push(Buffer.from(data, base64Encoded ? 'base64' : 'utf8'));
      if (eof)
        break;
    }
    await cdp.send('IO.close', { handle: stream });
    const mp4 = Buffer.concat(chunks);

    All three Chromium variants passed: MP4 ftyp and AV1 av01 entries, browser decoding at 320×240 with positive duration, concurrent JPEG callbacks, and separate WebM output. Starting JPEG screencasting on the native recorder's own session failed with Screencast is already active.

    I also ran the existing SC-009 start should record video with the requested fps test on Chromium, Firefox and WebKit: all three passed. This checks the configured output rate, not 60 distinct captured frames per second; Firefox and WebKit still capture up to 25 fps.

    I read #42752, #42929, the Chromium timestamp report, the cited Chromium change and the wrapper source. The cited change 7736461 is abandoned, but the native command is present and working in the tested build. No reporter code was executed.

    These are functional checks, not a reproduction of the Mac benchmark. I did not measure dropped frames, audio, 120 Hz capture or performance gains.

    Triaged on Linux by the Playwright bot - agent run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions