Communitygithub.com

Pitch Deck 真机演示片(真实应用)

用 Playwright 驱动真实应用,按实测旁白与元素框生成 1–2 分钟带字幕/卡片/配乐的产品演示片(Remotion)。UI 改动后约 2 分钟可重剪。README 附成品演示视频。

Pitch Deck 真机演示片(真实应用) 是什么?

Launch Video 第 1 步(主菜):真实应用 Playwright 录制 → 旁白定时长 Remotion 成片,含字幕、配乐、响度与联系表 QA。

兼容平台✓Claude Code~Codex CLI~Cursor
npx skills add RoderickQiu/pitch-deck-video-skill

在你喜欢的 AI 中提问

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

文档

/pitch-deck-video

从运行中的本地 Web 应用生成带有旁白的产品演示视频。剪辑是推导出来的,无需手动计时,因此当前端发生变化时,你重新录制,剪辑会自动跟随变化——无需修复帧编号。

专为实际情况而构建:在你需要视频时,UI 仍在变动中。

使用方法

/pitch-deck-video                          # 录制当前目录下的应用
/pitch-deck-video <path-to-app>            # 录制指定应用
/pitch-deck-video --rebuild                # 重新录制并重新剪辑现有视频项目
/pitch-deck-video --script                 # 仅旁白更改;复用上一次录制
/pitch-deck-video --render                 # 仅卡片/字幕更改;重新渲染

结构概览

四个生成文件驱动整个流程。只有第一个由人类编写。

文件内容编写者
shots.json旁白内容、语音、音乐、主题以及浏览器操作你
src/vo-durations.json每行旁白实际所需的时间scripts/tts.mjs
capture/marks.json每次镜头在录制中的开始时间及观察位置scripts/record.mjs
src/frames.json录制输出的帧数scripts/frames.mjs

src/timeline.ts 从上述文件推导出整个剪辑。场景时长基于实际测量的旁白音频。录像片段会根据该时长进行拉伸。镜头运动基于录制时实时测量的元素边界框,因此按钮移动后,镜头会跟随移动而不会被破坏。

工作流程

1 · 初始化项目

将此技能中的 template/ 目录复制到应用旁边的 <app-name>-video/ 目录,然后运行 npm install。模板自带初始 JSON 数据,在首次录制前即可进行类型检查和渲染。

切勿为单个项目编辑 ~/.claude/skills/pitch-deck-video/template/ 目录下的文件——这是共享模板。请编辑已复制的副本。

2 · 首先检查是否存在已保存的登录状态

