构建用户所述流程的演示视频。输出内容将放置在新的 demo/vN/ 文件夹中。
唯一重要的规则:每个屏幕都必须是真实 UI 的转录,而非印象。 编造布局、文案或组件的演示比没有演示更糟糕——它会让观看者认为存在一个不存在的产品。在编写任何标记之前,请先阅读每个屏幕的源代码。
输入
/create-product-demo-video <应该发生的操作> — 一个流程描述。如果描述模糊(例如“展示产品”),选择最窄的完整流程,以可感知的价值为终点,用一行说明选择了哪个流程,然后开始构建。不要因为提问而停滞。
步骤
-
将流程映射到路由。 将提示转换为用户会经过的真实路由的有序列表。首先找到路由器——
routes/目录、app/树、<Routes>块、路由清单——只列出存在的路径。如果流程需要先创建某个实体(例如项目)才能到达后面的屏幕(例如项目范围报表),要么包含该屏幕,要么选择不需要该实体的范围——不要静默跳过必需步骤。 -
读取每个屏幕的源代码。 对于每个路由:路由文件、其渲染的组件、应用的共享布局组件(外壳、页面标题、空状态)及其设计系统原语(
components/ui/或它们所在的位置)。同时读取任何生成演示中显示的字符串的内容——预览助手、派生名称、后端渲染/模板服务。逐字复制字符串;不要转述产品文案。 -
搭建脚手架。
mkdir -p demo/vN(下一个未使用的 N——切勿覆盖现有的 vN),然后复制assets/skeleton.html→demo/vN/index.html和assets/record.mjs→demo/vN/record.mjs。assets/位于此SKILL.md旁边,即技能安装的任何位置——插件缓存目录、~/.claude/skills/或项目的.claude/skills/。从技能自身的目录解析它,绝不能从被演示的仓库解析。骨架携带占位外壳、标记尺度和播放引擎。 对于带评分的演示,还要从assets/music/复制所选音轨 →demo/vN/music.mp3——参见音乐。复制进去(而不是引用技能文件夹)才能让vN/在以后可重新录制,record.mjs按版本复制也是出于同样的原因。 -
使骨架适应此产品。 所有标记为
REPLACE:的都是占位符,必须在编写任何场景之前替换,因为每个屏幕都继承自它们:在 index.html中替换为 PRODUCT应用的名称、地址栏显示的主机名及其真实 logo svg NAV从真实导航栏转录的侧边栏——相同的部分、相同的顺序、相同的标签 TOPBAR真实的顶部栏;删除应用没有的控件 :root标记应用样式表中的 :root块,以使颜色/圆角/类型匹配ICONS应用实际使用的图标集中的路径数据 删除流程不使用的可选 CSS 块(第三方屏幕、交付面板)。 -
编写场景。 每个屏幕一个
<section class="scene" data-scene="N">,按顺序排列。重用骨架的 CSS 类(.pagehead、.card、.btn、.seg、.opt、.chip、.scopeid、.statusbadge、.empty、.input、.pillbar、.toast)——它们被塑造成像 Tailwind/shadcn 样式系统的输出,因此对照实际组件的类进行检查并调整,而不是硬性假设。仅在骨架缺少某个组件时添加新 CSS,并从该组件的实际类派生。 -
编写
play()。 标题卡 → 屏幕 → 结尾。使用字幕命名每个步骤,并在脚本顶部设置CAPTIONS——样式,以及steps= 运行过程中say()调用的次数。交互通过指针助手进行,以便观看者能够跟随点击的轨迹。 -
录制。
node demo/vN/record.mjs→demo/vN/out/product-demo.mp4。添加--gif可生成 900px 的 gif。demo/vN/music.*文件会被自动识别;--music <path>指向其他位置的音轨,--music-db <n>调整音量级别,--no-music强制静音。 -
通过查看进行验证。 提取帧并阅读这些图像——这是不可选的,这是捕获布局错误的方式:
for t in 5 12 20 28 36 44; do ffmpeg -y -loglevel error -ss $t \ -i demo/vN/out/product-demo.mp4 -frames:v 1 /tmp/f$t.png; done检查:没有过大的图标,没有内容被裁剪,指针落在它声称要点击的元素上,文本没有被压缩成一行。修复并重新录制,直到干净为止。
帧无法显示音频。 对于带评分的演示,还要检查音频流和音量渐变——
volumedetect在 info 级别记录日志,因此-v error会吞掉其输出:ffprobe -v error -select_streams a:0 -show_entries stream=codec_name,duration \ -of default=nw=1 demo/vN/out/product-demo.mp4 for w in "-ss 0 -t 0.25" "-ss 12 -t 0.5" "-sseof -0.25"; do \ ffmpeg -hide_banner -nostats $w -i demo/vN/out/product-demo.mp4 \ -af volumedetect -f null - 2>&1 | grep mean_volume; done期望一个
aac流,持续时间与视频相差约 0.05 秒,max_volume低于 0 dB,并且开头和结尾的平均音量远低于中间部分——这是表明渐隐生效的证据。 -
编写
demo/vN/README.md——包含路由的场景表格、源文件映射、持续时间、录制时使用的CAPTIONS样式和音轨,以及流程特意跳过的内容。更新demo/README.md以列出新版本。
报告路径、持续时间和文件大小,然后打开 mp4 以便用户可以观看——macOS 上使用 open,Linux 上使用 xdg-open,Windows 上使用 start。
引擎 API
在 play() 内部可用:
| 调用 | 效果 |
|---|---|
scene(n) | 淡入场景 n,根据 URLS 更新地址栏 |
tap(sel, ms) | 将指针移动到元素并点击(波纹效果 + 按下) |
moveTo(sel, ms) / click(sel) | 拆分为两部分,当你需要在两者之间改变状态时使用 |
hideCursor() / place(x, y, 0) | 进入场景时重置指针 |
say(text, opts?) / hush() | 字幕进入/退出。{ at: sel } 锚定一个 coach 字幕;{ step: n } 强制指定索引 |
type(el, text, ms) | 逐字符输入到 <span> 中 |
wait(ms) | 等待 |
reveal(el) | 由 moveTo 自动调用——平滑滚动 .main 使折叠以外的目标可见 |
设置 window.__demoDone = true 在末尾(骨架已经这样做)——录制器等待它。
字幕设计
const CAPTIONS = { style: 'pill', steps: 6 } 与 URLS 一起放在引擎顶部。所有四种样式都随骨架提供;无论使用哪一种,say() 的调用方式都相同。根据视频选择:
style | 说明 | 何时选择 |
|---|---|---|
pill (默认) | 墨色胶囊,底部居中 | 任何简短且面向营销的内容。遮挡最少,每个字幕约 10 个词 |
lower-third | 左对齐块,带有步骤索引和进度条 | 较长的流程,观看者应感受到顺序;在 gif 中最易读 |
rail | 窗口下 68px 的带状区域,章节圆点 | 文档和支持片段,不能遮挡任何内容。会占用应用高度——见下文 |
coach | 锚定到播放元素的标注,其余部分变暗 | 跟随式操作指南。每个字幕都需要 { at: sel };没有的则回退到 pill |
steps 驱动索引、进度条和 rail 的圆点——统计 say() 调用的次数并设置它,否则运行结束时会显示 05 / 06。不确定哪种样式?在浏览器中打开 index.html 并切换 CAPTIONS.style——页面按 R 键重播,因此无需录制即可比较所有四种样式。
音乐
可选,并且仅在存在音轨时才开启。背景音乐在编码时混入——Playwright 完全不捕获音频,因此它不会影响演示页面或引擎。
node demo/vN/record.mjs # 使用 demo/vN/music.*(如果存在),不存在则静音
node demo/vN/record.mjs --music ~/beds/x.mp3 # 显式路径优先于同级文件
node demo/vN/record.mjs --music-db -4 # 更安静的背景音乐
node demo/vN/record.mjs --no-music # 即使有同级音轨也保持静音
- 捆绑音轨位于
assets/music/中,每行对应其LICENSES.md中的一个文件。没有音轨在没有可验证的 CC0/CC-BY 声明的情况下随附——未授权的 mp3 是所有安装此技能的人的问题,而不仅仅是你的。不确定?将其保留在仓库之外,并通过--music <path>指定。 - 音量是归一化的,而非手动设置。 每个音轨都被驱动到 −18 LUFS,并带有 −1.5 dB 真实峰值上限,因此版本之间替换的背景音乐无需手动调整即可匹配。
--music-db改变这个目标;它不会在顶部增加增益。 - 渐隐是自动的——1.5 秒渐入,2.5 秒渐出,渐出时间基于实际视频时长。
- 选择比视频长的音轨。 更短的内容会被循环,接缝处可能被听到;当必须循环时,录制器会发出警告。60 秒以上可覆盖正常的 40–60 秒演示。
- 不要有语音,不要有突兀的下降。 观看者同时正在阅读字幕和 UI 文案。
- 音频只进入 mp4。 webm 是原始静默捕获,gif 根本没有音频轨道——纯音乐更改在
--gif输出中不可见。
约定
- 舞台是一个固定的 1280×800 模拟浏览器;其中 44px 是浏览器边框,剩余 1280×756 用于应用。骨架附带了一个 48