免费

彩色舞台发布

16 到 20 秒发布片,把真实界面搬上明亮舞台:彩绘布景板摆入、硬边追光、巨大海报字、一次真实点击。

安装

把“彩色舞台发布”技能安装到 ~/.claude/skills/colour-stage。
下载下面每个文件,保存到这个文件夹:
https://skilllift.pages.dev/packs/colour-stage/SKILL.zh.md → SKILL.md
https://skilllift.pages.dev/packs/colour-stage/references/style.md → references/style.md
https://skilllift.pages.dev/packs/colour-stage/assets/engine.html → assets/engine.html
https://skilllift.pages.dev/packs/colour-stage/assets/timeline.template.json → assets/timeline.template.json
https://skilllift.pages.dev/packs/colour-stage/scripts/check.mjs → scripts/check.mjs
https://skilllift.pages.dev/packs/colour-stage/scripts/render.mjs → scripts/render.mjs
https://skilllift.pages.dev/packs/colour-stage/scripts/capture.mjs → scripts/capture.mjs
然后读一遍 SKILL.md,告诉我它是做什么的,并提醒我开一个新会话。

解压到 ~/.claude/skills

同一个技能,不同的需求

左边是预览。右边由另一个 Agent 按不同需求制作,它只有安装好的技能,没看过预览。

预览
预览
新需求,由另一个 Agent 制作
新需求,由另一个 Agent 制作

这是按虚构需求做的一次测试。系统字体不同时,字形可能略有差异。

制作 16 到 20 秒的无声产品发布片:把真实的产品界面放上明亮的剧场舞台,装进粗壮彩色边框的设备,彩绘布景板摆入,硬边追光落下,巨大的海报字踩点弹出,光标完成一次真实操作,让真实界面动起来,最后停在产品名和行动号召上。引擎确定性渲染,只用 CSS 透视,输出 1920x1080、30 fps、H.264,可选 1:1 和 9:16。当用户想要展示自家真实界面的发布片、功能预告或产品宣布视频,或点名要这种风格时使用。

交付前必须通过

  • 每个要交付的画幅,node scripts/check.mjs film.mp4 都以 0 退出,并且没有加 --short。
  • 每个画幅的 film.mp4.sheet.jpg 都看过,每个场景都看到了。
  • 看过 target-crop.png,框落在控件上。
  • 光标点的是真实存在的控件,点击后的画面就是产品真实的反应。
  • 点击后界面在动;如果只是静图切换,说明里写了原因。
  • 逐项看过“check.mjs 看不到的”,也看过 --frame press+30。
  • 每句文案要么写在 evidence 里,要么列为推断。没有编造的数字、客户或功能。
  • 片中只有一种语言。虚构界面在 copy.notice 里写明了虚构。
  • 没有残留进程:浏览器和 ffmpeg 都已退出。
阅读完整 SKILL.md
---
name: colour-stage
description: 制作 16 到 20 秒的无声产品发布片:把真实的产品界面放上明亮的剧场舞台,装进粗壮彩色边框的设备,彩绘布景板摆入,硬边追光落下,巨大的海报字踩点弹出,光标完成一次真实操作,让真实界面动起来,最后停在产品名和行动号召上。引擎确定性渲染,只用 CSS 透视,输出 1920x1080、30 fps、H.264,可选 1:1 和 9:16。当用户想要展示自家真实界面的发布片、功能预告或产品宣布视频,或点名要这种风格时使用。
version: 1.0.0
---

# 彩色舞台发布

风格全部写在 `assets/engine.html` 里,你不要改它。你要做的是截取产品界面,把几句海报文案写进 JSON 时间线,然后渲染。`scripts/check.mjs` 检查的是真实成片。

配色、字号、时间点见 `references/style.md`。下面的路径除了你自己的工作文件,都相对于这个技能的文件夹。

## 需要问用户的内容

简报里没有的,一次问完,放在同一条消息里。

必需:
1. 产品名。
2. 界面来源:打得开的网址、HTML 文件或截图。
3. 要展示的那一个操作:一个真实存在、点了之后界面有明显变化的控件。优先选结果会动的:数字增长、列表增加、图表变化。
4. 那一句主张,用用户的原话,或者产品上写着的话。

可选:开场要说的场景或问题、真实链接、语言(中文或英文,一条片子只用一种)、其他画幅(1:1、9:16)、设备边框的品牌色、16 到 20 秒之间的时长。

## 运行要求

