fix(recording): use CDP timestamps to preserve real-time video playback speed#4697
fix(recording): use CDP timestamps to preserve real-time video playback speed#4697octo-patch wants to merge 3 commits intobrowser-use:mainfrom
Conversation
Page.captureScreenshot can time out intermittently under load (e.g. in Docker containers with limited resources). Add up to 3 retries with a 0.5 s delay when a RuntimeError containing "timed out" is raised, so occasional flaky failures recover automatically instead of crashing the agent run.
…rowser-use#4662) When a file input has an accept attribute, validate the uploaded file's extension and MIME type against it before calling setFileInputFiles via CDP. CDP bypasses browser-native accept validation, so without this check the agent silently succeeds even when the file type is rejected by the UI. Supports extension tokens (.pdf), wildcard MIME types (image/*), and exact MIME types (application/pdf). Adds two regression tests covering rejection and acceptance paths.
…ck speed (fixes browser-use#4696) CDP screencast delivers frames only on visual change, not at fixed intervals. Without timestamps, all frames are played back at the configured framerate (30fps default), making automated sessions appear sped up. Fix: use the timestamp field from ScreencastFrameMetadata to detect pauses and insert duplicate frames to fill the gap, keeping playback in sync with wall-clock time. Long idles are capped at MAX_FILL_SECONDS (10s) to avoid bloated files. Tab-switches reset the timestamp so no spurious filler frames span different targets.
There was a problem hiding this comment.
1 issue found across 5 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="browser_use/browser/watchdogs/default_action_watchdog.py">
<violation number="1" location="browser_use/browser/watchdogs/default_action_watchdog.py:2668">
P2: Hard-failing `accept` validation on `mimetypes.guess_type()` can reject valid uploads when MIME inference is missing or OS-dependent.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
| accept_attr = (element_node.attributes or {}).get('accept', '').strip() | ||
| if accept_attr: | ||
| file_ext = os.path.splitext(event.file_path)[1].lower() | ||
| file_mime = mimetypes.guess_type(event.file_path)[0] or '' |
There was a problem hiding this comment.
P2: Hard-failing accept validation on mimetypes.guess_type() can reject valid uploads when MIME inference is missing or OS-dependent.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At browser_use/browser/watchdogs/default_action_watchdog.py, line 2668:
<comment>Hard-failing `accept` validation on `mimetypes.guess_type()` can reject valid uploads when MIME inference is missing or OS-dependent.</comment>
<file context>
@@ -2660,6 +2661,31 @@ async def on_UploadFileEvent(self, event: UploadFileEvent) -> None:
+ accept_attr = (element_node.attributes or {}).get('accept', '').strip()
+ if accept_attr:
+ file_ext = os.path.splitext(event.file_path)[1].lower()
+ file_mime = mimetypes.guess_type(event.file_path)[0] or ''
+ accepted_types = [t.strip().lower() for t in accept_attr.split(',') if t.strip()]
+ accepted = False
</file context>
|

Fixes #4696
Problem
When using
record_video_dir, the recorded video plays back much faster than real time. CDP screencast delivers frames only on visual change — during network waits or idle periods between agent steps, zero frames are produced. All captured frames are then written to the video at the configured framerate (30 fps default), so a 5-second page load appears to be instant in the video.Solution
ScreencastFrameMetadataincludes atimestampfield (Unix seconds). This PR threads that timestamp from the CDP event through toVideoRecorderService.add_frame(). When a new frame arrives, the recorder computes the wall-clock gap since the last frame and inserts duplicate filler frames to fill the silence — matching the video duration to actual session time.Key details:
int(gap_seconds * framerate) - 1(the current frame accounts for the last slot)MAX_FILL_SECONDS(10 s) are capped to keep file sizes reasonableadd_frame()behaves as beforeTesting
The change can be verified by recording a session that includes a few-second network wait and comparing the video duration to the actual elapsed time. Before this fix the video would be significantly shorter than wall-clock time; after the fix the durations match.
Summary by cubic
Preserves real-time playback speed in recorded videos by using CDP timestamps to fill idle gaps. Also validates file uploads against
acceptrules and retries flaky screenshot timeouts.ScreencastFrameMetadata.timestampto detect pauses and insert duplicate frames so video duration matches real time; cap idle fills at 10s and reset on tab switches; falls back to old behavior if no timestamp.Page.captureScreenshotup to 3 times with a 0.5s delay on transient "timed out" errors.<input accept>before upload (supports extensions like.pdf, wildcard types likeimage/*, and exact MIME types); raiseBrowserErroron rejection; add tests for reject/accept paths.Written for commit f73d9a2. Summary will update on new commits.