Skip to content

screencast output duration is ~2.6x longer than real elapsed time (timeline stretched / slow-motion playback) #2204

@nebrass

Description

@nebrass

Summary

screencast_start / screencast_stop produces a .webm whose playback duration is ~2.5–2.6× longer than the real elapsed recording time. The captured frames are correct, but they're muxed so the timeline is stretched — the video plays back in slow motion. This makes the output unusable for any timing-sensitive purpose (e.g. trimming clips to a fixed length, or any 1:1 "what happened on screen, when" record) without a manual re-timing/re-encode pass.

Repro

Minimal page that renders its own live elapsed-time clock via requestAnimationFrame, so the ground-truth recording duration is visible inside the video:

<!doctype html><html><head><meta charset="utf-8">
<style>html,body{margin:0;height:100%;background:#0b1020;color:#fff;font-family:monospace;display:flex;align-items:center;justify-content:center}
#t{font-size:160px;font-variant-numeric:tabular-nums}#s{position:fixed;top:24px;left:24px;font-size:28px;color:#7df}</style></head>
<body><div id="s">elapsed (page clock):</div><div id="t">0.00</div>
<script>const t0=performance.now(),el=document.getElementById('t');
function f(){el.textContent=((performance.now()-t0)/1000).toFixed(2);requestAnimationFrame(f)}requestAnimationFrame(f);</script>
</body></html>

Serve it locally, then via the MCP:

  1. new_page → the page URL
  2. screencast_start (filePath: repro.webm)
  3. wait ~10 seconds of wall-clock (nothing else)
  4. screencast_stop

Expected

The output video's playback duration ≈ the real recording window (~9–10 s), and the on-screen page clock advances at 1× (real time) during playback.

Actual

  • On-screen page clock in the final frame: 8.91 (i.e. ~8.9 s of real time actually elapsed and was captured)
  • Resulting video playback duration: 23.12 s — confirmed two ways:
    • last video packet pts_time = 23.120000
    • ffmpeg -i repro.webm -c copy remuxed.mp4format.duration = 23.120000
  • Stream: vp9, 1920×1080, r_frame_rate 25/1, 578 frames. 578 / 25fps = 23.12 s, but only ~8.9 s of content exists → the timeline is stretched ~2.6×, so the clock visibly counts 0 → 8.9 over 23 s of playback (slow motion).

I also saw the same effect on a real interaction recording (≈15 s of actual UI activity → an 83 s / 2078-frame webm) and on a simple video-playback recording (~13 s window → 27.2 s output), so it's consistent and reproducible, not a one-off.

Likely cause (hypothesis)

CDP Page.startScreencast emits frames on visual change with their own timestamps; it looks like the assembler writes them at a fixed nominal 25 fps (constant frame rate) rather than honoring each frame's capture timestamp, so a stream that was effectively captured faster than 25 fps gets stretched to fit 25 fps on the timeline. Honoring per-frame timestamps (VFR) or computing the real duration from first/last frame timestamps would fix it.

Environment

  • chrome-devtools-mcp: 1.2.0
  • Node: v24.16.0
  • OS: Linux 6.18 (WSL2)
  • MCP launched with --experimentalScreencast + --experimentalFfmpegPath /usr/bin/ffmpeg
  • Output format: .webm

Impact

For agent-driven video/demo capture (driving a UI and recording it), the clips can't be used directly — every clip needs ffprobe + a re-time pass to restore real-time playback, which defeats the convenience of the tool. Frame-accurate/real-time duration would make these recordings drop-in usable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions