rrvideo 使用指南:将 rrweb 会话录制转换为 WebM 视频
【免费下载链接】rrwebrecord and replay the web项目地址: https://gitcode.com/gh_mirrors/rr/rrweb
<output文章>
rrvideo 使用指南:将 rrweb 会话录制转换为 WebM 视频
导读
rrvideo 是 rrweb 生态中的命令行工具,核心职责是将 rrweb 录制得到的会话事件数据(JSON 格式)在无头浏览器中回放并录制为视频文件。本文以 packages/rrvideo/CHANGELOG.md 为脉络,结合 packages/rrvideo/src/index.ts 与 packages/rrvideo/src/cli.ts 的源码实现,完整讲解 rrvideo 的安装、命令行参数、配置文件与底层转换原理,并补充 2.x 版本以来的关键变更(视频质量优化、进度条、回放超时机制等)。读者学完后将能够独立完成"rrweb 事件 JSON → WebM 视频"的转换,并理解其内部工作机制。
说明:本文涉及的文件均位于仓库
packages/rrvideo/目录,源码细节以仓库当前状态(rrvideo 2.1.5)为准。
rrvideo 是什么
rrweb 的录制产物是结构化事件流(eventWithTime[]),而非像素画面。它体积小、可检索、可交互回放,但无法直接用于传统视频场景(如分享给非技术同事、投放到视频平台、作为 bug 上报附件)。rrvideo 的定位就是打通这条链路:读取 JSON 事件文件,在浏览器环境中用 rrweb-player 播放,同时用 Playwright 的视频录制能力把整个回放过程录成视频文件。
从源码看,rrvideo 同时提供两种使用形态:
- CLI 命令行工具:通过 packages/rrvideo/package.json 中的
bin字段暴露rrvideo命令(对应build/cli.js),是文档推荐的主用法; - 编程接口:核心转换逻辑封装在
transformToVideo(options)函数中(见 packages/rrvideo/src/index.ts),CLI 本质上只是对该函数的薄封装。
安装 rrvideo
rrvideo 的安装依赖 Node.js 运行时与 Playwright 浏览器。仓库package.json中的install脚本会在安装时自动执行playwright install下载 Chromium(可通过环境变量PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD跳过)。
官方文档给出的安装步骤:
- 安装 Node.JS;
- 全局安装 CLI:
npm i -g rrvideo安装完成后即可在任意目录使用rrvideo命令。若从本仓库开发调试,可先执行yarn build(该包构建脚本为tsc)生成build/产物,再用node ./build/cli.js直接运行。
快速开始:将 rrweb 会话转换为视频
最小命令
rrvideo --input PATH_TO_YOUR_RRWEB_EVENTS_FILE--input指向 rrweb 录制导出的 JSON 文件(一个eventWithTime[]数组)。运行成功后,会在当前工作目录生成默认输出文件rrvideo-output.webm。
CLI 对--input的处理位于 packages/rrvideo/src/cli.ts:使用minimist解析参数后,若缺少--input会直接抛出错误please pass --input to your rrweb events file。对应测试见 packages/rrvideo/test/cli.test.ts 中的should throw error without input path用例。
指定输出路径
rrvideo --input PATH_TO_YOUR_RRWEB_EVENTS_FILE --output OUTPUT_PATH--output支持相对路径或绝对路径。在 packages/rrvideo/src/index.ts 中,输入输出路径都会被解析为绝对路径(相对路径以process.cwd()为基准),视频文件最终以overwrite: true的方式移动(fs.move)到目标位置。
通过配置文件定制回放
rrvideo --input PATH_TO_YOUR_RRWEB_EVENTS_JSON_FILE --config PATH_TO_YOUR_RRVIDEO_CONFIG_FILE--config指向一个 JSON 文件,其内容会被解析后透传给 rrweb-player 的props(events字段除外)。仓库提供了完整的参考配置 packages/rrvideo/rrvideo.config.example.json,内容如下:
{ "width": 1400, "height": 900, "speed": 4, "skipInactive": true, "mouseTail": { "strokeStyle": "green", "lineWidth": 2 } }| 配置项 | 类型 | 含义 | 默认值(rrweb-player) |
|---|---|---|---|
width/height | number | 播放器尺寸(会被 rrvideo 覆写为缩放后的视口尺寸,见下文"视频质量优化") | 1024/576 |
speed | number | 回放倍速,同时也决定录屏时长与超时计算 | 1 |
skipInactive | boolean | 跳过无交互的空白时间段,缩短视频时长 | 取决于 rrweb-player |
mouseTail | object | 鼠标轨迹尾巴样式(strokeStyle为颜色,lineWidth为线宽) | — |
rrweb-player 的完整props类型定义见 packages/rrweb-player/src/types.ts,其中还包括maxScale、autoPlay、speedOption、showController、tags、inactiveColor等选项,均可写入配置文件。需要注意的是:rrvideo 在注入页面时会强制覆写showController: false(隐藏控制器)与autoPlay: false(先挂载事件监听再手动play()),因此这两个配置项在配置文件中不会生效。
深入源码:转换流程与关键机制
transformToVideo的完整流程(见 packages/rrvideo/src/index.ts):
- 读取并解析事件文件:将
--input指定的 JSON 解析为eventWithTime[]; - 计算最大视口:
getMaxViewport()遍历所有Meta事件,取width/height的最大值作为回放基准; - 构建 HTML 宿主页:
getHtml()内联 rrweb-player 的 UMD 产物(rrweb-player.umd.cjs)与样式表,将事件数据经JSON.stringify注入,</script>序列会被转义为<\/script>防止闭合;随后实例化rrwebPlayer并监听finish与ui-update-progress事件; - 启动 Chromium 并录屏:
chromium.launch({ headless })启动无头浏览器,browser.newContext设置与缩放后视口一致的viewport与recordVideo参数,录制过程写入临时目录__rrvideo__temp__; - 等待回放结束:通过
page.exposeFunction暴露onReplayFinish与onReplayProgressUpdate给页面调用;以事件首尾时间戳之差作为视频时长,结合speed计算出预期播放时长,加上 2 分钟缓冲作为超时上限; - 产出视频:回放结束后,将临时视频文件移动到
--output指定路径,并清理临时目录。
视频质量优化与分辨率缩放
rrvideo 2.0 引入了"缩放录制"机制(源码注释明确说明这是为了提高视频质量的 scaling method)。核心常量MaxScaleValue = 2.5,实际录屏分辨率计算如下:
const scaledViewport = { width: Math.round(maxViewport.width * (config.resolutionRatio ?? 1) * MaxScaleValue), height: Math.round(maxViewport.height * (config.resolutionRatio ?? 1) * MaxScaleValue), };即:录屏视口 = 事件流中的最大页面尺寸 ×resolutionRatio× 2.5,同时页面内的.replayer-wrapper会以scale(...) translate(-50%, -50%)进行等比缩放适配。resolutionRatio是 0~1 之间的数值,数值越高画质越好、文件越大;transformToVideo中将其钳制在 1 以内(> 1时强制置为 1),默认值取 0.8,源码注释称其为"画质与文件体积之间的良好折中值"。
因此最终视频的实际分辨率会高于原始会话页面的分辨率——这正是"视频质量优化"的由来。
回放超时机制
长时间录制的回放若按固定超时处理,容易在视频尚未播完时就误判失败。2.0.0 版本(CHANGELOG 中的 PR #1762)将超时改为基于视频时长动态计算:totalTimeout = expectedPlaybackTime + 120000,其中expectedPlaybackTime = 视频事件时长 / speed,2 分钟(timeoutBuffer)作为缓冲。同时,CLI 运行时会输出[DEBUG] Expected playback time...日志,便于定位"超时"类问题。
进度条与日志输出
cli.ts使用@open-tech-world/cli-progress-bar渲染进度条:onProgressUpdate回调将回放进度(0~1)转换为百分比渲染,进度达到 100% 时前缀切换为Transformation Completed!。转换结束后 CLI 会打印输出文件路径;若失败则打印Failed to transform this session.并输出错误详情后以退出码 1 结束。
编程式使用:transformToVideo 参数说明
除 CLI 外,也可在 Node.js 中直接调用transformToVideo。RRvideoConfig类型定义(见 packages/rrvideo/src/index.ts)包含:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
input | string | (必填) | rrweb 事件 JSON 文件路径 |
output | string | rrvideo-output.webm | 输出视频路径 |
headless | boolean | true | 是否无头运行 Chromium(false时可观察回放过程) |
resolutionRatio | number | 0.8 | 分辨率比例,0~1,越大画质越好 |
onProgressUpdate | (percent: number) => void | 空函数 | 回放进度回调 |
rrwebPlayer | 对象 | {} | rrweb-player 的props(不含events) |
测试验证与示例数据
仓库用 Jest 对 CLI 行为做了端到端验证(见 packages/rrvideo/test/cli.test.ts),覆盖三个场景:
- 不带
--input时抛出please pass --input to your rrweb events file; --input指向示例事件文件时生成rrvideo-output.webm;- 同时指定
--output时在目标路径生成视频。
测试所用的示例事件流位于 packages/rrvideo/test/events/example.ts,包含DomContentLoaded、Load、Meta、FullSnapshot与多条IncrementalSnapshot(DOM 增补、Input 输入)事件,是理解"rrweb 事件 JSON 长什么样"的最小样例。
版本变更速览
packages/rrvideo/CHANGELOG.md 记录了 rrvideo 2.x 的主要变更:
- 2.0.0 / 2.0.0-alpha.9:改进视频质量并新增 CLI 进度条(PR #1197);更新 Playwright 至 1.60.0(PR #1845);回放超时改为"视频时长 + 2 分钟缓冲"(PR #1762);修复 rrweb-player 用法,避免回放停滞(PR #1762);rrvideo 迁入 rrweb 的 monorepo(PR #1181);
- 2.0.0-alpha.10~20 及之后:以跟随 rrweb-player 依赖更新的 Patch 变更为主,未引入新的功能点;最新版本 2.1.5 仅更新依赖 rrweb-player@2.1.5。
注意事项与限制
- 输出格式:当前实现固定输出 WebM(Playwright 录制原生格式),无转码为 MP4 的能力;
- 运行时要求:转换依赖本地 Chromium 环境,请确保 Node.js 与 Playwright 安装完整;CI 或服务器环境注意磁盘与内存占用(录屏临时文件会先写入
__rrvideo__temp__); - 播放速度与时长:
speed配置会同时影响回放倍速、视频时长和超时计算,调整时需一并考虑; - 受 rrweb-player 能力约束:视频呈现的视觉效果(如鼠标轨迹、跳过空闲段、事件标签样式)以 rrweb-player 的实现为准,可在配置文件允许范围内定制。
参考文件索引
- 使用说明:packages/rrvideo/README.md、packages/rrvideo/README.zh_CN.md
- CLI 入口:packages/rrvideo/src/cli.ts
- 核心转换逻辑:packages/rrvideo/src/index.ts
- 配置示例:packages/rrvideo/rrvideo.config.example.json
- 版本记录:packages/rrvideo/CHANGELOG.md
- 测试用例:packages/rrvideo/test/cli.test.ts、示例事件 packages/rrvideo/test/events/example.ts </output文章>
【免费下载链接】rrwebrecord and replay the web项目地址: https://gitcode.com/gh_mirrors/rr/rrweb
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考