--- 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 ` 校验通过后进入 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 × 2(12s)的 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 --mode \ --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 --phase images ``` ### Step 2-C: 人工确认(可跳过) 告知图片路径给用户自行查看 → 用户可确认全部 / 替换候选图 / 删除不合格项。 用户确认后 `pipeline.js confirm --manifest --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 --phase upload,videos ``` 首尾帧模式额外检查过渡连贯性。 ### Step 4: TTS + 成片 ```bash node scripts/pipeline.js run --manifest --phase tts,assemble ``` - TTS 使用 script 字段 - 检查字幕准确、BGM 不盖配音 --- ## CLI 参考 ```bash # 创建账号 node scripts/pipeline.js create-account --id --name <名称> \ --desc <描述> --video-model veo3-fast --references ./ref1.png,./ref2.png # 校验账号 node scripts/pipeline.js validate-account --account # 初始化 manifest node scripts/pipeline.js init --account --mode \ --items '[{...}]' node scripts/pipeline.js init --account --mode single --items-file ./items.json # 校验 manifest node scripts/pipeline.js validate --manifest # 跑指定阶段 node scripts/pipeline.js run --manifest --phase images node scripts/pipeline.js run --manifest --phase upload,videos node scripts/pipeline.js run --manifest --phase tts,assemble # 断点续跑 node scripts/pipeline.js run --manifest --resume # 确认分镜图 node scripts/pipeline.js confirm --manifest --all # 查看进度 node scripts/pipeline.js status --manifest ``` **阶段顺序**: `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 ≤ estimatedVideoDuration(Kling=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 成片组装 |