- Node 18 或更高版本;ffmpeg 和 ffprobe 在 PATH 里(或设置 `FFMPEG`、`FFPROBE`)。
- 截取和渲染需要 Playwright:先 `npm install playwright`,再 `npx playwright install chromium`。如果它装在别处,设置 `NODE_PATH=/path/to/node_modules`。check.mjs 不需要任何依赖包。
- 渲染时间(在 16 GB 的 Apple 芯片 Mac 上实测):18 秒的 1920x1080 完整成片约 25 秒,半尺寸短测试约 10 秒,预检约 2 秒,带 90 个播放帧的截取约 10 秒。机器较慢时要多留几倍时间。
- 同一时间只跑一个渲染,命令前加 `nice -n 10`。渲染很吃资源,反复调整时用预检和 `--short --scale 0.5`。
- 成片没有声音,这个技能不生成音频。

## 步骤

1. **复述事实。** 写下用户告诉你的和你在产品里看到的。选定一个有明显结果的操作。
2. **截取界面。** 按下面的顺序,用第一个符合情况的方式:
   - 网址或 HTML:`nice -n 10 node scripts/capture.mjs --url http://localhost:3000 --selector "button.save" --size 1440x900 --out screens`(或用 `--html file.html`)。脚本会量出控件位置,验证它的中心点确实能点到,然后真的点一下,保存 `before.png`、`after.png` 和 `capture.json`。
   - 截图:打开图片,读出控件在图片里的像素框,然后 `nice -n 10 node scripts/capture.mjs --image shot.png --after shot2.png --rect 1040,620,220,64 --out screens`。视网膜截图加 `--pixel-ratio 2`。
   - 然后查看 `screens/target-crop.png`,洋红色的框必须落在控件上。
   - 虚构产品加 `--kind fictional`。用脚本打印的内容替换时间线里整段 `screen`。
   - **让界面动起来**(见下文)。界面只有两张静图时,片子只是在宣布功能,而不是展示功能。check.mjs 会提示这一点。
3. **填写时间线。** 把 `assets/timeline.template.json` 复制成 `timeline.json`,放在 `screens` 文件夹旁边。粘贴 capture.mjs 打印的 `screen` 段。按下表填字段,替换所有 `REPLACE`。
4. **检查文案:** `node scripts/check.mjs timeline.json`。
5. **逐个画幅预检:** `nice -n 10 node scripts/render.mjs --timeline timeline.json --format 16:9 --preflight`。预检不出视频,约 2 秒跑完布局规则。报错说什么就改什么。如果说界面看不清,就把它打印的裁切粘贴进去。
6. **短测试:** `nice -n 10 node scripts/render.mjs --timeline timeline.json --out test.mp4 --short --scale 0.5`,再 `node scripts/check.mjs test.mp4 --short`。短测试把五个场景压进约 6 秒,绝不能当成品交付。只看某一刻:`nice -n 10 node scripts/render.mjs --timeline timeline.json --frame press+30 --png frame.png`。
7. **渲染成片:** `nice -n 10 node scripts/render.mjs --timeline timeline.json --out film.mp4`。其他画幅加 `--format 1:1 --out film-square.mp4` 或 `--format 9:16 --out film-vertical.mp4`,一个接一个地跑。
8. **检查并亲眼看:** `node scripts/check.mjs film.mp4`。`film.mp4.layout.json` 要留在成片旁边,没有它只能跑技术和运动规则。查看它生成的 `film.mp4.sheet.jpg`,里面是从成片抽出的真实画面,覆盖每个场景。哪句读着别扭就重写。

## 让界面动起来

片子的高潮是点击之后真实界面的变化。截取到的状态按片子自己的时钟播放,`n` 是相对点击的帧数(点击前为负数)。按顺序用第一个符合情况的方式,把参数加到第 2 步的 capture.mjs 命令上:

| 你有什么 | 参数 | 效果 |
|---|---|---|
| 可以修改的 HTML 页面,或已有钩子的页面 | `--play-before 150 --play-after 150` | 页面定义 `window.setScreenFrame(n)`,这是只依赖 `n` 的纯函数,不用时钟和随机数。脚本逐步调用并截图,在 `n = 0` 时真实点击。 |
| 点击后页面本身有动画 | `--play-ms 3000` | 真实点击后,用受控时钟推进页面的定时器和 CSS 动画,并逐步截图。 |
| 只有截图 | `--sequence s2.png,s3.png --hold 12` | 点击后用真实截图快速切换。要在说明里写明这是切换。 |

规则:只展示真实产品有的状态。钩子的最后一帧必须是真实用户会看到的状态。过程中的数值只能向真实或用户给出的数值过渡,不能暗示产品从未显示过的数字。不要为了拍片给页面加功能。柱状图和计数最好在点击后 60 到 90 帧稳定下来,这时主张正好在屏幕上。播放帧可能很大,属于工作文件:成片渲染完就删掉 `screens/play/`,需要时用 capture.mjs 重新生成。简报信息不足时:如果产品没有会动的结果,又只有一张截图,`screen.play` 就填 `null`,接受提示,并在说明里写明片子是静图切换。

