Files
video-create/.claude/skills/video-from-script/SKILL.md

375 lines
16 KiB
Markdown
Raw Normal View History

---
name: video-from-script
description: 素材生产路由。两类成片A.幻灯片视频(图文成片)— 生图+配音+字幕B.AI视频视频片段成片— 生图+AI视频化+组装,含单图/首尾帧。触发词:做视频、图文成片、图生视频、首尾帧。
---
# 素材生产路由
**你是主 Agent导演。** 子 Agent 执行具体任务,你负责:意图理解 → 编排调度 → 质量卡点 → 用户沟通。
## 两类成片
| 类型 | 成品 | 流程 | 有 AI 视频? |
|------|------|------|-------------|
| **A. 幻灯片视频** | 图片 + 配音 + 字幕 + BGM + 转场 | 分镜 → 生图 → TTS → 组装 | ❌ 无 |
| **B. AI 视频** | 每张图先生成 AI 视频片段,再组装 | 分镜 → 生图 → 生视频 → TTS → 组装 | ✅ 有 |
B 模式又分两种:**单图模式**1 图 → 1 段视频)/ **首尾帧模式**2 图 → 过渡视频)
## 路由规则
| 用户意图 | 对应类型 | 子技能 |
|---------|---------|--------|
| "生图"、"批量图片" | 只生图 | `image-generator` |
| "图文成片"、"幻灯片视频"、"图片轮播" | A. 幻灯片视频 | `image-generator``capcut` |
| "图生视频"、"AI视频"、"图片转视频" | B. AI视频单图 | `image-generator``capcut` |
| "首尾帧"、"帧动画"、"关键帧" | B. AI视频首尾帧 | `image-generator``capcut` |
| "创建账号"、"新账号" | — | 见 [account-creation.md](references/account-creation.md) |
| "修改账号"、"改提示词"、"换风格" | — | 直接编辑 prompts/*.md |
| 只说"做视频" | **追问**:幻灯片视频 / AI视频 | — |
---
## 执行流程
### 核心约束
1. **不可跳步**
- A幻灯片分镜 → manifest init → 图片提示词 → 生图 → TTS+成片。无视频阶段
- BAI视频分镜 → manifest init → 图片提示词 → 生图 → 视频提示词 → 生视频 → TTS+成片
- 阶段之间必须审查
2. **manifest.json 是唯一状态源**`pipeline.js init` 在分镜确认后立即执行,创建 `output/{name}/` 目录和初始 manifest。后续所有子 Agent 输出回写此 manifest不再传裸 JSON
3. **禁止 curl 调 API**:生图/生视频必须通过 `pipeline.js` 或对应 generator 脚本
4. **并行优先**:独立子任务用子 Agent 并行
5. **分镜表是脊骨契约**:用户确认分镜表后,下游子 Agent 只能加字段,禁止改 shot 数量/顺序/字段值。主 Agent 每次接收子 Agent 输出,第一件事数数量是否对得上
6. **prompts/*.md 只被子 Agent 读**:主 Agent 读 account.json不读子 Agent 提示词模板
7. **中间产物落 output**所有中间文件items JSON、urls 缓存、子 Agent 输出)必须写入 `output/{name}/` 目录,禁止散落在项目根目录
### Step -1: 意图确认(逐项确认,缺一不可)
```
1. 成片类型A.幻灯片视频 / B.AI视频
→ AI视频继续追问单图 / 首尾帧?
2. 素材来源:有现成文案/图片/参考图?还是需要 AI 生成?
3. 账号:扫描 accounts/*/account.json → 展示可用账号 → 用户选
→ 未指定让选,不匹配告知并问是否新建
4. 参数:画幅、生图模型、(B 模式)视频模型 — 优先从 account.json 继承
```
→ 5 项确认后,输出执行计划让用户最终确认。用户说"开始"才进入 Step 0。
### Step 0: 前置检查
- 读取 `accounts/{account}/account.json`
- 检查 `prompts/分镜.md``prompts/图片提示词.md``prompts/视频提示词.md` 是否存在
- 缺失 → 按 [account-creation.md](references/account-creation.md) 创建账号 + 生成模板
- `pipeline.js validate-account --account <id>` 校验通过后进入 Step 1
### Step 1: 分镜脚本(子 Agent 执行)
主 Agent 获取账号专属模板路径 → 将**模板文件绝对路径 + 用户文案**传给子 Agent → 子 Agent **自行 Read 模板文件全文** → 按模板规则输出分镜表 JSON
**模板路径获取方式**
```bash
node .claude/skills/video-from-script/scripts/get-template-path.js --account <账号ID> --type storyboard
```
输出示例:`accounts\军事账号\prompts\分镜.md`
**时间线核心规则(固化铁律,必须透传给分镜子 Agent**
- 文案是时间轴唯一锚点:总音频时长 = 文案总字数 ÷ 5语速 5字/秒)
- Kling 可灵视频片段固定 6 秒
- **每个 shot 的 TTS 估算(= script字数÷5必须 ≤ 6 秒**
- TTS > 6s → 强制在语义断点处拆分,拆分后每段 script = 语义子句(原句切分),**禁止用完整句重复填充多 shot**
- 合并后 script 拼接 = 原句一字不差
- audioDur > videoDur × 212s的 shot 禁止合并,必须拆分
**子 Agent prompt 必须包含**
1. `模板文件绝对路径:{get-template-path.js 输出的路径,转为绝对路径}`,并指示子 Agent "先 Read 此文件全文,严格按模板规则执行"
2. 用户完整口播文案
3. 成片模式(图文/视频)
4. 输出格式要求JSON 数组)
**禁止**:主 Agent 不得摘要模板内容传给子 Agent必须让子 Agent 直接读文件。
```json
[{"id":1,"shotDesc":"英文画面描述","script":"中文口播文案","duration":"TTS估算=字数÷5","directorRef":"fincher"}]
```
**主 Agent 审查(时间线合规优先):**
1. 每个 shot 的 TTS 估算是否 ≤ 6s→ 超过必须打回
2. TTS > 6s 的 shot 是否已正确拆分script 是否为语义子句?
3. 时长合理隐性动势完整视频模式directorRef 已填?
4. 视频模式 script 拼接校验通过(一字不差)?
**分镜规划展示(每次必须输出此表):**
```
文案: [原文]
总字数: N字 | 总音频估算: X.Xs | 视频片段: N个 | 视频模型固定时长: Kling=6s
TTS语速: 1.15x(写死在 qwen-tts.js| 音频调速: 禁止 | 视频适配: 加速/截断
| # | TTS估算 | script字数| ratio估算 | 策略 | 拆分说明 | directorRef |
|---|---------|------------|---------|------|---------|------------|
| 1 | 4.8s | 你只有看清了...24字| 6/17.5=0.34 | ⚠禁止 | TTS>6s需拆 | fincher |
| 2 | 5.2s | 其实这是...26字| 6/27=0.22 | ⚠禁止 | TTS>6s需拆 | fincher |
...
```
ratio = estimatedVideoDuration(6s) / estimatedAudioDuration字数÷5
→ 展示给用户确认。确认后**分镜表锁定为脊骨契约**,下游禁止增减 shot。
### Step 2-0: Manifest 初始化
```bash
node scripts/pipeline.js init --account <id> --mode <single|framePair> \
--items '[{"id":1,"shotDesc":"...","script":"...","duration":5,"directorRef":"tarantino","keyword":"权力"}]'
```
- 分镜确认后立即执行,创建 `output/{name}/` 目录和初始 `manifest.json`
- 脚本从 account.json 继承imageModel、videoModel、format、references
- `imagePrompt` 暂为空Step 2-A 补充;`videoPrompt` 暂为空Step 3-A 补充
- 输出路径打印到控制台,后续所有操作以此为工作目录
### Step 2-A: 图片提示词(子 Agent 执行)
- 主 Agent 获取账号专属图片模板路径:`node .../get-template-path.js --account <账号ID> --type image`
- 将**模板文件绝对路径 + manifest 绝对路径**传给子 Agent
- 子 Agent **先 Read 模板文件全文**,再 Read manifest.json 的 items为每个 shot 追加 `imagePrompt` 字段后回写 manifest
- **硬约束:输出 shot 数量 == 输入 shot 数量**
**子 Agent prompt 必须包含**
1. `模板文件绝对路径:{get-template-path.js 输出的路径,转为绝对路径}`,并指示 "先 Read 此文件全文,严格按模板规则执行"
2. `manifest 绝对路径`,指示 "Read manifest.json 的 items 数组,为每个 item 生成 imagePrompt 后回写"
3. **禁止**:主 Agent 不得摘要模板内容传给子 Agent
**主 Agent 审查**:① 数量对得上?② shotDesc 内容完整保留?③ 光影策略对应 directorRef
### Step 2-B: 生图
```bash
node scripts/pipeline.js run --manifest <path> --phase images
```
### Step 2-C: 人工确认(可跳过)
告知图片路径给用户自行查看 → 用户可确认全部 / 替换候选图 / 删除不合格项。
用户确认后 `pipeline.js confirm --manifest <path> --all`,跳过则批量设置 `confirmed=true`
### Step 3-A: 视频提示词B 模式专属,子 Agent 执行)
- 主 Agent 获取账号专属视频模板路径:`node .../get-template-path.js --account <账号ID> --type video`
- 将**模板文件绝对路径 + manifest 绝对路径**传给子 Agent
- 子 Agent **先 Read 模板文件全文**,再 Read manifest.items含已确认分镜图路径为每个 shot 生成 `videoPrompt` 后回写 manifest
- **硬约束:输出数量 == 分镜表 shot 数量**
**子 Agent prompt 必须包含**
1. `模板文件绝对路径:{get-template-path.js 输出的路径,转为绝对路径}`,并指示 "先 Read 此文件全文,严格按模板规则执行"
2. `manifest 绝对路径`,指示 "Read manifest.json 的 items 数组,为每个 item 生成 videoPrompt 后回写"
3. **禁止**:主 Agent 不得摘要模板内容传给子 Agent
**主 Agent 审查**:① 数量对得上?② 描述运动而非内容?③ 字数 ≤ 50
### Step 3-B: 生视频B 模式专属)
```bash
node scripts/pipeline.js run --manifest <path> --phase upload,videos
```
首尾帧模式额外检查过渡连贯性。
### Step 4: TTS + 成片
```bash
node scripts/pipeline.js run --manifest <path> --phase tts,assemble
```
- TTS 使用 script 字段
- 检查字幕准确、BGM 不盖配音
---
## CLI 参考
```bash
# 创建账号
node scripts/pipeline.js create-account --id <id> --name <名称> \
--desc <描述> --video-model veo3-fast --references ./ref1.png,./ref2.png
# 校验账号
node scripts/pipeline.js validate-account --account <id>
# 初始化 manifest
node scripts/pipeline.js init --account <id> --mode <single|framePair> \
--items '[{...}]'
node scripts/pipeline.js init --account <id> --mode single --items-file ./items.json
# 校验 manifest
node scripts/pipeline.js validate --manifest <path>
# 跑指定阶段
node scripts/pipeline.js run --manifest <path> --phase images
node scripts/pipeline.js run --manifest <path> --phase upload,videos
node scripts/pipeline.js run --manifest <path> --phase tts,assemble
# 断点续跑
node scripts/pipeline.js run --manifest <path> --resume
# 确认分镜图
node scripts/pipeline.js confirm --manifest <path> --all
# 查看进度
node scripts/pipeline.js status --manifest <path>
```
**阶段顺序**: `tts``images``upload``videos``assemble`
> **流程变更**TTS 提前到图片生成之前确保音频时长在生图前已知ratio 可控。
**Item 状态**: `pending``generating``done` / `failed`
---
## 质量卡点
每阶段完成后主 Agent 自动校验,不通过则修复后继续。
### 分镜规划展示(每次必须输出)
```
文案: [原文]
总字数: N字 | 总音频估算: X.Xs | 视频片段: N个 | 视频模型: Kling=6s
| # | TTS估算 | script内容字数| 拆分说明 | audioDur估算→真实 | ratio |
|---|---------|----------------|---------|------------------|------|
| 1 | 4.8s | 你只有看清了...24字| ✅未超6s | 4.8→17.5s | 0.34⚠ |
| 2 | 5.2s | 其实这是...26字| ✅未超6s | 5.2→27.0s | 0.22⚠ |
...
```
ratio = estimatedVideoDuration / realAudioDuration⚠=需拆分
### 分镜质量卡点(固化)
| 检查项 | 标准 | 不通过则 |
|--------|------|---------|
| 单 shot TTS 估算 | duration ≤ estimatedVideoDurationKling=6s | **强制打回分镜阶段拆分** |
| 长句处理 | TTS>6s → 语义子句拆分script 不重复完整句 | 打回重写 |
| script 内容 | 每个 shot 的 script 是独立语义子句 | 打回重写 |
| 合并校验 | 所有 script 拼接 = 原文一字不差 | 打回重写 |
| ratio 预判 | estimatedVideoDuration / estimatedAudioDuration < 0.9 → 禁止 | 打回分镜重切 |
| 视频模型时长 | estimatedVideoDuration 已填入 manifest | 检查 pipeline init |
**assemble 阶段铁律:**
- 音频以 1.15x 原速导入 CapCut无 speed 字段
- 视频只允许加速speed_up或截断trim
- **禁止慢放slow_down/ 冻结帧freeze/ 音频调速**
### 生图
| 检查项 | 标准 | 不通过 |
|--------|------|--------|
| 数量 | 与 items 数量匹配 | 补生成失败项 |
### 配音
| 检查项 | 标准 | 不通过 |
|--------|------|--------|
| 音频数量 | 与 items 数量匹配 | 补充或裁剪 |
### AI视频
| 检查项 | 标准 | 不通过 |
|--------|------|--------|
| 视频数量 | 与 items 数量匹配 | 补生成失败项 |
### 成片输出
| 检查项 | 标准 |
|--------|------|
| 字幕准确 | 与原始文案一一对应 |
---
## 目录规范
```
output/{name}_{YYYYMMDD}_{NNN}/
├── manifest.json
├── images/ # scene_{NN}_{slug}.jpeg首尾帧加 _last 后缀)
├── videos/ # scene_{NN}_{slug}.mp4
└── audio/ # seg_001.mp3多句时 seg_{id}_{j}.mp3
```
命名对应:`scene_01_觉醒.jpeg``scene_01_觉醒.mp4`MJ 候选 `scene_01_觉醒_cand1.jpeg`
完整规范见 [batch-mode.md](../image-generator/references/batch-mode.md)。
---
## manifest.json
完整字段规范见 [manifest-schema.md](references/manifest-schema.md)。
核心规则:
- 脚本检测 `lastFrameUrl` → 首尾帧模式;否则 → 单图模式
- 顶层 `format` 自动传给视频模型作为画幅
- `account` 字段驱动 capcut_assemble 读取字幕风格配置
---
## 参考:视频模式
### 单图模式
每条文案生成 1 张图 + 1 个 videoPrompt。Grok、VEO、Kling 都支持。提示词描述运动如 "slow zoom in on subject"。
### 首尾帧模式
每条文案生成 **2 张图**firstFrame + lastFrame+ 1 个 videoPrompt。仅 VEO、Kling 支持。两帧必须是同一场景的不同状态,提示词描述过渡如 "transition from A to B"。
| 对比 | 单图模式 | 首尾帧模式 |
|------|---------|-----------|
| 图片数量 | N 张 | 2N 张 |
| 生图耗时 | 标准 | ~2 倍(可并行) |
| 视频连贯性 | 仅运动 | 场景变化(更强) |
| 可用模型 | Grok + VEO + Kling | VEO + Kling |
| 适用场景 | 风景、人物展示 | 状态变化、叙事过渡 |
---
## 参考:视频模型与降级
| 模型 | 时长 | 画幅 | 单图 | 首尾帧 | 特点 | API |
|------|------|------|------|--------|------|-----|
| Grok | 6s | 任意 | ✅ | ❌ | 快、稳定 | yunwu.ai |
| Veo3-fast | ~8s | 16:9, 9:16 | ✅ | ✅ | 超分、中文增强 | jimmyai.cn |
| Veo3-fast-frames | ~8s | 16:9, 9:16 | ✅ | ✅ | 多帧、质量最高 | jimmyai.cn |
| Kling | 6s | 任意 | ✅ | ✅ | 快、首尾帧支持 | yunwu.ai |
**注意事项**
- 并行提交(并发 3再并行轮询。单视频 60-300 秒,脚本内置 3 次重试
- VEO 独有:`enhance_prompt=true` 中文增强,`enable_upsample=true` 超分
- 同批次同模型,画幅统一跟随 manifest.format
- 个别 item 降级时在 manifest 标记 `videoModel` 以便追踪
**降级链**: `Grok ↔ VEO ↔ Kling`。同一 item 重试 5 次仍失败 → 备用模型补生成 → 上传 OSS → 回写 `videoUrl` → 继续 tts+assemble
---
## 共享资源
- `scripts/` — 生图、生视频、TTS、成片组装、OSS 上传等
- `accounts/` — 账号配置(项目根目录)
- `references/account-system.md` — 账号系统说明
- `skills/config.json` — API 密钥、路径配置
---
## 子技能
| 技能 | 触发词 | 职责 |
|------|--------|------|
| `image-generator` | 生图、批量出图、MJ、Gemini | 图片生成(双模型、单图/帧对) |
| `capcut` | 成片、组装、剪映、图片轮播 | CapCut 成片组装 |