首页
/ Playwright CLI 视频录制指南:用 playwright-cli 与 Screencast API 生成带章节与标注的 WebM 演示视频

Playwright CLI 视频录制指南:用 playwright-cli 与 Screencast API 生成带章节与标注的 WebM 演示视频

2026-09-06 18:09:07作者:彭桢灵Jeremy

Playwright 的视频录制能力用于把浏览器自动化会话捕获为 WebM(VP8/VP9 编码)视频,服务于调试复盘、交付演示与文档化场景。本指南以 video-recording.md 为主线,讲解 playwright-cli 三条录制命令的交互式用法,以及通过 run-code + page.screencast API 编写“脚本化录屏”,在视频中插入章节卡片、悬浮标注与元素高亮,产出专业级操作演示。

背景:video 命令在 playwright-cli 中的位置

playwright-cli 是一套供 Agent 与自动化程序驱动浏览器的命令行界面,其全部命令在 SKILL.md 中登记,其中视频相关命令归类于 devtools 能力组:

# record user actions in the browser, print them as Playwright code on stop
playwright-cli video-start video.webm
playwright-cli video-chapter "Chapter Title" --description="Details" --duration=2000
playwright-cli video-stop

这些命令的命令行参数定义位于 cli-daemon/commands.ts,每个命令映射到底层工具(tool),真正执行录制、章节与标注逻辑的是 tools/backend/video.ts 中导出的五个工具:browser_start_videobrowser_stop_videobrowser_video_chapterbrowser_video_show_actionsbrowser_video_hide_actions

基础录制流程

视频录制在已打开的浏览器会话上进行。核心命令如下:

