- 前端
- 可观测性
- 开发工具
【免费下载链接】rrweb
record and replay the web
rrvideo 是 rrweb 生态中一个轻量的命令行工具,用于把 rrweb 录制得到的会话数据(JSON 格式的事件流)在无头浏览器中回放并录制成 WebM 视频文件。本指南基于 packages/rrvideo/README.md 及其仓库源码,完整介绍安装、CLI 用法、配置文件编写,以及其底层“浏览器回放 + 录屏”的实现原理,读完即可把一份 rrweb 事件文件快速转成可分享、可归档的视频。
说明:本文对应的中文文档为 packages/rrvideo/README.zh_CN.md;rrvideo 的定位也可参考仓库中的实践文档 docs/recipes/export-to-video.md(“Convert To Video”)。
rrvideo 是什么:从事件流到视频
rrweb 录制产生的数据本质上是一份文本格式的事件序列(eventWithTime[]),体积小、易压缩,回放时能做到像素级还原。但它并不是真正的视频文件,无法直接放进播放器、社交平台或常规的视频工作流。rrvideo 解决的就是这个缺口:读取事件 JSON,在浏览器中完整回放,并把回放过程录制为 WebM 视频。
从源码结构看,rrvideo 包由三部分组成:
- packages/rrvideo/src/cli.ts:CLI 入口,负责解析命令行参数、读取配置文件、展示进度条并调用核心函数;
- packages/rrvideo/src/index.ts:核心导出
transformToVideo,承担读取事件、启动浏览器、注入播放器、等待回放结束并产出视频的完整流程; - packages/rrvideo/test/cli.test.ts:CLI 的自动化测试,验证了缺参报错、默认输出与指定输出三种场景。
安装 rrvideo
rrvideo 以全局 CLI 的方式分发,安装前需先准备好 Node.js 环境:
npm i -g rrvideo安装完成后,rrvideo命令即全局可用。从 packages/rrvideo/package.json 可以看到,包的bin字段将rrvideo命令指向build/cli.js,而其依赖包含playwright与rrweb-player——这意味着转换过程依赖 Playwright 下载的 Chromium 浏览器。安装脚本会根据环境变量PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD决定是否执行playwright install(见 package.json 的install脚本),因此若在 CI 或离线环境安装,需要留意浏览器二进制是否可用。
快速开始:一条命令生成视频
最基本的转换
rrvideo --input PATH_TO_YOUR_RRWEB_EVENTS_FILE其中PATH_TO_YOUR_RRWEB_EVENTS_FILE指向一份 rrweb 录制得到的事件 JSON 文件。运行该命令会在当前工作目录生成rrvideo-output.webm。
这一行为在 packages/rrvideo/src/index.ts 的默认配置中有明确对应:
const defaultConfig: Required<RRvideoConfig> = { input: '', output: 'rrvideo-output.webm', // 未指定输出时的默认文件名 headless: true, resolutionRatio: 0.8, // 质量与体积的折中值 onProgressUpdate: () => {}, rrwebPlayer: {}, };同时,CLI 会对--input做必填校验——packages/rrvideo/src/cli.ts 第 11 行起,缺少--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可以是一个文件名或完整路径,转换完成后的视频会被移动到该位置。需要注意的是,--input与--output都支持绝对路径与相对路径——在 packages/rrvideo/src/index.ts 中,相对路径会基于process.cwd()解析为绝对路径。
通过配置文件定制回放
rrvideo 提供了一种更灵活的方式:编写一个 JSON 配置文件,把 rrweb-player 的配置项传入回放过程。
rrvideo --input PATH_TO_YOUR_RRWEB_EVENTS_JSON_FILE --config PATH_TO_YOUR_RRVIDEO_CONFIG_FILE仓库中提供了一份可直接参考的示例配置:packages/rrvideo/rrvideo.config.example.json,内容如下:
{ "width": 1400, "height": 900, "speed": 4, "skipInactive": true, "mouseTail": { "strokeStyle": "green", "lineWidth": 2 } }CLI 读取该 JSON 后,会将其作为rrwebPlayer的 props 传入核心函数(packages/rrvideo/src/cli.ts 第 17~26 行),类型上对应rrweb-player构造参数的props(去掉events字段),可用的配置项可从 packages/rrweb-player/src/types.ts 中查证。
配置项说明
| 配置键 | 默认值 | 说明 |
|---|---|---|
width | 1024 | 播放器宽度(像素),rrvideo 内部会结合分辨率再放大视口,详见下文“分辨率放大” |
height | 576 | 播放器高度(像素) |
speed | 1 | 回放速度倍率,例如4表示 4 倍速;同时用于估算回放耗时以设置超时 |
skipInactive | false | 是否跳过无操作的空闲时间段,可显著缩短长会话视频的时长 |
mouseTail | — | 鼠标轨迹尾迹样式,示例中使用strokeStyle: "green"与lineWidth: 2配置颜色与线宽 |
autoPlay/showController | — | 注意:这两个键会被 rrvideo 强制覆盖。在 packages/rrvideo/src/index.ts 的getHtml中,播放器 props 的展开顺序为...userConfig在前、showController: false与autoPlay: false在后,因此用户配置无法改变它们——视频录制不需要控制条,也必须在事件监听器挂载完成后由 rrvideo 主动调用play() |
此外,由于 rrweb-player 的 props 是& Partial<playerConfig>的交叉类型,@rrweb/replay的播放器配置(如mouseTail、skipInactive、unloadCanvas、useVirtualDom等)同样会被透传,具体可参考 packages/rrweb-player/README.md 的 Options 章节。
以编程方式调用:transformToVideo
除了 CLI,rrvideo 的核心能力通过transformToVideo(options)导出(packages/rrvideo/src/index.ts),可在 Node.js 脚本中直接使用。其完整参数如下:
type RRvideoConfig = { input: string; // 必填:rrweb 事件 JSON 文件路径 output?: string; // 可选:输出视频路径,默认 'rrvideo-output.webm' headless?: boolean; // 可选:是否无头运行浏览器,默认 true resolutionRatio?: number; // 可选:0~1 之间的数值,越高画质越好,默认 0.8,超过 1 会被截断为 1 onProgressUpdate?: (percent: number) => void; // 回放进度回调,percent 为 0~1 rrwebPlayer?: Omit<ConstructorParameters<typeof Player>[0]['props'], 'events'>; };示例:
const { transformToVideo } = require('rrvideo'); transformToVideo({ input: './session.json', output: './session.webm', resolutionRatio: 1, onProgressUpdate: (percent) => console.log(`进度:${Math.round(percent * 100)}%`), }).then((file) => console.log(`转换完成:${file}`));CLI 内部也正是这么用的——它通过@open-tech-world/cli-progress-bar在终端渲染进度条,并把percent映射为百分比(packages/rrvideo/src/cli.ts 第 28~40 行)。headless: false时浏览器窗口可见,方便调试回放与录制过程。
实现原理:无头浏览器回放 + 录制
理解 rrvideo 的内部机制,有助于判断它在什么场景下适用、如何调优。整个流程在transformToVideo中串成一条链路,主要分为五步。
1. 预处理:计算最大视口并放大分辨率
rrvideo 首先遍历全部事件,从EventType.Meta事件中取出出现过的最大width/height,作为回放视口基准(getMaxViewport)。随后执行超采样放大以提升视频清晰度:
const 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,录制的视频再被 CSStransform: scale(...)缩回原比例(见getHtml中的resize事件处理),从而获得高于原始分辨率的录制画质——这就是配置项里“越高画质越好”的实现来源。
2. 启动浏览器并录制视口
使用 Playwright 启动 Chromium(headless由配置决定),并以scaledViewport作为视口尺寸创建上下文,同时开启recordVideo录制:
const context = await browser.newContext({ viewport: scaledViewport, recordVideo: { dir: defaultVideoDir, size: scaledViewport }, });录制过程中产生的临时文件会写入__rrvideo__temp__目录,转换结束后被清理。
3. 注入 rrweb-player 并回放
rrvideo 在运行时读取已安装的rrweb-player的 UMD 产物与样式文件(dist/rrweb-player.umd.cjs与style.css),连同事件数据一起拼装成一个自包含的 HTML 页面,注入到about:blank页面中执行。页面脚本的关键逻辑:
- 以
new rrwebPlayer({ target: document.body, props: { ...userConfig, events, showController: false, autoPlay: false } })创建播放器; - 监听
finish事件,触发页面侧的onReplayFinish通知 Node 进程回放结束; - 监听
ui-update-progress事件,把进度透传给onProgressUpdate回调; - 在
resize事件中通过 CSS transform 把播放器缩放回原始比例。
4. 等待回放完成(含超时保护)
Node 侧用一个 Promise 等待回放结束,超时时间按事件时间轴估算:
const expectedPlaybackTime = (最后事件时间戳 - 首事件时间戳) / speed; const totalTimeout = expectedPlaybackTime + 120000; // 额外 2 分钟缓冲即:预估播放耗时 = 事件总时长 ÷ 播放速度,再加上 2 分钟缓冲;若finish事件始终未触发,会以Replay timeout拒绝并结束进程。这解释了为什么配置文件中的speed不仅影响成片速度,也影响整体转换的耗时上限。
5. 收尾:移动视频并清理
回放结束后,从page.video()取得录制的临时视频路径,将其移动到output指定位置(默认覆盖同名文件),随后关闭浏览器上下文、删除临时目录。
事件文件长什么样
rrvideo 的输入是标准的 rrweb 事件数组(eventWithTime[])。仓库测试中内置了一份最小可用的示例:packages/rrvideo/test/events/example.ts,它依次包含DomContentLoaded、Load、Meta、FullSnapshot、IncrementalSnapshot(Mutation)以及输入事件,可以作为手写测试事件或校验录制链路的参考——CLI 测试正是把这份事件写入example.json后喂给rrvideo的(packages/rrvideo/test/cli.test.ts)。
验证与常见问题
如何验证安装与转换
仓库的 CLI 测试覆盖了三种关键路径(packages/rrvideo/test/cli.test.ts):
- 不带
--input运行 → 抛出please pass --input to your rrweb events file; - 仅带
--input→ 在当前目录生成rrvideo-output.webm; - 带
--input与--output→ 在指定路径生成视频。
在自己的项目中,可先确认rrvideo --help(或直接运行)能正常输出,再准备一份合法的事件 JSON 做最小验证。
常见注意点
- 输出格式固定为 WebM:录制来自 Playwright 的视频,产出为 WebM;如需 MP4,可在转换后用 ffmpeg 等工具二次转码;
- 首次运行需下载浏览器:依赖 Playwright Chromium,首次运行或安装时若被网络策略阻断,需提前完成
playwright install; - 长会话会拉长转换时间:视频转换是“实时回放 + 录制”,转换耗时约等于事件总时长 ÷ 播放速度,可通过提高
speed或开启skipInactive缩短; - 画质与体积的权衡:
resolutionRatio默认0.8是质量与文件大小的折中,追求画质可设为1,但文件会更大;该值超过1会被代码截断为1(packages/rrvideo/src/index.ts 第 111 行); - 控制条不会出现在视频中:
showController被强制关闭,成片是纯净的回放画面。
延伸阅读
- 中文文档 与 示例配置
- 核心实现:CLI 入口、转换函数
- 播放器配置项来源:packages/rrweb-player/src/types.ts、packages/rrweb-player/README.md
- 相关的实践文档:docs/recipes/export-to-video.md
- 若要了解 rrweb 事件数据本身的结构,可阅读 docs/events.md 与 docs/replay.md
- 前端
- 可观测性
- 开发工具
【免费下载链接】rrweb
record and replay the web
相关推荐
rrvideo 使用指南:将 rrweb 会话录制转换为 WebM 视频
rrvideo 使用指南:将 rrweb 会话录制转换为 WebM 视频 <output文章 rrvideo 使用指南:将 rrweb 会话录制转换为 WebM
前端可观测性开发工具rrweb 录制数据转视频实战:使用 rrvideo 将会话回放导出为 WebM 视频
rrweb 录制数据转视频实战:使用 rrvideo 将会话回放导出为 WebM 视频 rrweb 的录制数据是高效的文本 JSON 格式,可在浏览器中做像素级
前端可观测性开发工具rrweb 录制数据转视频实战:使用 rrvideo 将会话回放导出为 WebM 视频
rrweb 录制数据转视频实战:使用 rrvideo 将会话回放导出为 WebM 视频 rrweb 的录制产物是一种高效、易于压缩的文本格式事件流,回放时可达到
前端可观测性开发工具
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考