Community编程与开发github.com

lanceriedel/旁白演示技能

将智能体当前工作内容转化为一段简短的旁白演示视频(TTS语音解说 + 屏幕/浏览器录制 + 底部字幕 → 一个 H.264 .mov 文件)。当用户要求制作演示片段、操作演示视频、带旁白的录制或“把这个做成视频”时使用。它会访谈用户(受众、故事、场景)、编写场景规格、逐场景渲染,并可选发布到 Slack。

旁白演示技能 是什么?

该技能专为 AI 智能体(如 Claude Code)设计,用于自动将开发者的工作流转换为专业的演示视频。它首先通过五个问题快速访谈用户以确定受众、核心信息、屏幕内容、关键“实时”时刻和语音风格,然后智能体从其已有的上下文中补充细节。接着,它生成一个结构化的 YAML 场景规范(4-8个场景,每个约 25-45 字的旁白),描述屏幕捕获(浏览器操作、终端录制或静态图片)、旁白文本和字幕。渲染器(`scripts/render_clip.py`)按场景处理:先使用 TTS 生成语音,然后捕获屏幕/浏览器画面,将视频剪辑对齐到旁白时长,叠加字幕,最后合并所有片段。关键设计原则包括“先展示核心内容”(从关键操作点开始剪切)、每个场景一个核心观点、旁白与屏幕内容一致,以及通过文本哈希和每场景视频缓存实现可重入和快速迭代。该技能支持 macOS 屏幕录制(带区域选择以保护隐私)和基于 Playwright 的无头浏览器捕获,并提供一个可选的 Slack 发布脚本。它是一个完整的端到端工具,适用于创建供高管、同事或 Slack 频道消费的简洁、叙事驱动的演示视频,而无需手动视频编辑。

兼容平台~Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/lanceriedel/narrated-demo-skill/tree/main

Installed? Explore more 编程与开发 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

旁白演示

一个智能体,一个下午,一个 VP 能在手机上观看的 .mov 文件。经过五个视频片段(时长 69–188 秒)验证的配方:

  1. 访谈用户——五个问题,不超过(见下文)。根据你已有的上下文起草故事;用户进行编辑,而非写作。
  2. 编写场景规格(clips/<name>.yaml):4-8 个场景,每个场景旁白约 25-45 字(≈ 10-18 秒演讲)。每个场景都有一个核心内容——事物出现的时刻——视频剪辑使得核心内容尽早显示,而非最后。
  3. 渲染:scripts/render_clip.py clips/<name>.yaml。按场景处理:TTS → 捕获 → 将视频适配到音频 → 字幕 → 混流;然后合并。
  4. 审查渲染器生成的静态图像(out/_<clip>_<scene>.png),使用 read 工具确认无误后再声明完成。使用 --only s2 重新渲染单个场景。
  5. 发布(可选):scripts/slack_post.py <channel_id> out/<clip>.mov "<简介>"。

所有步骤均可重新运行且已缓存(TTS 通过文本哈希缓存,按场景缓存视频),因此迭代一句话仅需数秒。

1. 访谈(依次提问,然后起草)

一次性提出全部五个问题;接受部分答案,并从上下文中补全其余信息,同时标注你做出的假设。

  1. 视频给谁看,他们有多少时间?(同行工程师 3 分钟 · 高管 90 秒 · Slack 滚动 60 秒)→ 确定场景数量和节奏。
  2. 他们看完后应该相信什么? → 成为场景 1 的第一句话和最后一场景的最后一句话。
  3. 屏幕上必须显示什么?(用户界面、终端、文档、图表、文件)→ 决定捕获类型。询问 URL / 命令 / 路径。
  4. ‘实时’时刻是什么? 某个可见的、正在发生的事件(查询返回、构建完成、数字出现)。每个视频至少一个。
  5. 语音和语气? 默认:onyx,“平静、清晰、自信的技术演示旁白,中等语速,数字稍加重”。如果他们想要更轻松的,可以提供 alloy/nova。

然后以表格形式提出分镜故事板(场景 · 屏幕内容 · 一行旁白要点 · 核心内容)并获得确认后再渲染。渲染一个 5 场景的视频大约需要 3-6 分钟;在获得确认前不要渲染。

2. 场景规格

clip: 1-setup                 # 输出名称 → out/1-setup.mov
size: 1440x900                # 可选:所有场景的通用帧大小(适配并填充)——在混合屏幕和浏览器场景时设置
voice: onyx
instructions: "平静、清晰、自信的技术演示旁白。中等语速,在有句号处自然停顿。数字稍加重。"
scenes:
  - id: s1                    # 简短、稳定的 ID → 缓存键
    caption: "主题 · 一个图表,四项证据"     # 底部字幕;保持 ≤ 60 字符
    narration: "…25-45词…"                        # 如果 TTS 处理数字有问题,请用文字写出数字(如“一万八千”)
    # 每个场景仅一个捕获源:
    url: "http://127.0.0.1:4300/#mode=purchase"       # (a) 通过 Playwright 的浏览器捕获——外加可选操作:
    actions:                                          #     在加载后按顺序执行;`ready` 标记核心内容
      - fill: ["#prompt", "Acne Studios"]
      - press: ["#prompt", "Enter"]
      - wait: ".layer-chip"                           #     选择器(45 秒超时)→ 设置 ready
      - click: "button:has-text('fit')"
      - select: ["#graph-layout", "brand"]
      - scroll_to: "#join"                            #     scrollIntoView(用于长文档)→ 设置 ready
      - hover: ".card"
    # video: "cache/cr_s3"                            # (b) 预录制目录(page.mov + marks.json)或文件——参见 record_screen.sh
    # still: "docs/figure.png"                        # (c) 静态图像(图表、幻灯片)——无 Ken Burns 效果,按旁白时长保持显示
    hold: 2                                           # 最后一次操作后额外等待的秒数
    speed: 1                                          # 预加速源视频(8 = 慢速爬升以 8 倍速度显示)
    scale: 2560                                       # 按场景缩放的宽度(屏幕录制);font: 28 = 此场景的字幕像素大小