## 节拍和帧号

预检会打印这条片子的节拍表。18 秒时:hook 0-89,reveal 90-164,action 165-284,点击 276,claim 285-434,end 435-539。想看某一刻,用名字,不用自己加帧数:`--frame hook`、`reveal`、`action`、`press`、`press+30`、`claim`、`end`,都可以带偏移。做封面用 `--frame claim`,或从成片取这一帧:文字、设备和结果都在画面里。第 0 帧只有第一块布景板和追光,当缩略图还行,当封面不够。

## 怎么写开场

开场是观众最先读到的字,要写得像海报,最多 3 行。优先顺序:
1. 用户原话里的场景或问题:`车胎瘪了。/ 没空修。`
2. 简报里没有时,用产品界面上已有的问题或标题,一字不改,并列为推断。
3. 两者都没有时,用 `就是它` 或 `HERE IT IS`。

绝不编造痛点。各行长度要平衡:最后一行只剩很短的一个词就是孤行,check.mjs 会拒绝。把词挪下来,或者改写。每行上限是中文 9 字或拉丁字母 16 个。

## 时间线字段

中文和拉丁字母的上限都按字符数算。字号会自动计算,句子越短字越大。

| 字段 | 含义 | 上限 | 简报信息不足时 |
|---|---|---|---|
| `lang` | 片中所有文字的语言。 | `en` 或 `zh` | 用用户的语言。不要擅自翻译;第二种语言另做一份时间线。 |
| `duration_s` | 片长。 | 16 到 20 的整数 | 18。 |
| `palette` | 配色方案。 | `carnival`、`seaside`、`orchard` | `carnival`。 |
| `bumper` | 设备边框颜色,通常用品牌色。 | `#RRGGBB` 或 `null` | `null`。 |
| `product.name` | 片尾的产品名,大小写保持原样。 | 中文 20 字或拉丁字母 40 个 | 用产品上写的名字。没有就停下来问,绝不编造。 |
| `product.name_lines` | 长名字的断行,用数组,连起来必须和产品名一字不差。 | 3 行 | 拉丁文名字填 `null`。超过 8 个字的中文名,要在词语之间断开。 |
| `copy.hook` | 开场海报:见“怎么写开场”。最后一行不能是孤行。 | 1 到 3 行;每行中文 9 字或拉丁字母 16 个 | 有界面上的问题或标题就用它,否则 `["就是它"]` 或 `["HERE IT IS"]`。绝不编造痛点。 |
| `copy.intro` | 设备旁边的字:这个产品是什么。 | 1 到 2 行;每行中文 9 字或拉丁字母 16 个 | 名字放得下就用 `["这就是", "<产品名>"]`,或用页面自己的标题。 |
| `copy.action_label` | 说出那一个操作。如果有两行,第二行一定正好落在点击那一帧。在高屏或易读的屏幕旁边时上下叠放;在信息密集的宽屏上方时可能排成一排,但仍然分两拍出现。只有一行时会在点击前出现,所以尽量写两行。 | 1 到 2 行;每行中文 7 字或拉丁字母 12 个 | 用控件上的文字并分开,如 `["点一下", "就好"]`、`["ONE", "TAP."]`。 |
| `copy.claim` | 那一句主张。只写界面上有的,或用户说过的。第 1 行在点击后一拍(15 帧)落下,这时下一块布景板摆入,界面正在变化。 | 1 到 3 行;每行中文 9 字或拉丁字母 16 个 | `["亲眼看它运行"]` 或 `["SEE IT WORK"]`。 |
| `copy.cta` | 下一步做什么。 | 中文 12 字或拉丁字母 22 个 | `"亲自看看"` 或 `"See it for yourself"`。 |
| `copy.link` | 用户给你的真实地址。 | 34 个字符,或 `null` | `null`。绝不猜域名。 |
| `copy.notice` | 全片印在舞台前沿的一行小字,始终不压设备。虚构界面必须有,并且要写明虚构。 | 中文 30 字或拉丁字母 60 个,或 `null` | 真实产品填 `null`。 |
| `screen.kind` | `real`,虚构产品填 `fictional`。 | | 只有确实是用户的产品才填 `real`。 |
| `screen.before`、`after`、`capture` | capture.mjs 生成的文件,路径相对于时间线,必须是本地文件。 | png、jpg 或 webp | 只有一个状态时 `after: null`。这时片子只有点击没有结果,要在说明里写清楚。 |
| `screen.play` | capture.mjs 生成的 `play.json` 路径:界面真实的变化过程。见“让界面动起来”。 | | 只有确实没有可动内容时才填 `null`,并写明。 |
| `screen.width`、`height` | 界面的逻辑像素尺寸。 | | 从 capture.mjs 粘贴。 |
| `screen.crop` | 只展示界面的一部分,单位是逻辑像素。 | 必须包含目标控件 | 填 `null`,等检查脚本要求时再加。 |
| `screen.crop_by_format` | 只对某个画幅生效的裁切:`{"9:16": {x, y, w, h}}`。 | 必须包含目标控件 | `null`。 |
| `screen.target` | 控件的框;`source` 是 `selector` 或 `manual`。 | 在界面范围内 | 从 capture.mjs 粘贴,不要修改。 |
| `screen.target.skip_pixel_check_reason` | 说明手填的目标为什么没有可见边缘,比如纯文字链接。 | 文字 | 不填,除非你看过 `target-crop.png`,确认框是对的。 |
| `allow_latin` | 中文片里允许出现的英文产品术语,用数组。 | | 不填。 |
| `evidence.screen`、`action`、`claim` | 你在哪里看到的:文件、页面或用户的原话。文案里的任何数字都必须出现在这里。 | 至少 10 个字符 | 引用简报,或写明你读的文件。 |

