深入 Remotion Canvas Capture:用 Chromium 的 HTML-in-canvas 录制超高清网页视频
【免费下载链接】remotion🎥 Make videos programmatically with React项目地址: https://gitcode.com/GitHub_Trending/re/remotion
导读
Remotion Canvas Capture 是 Remotion 生态中的一款高保真网页录制 Chrome 扩展:它可以选定页面上的任意区域,或直接录制整个网页,并借助 Chromium 的实验性 HTML-in-canvas 实现,输出分辨率高于本机屏幕的 H.264 MP4 或 VP9 WebM 视频。本文以 README.public.md 为骨架,结合 monorepo 中该扩展的完整源码与官方安装文档,为你讲清它的适用场景、安装步骤、录制工作流,以及它如何用「把网页画进 Canvas」的底层机制实现超分辨率捕获——读完你既能上手录制产品演示,也能理解其内部实现原理。
Remotion Canvas Capture 是什么
根据官方公开说明,Remotion Canvas Capture 的核心能力是:
Records an area—or a whole webpage—as a high-resolution H.264 MP4 or VP9 WebM using Chromium's experimental HTML-in-canvas implementation.
翻译成大白话就是:选择一个页面区域或整个网页,录制为高分辨率视频文件。它区别于传统"录屏"的关键点在于两点:
- 不依赖屏幕分辨率:传统录屏只能拿到显示器上的像素,而 Canvas Capture 使用 Chromium 的实验性 HTML-in-canvas(Canvas Draw Element)实现,把 DOM 直接重绘到 canvas 中,因此可以以高于原生显示分辨率的分辨率录制内容;
- 输出是标准编码文件:录制结果可以是 H.264 编码的 MP4,也可以是 VP9 编码的 WebM,便于直接放入视频编辑流程或分享。
Remotion 官方将其定位为"high-fidelity webpage recorder",最适合的产品形态是"展示 UI 局部特写的产品演示视频"(product demos showing closeups of UI)——例如放大展示某个按钮、某个复杂交互区域的录屏,画面仍然清晰锐利。
需要注意的是,当前的官方文档明确写明Canvas Capture 目前要求 Apple Silicon(M 系列)Mac,并且依赖一个"钉死"版本(pinned)的 Chrome for Testing,相关前提将在下文详述。
使用前提:为什么需要固定的 Chrome for Testing
HTML-in-canvas 目前是 Chromium 的实验性 API,并非每个版本的浏览器都稳定可用。Remotion 团队对此的处理方式非常"工程化":把一个已知能工作的 Chromium 修订版本固定下来。
在 monorepo 的安装文档和扩展包内部 README 中,可以看到如下硬性前提:
- 操作系统:Apple Silicon Mac;
- 浏览器:Chrome for Testing
150.0.7842.0(对应 revisionr1631007)——这是已知支持所需 HTML-in-canvas API 的确切版本; - 该浏览器不接收安全更新,官方建议只用来访问可信网站;
- 不能用 Chrome Canary 或普通 Chrome 替代:它们会自动更新,可能移除或改变这个实验性 API 的行为。
为什么必须是 Chrome for Testing 而非开源 Chromium?内部 README 给出了明确理由:Chrome for Testing不会自动更新,且与开源构建不同,它内置了专有编解码支持,因此浏览器既能编码也能播放本扩展产出的 H.264 MP4 文件。这与项目内通过 wxt.config.ts 声明的一组启动参数完全对应:
--user-data-dir=.../Chrome for Testing Canvas Capture r1631007 --enable-features=CanvasDrawElement --enable-blink-features=CanvasDrawElement --disable-component-update --no-first-run --no-default-browser-check其中CanvasDrawElement正是 Chromium 中 HTML-in-canvas 实验能力的开关。
安装与首次启动流程
完整的分步安装命令以仓库内文档 installation.mdx 为准,整体流程如下四步:
第 1 步:下载已构建好的扩展。通过git clone --depth=1把 Canvas Capture 的生产构建产物克隆到一个持久化位置(例如"$HOME/Applications/Remotion Canvas Capture Extension")。注意官方文档特别强调:该仓库里已经包含生产构建,你不需要克隆或构建整个 Remotion。
第 2 步:安装固定的 Chrome for Testing。运行扩展附带的安装脚本:
"$HOME/Applications/Remotion Canvas Capture Extension/install-browser.sh"该脚本会安装上面提到的 Chrome for Testing150.0.7842.0(revisionr1631007)。
第 3 步:打开实验开关。启动 Chrome for Testing 后,进入chrome://flags,搜索Canvas Draw Element,将其设为Enabled并选择 Relaunch(重启浏览器)。
第 4 步:以开发者模式加载扩展。打开chrome://extensions,开启Developer mode(开发者模式),点击Load unpacked(加载已解压的扩展程序),在文件选择器中选中前面克隆好的Remotion Canvas Capture Extension目录。之后打开任意网页,点击扩展图标即可开始录制。
录制工作流:区域 / 整页、格式与倍率
加载扩展后,录制器的交互流程(见扩展包内部 README 的 Build and install 一节)大致如下:
- 在网页上点击扩展图标,打开录制器窗口(recorder window);
- 选择输出格式:H.264 MP4或VP9 WebM;
- 设定输出倍率(output scale);
- 选择捕获目标:拖拽框选一个区域(拖拽过程中页面获得焦点,但录制器窗口保持打开),或直接选择Whole page(整页);
- 点击Record开始录制,点击Stop结束。
这里有两个体现工程细节的交互,都值得开发者留意:
- "Record"按钮并非时刻可点。录制器只有在浏览器确认当前分辨率下 Mediabunny(底层媒体封装库)的"高质量、实时"精确编码配置可用后,才启用 Record 按钮。换句话说,扩展会针对你当前选定的输出尺寸先做一次编码能力预检,而不是等录完才发现不行。
- 录制过程中可以关掉录制器窗口。录制不会中断;重新点击扩展图标即可再次打开录制器,之后可以选择Stop and open in Convert(把录制结果直接送入 Remotion Convert 网页工具继续处理,无需先下载),或Stop and download(直接保存文件)。
底层实现:源码级解析
整个扩展是一个标准的 WXT(MV3)Chrome 扩展,其源码位于 packages/canvas-capture-extension。先看它的目录布局与关键文件职责:
src/ ├── entrypoints/ │ ├── background.ts # Service Worker 入口 │ ├── capture.ts # 内容脚本入口(区域捕获/整页捕获渲染源) │ ├── receiver.content.ts │ └── recorder/ # 录制器窗口 UI(React) │ ├── App.tsx / main.tsx / style.css / index.html ├── public/logo.svg ├── background.ts ├── capture.ts # PageCapture:核心捕获与编码逻辑 ├── content.ts # 页面内控制器:选区、状态机、录制控制 ├── handoff.ts # 把录制结果交接给 Remotion Convert ├── messages.ts # 扩展与录制器之间的消息协议 ├── receiver.ts ├── recorder.ts # HTML-in-canvas 封装、编码预检 ├── selection.ts # 选区矩形工具扩展清单与权限
从 wxt.config.ts 可以看到,扩展采用Manifest V3,权限包含activeTab、scripting、storage、unlimitedStorage(unlimitedStorage显然是为承载大尺寸录制的缓存/中间数据服务);默认弹窗(default popup)被指向录制器页面recorder.html。此外 WXT 配置还顺带定义了开发模式与生产模式的产物位置差异:开发构建直接写入~/Applications/Remotion Canvas Capture Extension Dev,从而保证开发产物与手动加载的生产扩展互不干扰、扩展 ID 在多个 worktree 间保持稳定。
页面内容脚本:以 Shadow DOM 实现选区层
在 content.ts 中可以看到一套完整的录制状态机(其状态字段包括supported、selecting、hasTarget、encoderSupport、outputSize、recording、finalizing、hasCompletedRecording、scale、format、status等)。选区交互层通过一个覆盖全页、zIndex为2147483647、pointer-events: none的宿主元素 +Shadow DOM实现:
.selection-layer(十字光标、可捕获指针事件)用于拖拽框选;.selection-box/.highlight用于实时显示选区与选中后的高亮框;- 监听
pointerdown/pointermove/pointerup完成框选,支持按Escape 取消选区(selection.ts 中makeSelectionRectangle以 min/max 归一化拖拽方向,保证反向拖拽也能得到正确矩形); - 选区坐标再相对
document.body的包围盒换算成页面内的裁剪矩形(CaptureCrop),之后交给捕获层。
内容脚本与录制器窗口之间的所有交互都通过类型化消息协议(messages.ts中的CaptureControllerRequest/CaptureControllerState)完成,命令包括get-state、set-options、select-area、select-whole-page、start-recording、stop-recording、open-in-convert、download等。
超分辨率捕获:layoutSubtree + OffscreenCanvas
核心捕获逻辑集中在 capture.ts,这里给出了"为何能高于屏幕分辨率"的实现答案。文件中定义了两个关键常量:
const maxCanvasDimension = 32_767; const maxEncodedDimension = 32_766;捕获过程中,页面会被临时"包"进一个设置了canvas.layoutSubtree = true的 HTML-in-canvas 画布(WrappedPage),录完后再恢复原状。整页捕获的尺寸取scrollWidth / scrollHeight与视口宽高的最大值,不受当前显示器像素的限制。
源码还揭示了"整页高保真 + 裁剪放大"的实现策略(见扩展包内部 README):整页子树先按显示器的原生像素密度(DPR)绘制,再把所选裁剪区域拷贝进一个可复用、尺寸精确的OffscreenCanvas——这正是超分辨率局部特写的来源。整个录制过程中还维护了一个预检(preflight)流程getCapturePreflight,根据scale与crop计算输出尺寸,再用 recorder.ts 中的canEncodeCapture(format, outputSize)探测该尺寸下 H.264 / VP9 编码是否可用;H.264 不可用时就自动降级尝试 VP9,两者都不可用则提示用户降低倍率或缩小选区。底层的媒体封装与高质量实时编码配置来自mediabunny依赖(见 package.json)。
完成后交接:下载或送入 Remotion Convert
录制结束拿到File后,用户有两种出口(content.ts 的consumeCompletedRecording):直接构造 object URL 触发<a download>下载;或者调用 handoff.ts 交接给 Remotion Convert。background.ts 中可以看到后者的桥接实现:扩展收到类型为remotion-canvas-capture-open-convert、携带captureId的消息后,就打开 Remotion Convert 页面并在 URL 中附带该捕获 ID,让录制结果无缝进入网页端继续处理。
已知限制
有两处限制来自源码与官方文档,值得在使用前了解:
- 页面内容会经历"包装再还原":录制期间页面内容被临时放进一个
layoutSubtreecanvas,结束后恢复。因此依赖直接子元素 CSS 选择器(如body > div)的网站,在捕获过程中可能看起来略有不同; - Chrome 自带页面与 Chrome Web Store 页面不允许扩展注入脚本,这些页面无法直接录制。
在 monorepo 中进行开发调试
如果你希望在 Remotion monorepo 内开发/调试该扩展,官方流程是:
cd packages/canvas-capture-extension bun run dev(对应 package.json 中的"dev": "bunx --bun wxt"。)
WXT 会启动 Vite,把开发版扩展写入独立的~/Applications/Remotion Canvas Capture Extension Dev目录,并自动以持久化 profile 启动前面钉死版本的 Chrome for Testing、加载扩展。开发体验上有两个特点:
- 录制器窗口支持热更新(HMR):编辑
src/entrypoints/recorder下的 React/CSS 时无需重新构建或重载窗口; - 核心逻辑改动自动重载:当 background、capture、receiver 或 manifest 变化时,WXT 会重新构建并重载对应扩展上下文。
关于本仓库的构建产物说明
最后提醒一点关于该文档的定位:packages/canvas-capture-extension/README.public.md是随已构建扩展一起发布的公开说明。它明确指出——本目录下的 README.md 更偏内部工程文档,而公开仓库中的扩展是由 Remotion monorepo 里的packages/canvas-capture-extension包经发布流水线生成的,直接在该仓库内做的修改会被后续发布覆盖;bug 反馈与代码贡献都应回到 Remotion 主仓库进行。也就是说,本文讲解的所有源码(content.ts、capture.ts、recorder.ts、wxt.config.ts 等)才是这个扩展的"真实源头"。
小结
Remotion Canvas Capture 的技术思路可以概括为一条清晰的链路:钉死一个支持实验性 API 的 Chromium → 用 HTML-in-canvas 把 DOM 以任意倍率重绘到 canvas → 框选/整页裁剪后经 Mediabunny 实时编码为 H.264 MP4 或 VP9 WebM → 下载或送入 Remotion Convert 进一步处理。它把"网页录屏"从像素复制升级成了"矢量级重绘",从而实现了超越屏幕分辨率的局部特写质量。若你需要在产品演示中呈现清晰的 UI 细节,且手头有 Apple Silicon Mac,就可以照着官方安装文档和本文给出的源码线索,立刻搭起这套录制链路。
【免费下载链接】remotion🎥 Make videos programmatically with React项目地址: https://gitcode.com/GitHub_Trending/re/remotion
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考