如果应用需要认证,请查找仓库中已有的 Playwright 存储状态(用于自身 e2e 测试,如 .auth/*.json、storageState、playwright/.auth/)。将 app.storageState 指向该文件,录制将直接从已登录状态开始,无需在镜头中显示登录流程。仅在没有此类文件时构建登录镜头——然后使用 {"type": {"sel": "…", "env": "DEMO_PASSWORD"}},这样密码就不会写入 shots.json。

3 · 在编写任何内容前先了解应用

启动应用的开发服务器,以 1920×1080 分辨率截取每个路由的截图,然后阅读这些图片。不要根据源代码编写旁白。你要写的是评委将看到的内容,只有截图能告诉你这些。

// 一次性的脚本;模板自带 Playwright
for (const r of routes) {
  await p.goto(base + r, { waitUntil: 'networkidle' });
  await p.waitForTimeout(700);
  await p.screenshot({ path: `/tmp/shots/${r}.png` });
  console.log(r, await p.evaluate(() => document.documentElement.scrollHeight));
}

注意滚动高度:任何超过 1080 的内容都需要 scroll 操作,否则它将永远不会出现在镜头中。

4 · 编写 shots.json

从 template/shots.example.json 开始。有关每个字段和操作的详细信息,请参阅 references/shots-reference.md。

从应用自身的设计令牌中提取 theme.colors,使卡片和录制片段看起来浑然一体。用真实的架构填充 cards.arch.nodes——哪些模块是模型调用,哪些是确定性代码。这一点正是区分演示与包装的关键,评委们会关注它。

重要的旁白规则:

  • 12–16 个段落,总计 1:30–1:50。 在 2:00 的限制下,留出 10 秒的余量。
  • 每个段落只有一个想法。 当该想法结束时,段落也随之结束。
  • 说出具体数字。 “六个人评分,Priya 获胜”优于“它选择了某人”。
  • 永远不要描述 UI。 不要说“这里我们点击批准”——要说出它的含义。
  • 以用户语言描述的问题开场,在产品名称出现之前。
  • 用一句话结尾,你想要这句話留在屏幕上。

5 · 构建

APP_DIR=/path/to/app npm run all

旁白 → 录制 → 帧处理 → 渲染。如果 app.url 没有服务,它会启动开发服务器,读取应用自身的 dev 脚本以确定该框架如何指定端口。如果需要特定操作,可设置 app.devCommand。典型的完整重建:约 2 分钟。

shots.json 会首先进行验证,因此重复的 ID 或未知的操作会在两秒内失败,而不是在两分钟后生成一个令人困惑的视频。

6 · 通过查看进行质量检查——这是必需的

npm run qa          # 每个镜头一张静态图,堆叠成联系表
npm run qa 3        # 每个镜头三张静态图,用于检查过渡效果

然后以图片形式阅读联系表。逐帧检查视频速度慢且容易遗漏问题;联系表只需几秒就能捕捉到真正重要的失败点。

检查:capture/marks.json → warnings 是否为空(缺少选择器是警告,而非崩溃——你仍然能获得视频,并获得一份损坏内容的列表)。然后:每条字幕是否落在支撑它的帧上?是否有空白或白色的帧?小文本是否清晰,还是需要 focus?

references/troubleshooting.md 包含了此流程实际遇到过的所有失败情况及相应的修复方法。在从头调试之前,请先阅读它。

UI 更改后重新剪辑

这正是整个工具的价值所在。

APP_DIR=/path/to/app npm run all

大多数更改无需额外操作——移动的元素、重新样式化的页面、新文案。仍需判断的情况:

  • 页面已被删除或重命名 → 重新指向或替换该镜头。
  • 功能已被重写 → 该段落的旁白现在是对不存在的功能的描述。重写该行。
  • 选择器确实消失了 → 检查警告列表并进行修复。

旁白会按行缓存,因此只有编辑过的行才会重新合成。

语音

语音是成品视频中最重要的质量差异因素,而默认选项的质量确实很差。 在首次构建之前就要明确说明这一点,而不是之后。

  • tts.provider: "minimax" — 很好。询问用户的 MiniMax 密钥在哪,并将 tts.envFile 指向该文件。语音 ID 来自 MiniMax 的系统语音列表;语音上的语言标签只是一个提示,而非限制(乌克兰语标签的语音在 languageBoost: "English" 设置下可以很好地朗读英语)。
  • tts.provider: "say" — macOS 的内置合成器,通常只安装了旧版语音。听起来很机械,容易读错产品名称,观众一听就能察觉。可用于检查时机,但一旦有评委或客户观看,效果就很差。
  • **人工录制优于任何合成方案。**将 <id>.wav 文件放入 public/vo/,然后运行 npm run script;时长会被重新测量,整个视频会自行重新调整时间,无需其他编辑。

如果没有密钥,仍然可以构建视频——但需要事先告知用户,语音是薄弱环节,要么提供密钥,要么花十分钟用麦克风人工录制来解决。不要悄无声息地使用 say 语音作为最终成品。

如果 API 不可用,MiniMax 会按行回退到 say,因此运行永远不会完全失败。

切勿将 API 密钥复制到项目中。scripts/tts.mjs 会从环境变量读取 MINIMAX_API_KEY / MINIMAX_GROUP_ID,否则会从 tts.envFile 所指向的文件中解析它们。询问用户的密钥位置,并将 envFile 指向该文件。

人工录制优于任何合成方案:将 <id>.wav 文件放入 public/vo/,然后运行 npm run script——它会重新测量时长并重新调整整个视频的时间。

音乐

scripts/music.mjs 使用 yt-dlp 获取 music.url 中指定的曲目,并剪裁出适合当前视频长度的背景音乐。告知用户在发布前检查曲目的许可证——库曲目通常在使用时免费但需要在描述中注明出处,付费使用则无需注明。曲目标题和 URL 会保存在 public/music/SOURCE.txt 中,方便复制出处信息。

禁忌

  • 不要手动调整时间。如果某段落显得仓促,说明旁白对于镜头来说太长——请修复 shots.json,而不是时间线。
  • 不要将 <Screen /> 放在 <Sequence> 内部。它设计为读取绝对时间;在 Sequence 内部使用 useCurrentFrame() 会返回 Sequence 局部的帧数。这种做法曾经导致视频出现问题,且症状(画面与声音微妙不同步)难以察觉。
  • 不要让设置时间出现在镜头中。导航、数据加载和关闭横幅等操作都发生在镜头的捕获窗口内,并会在旁白下被拉伸。在设置步骤后添加 {"cut": true};录像将从那里开始。
  • 不要录制任何暂存的内容。如果某个按钮返回“连接后端”,请将其排除,并告知用户在该功能就绪后添加哪个镜头。
  • 不要在没有检查警告列表的情况下发布。
  • 不要描述一个在不同运行中数字明显变化的画面,也不要描述一个在当前账户下为空的屏幕称其为满屏。评委一旦发现虚假陈述,就会怀疑其余内容。

相关技能