## 信息不全时怎么办

- **简报信息不足:** 复述用户给的事实,绝不编造,并在交付说明里列出每一句由你推断的文案。用上表最后一列的写法,这些备用文案都能通过检查。
- **没人能回答:** 用备用文案继续做,把假设列在说明最前面。
- **想要别的时长:** 引擎只做 16 到 20 秒。要更短的片段,就自己裁剪成片,并告诉用户裁剪后不再符合 check.mjs 的时长规则。不要拉长。
- **没有真实链接:** `copy.link: null`,加上备用的行动号召。不要编造域名。
- **界面打不开,比如要登录:** 向用户要截图。没有截图就不要伪造。模拟界面只能用于明确虚构的示例:`screen.kind: "fictional"`,并加上标注。
- **点了界面没变化的控件:** 换一个。capture.mjs 在点击没有带来变化时会提示。
- **信息很密的仪表盘:** 检查脚本会要求裁切,粘贴进去就好。这是把真实界面拉近看,并不失实。
- **还没做出来的功能:** 不能进片子。直接说明,改用已有的功能。
- **选第一帧或缩略图:** 用 `--frame claim`,不要用第 0 帧。
- **验证确定性:** 用 `--frame n --png` 渲染同一帧两次,再用 `shasum` 比较,结果逐字节相同。从 MP4 解码出来的帧因为编码不会完全相同,这是正常的。
- **报告文件:** 只有最终成片旁边的 `film.mp4.layout.json` 有用。预检写到系统临时文件夹,短测试的报告可以和测试片一起删掉。

## check.mjs 看不到的,要你亲眼看

它读的是引擎的布局数据和解码后的成片,看不懂画面的意思。在联系表和 `--frame press+30` 上,留意:
- 片子是让人兴奋,还是只在罗列功能?点击后有东西明显动起来吗?
- 动起来的状态是否真实:确实是产品的行为,没有产品从未显示过的数字。
- 同一行里字符是否挤在一起(比如问号紧贴前一个字母)。
- 点击那一刻,光标有没有挡住内容;观众能不能在屏幕上找到结果。
- 特写有没有把屏幕上重要的部分裁掉。
- 文案是否属实,读起来是否像人写的。

## 交付物

- `film.mp4`:1920x1080、30 fps、H.264、yuv420p、无声、16 到 20 秒。
- 旁边的 `film.mp4.layout.json`;如果要了其他画幅,还有 `film-square.mp4` 和 `film-vertical.mp4`。
- 一段简短说明:用到的事实、推断的文案、假设、检查结果和渲染时间。

## 交付前检查

- [ ] 每个要交付的画幅,`node scripts/check.mjs film.mp4` 都以 0 退出,并且没有加 `--short`。
- [ ] 每个画幅的 `film.mp4.sheet.jpg` 都看过,每个场景都看到了。
- [ ] 看过 `target-crop.png`,框落在控件上。
- [ ] 光标点的是真实存在的控件,点击后的画面就是产品真实的反应。
- [ ] 点击后界面在动;如果只是静图切换,说明里写了原因。
- [ ] 逐项看过“check.mjs 看不到的”,也看过 `--frame press+30`。
- [ ] 每句文案要么写在 `evidence` 里,要么列为推断。没有编造的数字、客户或功能。
- [ ] 片中只有一种语言。虚构界面在 `copy.notice` 里写明了虚构。
- [ ] 没有残留进程:浏览器和 ffmpeg 都已退出。

## 不适合的情况

- 很长的演示或教程:这条片子只展示一个操作。
- 严肃、奢侈或医疗类题材:这种热闹的马戏团配色会削弱它。
- 没有界面的产品。
- 需要旁白或音乐的片子:这条片子是无声的。

用在这些流程里

相似技能