| name | video-editor |
| description | 9:16 + 16:9 双画幅短视频合成 / 剪辑 skill(做视频的唯一入口)。三个子模块——**opener**(黄字衬线 4.5s 标题卡)、**animator**(chyron / cutaway / listicle / spec_review HTML 评审,走"三道门"工作流)、**subtitle**(whisper 自动转写 + 关键词高亮 PNG overlay 烧字幕)。触发后**先问做什么**:① 只下字幕 ② 只烧标题 ③ 做新动画 cue / 整片合成 ④ 全流程(口播→cue→动画→合成→字幕)。输出(默认三类,落 Movies 交付文件夹)① 整片 mp4 / 可选 alpha 通道 broll 层 mov ② 3:4 标题透明图层 PNG ③ 章节时间轴 txt。触发关键词:"剪一下这个视频"、"剪视频 / 剪辑"、"做一期视频"、"出整片"、"加动效 / 动画"、"加字幕 / chyron / 弹出文字"、"片头 / 标题卡 / opener"、"把口播和 B-roll 合成"、"新一期 X 系列"。实拍 stock 素材由本 skill 当总指挥委托 footage-finder 抓取(横 / 竖屏均可)。 |
Video Editor · 视频工人
把 9:16 / 16:9 talking-head 口播 + 叠层素材(标题 / B-roll cutaway / chyron / 字幕)合成出短视频。合成核心自给自足;实拍 stock / 新闻卡素材由本 skill 当总指挥派活给 footage-finder / news-highlight 抓取。
何时触发
用户说:
- "剪一下这个视频"、"剪视频"、"剪辑" —— 最常见入口
- "做一期视频"、"出整片"、"把口播和 B-roll 合成"
- "新一期 [出海 / AI 创业 / X 系列]"
- "给口播加字幕 / chyron / 弹出文字 / 标题卡"
- "加动效 / 加动画 / 加视觉"
不触发但相关(委托给兄弟 skill,video-editor 当总指挥):
- 实拍 stock 素材 / stock footage / B-roll 空镜 → 调
footage-finder skill
- 新闻 highlight 卡(真源头截图 + 黄光划重点)→ 调
news-highlight skill
- 纯 voice-over 生成、低于 30s 的短素材 → 不触发
委托:分镜 cue 类型 → 哪个 skill
分镜(门 1)阶段给每个 cue 标类型;非本 skill 自带的两类委托出去:
| cue 类型 | 谁做 | 产物 |
|---|
real_footage | footage-finder skill | 裁好画幅的实拍 mp4 候选 + 评审页 |
news_highlight | news-highlight skill | 真新闻黄光划重点卡 mp4(Vox 式) |
| opener / chyron / cutaway / listicle / spec_review | 本 skill animator/opener | HTML→mov/mp4 |
| 字幕 | 本 skill subtitle | 关键词高亮烧字幕 |
第零步 · 画幅 + 入口(★ video-editor 是整条工程的唯一入口)
video-editor 是总指挥——用户做视频从这里进,不用自己先去点 footage-finder / news-highlight / data-viz。触发后第一件事用 AskUserQuestion 问画幅:
这条视频是竖屏还是横屏?
- 9:16 竖屏(抖音 / 小红书 / 视频号 / Reels)→ 1080×1920
- 16:9 横屏(YouTube / B站)→ 1920×1080
- 3:4 实操教学片(录屏演示 / "我怎么用 AI 做 X")→ 1080×1440 · 走
slidecast/ 子模块
画幅跟内容类型走:实操教学 / 录屏演示类默认 3:4(slidecast);讲观点 / vlog / 泛文化等其它口播才是 9:16。别把普通口播硬塞进 3:4 录屏窗版式,也别把实操教学做成 9:16。
判断捷径:用户已经说了画幅("做个 16:9 的" / "发 YouTube" / "发 B站")就别问,直接定。
画幅决定下游:
| 9:16 | 16:9 |
|---|
| 子模块画布 | 1080×1920 | 1920×1080 |
| 实拍空镜 | footage-finder --vertical | footage-finder(默认横屏) |
| 新闻卡 | news-highlight(改竖版) | news-highlight(Root 默认 1920×1080) |
| 数据图 | data-viz(1080×1920) | data-viz(1920×1080) |
| compose | recipes/compose_dual.sh.template | recipes/compose_16x9.sh.template |
| 安全区 | CONVENTIONS 第三节 | CONVENTIONS 第一节 16:9 行 |
这些子 skill 都已支持横屏;video-editor 负责派活 + 最后合成,用户全程只跟 video-editor 对话。16:9 还多一个 person-pip 能力(干净人脸口播 → 没内容人满屏、有内容缩右下小窗,见 CONVENTIONS 第九节 + compose_16x9 模板)。
确定画幅后,再走下面的成品形态路由。
第一步 · 路由问询(★ 触发后立即执行)
不要预设用户要走全流程。先用 AskUserQuestion 问一次。按"最后要做成什么样"(成品形态)来分,不是按"你要干什么"(动作)——用户脑子里装的是成品,不是流程。
你这次最后要做成什么样?
- 一条带字幕的成片:已有成片,只加字幕 →
subtitle/ 子模块(不走三道门)
- 一个标题卡 / 片头:4.5s 透明 alpha 叠层 →
opener/ 子模块(不走三道门)
- 一条带动效的整片:加 chyron / cutaway / 列举动画 →
animator/ 子模块(走三道门)
- 从零做成一整条:口播 → 标题 → 动效 → 字幕 全包 → opener → animator → subtitle 依次串
- 口播实操教学片(3:4):口播 → case-step 录屏窗 slide + 字幕,你叠录屏/脸 →
slidecast/ 子模块(走三道门)
选项标号规范:AskUserQuestion 的选项前缀只用纯数字 1 / 2 / 3 / 4,禁用 ①②③④、㋐㋑㋒㋓ 之类带圈 / 片假名字符——用户字体常不支持,渲染成乱码。
判断捷径(不用问就能直达的情况):
| 用户原话 | 直达 |
|---|
| "帮我下字幕 / 加字幕 / 烧字幕" | 1 · subtitle/ |
| "做个片头 / 标题卡 / opener" | 2 · opener/ |
| "新一期 X 系列" / "做一期视频" / "出整片" | 4 · 全流程 |
| 上下文已经在做整片,想加 chyron / cutaway | 3 · animator/ |
| "实操教学 / 录屏演示 / 我怎么用 AI 做 X" / 100 个 AI 实操案例系列 | 5 · slidecast/(3:4) |
关键原则:1、2 是单点操作,不走三道门;3、4 必须走三道门。
★ 三道门工作流(选项 3、4 必走,不许跳)
⚠ 路由选项不是渲染许可——用户选了 3 或 4 只代表"想走 animator 流程"。进 animator 之后必须按三道门走,每道门 STOP 等用户明确确认才能进下一步。即使用户已经告诉你标题 / cue 数 / 文案,也不代表他允许你跳门。
门 1 · 文字方案 ─► 在 chat 里给 markdown cue 表
STOP · 等用户回「OK / 改 X / 砍 Y / 锁定」之类明确表达
❌ 不要写任何 cue HTML
❌ 不要开始渲染
│
门 2 · Spec Review ─► 写每个 cue 的 HTML
★ 先跑 node recipes/lint_layout.js --all <cue目录>
(安全区/最小字号/文字宽度/居中,FAIL 修完才继续)
再生成 _review/spec_review.html
STOP · 告诉用户「打开 file:///<project>/_review/spec_review.html 看,反馈后回我」
❌ 不要渲染 ProRes mov
❌ 不要 compose 整片
│
门 3 · 渲前 last call ─► AskUserQuestion: recap + judgment calls + 输出形式三选一
STOP · 等用户选完
❌ 不要预设输出形式
│
渲染 + compose + 字幕
用户没说"锁定 / 确认 / 开始 / 渲 / OK"等明确肯定表达之前,你都还在前一道门。
❌ 反例(不要这么干)
| 错误行为 | 损失 |
|---|
| 用户选了 4 + 给了标题 → 你直接抽口播 + 转录 + 写 HTML + 渲染 | 跳过门 1 "改 1-2 行字就修"的最便宜 checkpoint,省 5-10 min + 10k token |
| 用户说"我要这样" → 你判断"既然他要那就直接开渲" | 跳过门 2,HTML 视觉/字号错了重渲贵 5 倍(30s 渲 × 失败次数) |
| 用户在门 2 反馈"cue 3 改 X" → 改完直接渲 | 跳过门 3 last call,没让用户挑输出形式(合成原片 / broll 透明轨 / 两个都要),可能多渲 500MB ProRes |
| 用户没说肯定 → 你猜他想推进就推进 | 用户审视未完成,渲出来跑偏要重做整轮 |
✅ 正例
"进入 animator。先转录 + 出 cue plan markdown 表给你看。这是门 1——不写 HTML 不渲染,等你回 OK / 改 / 砍。"
每道门结束都用类似句式 explicit 告诉用户"现在到门 X,等你 OK"——别默默推进。
详细流程 + 各门具体产物清单 + cue 数量 baseline 见 animator/README.md。
子模块入口
| 子模块 | 干嘛 | 入口文档 |
|---|
opener/ | 4.5s 黄字衬线标题卡,透明 alpha 叠层 | opener/README.md |
animator/ | chyron / cutaway / listicle / spec_review,三道门工作流 | animator/README.md |
subtitle/ | whisper 转写 → 关键词高亮 PNG overlay → 烧字幕 | subtitle/README.md |
slidecast/ | 口播实操教学片(3:4):口播 → case-step 录屏窗 slide 按时间码硬切 + 字幕 → 预览 mp4 + 透明层 mov | slidecast/README.md |
共用规范
- 交付规范:
做内容/_运营文档/视频成片流水线-模板.md —— 一条视频 = 两个同名文件夹(工作 / 交付)+ 门 3 默认三产物(成片 / 3:4 标题层 / 时间轴)落 ~/Movies/<系列>/<视频代号>/。整片流程走这份
- 交付产物 recipe:
recipes/deliverables.md(标题透明层怎么渲 · 时间轴怎么从 cue plan 生成 · 交付文件夹命名)
- 视觉规范:
CONVENTIONS.md(safe zone、Hana 调色板、chyron 时序、字号层级、climax 规则) —— 任何子模块写 HTML 前必读
- 布局 lint(★ 门 2 必跑):
node recipes/lint_layout.js <cue.html>——puppeteer 渲染后机器检 安全区 / 最小字号 22px / 文字宽 ≤920 / 居中偏移 / 字号种数,9:16·16:9·3:4 三预设自动识别,动画 cue 按落定状态判。FAIL 修完才能给用户看 spec review。故意越界的装饰元素加 data-lint-ignore
- 环境自检:
bash recipes/doctor.sh——新机器 / 渲染报错先跑(ffmpeg / whisper / Chrome / puppeteer-core / avconvert / 字体 11 项)
- ffmpeg 双输出 recipe:
recipes/compose_dual.sh.template(mp4 + 可选 alpha mov)
- 已知坑:
recipes/PITFALLS.md(broll_reel 闪现 / HyperFrames webm 无 alpha / ffmpeg # 转义 / alpha 层变灰 / 中文路径 TCC 等 23 条)
- 历史案例索引:
recipes/examples.md(你的真实视频中的 11 个 cue 范式)
双输出策略
| 文件 | 用途 | 何时出 | 规格 |
|---|
<片名>_整片.mp4 | 预览 / 发布 / review | 每轮迭代都出 | H.264 yuv420p · CRF 20 · 含音频 + 叠层 |
<片名>_broll层.mov | 剪辑软件叠层(Premiere / AE / FCP) | 用户明说"定稿 / 出剪辑层 / 出 ProRes 层 / B-Roll only"才出 | ProRes 4444 yuva444p10le · 透明 · 静音 |
迭代期间默认只出整片 mp4。broll 层单次渲染 ~30s + 写盘 ~500MB,迭代期间 review 用不到。
⚠ broll 层永远是一条对好时间的完整轨。用户说 "B-Roll only" 时就是要这一条整轨,绝不是把 N 个 cue 分片 mov 丢给他自己去剪。
非重叠 cue 的 alpha 整轨必须用 concat 方式合成:透明 gap + cue + 透明 gap + cue,gap 按 ffprobe 的实际 cue 时长/帧数计算。不要把半透明卡片逐个 overlay 到 black@0.0 透明画布上;这会让米白卡片在最终叠回口播时变成灰黑。详见 recipes/PITFALLS.md 第 23 条与 recipes/compose_dual.sh.template。
交付 broll 层前必须做真实底图 QA:把最终 <片名>_broll层.mov 叠到原口播上抽 4-8 张关键帧/contact sheet,看颜色、alpha、遮脸和 timing。spec_review.html 只能审 HTML/动画,不能替代最终 ffmpeg 合成检查。
标题决策矩阵(用户说"加标题 / 加片头 / 重点字"时如何抉择)
| 用户说 | 默认 = | 关键参数 |
|---|
| "加标题" / "title card" / "片头" / "opener" | opener/yellow.html(黄字衬线大标题 + 白色斜体副标题) | 透明 alpha · 0s 视频起始 · top-third(padding-top 280px)· 4.5s · ProRes 4444 mov |
| "在 X 时刻强调某个词" / "弹出文字" | animator/chyron/chyron.html | 黄胶囊 · top 16% (y≈307 中心) · 1-2s pop |
| "1, 2, 3 列举" / "三点 / 四点要素" | animator/cutaway/scene_listicle.html | 编号列表逐行揭示 · 卡片 top 280px |
| "全屏数据卡 / 对比图" / "切到 X 数据" | animator/cutaway/scene_blank.html | 全屏白底 cutaway · caption top 280px · 不透明 mp4 |
关键原则:
- 视频"标题" = 0s 片头,默认就是。即使口播在 22s 才说到这个 phrase,标题仍然在 0s 出。
- 片头标题 = 透明 alpha 叠在 talking head 上。不是金色实底独立镜头。
- 数据卡 cutaway = 不透明全屏,覆盖 talking head;其他叠层(标题 / chyron)默认透明。
配套 skill
hyperframes / hyperframes-cli — HyperFrames CLI(渲 HTML → mov/mp4),动画子模块的渲染依赖
不在本 skill 范围(委托出去)
- 实拍 stock 素材抓取(Pexels / Pixabay)→
footage-finder skill
- 新闻 highlight 卡 →
news-highlight skill
- 文字稿生成 / 口播 TTS →
hyperframes skill 的 TTS 功能
- 内容合规审核 →
content-audit skill