使视频效果良好的规则:

  • 核心内容优先。 渲染器在 ready 之前约 2.5 秒开始每个场景,如果旁白更长则填充最后一帧,如果更短则裁剪。一个场景的“核心内容”在 45 秒录制的第 40 秒出现,它将变成一个从核心内容开始的 12 秒场景。
  • 旁白与屏幕一致。 旁白中每个大写名称和每个数字必须在屏幕上可见或即将可见。删除那些没有的画面语句。
  • 每个场景一个想法。 如果一个句子以“此外”开头,那么它应该是一个新场景,或者被删除。
  • 字幕即大纲。 只阅读字幕就应该能了解整个故事。
  • 绝不虚构旁白中的数字。 从你刚获取的结果文件或实时响应中获取;如果四舍五入,请说“大约”。

3. 捕获源

  • 浏览器(url + actions) — Playwright Chromium,1440×900,无头模式,录制 webm。需要包含 @playwright/test 和 Chromium 的 Node 项目;设置 PW_REPO=/path/to/that/project(默认:技能自带的 pw/ 目录——运行 scripts/setup.sh 一次来创建)。
  • 屏幕 / 终端(video) — scripts/record_screen.sh <scene> <seconds> [--rect x,y,w,h] -- <command…>:启动 screencapture -V,运行你的命令,当命令通过打印 MARK 表示核心内容已就绪时,写入带有 started(毫秒)的 marks.json。 陷阱: screencapture -V 仅在像素变化时前进;静态的终端窗格会冻结录制。保持某个内容在变化(如 1 Hz 时钟行),或使用 show_file.sh 为文件分页并附带时钟。使用 DEMO_SCALE=2560 缩小宽屏捕获。 隐私: 录制一个矩形区域(--rect,以点为单位;screencapture -R),以便仅捕获你想要的窗格——不包含窗口标题、标签栏、侧边栏、停靠栏、通知或背景窗口。在发布之前,阅读每张审查静态图像并询问:屏幕上是否有任何内容能识别雇主、主机、内部 URL、其他人?对你分页的文本进行脱敏处理(show_file.sh)——它只是演示内容,而不是你的真实文件。
  • 静态图像(still) — 一个 PNG/JPG,按旁白时长保持显示;用于图表、表格、幻灯片。
  • 预录制(video: file.mov) — 配合场景中的 ready: <seconds> 使用。

4. 渲染、审查、发布

export OPENAI_API_KEY=…                     # TTS(gpt-4o-mini-tts);或 TTS_URL=https://<proxy>/v1/audio/speech TTS_API_KEY=… 用于兼容代理
scripts/render_clip.py clips/1-setup.yaml            # 完整视频 → out/1-setup.mov(+ out/_1-setup_<scene>.png 静态图像)
scripts/render_clip.py clips/1-setup.yaml --only s2  # 重新渲染单个场景,重新合并
DEMO_FONT=26 scripts/render_clip.py …                # 字幕大小(1440 px 时 22,2560 px 源时 26-30)

审查:使用 read 查看两到三张 out/_*.png 静态图像。如果浏览器场景记录 wait failed: … Timeout,说明应用过慢或选择器已更改:该场景仍从 t=0 开始渲染(没有核心内容裁剪)——修复选择器,或当应用空闲时使用 --only <id> 重新运行该场景。检查字幕是否清晰、核心内容是否在屏幕上、没有敏感信息可见(令牌、买家级行、其他人的消息)。如果可以,观看 .mov 文件的前 5 秒和后 5 秒。

发布到 Slack,附带不超过三行的简介:内容 · 时长 · 一个数字。scripts/slack_post.py C0123… out/1-setup.mov "…" 使用 ~/.config/slack-mcp/credentials.json 中的 slack-mcp 浏览器会话凭据;如果不存在,请将文件连同简介一起交给用户。

5. 约定(保持项目整洁)

clips/ 规格文件 · cache/ TTS 和每场景视频(已加入 gitignore) · out/ 最终文件和静态图像 · blurbs/ Slack 文本。按播放顺序命名视频(0-…, 1-…, 2a-…)。保留一个 storyboard.md,包含访谈中的表格;这是视频制作后人们会要求查看的产物。

依赖项:ffmpeg/ffprobe,node ≥ 18,Playwright Chromium(用于浏览器场景),macOS screencapture(用于屏幕场景),一个 TTS 密钥。scripts/setup.sh 会检查并安装它所能安装的内容。

相关技能