# Motion Showreel

> 用代码制作图形、文字或界面动画视频，输出 MP4 和可编辑源码，最长 20 分钟。适用于动效作品集、产品片、UI 动效、动态排版、Logo 片头、生成艺术与讲解视频；支持独立选择 BGM/音效来源、用户口播，以及用用户提供的口播稿通过 TTS 合成语音。不用于实拍制作、写实人物生成或一般视频剪辑。

- Skill: `yhyu13/motion-showreel` (Agent Skill, multi-file: 114 files)
- Install (CLI): `npx get-skill add yhyu13/motion-showreel`
- Raw SKILL.md: https://api.skillmd.com/api/skills/yhyu13/motion-showreel/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Design & Media
- Author: yhyu13 (https://skillmd.com/u/yhyu13)
- Updated: 2026-11-12
- Page: https://skillmd.com/skills/yhyu13/motion-showreel

---


# Motion Showreel

把一个想法做成以图形、文字或界面动画为主的视频，交付 MP4 和能重建的源码。保留短片的动效密度和创意自由，也支持按章节制作最长 20 分钟的内容。

**原理**：页面暴露确定性的 `render(t)`，脚本逐帧截图，再用 ffmpeg 合成 MP4。画面、口播、配乐和音效共用 `timeline.js`。无口播时按内容和音乐节拍组织画面；有口播时以真实语音时间为准，再安排音乐和音效。

**默认先预览，再导出**：所有类型都先打开剪辑工作区让用户查看真实画面与声音。用户点击「导出视频」或在对话中确认预览通过、可以导出后，才合成 MP4。首次要求「做一个视频」不等于预览已经通过；只有用户明确免除预览时才能直接导出。静帧、自查和音频准备可提前进行，不默认生成代理 MP4 或整片样片。

**按需观看制作过程**：需求问答时识别「边做边看、实时进度、每个阶段看看」等意愿；用户表达后就提前打开进度页，从需求说明到风格帧、口播样例、镜头与混音逐步展示。按 `references/progress.md` 发布已自查的阶段成果，不直接加载半成品代码。收到用户确认后，先用 `progress.mjs <project> --stage <当前阶段> --confirm --message "已确认，正在……"` 解除等待，再进行调研、下载或制作；不等产物做完才补进度。未提出时保持默认的最终工作区预览；不改变制作标准、确认节点和成片验收。

**好片子从哪来**：变化密度、运动质感、一个记忆点、音画关系，这四项通常决定观感。但具体怎么动、动多少，由**风格和内容**决定，不是每支片子都要多机位、弹簧和满屏音效。全局只守几条底线（见「底线」），其余都是给模型的起点，不是天花板。

**视频感**：讲解、产品演示和叙事片要让对象的行为与关系随内容发展，保持镜头间的空间承接。不能把口播逐句变成静态标题卡，再用淡入、缩放和背景粒子包装。分镜先写清「观众要看懂什么变化、主体前后状态、如何接上一个镜头」，再选动效。Logo、动态排版、循环与刻意静止的风格仍按自身语法制作；不靠持续乱动或强制 60fps 判定好坏。具体方法见 `references/craft.md` 的「连续叙事」。

---

## 适用范围

| 用户想要 | 用这个 Skill？ |
|---|---|
| 产品宣传短片、动效作品集、UI 动效、动态排版 / 卡点、Logo 演绎、片头、循环动图 | ✅ |
| 视频模型生成的绿幕人物 + 代码做的场景、大字、动效 | ✅ 人物由用户提供（`references/formats.md` H 类） |
| 用户提供口播稿或录音，要导出有讲解的 MP4 | ✅ 口播驱动模式；TTS 必须使用用户提供的原稿 |
| 需要点击推进、现场演讲、交互式网页演示，或文章转口播稿 | 用 `web-video-presentation` |
| 网页、落地页、交互原型、静态视觉稿 | ❌ 用 `web-design-engineer` |
| 写实人物表演、实拍质感、剪辑已有素材、用视频模型直接出画面 | ❌ |

**时长**：最长 20 分钟（1200 秒），以用户确认的时长为准。短片仍适合 5–60 秒，不把长片做成连续二十分钟的高密度卡点。超过 2 分钟，读 `references/long-form.md`，按章节规划、制作和审片。用户指定时长与口播实际长度或内容量冲突时，停下来确认调整方案，不擅自截断、加速口播或改变片长。

## Opus 的长处和默认坑

- **长处**：一个文件里能混用 Canvas、SVG/DOM、WebGL、Three.js，甚至每段换一种媒介；运动可以用公式精确计算（闭式弹簧、节拍网格、子帧运动模糊）；声音和画面读同一张时间表；能长时间自主「渲静帧 → 看图 → 修改」；审美判断力强，一句「全力以赴」就可能出很惊艳的东西。
- **默认坑**：没有约束时，画面会落到深色背景、居中大字、所有元素一起淡入、紫蓝渐变加发光、机位不动；配乐会落到 A 小调四踩、每个重拍 impact + crash、钟声落版，几支片子听起来像同一首歌。所以要先找对标（画面和声音都要）、写清风格和禁止清单。但约束也不能写死：这个 Skill 的风格库和手法库都是起点，主题需要时随时改造、混搭或自定义。
- **做不好的**：写实人物、复杂的手部 / 布料 / 毛发、需要真实物理精度的东西、照片级产品（除非用户提供模型或图片）。遇到这些就风格化处理，或者换成绿幕人物 + 代码场景的分工。

---

## 工作流

```
0 环境检查（一次）
1 需求确认 ──────── 补齐必填项，汇总要求 → 🛑 等用户确认
2 brief.md ──────── 对标 → 用途 + 风格 → Reel Read → 分镜 + 声音计划
3 风格帧 ────────── 已定风格：3 张帧；未定风格：3 个方向各 1 张 → 🛑 等用户确认
4 制作 ──────────── 有口播先准备真实音频及时间戳 → timeline → 逐镜头 → 网页自查
5 配乐与混音 ────── BGM、音效独立选来源；有口播时人声优先
6 工作区预览 ────── 主动打开剪辑工作区，修改后复看 → 🛑 等用户确认导出
7 导出与验收 ────── 合成 MP4 → 技术检查（必须全过）+ 成片复核
8 交付
```

工作目录：在用户当前目录下建 `<slug>/`，所有文件都放在里面：`brief.md`、`index.html`、`motion.js`、`timeline.js`、`score.mjs` 或 `score.tone.js`（按 scaffold 的 `--audio` 选择）、`build.sh`、`fonts/`、`assets/`、`audio/`、`qa/`、`out/`。

### 第 0 步：环境

第一次使用时运行 `sh <skill>/scripts/setup.sh`：它会安装 Playwright 和 Chromium，再跑 `check-env.mjs`。需要 Node 18+ 和 ffmpeg；缺了就告诉用户怎么装，不要替用户装系统软件。工具自带测试：`cd <skill>/scripts && npm test`。

### 第 1 步：需求确认（停下来等用户）

集中补问缺失项，已经提供的不要重复问。以下信息必须明确，不能用固定默认值代替用户决定：

| 必填信息 | 需要明确什么 |
|---|---|
| 核心主题、制作内容 | 要呈现什么，哪些内容必须出现 |
| 时长 | 明确秒数或分钟数，是否允许小幅浮动；不得超过 1200 秒 |
| 横屏或竖屏 | 按选择确定实际尺寸；也保留用户明确指定 1:1 等其他画幅的能力。分辨率、帧率可提出建议，并写入确认摘要 |
| BGM 来源 | AI 自主合成 / 用户提供；用户也可明确关闭 |
| 音效来源 | AI 自主合成 / 用户提供；与 BGM 分开选择，也可关闭 |
| 口播方式 | 无口播 / AI TTS / 用户提供录音 |

**条件必填**：选 TTS 时必须由用户提供口播稿，不代写、不补写、不改写后擅自合成；同时明确 TTS 服务及所需 API 配置（已有配置复用，凭据用环境变量，不写进 brief）。支持 Gemini、MiniMax 和自定义适配器，按需读 `references/narration.md`。选用户录音时，需要录音文件或可访问地址；选用户 BGM/音效时，需要相应文件。口播语言、音色等能从稿件或配置判断的写入摘要，否则一并询问。

**可选信息**：相关资料、受众与发布平台、主题风格。受众和平台未给时根据内容推断，并在摘要说明。风格未给时留到风格帧阶段提供三个方向。

**制作进度偏好**：从用户已有反馈判断是否希望看过程，明确表达就记录并启用，不重复确认、不增加必答题。启用时读 `references/progress.md`，尽早启动 `editor.mjs <slug> --progress` 并主动打开；目录可以暂时没有动画或音频。在需求摘要中写明会逐阶段展示，后续仍等原有需求与风格确认。

**素材怎么处理**：用户已经给了具体内容并授权 AI 生成，就据此制作；用户未给足具体内容时，询问必要资料，也可以根据主题开展网上调研并保留来源。有口播稿时先从原稿提取信息，不再让用户重复填写。AI 可生成插画、场景、抽象图形和明确标注的示意内容；真实产品功能、数字和品牌素材仍守「底线」，不能用虚构资料冒充真实内容。品牌 Logo 或真实产品截图的要求见 `references/stack.md`。

- 用户给了参考视频：先跑 `inspect.mjs sheet <ref> --cells 30` 看全貌，`inspect.mjs grid <ref> --strips` 量出剪点和它们落的节拍网格（BPM 候选、每段占几步、每个转场的连续帧），`inspect.mjs heat <ref>` 看每段里哪里在动、动多大面积。把量到的数写进 brief 的对标一栏。只学结构和手法，不搬素材。
- 用户给了曲子：无口播时先跑 `audio.mjs beats <track> --out <slug>/audio/beats.json`；有口播时音乐拍点服从讲述节奏。
- 画面里要出现的产品、品牌或技术名词，不确定的先查证。

补齐后汇总主题、时长、画幅、BGM/音效各自来源、口播方式和素材情况，**停下来等用户确认，再写 brief**。即便首次请求信息齐全，也先发摘要确认。用户说「全力以赴」「给我惊喜」「你看着办」只授权创意选择，不代表可省略必填信息或跳过确认；只有用户明确要求跳过某次确认时才可继续，记录其授权。

**放手模式**：保留创意自主权，只守底线和技术管线，风格、结构、手法可自行判断，也可完全不用风格库。仍写 brief、提供三个方向，完成需求与风格确认；制作后同样先在工作区预览，再确认导出。用户明确免除的确认除外。

### 第 2 步：brief.md

**先找对标**：动笔前为这支片子（这个主题 + 这种用途）挑 1–2 个对标作品，可以是电影片头、广告、游戏、动效作品、设计流派。在 brief 里写下「学什么」（构图、节奏、镜头语法、配色逻辑、配乐结构）和「不学什么」（角色、具体镜头、旋律、logo、字体文件）。对标比任何规则都更能拉高上限。

**再想三个候选结构**：比如一段旅程、一次前后对比、一次倒数、一个变成另一个、一个不切镜头的长镜头。各用两三行写下来，选一个并写明理由。第一个冒出来的想法往往是这个风格的陈词滥调。

**用途**和**风格**分开选：
- 用途（拍什么、按什么结构讲）看 `references/formats.md`，只读对应的那一节。
- 风格（长什么样、怎么动、什么声音）先看 `references/styles/INDEX.md`，再**只读选中的 1–2 个风格文件**。风格可以直接用、改造（替换其中一两条规则）、混搭（一主一辅，或者按段落切换媒介），也可以按 `styles/_template.md` 自定义。风格规则保持不变，故事、镜头和结构从用户的主题来，不要沿用别的片子。每个风格文件都有「辨识信号」和「最俗的版本」两节：按主题挑 2–3 个信号（至少一个不在俗套里），在 brief 里写明翻掉了俗套的哪几条，或者为什么保留。用户选了风格，要的是一眼认出这个风格，两三个信号就够了。
- 再按需翻 `references/craft.md`（手法库）。

按 `references/brief-template.md` 写 brief，核心是：

```yaml
Reel Read:
  format: [用途，formats.md 里的类型]
  benchmark: [对标作品 · 学什么 · 不学什么]
  structure: [三个候选结构 → 选中哪个、为什么]
  style: [styles/ 里的风格（含改造点），或者混搭方案，或者自定义规则]
  signals: [挑了哪 2–3 个辨识信号、为什么；翻掉了俗套的哪几条]
  takeaway: [观众记住的一句话或一个画面]
  hook: [前 1 秒发生什么]
  signature: [记忆点：第几秒、什么手法]
  palette / type / motion / camera / texture: [按所选风格写出具体值]
  sound: [无声 / 合成（声音对标、律动、和声、配器、曲线，见 sound.md 第 2 节）/ 用户曲子（BPM、drop）]
  audio-sources: [BGM 与音效各自为 AI / 用户 / 关闭]
  narration: [无 / 用户原稿 TTS / 用户录音；有口播时句段时间轴路径、人声优先]
  forbidden: [这支片子的禁止清单]
```

接着写分镜表：无口播时保留**节拍网格 + 分镜表**。有口播时把句段关联到镜头与事件，写明 `镜头 / 句段 ID | 要解释的变化 | 对象起止状态 | 继承的对象与空间 | 关键事件及时间依据 | 镜头与声音`。一镜可以覆盖多句，一句可以有多个动作；不把口播分句当作切镜指令，也不要求逐句把原稿写满屏。实际区间在音频准备后回填，不把字数估时当成最终对齐依据。长片另写章节表、各章时长和跨章一致性规则。

用户只说了一句「全力以赴」，也要把它翻译成上面这份具体约束，否则结果就是抽卡。

### 第 3 步：风格帧（第二次停下来等用户）

建项目：`sh <skill>/scripts/scaffold.sh <slug> [--audio synth|tone|layer|file|none]`（synth = 第 1 档合成；只拷贝选中的那份 score，`file` 使用已准备好的最终音轨）。脚手架的引擎默认值只用于技术初始化，不能代替需求确认。starter 只用来验证管线能跑通，画面和文案都要换掉。

**A. 用户已经定了风格**（或者给了明确的参考）：
以下命令中的秒数只是示例，实际取本片开场、记忆点与结尾的有效时间；短片和长片都不要照抄 14.5 秒。
1. 用真代码搭出 hook 帧、记忆点帧、结尾帧，配色、字体、文案都用最终的。
2. `render.mjs <slug> --still 0.6,7.2,14.5 --sheet`，自己先看一遍，明显的问题修完再给用户。依赖运动的方向，在工作区中展示本节要求的连续片段，不先编码成 MP4。
3. 把 Reel Read 摘要、分镜概要、风格帧发给用户，问「方向对吗？」。

**B. 用户没定风格（包括放手模式）**：给 **3 个拉开差距的方向**，规则见 `styles/INDEX.md`：
- A 贴合主题 / 品牌，B 换一种画面语言（来自另一个分组），C 大胆（自定义、混搭或结构上很大胆，至少一个方向不是库里现成的）。
- 每个方向写一段迷你 Reel Read（风格、对标、记忆点、配乐方向，3–5 行），并用真代码渲**一张**最能代表它的关键帧。三个方向的页面放在同一个项目里，用 `?dir=a|b|c` 切换。B、C 只为这一张关键帧服务，不必做成能播的整片。
- `render.mjs <slug> --directions a,b,c --at 14.5,2,0` 一次渲出三张并拼成带标签的 `qa/directions.png`，发给用户，问「选哪个，或者怎么混合？」。

两种情况都**真的等用户回复**，再进入制作。TTS 项目同时附用户原稿的分段方案和音色短样（只使用用户给的文字），一起确认声音方向，不额外增设必停节点。用户事先明确说过不用确认的，就自己选一个、写明理由，自查后继续；交付时把没选的方向一起给用户（B 情况附上 `qa/directions.png`，A 情况各写一句另外两个可能的方向），让用户回来还能换。

对依赖连续动作的方向，静帧之外在工作区中展示 6–10 秒代表性运动片段（短于 6 秒的片子用全片），用播放头和循环试听选区定位，覆盖一次状态变化及前后承接；先自行看连续帧排除跳变。片段随风格帧一起确认，无需提前导出样片。口播尚未生成时明确标为动作预演，不能声称已与语音精确对齐。风格确认与最终预览确认分别确认方向和成片内容。

### 第 4 步：制作

制作前先读 `references/stack.md`（页面契约、确定性、各技术的坑）。要现成写法时查 `references/recipes.md`。

**有口播时先锁定口播时间轴**：按 `references/narration.md` 合成用户原稿或导入用户录音，取得真实时长和句段时间戳，再安排画面。用户录音需通过可用转录工具或用户提供的 SRT/JSON 获得文本与时间；没有可靠时间戳时不能声称已完成逐句对齐。发现时长冲突先确认，不静默填充、裁切或变速。将真实区间导入镜头表，保留口播停顿和重点，不强行对齐音乐小节。超过 2 分钟按 `references/long-form.md` 分章制作，保留章节缓存。

句段只提供同步范围，镜头和主体运动可以连续跨句。关键变化需要词级同步时，用真实词时间或人工标注锚点，通过 `narration.js` 查询，让画面与音效引用同一事件；只有句级时间时维持句级同步，不伪造逐字时点。制作过程中默认用 `editor.mjs` 带声音预览、拖动与逐帧检查；`preview.mjs` 保留为轻量调试工具。预览只驱动同一个 `render(t)`，不进入正式渲染。

1. 时间点全部写进 `timeline.js`，页面和 `score.mjs` 都从这里 import。镜头表写进 `SHOTS`（验收时按镜头报运动），刻意的停留写进 `HOLDS`（比如落版 `[[b(36), DUR]]`），要留呼吸的重拍写进 `DROPS`，验收工具会读它们。转场要对拍时，用 `revealOn(拍点, 转场时长, 揭开点)` 倒推起点，让新画面露出来的那一帧落在拍上。
2. 逐个镜头做。用户要看制作过程时，每镜自查通过即发布该镜头的独立可播放成果（`progress.mjs --stage scenes --shot <id> --total <镜头总数> --publish <该镜预览目录>`），然后再做下一镜；不把所有镜头写完后一次补成 3/3，也不等全片素材齐全才给第一个预览。每个镜头渲开头、中段、结尾 3 张静帧；关键状态变化和镜头接缝另看连续小样，检查主体是否凭空重置、动作速度是否突变、镜头是否中断。静帧好看不能替代运动检查，快速动作用 `inspect.mjs strip` 看连续帧。
3. 跑确定性检查 `render.mjs <slug> --determinism`，不通过就先修。
4. 用网页预览检查节奏与连续动作，不默认渲染低清代理或 MP4 小样；静帧和确定性检查照常进行。确实需要离线片段时说明原因，在用户同意后只渲必要范围。
5. 按 brief 配好 `FPS`、`SIZE`、`AUDIO`、`LOOP`，完成下方声音准备后进入第 6 步。此时不执行 `build.sh`、视频模式的 `render.mjs` 或 `build-long.mjs`。

**硬规则**：
- 画面只由 t 决定：不用 `Math.random`、`Date.now`、rAF、定时器、CSS 动画，帧和帧之间不保存状态。
- 字体和素材全部加载完，再设置 `READY = true`；字体放进项目自托管。
- 布局从 `stageSize()` 返回的宽高推导，不写死像素。

使用子帧运动模糊且有文案硬切时，可按 `references/stack.md` 的可选采样上下文区分文案状态与连续运动；导出后检查切换点的连续帧，避免子帧平均造成一帧文字叠印。

启用制作进度时：风格帧与口播短样自查后发布为图片/音频成果；镜头和混音形成可播放阶段后，用 `progress.mjs --publish` 发布稳定副本。开工前更新 `running`，完成后把成果挂在对应阶段：需求/脚本可发布 Markdown，风格帧发布图片，声音发布音频，逐镜头发布可播放版本。等待用户选择用 `waiting`；未完成部分写清楚，数量由成功发布的镜头计算。阶段预览不增加确认节点，不触发 MP4 合成。最终短片用 `review --final` 在同一进度页进入可调音、可导出的工作区；长片仍逐章展示，确认全片后按原流程构建。

### 第 5 步：BGM、音效与混音

看 `references/sound.md`。BGM 和音效分别按确认的来源制作，允许用户配乐 + AI 音效等组合。下表是 AI 合成的引擎选择，不能用引擎默认值覆盖已确认的素材来源。声音方向（对标、律动、和声、配器、曲线）在 brief 里就定好：

| 档 | 用什么 | 适合 |
|---|---|---|
| 第 1 档 · 内置合成 | `score.mjs`，Node 里的合成器（鼓、手鼓、贝斯、铺底、拨弦、马林巴 / 钢片 / 卡林巴、风琴、人声铺底、FM、环境底噪、音效、侧链、混响、lo-fi 处理），零依赖 | 电子、UI、芯片音乐、氛围、lo-fi、手作与玩具、大多数动效片 |
| 第 2 档 · Tone.js | `score.tone.js`，在无头浏览器里用 Tone.js 离线渲染：采样乐器（`audio.mjs samples salamander` 下载 CC BY 钢琴）、卷积混响、更丰富的合成器和效果 | 需要真实乐器、空间感、电影感的风格 |
| 外部曲子 | 用户提供的音乐（自己的、授权的、AI 音乐服务生成的） | 用户已有配乐 |

- 构建：`audio.mjs build <slug>/score.mjs` 或 `score.tone.js`，都会输出 −14 LUFS 的 `audio/music.wav`。
- 用户曲子：无口播时先跑 `audio.mjs beats`（有 librosa 时自动使用）对齐 timeline，再在 score 里 `S.load()` 叠音效。有口播时只把音乐节拍作为参考，调整音乐和音效配合语音，不移动已确认的口播时间轴。
- 无声：BGM、音效和口播均关闭时跳过；仅关闭 BGM 不代表整片无声。
- 有口播：音乐减少主旋律、密集打击和大动态；音效只保留有信息作用的动作，避开关键词与句首。保留独立轨，通过 `narration.mjs mix` 做人声期间的避让、统一响度和峰值处理。用真实句段时间戳核对画面，听感仍需用户终审。

每次 build 之后都要对最终混音跑 `audio.mjs check`，看数值和图；宿主支持试听时再听，不能把数值通过写成「听感已确认」。`timeline.js` 里写了 `DROPS` 时，它还会量出重拍前的凹陷和抬升，没有呼吸就给 WARN。

### 第 6 步：工作区预览（默认入口，等用户确认导出）

每次制作都读 `references/editor.md`。已启用制作进度的短片，在同一进度页发布 `review --final` 作为最终工作区，沿用已确认的规格和导出质量参数，无需另开入口；其余情况运行 `node <skill>/scripts/editor.mjs <slug> --size <本片尺寸> --fps <本片帧率>`，并主动打开打印的网址；宿主不能打开浏览器时提供可访问的本机链接，等待用户预览反馈。无声、无口播、短片、循环片也走这一步，不需要用户再次提出「打开工作区」。长片按 `long-form.md` 逐章打开工作区预览，第一版不假称有跨页面整片时间线。

先自行检查画面、音轨、时长和错误，再交给用户播放、拖动和调音。未编辑时直接使用原混音；音轨调整后更新试听，确认当前混音已经加载。用户提出修改就改完后刷新、复看，不因上一版通过而自动导出修改版。只有用户点击「导出视频」或明确确认当前预览通过、可以导出，才进入下一步；两者都是导出确认，无需再重复询问。

把预览链接、反馈、确认导出的版本及音轨编辑记录写进 `brief.md` / `qa/review_log.md`。如果服务或浏览器不可用，说明阻碍并提供网页预览替代方案，不擅自改成先生成 MP4。子帧混合、DPR 超采样和 ffmpeg 颗粒仍属于导出设置，告知预览尚未模拟的部分，不静默降低成片质量。用户明确要求不预览、直接导出时记录其指示，保留下面的全部技术验收。

### 第 7 步：导出与验收

预览通过后，单页面优先在工作区点击「导出视频」，由现有渲染器和验收工具输出编辑版 MP4。工作区的音频修改不会自动写回 `build.sh`，有编辑时导出必须使用已试听的当前会话，不能绕回原混音。未使用工作区音频编辑时，也可在用户确认后运行 `sh <slug>/build.sh`；它会构建配乐、检查确定性、渲染、生成文字审片材料，并按相同规格验收。混合音轨沿用 `AUDIO=file AUDIO_FILE=audio/final.wav sh build.sh`，旧的 synth/tone/layer/none 方式仍可用。长片确认后用 `build-long.mjs` 持久分章构建，详见 `references/long-form.md`。

`--subframes`、`--dpr`、`--grain` 按 brief 传入，工作区出口和手动构建使用同一组已确认规格；这些参数会增加耗时，开渲前报告预计时间。循环片另带 `--loop` 验收。预览确认不替代导出后的技术检查和成片复核。

**技术检查**：由程序判定，失败就不能交付。

```bash
node <skill>/scripts/inspect.mjs qa <slug>/out/final.mp4 --out <slug>/qa/final \
  --expect-size 1920x1080 --expect-fps 30 --expect-duration 16 --audio required   # 无声片用 --audio none；循环片加 --loop
```

它检查文件能否解码、尺寸、帧率、时长、帧数、音轨、黑帧、响度、真峰值，以及循环接缝（需要时）。只要有一项 FAIL，退出码就是 1，必须修好。没传的规格项会列成 `NOT CHECKED`，这时不算验收通过。`build.sh` 会自动带上规格。渲染工具本身也会拒绝发布帧数不对的文件。

**审片**：给人判断用，不是程序判定。看抽帧图、手机尺寸抽帧图、冻结段（`HOLDS` 里声明过的会标成刻意停留，其余要判断是不是空拍）、切点、按镜头的运动和闪帧、文字框景的标记图（`qa/text-*.png`）、音频图，按 `references/review.md` 的审片表逐项写下观察和最严重的 3 个问题，有数字和图表的片子要核对内容与数字口径。修完只重渲有问题的那一段，再出整片，过程记到 `qa/review_log.md`。宿主支持子 agent 时，再派一个没参与制作的 agent 只看这些材料挑问题（review.md「独立审片」）。

有口播时额外运行 `narration.mjs check`，核对句段时间覆盖、音频长度与确认规格；逐句审查原稿、画面与语音是否一致，自动检查不能代替听感审片。长片逐章审片，并检查拼接处的画面、声音和时间轴。

审片结论是给用户的参考，**不能代替用户自己看片**。不适用的项标「不适用」，比如无声作品的音画同步，不要硬给分数。

### 第 8 步：交付

告诉用户：
- 实际成片路径：工作区导出为 `out/editor-<task-id>.mp4`，原构建为 `out/final.mp4`；同时给出 `out/poster.png`（poster：`render.mjs <slug> --poster <t>`）。
- `brief.md`：完整的结构化提示词、需求与风格确认、最终预览及导出确认记录，可以复用，不含 API 凭据。
- 有口播时附用户原稿、句段时间轴和各轨来源；长片附章节 manifest 和断点重建命令。
- 技术检查结果（全部 PASS）、审片记录里还没解决的问题、渲染用时。
- 怎么重新打开工作区、如何重建当前编辑版（见 editor.md），原构建仍可 `sh build.sh`，以及怎么只改一段。
- 第三方素材（字体、用户素材、曲子）的来源和授权；事实类内容提醒用户再核对一遍。

复盘结论和复核证据保存在项目的 `qa/review_log.md`，与本次制作文件一起交付。

---

## 底线（所有风格都要守）

1. **需求与原稿**：必填信息经确认；视频不超过 20 分钟；TTS 原稿必须来自用户。时长冲突须确认，不擅自改稿、截断或变速。
2. **事实准确**：产品功能、数字、名称只来自用户或可靠来源，不确定的标出来。
3. **文字可读**：字号在手机尺寸下看得清，停留时间够读完（见 craft.md 第 7 节）；文字不溢出、不重叠、不被遮挡。
4. **素材有授权**：logo、截图、字体、曲子都要能用，并在交付时列出来。
5. **技术正确**：确定性渲染，技术检查全部通过，没有黑帧，结尾不能戛然而止（落版定格或无缝循环）。
6. **风格一致**：选定的风格规则从头守到尾，不落入 brief 的禁止清单。

除此之外，镜头动多少、用不用弹簧、音效密度、节奏快慢，都按风格和内容来定（见 references/styles/ 和 craft.md）。

---

## 工具速查（`S=<skill>/scripts`）

| 目的 | 命令 |
|---|---|
| 装依赖 / 查环境 / 自测 | `sh $S/setup.sh` · `node $S/check-env.mjs` · `cd $S && npm test` |
| 建项目 | `sh $S/scaffold.sh <slug> [--audio synth\|tone\|layer\|file\|none]` |
| 静帧 + 拼图 | `node $S/render.mjs <slug> --still 0.5,3,7.2 --sheet` · `--range 0:15:1 --sheet` |
| 三个方向 / 封面 | `node $S/render.mjs <slug> --directions a,b,c --at 14.5,2,0` → `qa/directions.png` · `--poster 14.5` → `out/poster.png` |
| 确定性 | `node $S/render.mjs <slug> --determinism` |
| 文字框景（审片材料） | `node $S/render.mjs <slug> --text-check [--safe auto\|none\|T,R,B,L]` → `qa/text.json` + 标记图（build.sh 自动跑） |
| 拆参考片 | `node $S/inspect.mjs grid <ref> --strips`（剪点 + 节拍网格 + 转场连续帧）· `heat <ref>`（每段的运动热图） |
| 确认后导出 / 分段 | 工作区「导出视频」；未改音轨时也可 `sh <slug>/build.sh --subframes 2 --grain 4`（规格在 build.sh 顶部）。离线片段仅按需 `--start 6 --duration 3 --out out/seg.mp4` |
| 声音 | `node $S/audio.mjs build <slug>/score.mjs`（或 `score.tone.js`）· `samples salamander` · `beats <track> --out audio/beats.json` · `check audio/music.wav`（读 `DROPS`） |
| 口播 / 最终混音 | `node $S/narration.mjs tts …` · `import …` · `mix …` · `check …`（参数见 narration.md） |
| 长片重建 | `node $S/build-long.mjs <slug>/chapters.json`（参数见 long-form.md） |
| 按需展示制作进度 | `node $S/editor.mjs <slug> --progress`；`node $S/progress.mjs <slug> --stage scenes --publish . --size 1920x1080 --fps 30`（用户想看过程时启用，见 progress.md） |
| 默认工作区预览 | `node $S/editor.mjs <slug> --size 1920x1080 --fps 30`（制作后主动打开，用户预览确认后才导出，见 editor.md） |
| 轻量调试预览 | `node $S/preview.mjs <slug> --size 1920x1080 --fps 30`（可加 `--audio audio/final.wav`；用法见 stack.md，不替代默认工作区审片） |
| 验收与审片材料 | `node $S/inspect.mjs qa out/final.mp4 --expect-…`（build.sh 自动带）· `sheet` · `phone` · `strip --at 4.2` · `loop` · `motion`（读 `SHOTS` / `HOLDS`：按镜头的运动、跳变、闪帧） |

## 参考文件（按需读）

| 文件 | 什么时候读 |
|---|---|
| `references/formats.md` | 第 2 步：用途，比如宣传短片、作品集、UI 动效、排版卡点、Logo、数据爆点、绿幕合成 |
| `references/styles/INDEX.md` | 第 2 步：43 种风格的目录、三方向规则、混搭规则；然后只读选中的 `styles/<slug>.md`。自定义用 `styles/_template.md` |
| `references/craft.md` | 第 2 和第 4 步：节奏、运动、转场、镜头、排版、配色、质感、记忆点、默认味清单 |
| `references/brief-template.md` | 写 brief 时 |
| `references/stack.md` | 第 4 步：页面契约、确定性、各技术的坑、字体、素材、多画幅、性能 |
| `references/recipes.md` | 要现成写法时 |
| `references/sound.md` | 第 2 步（第 2 节：声音方向）和第 5 步 |
| `references/review.md` | 第 6 步：技术检查说明、审片表、独立审片、常见问题、交付清单 |
| `references/narration.md` | 选择 TTS、用户口播、独立 BGM/音效混音时 |
| `references/long-form.md` | 超过 2 分钟：章节规划、持久缓存、分段音频与断点续建 |
| `references/progress.md` | 初始反馈表达想看制作过程时；提前打开、阶段成果发布、稳定版本与最终预览 |
| `references/editor.md` | 每次制作的默认预览入口；准备工作区、多轨声音调整、编辑保存和确认后导出时 |

