在 `phase-upload` 中添加 `autoFixFile` 逻辑,当 `item.file` 指向不存在的文件时,自动从 `candidates` 中匹配实际存在的文件并更新 `item.file`,避免上传阶段因用户手动换图删除候选文件而导致失败。同时修复 `capcut-timeline` 音频/视频时长计算,使用 `Math.round` 避免微秒级浮点精度问题。
317 lines
13 KiB
Markdown
317 lines
13 KiB
Markdown
---
|
||
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+成片。无视频阶段
|
||
- B(AI视频):分镜 → 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 prompt 必须包含**:
|
||
1. `模板文件绝对路径:{get-template-path.js 输出的路径,转为绝对路径}`,并指示子 Agent "先 Read 此文件全文,严格按模板规则执行"
|
||
2. 用户完整口播文案
|
||
3. 成片模式(图文/视频)
|
||
4. 输出格式要求(JSON 数组)
|
||
|
||
**禁止**:主 Agent 不得摘要模板内容传给子 Agent,必须让子 Agent 直接读文件。
|
||
|
||
```json
|
||
[{"id":1,"shotDesc":"英文画面描述","script":"中文口播文案","duration":5,"directorRef":"tarantino","keyword":"权力"}]
|
||
```
|
||
|
||
**主 Agent 审查**:时长合理?隐性动势完整(视频模式)?directorRef 已填?视频模式 script 拼接校验通过?
|
||
|
||
→ 展示给用户确认。确认后**分镜表锁定为脊骨契约**,下游禁止增减 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>
|
||
```
|
||
|
||
**阶段顺序**: `images` → `upload` → `videos` → `tts` → `assemble`
|
||
|
||
**Item 状态**: `pending` → `generating` → `done` / `failed`
|
||
|
||
---
|
||
|
||
## 质量卡点
|
||
|
||
每阶段完成后主 Agent 自动校验,不通过则修复后继续。
|
||
|
||
### 生图
|
||
|
||
| 检查项 | 标准 | 不通过 |
|
||
|--------|------|--------|
|
||
| 数量 | 与 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 成片组装 |
|