做一条产品演示视频,通常得自己开录屏软件、点一遍流程、再进剪辑器加缩放和标注。Screenplay 把这件事交给编码 Agent:它去逛你的网站或桌面应用,写出一份 JSON 分镜,然后照着分镜真实操作、拍摄、剪成 MP4。本教程六步跑通安装接入、写分镜、演练、录制、重剪与登录态,全部命令来自项目 README,跟着做就能出片。
先弄清:这摊活到底由谁干
Screenplay 自身不含 AI,也不需要模型 API Key。它是一套 MCP server + CLI + 技能指南:负责执行分镜、拍摄、剪辑。理解「谁写分镜、谁执行」是避免踩坑的关键——写分镜的是你的 MCP 客户端里的模型,Screenplay 只照着做。
| 角色 | 干什么 | 你要准备什么 |
|---|---|---|
| 编码 Agent(Claude Code / Codex / Cursor) | 逛站点、写 scenario JSON、决定镜头 | 已有可用的客户端与模型 |
| Screenplay MCP server | 注册到客户端,暴露能力并接收分镜 | npx agent-screenplay init |
| Playwright + headless Chromium | 网页场景下按选择器真实点击与输入 | init 时下载一次 |
| agent-desktop + ffmpeg | 桌面应用场景下走系统无障碍 API 并录屏 | 随 Screenplay 安装;需要真实屏幕 |
| Skia + ffmpeg | 逐帧绘制、加速长等待、镜头缩放、字幕与音轨 | 随包提供 |
版本口径要先说清楚:项目 README 正文明确写了 npm 包名是 agent-screenplay、全局安装后命令名是 screenplay,但没有在 README 正文里声明当前包版本号(社区汇总提到 2026-11-03 的 v0.1.7,属页面提交信息,不是 README 的版本声明)。动手前用 npm view agent-screenplay version 确认你装到的版本,不要照抄旧文章里的命令。另外 README 没给出 screenplay <子命令> 的完整示例,本教程统一使用 README 明确写出的 npx agent-screenplay <子命令> 形式。
Step 1:一条命令装好 MCP,然后重启宿主
在项目目录里执行 init。按 README,它会做四件事:下载 Chromium(仅一次)、把 Screenplay MCP server 添加到它发现的 Claude Code / Codex / Cursor、安装教 Agent 写好视频的 guide,以及要求你重启 Agent。
# 进入你要做演示的项目目录
cd my-demo
# 安装:下载 Chromium、注册 MCP server、写入 guide
npx agent-screenplay init
# 可选:全局安装。包名 agent-screenplay,装好后的命令名叫 screenplay
npm i -g agent-screenplay
# 动手前核对版本,避免照抄旧示例
npm view agent-screenplay version
/screenplay 命令,例如 /screenplay Make a 30-second walkthrough of https://askli.co;Codex、Cursor 或任何挂了该 MCP server 的 Agent,直接用自然语言说「录一段……的操作演示」即可。重启 Agent 后配置才生效,别漏掉这一步。平台前置不能跳:Windows 无需额外授权;macOS 要在「系统设置 → 隐私与安全性 → 屏幕录制 / 辅助功能」里允许你的终端或 Agent 应用;Linux 需要 X11 会话与 AT-SPI 无障碍总线(GNOME 默认自带)。Wayland 不受支持,它在设计上就拦截截屏与合成输入。
Step 2:写一份能被执行的 scenario.json
分镜就是一个 JSON 文件:顶层给 url 与 style,steps 数组里按顺序写动作与镜头指令。下面这份改自 README 示例,可以原样存成 demo.json 练手:
{
"url": "https://app.example.com/inbox",
"style": { "background": "dawn" },
"steps": [
{ "title": "人工接管,只需一次点击", "subtitle": "New in 2.4" },
{ "click": "text=Camille Laurent",
"say": "当 AI 智能体卡住时,会话会落到你的收件箱。" },
{ "callout": "role=button[name='Take over']",
"text": "从 AI 智能体手里接管" },
{ "click": "role=button[name='Take over']" },
{ "type": "Hi Camille, I'm on it.",
"into": "placeholder=Write a reply…" },
{ "highlight": "text=Assigned to you",
"text": "同事会看到这单归你" },
{ "end": "所有套餐现已可用" }
]
}
text=…、role=button[name='…']、label=…、placeholder=…、testid=…;css=… 仅限网页,at=x,y 仅用于没有可访问元素的桌面应用。动作有 goto / click / type / press / hover / scroll / select / wait / pause,镜头指令有 title / end / callout / highlight / zoomTo / say / zoom / hold。完整字段用 npx agent-screenplay schema 打印,或看仓库里的 schema/scenario.schema.json。示例里刻意没有放 Send 这类写入动作。所有步骤都会被真实执行,读者照着练时请用自己搭的演示页或刚建的测试账号,不要拿生产收件箱试手。
Step 3:先演练,别急着拍
check 会快速把步骤走一遍但不拍摄,用来确认每个元素都能找到、顺序也顺。配合 guide 与 schema,写完分镜先过这三行:
# 打印写分镜的指南
npx agent-screenplay guide
# 快速执行步骤、不录制(桌面场景下屏幕 pill 会显示 rehearsing)
npx agent-screenplay check demo.json
# 打印完整 scenario JSON Schema
npx agent-screenplay schema
红线:check 和 record 真的会执行步骤,README 原话是「a "Send" click sends」。把分镜指向 demo 账号或 staging 环境;涉及下单、发消息、删数据的动作,先换成只读步骤。演练时若站点要求人工验证(bot check),check 会明确告诉你,见 Step 6 的登录态处理。
check 当成前端里的「跑一遍选择器测试」:它比直接录制便宜得多,改一个 role=button[name='…'] 就能立刻复验,不用等整条视频渲染完。Step 4:录制并拿到成片
# 拍摄 + 剪辑,产出 demo.mp4 与 demo.storyboard.png
npx agent-screenplay record demo.json
按 README 的工作流,录制会先落一份 take(画面帧 + 动作时间线),再进入编辑:长等待被加速、镜头按动作做弹簧缩放、鼠标轨迹平滑、叠加注释与字幕,最后逐帧绘制(Skia)交给 ffmpeg 编码成 MP4。默认输出 1920×1080 / 30 fps,最大可到 4K、24–60 fps,也能导出 GIF。
demo.storyboard.png 再决定要不要改镜头:它是最后一次录制的分镜缩略图,比反复播放 MP4 快得多。改外观不必重拍,交给 Step 5。桌面录制需要真实屏幕,无法在 headless 容器里跑(网页录制可以)。另外 Windows 与 macOS 上屏幕顶端会出现录制 pill 并带 Stop 按钮,pill 本身不会被拍进视频。
Step 5:不重拍,只重剪
style 会在浏览器里打开编辑器,停在最近一次录制的某一帧上:挑渐变、颜色或图片,调留白、圆角、阴影,然后保存到「这条视频」或「所有视频」。render 则拿最后一次 take 重新剪辑,不重新拍摄。
# 浏览器里调外观,保存后可直接重剪
npx agent-screenplay style demo.json
# 只重剪(改样式 / 缩放 / 文字 / 旁白),不重新拍摄
npx agent-screenplay render demo.json
# 也可以手写样式,存进 scenario 的 style 字段
{
"style": {
"background": { "gradient": ["#0ea5e9", "#6366f1"], "angle": 135 },
"padding": 96,
"radius": 20,
"shadow": true
}
}
screenplay.config.json,对它所在目录及子目录里的所有 scenario 生效;scenario 自己的 style 逐项优先。开头与结尾卡片(title / end)默认关闭,用 "cards": true 打开。旁白可写 "voice": { "enabled": true, "language": "fr" }:三条路是 CARTESIA_API_KEY、ELEVENLABS_API_KEY(两个都设时默认 Cartesia,除非写 "provider": "elevenlabs"),或完全不用密钥地给某一步加 "audio": "voice/02.mp3"。旁白有缓存,文本不变时重剪不额外产生合成开销;不开语音时 say 仍会作为字幕显示。密钥安全:语音服务的 API Key 属于账户凭据,只放在环境变量里,不要写进 scenario JSON、不要提交到仓库、不要贴进工单。${EMAIL} 这类占位符由环境变量注入,密码步骤务必加 "secret": true 让字幕与日志遮蔽。
Step 6:登录态与桌面场景
遇到要登录的站点,先用 login 手工过一次验证,会话会保存成文件,再在 scenario 里引用它;桌面应用则把 url 换成 app。
# 打开浏览器窗口手工登录,登录后关掉窗口(终端里按 Enter 亦可)
npx agent-screenplay login https://app.example.com
# scenario 顶层引用会话文件
"auth": { "storageState": ".screenplay/auth.json" }
# 登录步骤:占位符从环境变量读取,密码步骤加 secret 遮蔽
{ "type": "${EMAIL}", "into": "label=Email" }
{ "type": "${PASSWORD}", "into": "label=Password", "secret": true }
# 桌面场景:用 app 代替 url;screen 拍整屏;open 启动或置前应用
"app": "Notes" # 官方文档写作 "app": "<name>"
"screen": true
{ "open": "Notes" }
"surface": "menubar" # 也可 menu / sheet / popover / alert
"hideOthers": true # macOS 隐藏其他应用
三条容易翻车的边界:① .screenplay/auth.json 保存的是登录会话,README 明确要求「Keep that file out of git」,请加进 .gitignore;② 站点若要人工验证,check 会提示你先跑 login 过验证再设 auth.storageState,而每次访问都要求验证的站点无法自动录制;③ "screen": true 会把桌面图标与通知一起拍进去,先收拾屏幕,macOS 可用 hideOthers。macOS / Windows 的录制 pill 可用 SCREENPLAY_INDICATOR=0 关掉。
"app"。Linux 上的桌面录制仍需 X11 + AT-SPI,Wayland 不行。常见问题速查
| 现象 | 排查方向 |
|---|---|
| Agent 里看不到 /screenplay | init 后没重启 Agent;或客户端不在自动发现的 Claude Code / Codex / Cursor 之列,需手工挂 MCP server |
| check 找不到元素 | 选择器写错,先试 text= / label=;网页可用 css=,桌面才用 at=x,y |
| 录制到一半被站点拦下 | 触发了人工验证,按 Step 6 跑 login 并配置 auth.storageState |
| 桌面录制在服务器上失败 | 桌面场景需要真实屏幕,headless 容器只能录网页;Wayland 会话不受支持 |
| 改了配色却要重拍 | 不必,用 style 改完再 render,复用最后一次 take |
| 视频里出现桌面图标或通知 | 用了 "screen": true;收起通知,macOS 加 "hideOthers": true |
做到哪一步算成功
跑完这六步,你应当能拿出两个文件:demo.mp4 与 demo.storyboard.png;分镜图上的镜头顺序与 demo.json 里的 steps 一一对应;用 style 改一次背景后执行 render,画面变化但内容不需要重新点击一遍。再进一步,把 /screenplay 交给 Claude Code 说一句「录一段我们收件箱的人工接管流程」,它应当自己探索页面、写出 scenario、拍摄并把 MP4 交回给你——这条链路通了,就说明 MCP 接入与分镜执行都正常。