[Bug]: Agent preview recordings ignore the "Browser recording frame rate" setting and are capped at 30 fps#19442

opened10d agobyVVantrongs

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/server

Steps to reproduce

  1. In Settings → Browser, set Browser recording frame rate to 60 fps.
  2. Serve a page that repaints every frame, for example:
    html
    1<div id="n">0</div>
    2<script>let n=0;(function f(){document.getElementById('n').textContent=++n;requestAnimationFrame(f)})()</script>
  3. From an agent: preview_open that page, preview_recording_start, wait 4 seconds, preview_recording_stop.
  4. Count the frames in the returned MP4, for example with ffprobe -count_frames, and the gaps between their timestamps.

Expected behavior

Up to 60 fps, as the setting says ("Maximum recording rate. 30 fps saves CPU and storage; 60 fps is smoother."). Before #15328, agent recordings went through the same recorder as the record button and followed this setting.

Actual behavior

The page ran at 60 fps inside the tab (counted with requestAnimationFrame), but the recording has about 29 fps:

ViewportMP4 sizeFrames / durationMean gapLongest gap
1600×9003200×1800159 / 5.45 s34.3 ms232 ms
800×4501600×900141 / 4.91 s34.8 ms266 ms

A quarter of the pixels gives the same rate, so the limit is not frame size. A 140 ms CSS fade, which is what I was recording, gets three or four frames.

From the source at 26c48bb:

  • The agent's recording is encoded on the server, with a fixed rate: canvas.captureStream(30), and the bitrate formula also assumes 30. The screencast it reads from is RECORDING_SCREENCAST.
  • browserRecordingFrameRate is read only by the record button's path (startBrowserRecording, which passes it to getDisplayMedia). Nothing on the server reads it.
  • Both lines came with #15328. Before it, the recordingStart automation command was handled in PreviewAutomationHosts.tsx by startBrowserRecording, so the setting applied to agent recordings too.

The setting is client-local by design (comment in settings.ts), so the server cannot read it as it is. One way to fix it: have the client that starts or owns the tab pass its frame rate with recordingStart, or move the setting into server settings, and use that value in captureStream() and the bitrate.

Impact

Minor bug or occasional failure

Version or commit

0.0.46-nightly.20261014.3093 (107f602); main at 26c48bb has the same code

Environment

Desktop app on Linux (NixOS, Wayland, niri), 2× display scale

Logs or stack traces

No response

Screenshots, recordings, or supporting files

No response

Workaround

No response

Note

Grok responding on behalf of Julius.

Confirmed on main: agent recordings are encoded on the server with a fixed canvas.captureStream(30) and a bitrate that assumes 30 fps (apps/server/src/preview/ServerBrowserPage.ts L587–588). Nothing on the server reads browserRecordingFrameRate, which is a client-local setting used only by the record button.

This is a regression from #15328, not intended behavior. That PR moved agent recording to the server browser but left the setting behind. The setting doesn't say it applies only to manual recordings, and before #15328 it covered agent recordings too. The settings.ts comment explaining why the setting is client-local still describes the old desktop-owned guest, so it's out of date.

Not a duplicate. #10494 is about resizing during a recording corrupting the MP4.

Likely fix: send the requesting client's frame rate with recordingStart, or move the setting into server settings, and use it in both captureStream() and the bitrate.

Until then, agent recordings are limited to 30 fps. For 60 fps, use the record button.