Skip to content

fix(web): keep preview recordings valid across viewport resizing - #10495

Open
MansTomb wants to merge 1 commit into
pingdotgg:mainfrom
MansTomb:fix/preview-recording-resize
Open

MansTomb wants to merge 1 commit into
pingdotgg:mainfrom
MansTomb:fix/preview-recording-resize

Conversation

@MansTomb

@MansTomb MansTomb commented Sep 7, 2026 •

Copy link
Copy Markdown

What Changed

Resizing Preview during recording currently produces corrupt H.264 frames in the exported MP4. Prefer supported avc3 MP4 profiles so updated decoder parameters travel with the frames when capture dimensions change. Keep the existing WebM fallback, bitrate calculation and fitted preview behavior.

Move recorder construction into a small dependency-free module so an Electron regression can exercise the production configuration with a real MediaRecorder. The regression records desktop → mobile → desktop dimensions, decodes the complete file with FFmpeg, and checks frame dimensions, final-frame coverage and increasing timestamps. Existing recording tests cover format selection and the recorder's actual saved MIME type.

Closes #10494.

Why

The native capture stream changes dimensions when the viewport changes. Chromium's avc1 muxing writes the codec description once and omits updated SPS/PPS from samples. Its MediaRecorder implementation recommends avc3 when recording dimensions change.

Both baseline resize takes failed full-file decoding; fixed desktop and mobile controls passed. With this change, all four corresponding exports decode successfully. Frame inspection verifies desktop and mobile geometry within each resized recording. Source packet DTS values increase strictly. All four fixed exports played to the end in Electron, including both dimension transitions. The final resized frame shows 8.000 seconds and Complete.

Validation:

  • cd apps/web && vp test run src/browser/browserRecording.test.ts --project unit: 33 tests passed.
  • node --test apps/desktop/scripts/browser-recording-media.test.mjs: native regression failed with the old configuration and passed with the fix. Requires a graphical session, installed desktop Electron dependency, FFmpeg and ffprobe. This focused check is not added to CI.
  • Targeted lint and formatting for the four changed files passed.
  • cd apps/web && vp run typecheck passed.
  • Isolated T3 desktop capture using Electron 43.4.1 and Chromium 150.0.7871.224 at DPR 1.25, with fixed desktop, fixed mobile and two desktop-to-mobile takes. Full-file decode and source timestamp checks use the commands in the linked issue.

UI Changes

Original application exports, with an eight-second animation and a viewport resize around three seconds:

Before: Corrupt resize recording

before-resize.mp4

After: Valid resize recording

after-resize.mp4

Native-resolution frames from the fixed recording:

Desktop frame

Mobile frame

Completed animation

The recording format supports changing frame dimensions. Container-level width and height alone do not describe every frame. Playback outside Electron/Chromium and FFmpeg has not been verified.

The fitted preview remains unchanged. CSS scaling can reduce the source's rendered detail before screenshots or video capture. This change does not restore that detail. Screenshot softness is tracked in #9872 and proposed screenshot changes are in #9916; neither is closed by this PR.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes. No controls or layout changed; recording evidence is included above.
  • I included a video for animation/interaction changes

Model: GPT-6 Astra. Harness: Codex.

Summary by CodeRabbit

  • New Features

    • Browser recordings now select the best available video format, preferring resize-capable MP4 encoding and falling back to WebM when needed.
    • Recording bitrate is automatically adjusted based on video dimensions and frame rate, with sensible limits for consistent quality.
  • Bug Fixes

    • Improved recording compatibility across desktop and mobile capture phases.
    • Verified exported recordings decode correctly with valid dimensions, duration, and timestamps.

@github-actions github-actions Bot added the vouch:unvouched PR author is not yet trusted in the VOUCHED list. label Sep 7, 2026
@github-actions github-actions Bot added the size:M 30-99 changed lines (additions + deletions). label Sep 7, 2026
@macroscopeapp

macroscopeapp Bot commented Sep 7, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This focused fix changes the default codec selected for existing browser recordings from avc1 to avc3, altering production output even though bitrate and fallback behavior remain intact. The added unit and Electron regression coverage lowers implementation risk but does not remove the need to review the default transition.

Notes:

  • Diff unchanged. Approvability was decided on eligibility alone.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Sep 7, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Team

Run ID: 2746cf2d-426f-40c4-b758-f4e47d7ac1a6

📥 Commits

Reviewing files that changed from the base of the PR and between dc39615 and 989e647.

📒 Files selected for processing (4)
  • apps/desktop/scripts/browser-recording-media.test.mjs
  • apps/web/src/browser/browserMediaRecorder.ts
  • apps/web/src/browser/browserRecording.test.ts
  • apps/web/src/browser/browserRecording.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

The change extracts browser recorder creation, prefers resize-capable avc3 codecs, preserves WebM fallback and bitrate calculation, and adds unit and Electron regression tests for recordings that change resolution.

Changes

Browser recording

Layer / File(s) Summary
Centralize recorder creation
apps/web/src/browser/browserMediaRecorder.ts, apps/web/src/browser/browserRecording.ts
The new createBrowserMediaRecorder factory selects the preferred MIME type and calculates the bitrate. browserRecording uses the shared factory.
Validate codec selection
apps/web/src/browser/browserRecording.test.ts
Tests verify avc3 preference, WebM fallback, and preservation of the recorder’s actual output format.
Validate resized media exports
apps/desktop/scripts/browser-recording-media.test.mjs
The Electron test records desktop, mobile, and desktop canvas phases, decodes the MP4 with ffmpeg, and checks dimensions, duration, and monotonic timestamps.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk: ⚪ Minimal · up to 989e6

This change switches recording preference to resize-capable avc3 MP4 profiles while retaining WebM fallback and bitrate behavior, with coverage for resized recordings. No merge-blocking risk remains.

Suggested reviewers: juliusmarminge

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 4 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes satisfy issue #10494 by preferring supported avc3 profiles, retaining WebM fallback and bitrate calculation, adding codec tests, and adding an Electron regression for resized recordings an…
Out of Scope Changes check ✅ Passed The changes remain within scope for issue #10494. The recorder extraction and regression coverage directly support the fix, and capture softness remains explicitly out of scope.
Title check ✅ Passed The title clearly and concisely describes the primary fix: preserving valid preview recordings during viewport resizing.
Description check ✅ Passed The description is complete and relevant. It explains the change, motivation, validation results, UI impact, scope boundaries, and checklist items. It also includes the required recording evidence.
  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@juliusmarminge juliusmarminge added the macroscope-review Opt PRs made by unvouched contributors in for Macroscope review. Vouched contributors auto-reviews label Oct 1, 2026 — with ChatGPT Codex Connector

This branch has not been deployed

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

Labels

macroscope-review Opt PRs made by unvouched contributors in for Macroscope review. Vouched contributors auto-reviews size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Resizing a Preview viewport during recording corrupts the exported MP4

2 participants