命令 作用 关键参数
video-start 开始录制 filename(保存文件名,可选);--size=WxH(视频帧尺寸,如 800x600
video-chapter 在录制流中加入章节卡片 title(标题,必填);--description(描述);--duration(卡片展示毫秒数)
video-stop 停止录制并保存视频

一段最小可用的交互式录制流程:

# 先打开浏览器
playwright-cli open

# 开始录制
playwright-cli video-start demo.webm

# 为章节切换插入章节标记
playwright-cli video-chapter "Getting Started" --description="Opening the homepage" --duration=2000

# 导航并执行操作
playwright-cli goto https://example.com
playwright-cli snapshot
playwright-cli click e1

# 添加另一个章节
playwright-cli video-chapter "Filling Form" --description="Entering test data" --duration=2000
playwright-cli fill e2 "test input"

# 停止并保存
playwright-cli video-stop

几点参数细节可从命令定义中确认:

  • 文件名可省略video-startfilename 是可选参数。底层 browser_start_video 工具会在未提供文件名时按 video-{timestamp}.webm 规则命名,并把相对路径解析到工作区根目录(见 tools/backend/video.ts)。若给不出更贴切的名字,省略它让系统自动命名即可。
  • 尺寸参数video-start --size 支持 "800x600" 这样的 宽x高 字符串,命令层会把它解析为 { width, height } 结构后透传给底层(见 commands.ts)。未指定时,服务端会以当前页面视口为基准做缩放:默认在 800×800 的边界内按比例取整尺寸(见 server/screencast.ts)。
  • 章节标记video-chapter 在当前标签页的页面上调用 page.screencast.showChapter(title, { description, duration }),会在页面正中显示一张带模糊背景的全屏章节卡片,duration 为 0/省略时该卡片不会自动消失(见 tools/backend/video.ts)。
  • 停止即保存video-stop 对应 browser_stop_video,会返回录制到的全部视频文件并解析为最终产物(见 tools/backend/video.ts)。

录制一旦开始,页面上的真实操作(gotoclickfill 等)都会被连续帧捕获,因此流程中自然的 snapshot 停顿或 waitForTimeout 就是视频中的“留白”,可以用来控制节奏。

录制自动标注:video-show-actions 与 video-hide-actions

除章节卡片外,CLI 还提供一对动作标注命令(同样属于 devtools 能力组,见 SKILL.md):

# 为后续每个动作(click、type…)在页面上叠加“动作名 + 目标高亮”标注
playwright-cli video-show-actions --duration=600 --position=top-right
playwright-cli video-hide-actions

参数说明(定义见 commands.ts):

参数 含义 默认值
--duration 每个动作标注停留的毫秒数 500
--position 动作标题位置:top-left/top/top-right/bottom-left/bottom/bottom-right top-right
--cursor 光标装饰:pointer 会在动作点之间动画一个鼠标指针;none 关闭 pointer

底层实现上,browser_video_show_actions 会调用 tab.page.screencast.showActions(...),随后每当真实输入动作(点击、键入等)发生前,服务端都会在页面上短暂渲染一次标注:渲染动作标题、定位目标边界框并叠加指针动画,再在 duration 毫秒后移除(见 server/screencast.ts)。这非常适合“边执行边录制”的场景——无需任何脚本即可让最终视频里的每一步操作都有视觉说明。

最佳实践:用 run-code 录制完整脚本

文档特别强调:当录制给用户观看的“成品视频”或用作工作交付证明时,不要逐条敲 CLI 命令,而是把整个场景写成一段代码,交给 run-code 执行。这样可以在动作之间插入恰到好处的停顿,并为视频逐段添加旁白与标注。

推荐的完整流程分三步:

  1. 先用 CLI 走一遍场景,用 snapshot 记录下所有关键元素的 ref 与 locator,随后利用 locator 去请求对应的边界框(bounding box)以便做高亮。
  2. 把目标视频写成脚本文件:使用 pressSequentially 配合 delay 模拟自然的打字节奏,并在动作之间加入合理的等待。
  3. playwright-cli run-code --filename your-script.js 执行,一次跑完整个场景并自动产出视频。

run-code 命令本身接受 --filename 从文件加载代码,也可以直接用 --code 传入内联函数(定义见 commands.ts),代码以 async page => { ... } 形式编写。

完整示例脚本(改编自原文档):

async page => {
  await page.screencast.start({ path: 'video.webm', size: { width: 1280, height: 800 } });
  await page.goto('https://demo.playwright.dev/todomvc');

  // 章节卡片:模糊页面并弹出对话框,duration 到期后自动移除。
  // 简单场景用 showChapter 即可;如需更漂亮的叠加层,
  // 随时可以用 await page.screencast.showOverlay() 手工定制。
  await page.screencast.showChapter('Adding Todo Items', {
    description: 'We will add several items to the todo list.',
    duration: 2000,
  });

  // 执行动作
  await page.getByRole('textbox', { name: 'What needs to be done?' }).pressSequentially('Walk the dog', { delay: 60 });
  await page.getByRole('textbox', { name: 'What needs to be done?' }).press('Enter');
  await page.waitForTimeout(1000);

  // 展示下一章节
  await page.screencast.showChapter('Verifying Results', {
    description: 'Checking the item appeared in the list.',
    duration: 2000,
  });

  // 添加一个“粘性”标注,标注保持显示的同时仍可继续操作页面。
  // 叠加层是 pointer-events: none,不会挡住点击。
  const annotation = await page.screencast.showOverlay(`
    <div style="position: absolute; top: 8px; right: 8px;
      padding: 6px 12px; background: rgba(0,0,0,0.7);
      border-radius: 8px; font-size: 13px; color: white;">
      ✓ Item added successfully
    </div>
  `);

  // 标注显示期间继续执行动作
  await page.getByRole('textbox', { name: 'What needs to be done?' }).pressSequentially('Buy groceries', { delay: 60 });
  await page.getByRole('textbox', { name: 'What needs to be done?' }).press('Enter');
  await page.waitForTimeout(1500);

  // 移除标注
  await annotation.dispose();

  // 也可以高亮相关 locator 并提供上下文标注:
  const bounds = await page.getByText('Walk the dog').boundingBox();
  await page.screencast.showOverlay(`
    <div style="position: absolute;
      top: ${bounds.y}px;
      left: ${bounds.x}px;
      width: ${bounds.width}px;
      height: ${bounds.height}px;
      border: 1px solid red;">
    </div>
    <div style="position: absolute;
      top: ${bounds.y + bounds.height + 5}px;
      left: ${bounds.x + bounds.width / 2}px;
      transform: translateX(-50%);
      padding: 6px;
      background: #808080;
      border-radius: 10px;
      font-size: 14px;
      color: white;">Check it out, it is right above this text
    </div>
  `, { duration: 2000 });

  await page.screencast.stop();
}

脚本中的关键约定:

  • screencast 生命周期page.screencast.start(...) 开始录屏并返回一个 DisposableStubpath 指定视频保存位置、size 指定画面尺寸;page.screencast.stop() 结束录制并落盘。客户端侧实现见 client/screencast.ts
  • 叠加层不拦截事件:所有 overlay 都带 pointer-events: none,因此即使把粘性标注一直显示在页面上,后续的 clickfill 等操作也完全不受影响(原文档特别提醒这一点)。
  • showChapter 会阻塞:章节卡片持续到 duration 耗尽后自动移除,才继续执行后续代码,因此它天然充当了“暂停—解说—继续”的节奏控制点。
  • boundingBox() 配合 overlay:先取目标元素的边界框,再据此生成一个绝对定位的高亮矩形与说明气泡,是制作“注视某个元素”效果的标准手法。
  • 创造力不受限:overlay 就是注入到页面的任意 HTML,你可以按需定制任意样式,做出远比内置卡片更丰富的视觉效果。

Overlay API 汇总

原文档给出如下 API 对照表,可直接用于脚本:

方法 适用场景
page.screencast.showChapter(title, { description?, duration?, styleSheet? }) 全屏章节卡片 + 模糊背景 —— 适合章节切换
page.screencast.showOverlay(html, { duration? }) 自定义 HTML 叠加层 —— 用于提示框、标签、高亮
disposable.dispose() 移除未带 duration 的粘性叠加层
page.screencast.hideOverlays() / page.screencast.showOverlays() 临时隐藏 / 恢复显示所有叠加层

这些方法都由 Screencast 客户端类实现并逐一通过协议通道下发(见 client/screencast.ts):showOverlay 会获得一个 overlay id,返回的 DisposableStub 在 dispose 时触发 screencastRemoveOverlayhideOverlays/showOverlays 则通过 screencastSetOverlayVisible 统一控制全部叠加层的显隐,方便在需要展示“干净页面”的时刻临时收拢标注。

最佳实践:文件名与目录组织

视频文件会堆积在输出目录中,建议在文件名中携带足够的上下文,方便日后检索:

# 在文件名中包含上下文
playwright-cli video-start recordings/login-flow-2024-01-15.webm
playwright-cli video-start recordings/checkout-test-run-42.webm

录制多个场景时,按 场景-日期流程-运行号 的命名习惯(如 login-flow-2024-01-15.webm)能显著提升可追溯性。也可以省略 filename,让系统以 video-{timestamp}.webm 自动命名并写入输出目录。

Tracing vs Video:如何选择

录制浏览器会话还有另一条途径——Tracing(可配合 playwright-cli tracing-start / tracing-stop 使用)。两者的能力边界如下:

特性 Video Tracing
输出 WebM 文件 Trace 文件(可在 Trace Viewer 中查看)
展示内容 视觉录制画面 DOM 快照、网络、控制台、动作序列
适用场景 演示、文档 调试、分析
体积 较大 较小

选择依据:当你需要“给人看”的画面(产品演示、交付证明、教学视频),选 Video;当你需要“给程序分析”的结构化数据(复现 bug、审查请求与状态),选 Tracing。二者并不互斥,同一场景可以同时开启。

底层实现与已知限制

从服务端实现可以佐证视频产出的几个工程细节:

  • 输出编码为 VP8 的 WebM:服务端 _startScreencast 在未指定尺寸时会依据视口等比例缩放进 800×800 的盒子,并把宽高强制转换为偶数——注释明确说明“两个维度都必须为奇数……vp8 需要”(实际代码 width & ~1 / height & ~1 向下取偶,见 server/screencast.ts),同时 JPEG 帧质量默认 90。
  • 客户端 API 与类型page.screencast 对应的公开类型位于 client/screencast.tsScreencast 实例通过监听页面的 screencastFrame 通道事件接收帧,并在 stop() 时把产物 Artifact 保存到 path
  • 一个录制会话可被多方消费:服务端维护多个 client,帧会同时分发给视频录制与 tracing 等消费者,且按“任一 consumer 完成即 ack”的 OR 逻辑保证帧流不被最慢的一方阻塞(见 server/screencast.ts)。

需要留意的局限(原文档明确列出):

  • 录制会带来轻微自动化开销:帧捕获与编码占用 CPU,长场景下可能使操作略有延迟。
  • 大录制会消耗显著磁盘空间:分辨率越高、时长越长,产物越大。建议明确指定 --sizesize 以控制体积,录完即检查磁盘占用。

延伸阅读

登录后查看全文
热门项目推荐
相关项目推荐