From b6ec208bccf450dd9027de906e023d68e87d57f8 Mon Sep 17 00:00:00 2001 From: sion123 <450702724@qq.com> Date: Fri, 1 May 2026 22:38:43 +0800 Subject: [PATCH] =?UTF-8?q?docs(video-from-script):=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E6=8A=80=E8=83=BD=E6=96=87=E6=A1=A3=E5=B9=B6=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E5=9B=BE=E7=89=87=E7=94=9F=E6=88=90=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 简化并重组 SKILL.md 文档,清晰划分两类成片流程(幻灯片视频/AI视频) - 移除冗余的 ASCII 图表和重复内容,使文档更具可读性 - 更新路由规则和示例,与新的分类标准保持一致 - 重构质量卡点部分,使其更简洁并明确检查标准 - 优化 phase-images.js 中的 MJ 图片生成函数,传递完整的 manifest 对象以供参考 --- .claude/skills/video-from-script/SKILL.md | 510 +++++++----------- .../scripts/lib/phase-images.js | 4 +- accounts/_template/prompts/通用分镜.md | 68 ++- accounts/军事账号/prompts/分镜.md | 68 ++- 4 files changed, 320 insertions(+), 330 deletions(-) diff --git a/.claude/skills/video-from-script/SKILL.md b/.claude/skills/video-from-script/SKILL.md index af08db7..b104d55 100644 --- a/.claude/skills/video-from-script/SKILL.md +++ b/.claude/skills/video-from-script/SKILL.md @@ -1,274 +1,249 @@ --- name: video-from-script -description: 素材生产路由。根据用户意图分发到对应子技能:image-generator(生图)、capcut(成片)。支持单图和首尾帧两种视频模式。触发词:做视频、视频素材、生图+成片、图生视频、首尾帧。 +description: 素材生产路由。两类成片:A.幻灯片视频(图文成片)— 生图+配音+字幕;B.AI视频(视频片段成片)— 生图+AI视频化+组装,含单图/首尾帧。触发词:做视频、图文成片、图生视频、首尾帧。 --- # 素材生产路由 -## 强制规则 +**你是主 Agent(导演)。** 子 Agent 执行具体任务,你负责:意图理解 → 编排调度 → 质量卡点 → 用户沟通。 -1. **工作流不可跳步**:分镜 → 图片提示词 → 生图 → 视频提示词 → 生视频 → TTS+成片。每阶段之间必须审查结果 -2. **manifest.json 是唯一状态源**:任何操作(生图、上传、替换素材)完成后必须立即回写 manifest -3. **禁止 curl 调用生图/生视频 API**:必须通过 `pipeline.js` 或对应 generator 脚本执行 -4. **并行优先**:多个独立子任务必须用子 agent 并行,不要在主对话中串行完成 -5. **prompts/*.md 只被子 Agent 读取**:主 Agent 读 account.json 获取配置信息,不读子 Agent 提示词模板 +## 两类成片 -**禁止**:跳过分镜 / 不更新 manifest 就继续 / 一口气跑完 pipeline 不审查 / 主 Agent 替代子 Agent 生成提示词 +| 类型 | 成品 | 流程 | 有 AI 视频? | +|------|------|------|-------------| +| **A. 幻灯片视频** | 图片 + 配音 + 字幕 + BGM + 转场 | 分镜 → 生图 → TTS → 组装 | ❌ 无 | +| **B. AI 视频** | 每张图先生成 AI 视频片段,再组装 | 分镜 → 生图 → 生视频 → TTS → 组装 | ✅ 有 | ---- - -**你(主 Agent)是整个流程的导演。** 子 Agent 是执行者,你负责:理解意图、编排调度、质量卡点、用户沟通、错误恢复。 - -## 主 Agent 职责 - -| 职责 | 说明 | -|------|------| -| 意图理解 | 分析用户需求,选择正确的模式、视频模型和帧模式 | -| 编排调度 | 决定 Agent 串行/并行、传递参数、收集结果 | -| 质量卡点 | 每个阶段完成后校验结果,不合格则要求子 Agent 重做 | -| 用户沟通 | 汇报进度、请求用户决策(挑选图片、确认风格) | -| 错误恢复 | API 失败时重试或换模型,质量不达标时补生成 | - ---- +B 模式又分两种:**单图模式**(1 图 → 1 段视频)/ **首尾帧模式**(2 图 → 过渡视频) ## 路由规则 -| 用户意图 | 执行流程 | 子技能 | +| 用户意图 | 对应类型 | 子技能 | |---------|---------|--------| -| "生图"、"批量图片" | 生图 | `image-generator` | -| "图片成片"、"图片轮播" | 已有图片 → 组装 | `capcut` | -| "图文成片"、"生图+成片" | 生图 → TTS+字幕+组装 | `image-generator` → `capcut` | -| "图生视频"、"图片转视频" | 生图 → AI视频 → 组装 | `image-generator` → Grok/VEO/Kling → `capcut` | -| "首尾帧"、"帧动画"、"关键帧" | 生图(成对) → 视频过渡 → 组装 | `image-generator`(帧对) → VEO/Kling → `capcut` | -| "文案转视频"、"配音视频" | 生图 → TTS+字幕+组装 | `image-generator` → `capcut` | -| "创建账号"、"新账号" | Q&A 收集信息 → 生成 prompts | 见 [account-creation.md](references/account-creation.md) | -| "修改账号"、"改提示词"、"换风格" | 读取现有 prompt → 确认修改范围 → 重写 | 直接编辑 prompts/*.md | -| 只说"做视频" | **询问**:图文成片 / 图生视频(单图/首尾帧)? | — | - -**"图生视频"的后续追问**:用户说"图生视频"时,追问视频模式: -- **单图模式**:一张图 → 一段视频(Grok / VEO / Kling) -- **首尾帧模式**:起始帧+结束帧 → 一段过渡视频(VEO / Kling) +| "生图"、"批量图片" | 只生图 | `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视频? | — | --- -## Pipeline 执行流程 +## 执行流程 -Agent 创建 manifest.json 后,用 `pipeline.js` 分阶段执行。**不要一口气跑完,必须在阶段之间审查结果。** +### 核心约束 -### 分工 +1. **不可跳步**: + - A(幻灯片):分镜 → 图片提示词 → 生图 → TTS+成片。无视频阶段 + - B(AI视频):分镜 → 图片提示词 → 生图 → 视频提示词 → 生视频 → TTS+成片 + - 阶段之间必须审查 +2. **manifest.json 是唯一状态源**:任何操作完成后立即回写 +3. **禁止 curl 调 API**:生图/生视频必须通过 `pipeline.js` 或对应 generator 脚本 +4. **并行优先**:独立子任务用子 Agent 并行 +5. **分镜表是脊骨契约**:用户确认分镜表后,下游子 Agent 只能加字段,禁止改 shot 数量/顺序/字段值。主 Agent 每次接收子 Agent 输出,第一件事数数量是否对得上 +6. **prompts/*.md 只被子 Agent 读**:主 Agent 读 account.json,不读子 Agent 提示词模板 -| 角色 | 职责 | -|------|------| -| **Agent**(你) | 读取 account.json → **分镜规划** → 图片提示词生成 → 视频提示词生成 → 审查每阶段结果 | -| **Pipeline** | 机械执行:生图 → 上传 → 生视频 → TTS → 成片。每完成一个 item 写盘,支持断点续跑 | - -### 执行步骤 +### Step -1: 意图确认(逐项确认,缺一不可) ``` -Step -1: 意图确认(进入任何步骤前必须完成,逐项确认,缺一不可) +1. 成片类型:A.幻灯片视频 / B.AI视频? + → AI视频继续追问:单图 / 首尾帧? - 1. 内容意图:用户要做什么? - - 生图 / 图生视频 / 图片成片 / 配音视频 / 首尾帧 - - 模糊时追问到明确,不要自己猜 +2. 素材来源:有现成文案/图片/参考图?还是需要 AI 生成? - 2. 素材来源: - - 有现成文案/图片?还是需要 AI 生成文案? - - 有参考图/风格参考? +3. 账号:扫描 accounts/*/account.json → 展示可用账号 → 用户选 + → 未指定让选,不匹配告知并问是否新建 - 3. 视频模式(涉及视频时必问): - - 单图模式:1 张图 → 1 段视频(Grok / VEO / Kling) - - 首尾帧模式:2 张图 → 过渡视频(VEO / Kling) - - 4. 账号确认: - - 扫描 根目录 accounts/*/account.json 获取最新账号列表 - - 展示:ID、名称、风格、画幅 - - 未指定 → 让用户选 - - 指定了但不匹配 → 告知可用账号,问是否新建 - - 确认后记住 account ID - - 5. 参数确认: - - 画幅(9:16 / 16:9)、生图模型(Gemini / MJ)、视频模型(VEO / Grok / Kling) - - 有账号时从 account.json 继承默认值,只问是否覆盖 - - → 以上 5 项全部确认后,agent 写出完整执行计划,让用户最终确认: - - 执行计划示例(根据实际任务调整): - 1. 读取 {account} 账号配置(id = 目录名) - 2. 子 Agent 读取 prompts/分镜.md → 根据用户文案生成分镜表(N shot) - 3. 子 Agent 读取 prompts/图片提示词.md → 为每个 shot 生成 imagePrompt - 4. pipeline.js init → 创建 manifest.json + 输出目录 - 5. pipeline.js run --phase images → 生图 → 人工审查确认(可选) - 6. 子 Agent 读取 prompts/视频提示词.md → 为每个 shot 生成 videoPrompt - 7. pipeline.js run --phase upload,videos → 上传 + 生成视频 - 8. pipeline.js run --phase tts,assemble → TTS + 成片 - - 用户确认 "开始" → 进入 Step 0 - 用户修改 → 调整计划后重新输出 - → 禁止在用户未确认执行计划的情况下进入 Step 0 - -Step 0: 前置检查(账号+提示词模板校验) - - 读取 根目录 accounts/{account}/account.json - - 检查 prompts/ 目录下的提示词模板是否存在(分镜.md、图片提示词.md、视频提示词.md) - - 如果账号不存在或缺少模板: - → 按 [account-creation.md](references/account-creation.md) 的 Q&A 流程创建账号 - → 基于通用模板(`_template/prompts/`)+ 用户回答生成 3 个 prompt 文件 - - 校验账号完整性:`pipeline.js validate-account --account ` - - 全部就绪则继续 Step 1 - -Step 1: 分镜脚本生成(子 Agent 执行) - - 读取 account.json 中的 storyboardPrompt 字段,定位分镜模板文件(如 prompts/分镜.md) - - 主 Agent 将用户文案 + 模板交给子 Agent - - 子 Agent 按模板要求输出分镜表 JSON: - ```json - [{"id":1,"shotDesc":"英文画面描述,40-80词","script":"中文口播文案,≤22字","duration":5,"directorRef":"tarantino","keyword":"权力"}] - ``` - - 主 Agent 审查分镜表(时长合理、隐性动势完整、directorRef 已填) - - 展示给用户确认,确认后进入 Step 2-A - -Step 2-A: 生成图片提示词(子 Agent 执行) - - 读取 account.json 中的 imageStylePrompt 字段,定位图片提示词模板(如 prompts/图片提示词.md) - - 子 Agent 为每个 shot 生成 imagePrompt: - - 入参:shotDesc + script(情绪参考)+ directorRef(光影策略)+ 目标模型 - - 出参:imagePrompt(可直接送给图片模型的英文提示词) - - 主 Agent 审查 imagePrompt 质量(shotDesc 内容完整保留、光影词库对应 directorRef) - -Step 2-B: 生成静态分镜图 + Manifest 初始化 - - 组装 items 并初始化 manifest(**不含 videoPrompt**): - ```bash - node scripts/pipeline.js init --account --mode \ - --items '[{"shotDesc":"...","script":"...","duration":5,"imagePrompt":"...","directorRef":"tarantino","keyword":"权力"}]' - ``` - - 脚本自动从 account.json 继承:imageModel、videoModel、format、references - - 所有 item.confirmed = false - - 生成分镜图:`pipeline.js run --manifest --phase images` - - 参考图在此阶段介入(Gemini 图生图 / MJ --sref) - - 首尾帧模式额外要求:每个 item 必须有 `lastFramePrompt` - -Step 2-C: 人工确认(可选卡点) - - 展示所有分镜图给用户 - - 用户可:确认全部 / 替换 MJ 候选图(改 item.file = item.candidates[N]) / 删除不合格 item / 跳过确认直接继续 - - 用户确认后:`node scripts/pipeline.js confirm --manifest --all` - - 跳过确认时:批量设置 `confirmed = true`,直接进入 Step 3 - -Step 3-A: 生成视频提示词(子 Agent 执行) - - 读取 account.json 中的 videoStylePrompt 字段,定位视频提示词模板(如 prompts/视频提示词.md) - - 子 Agent 为每个 shot 生成 videoPrompt: - - 入参:shotDesc + directorRef(运动策略)+ 已确认的分镜图 + 目标模型 - - 出参:videoPrompt(描述镜头运动的英文提示词) - - Agent 将 videoPrompt 回写到 manifest items(直接编辑 manifest.json 的每个 item) - - 主 Agent 审查 videoPrompt 质量(描述运动而非内容、字数≤50) - -Step 3-B: 生成视频片段 - - 上传 + 生成视频:`pipeline.js run --manifest --phase upload,videos` - - 跳过确认时由 Step 2-C 自动批量设置 confirmed=true - - 首尾帧模式检查过渡连贯性 - -Step 4: TTS + 成片 - - 跑 tts + assemble 阶段:`pipeline.js run --manifest --phase tts,assemble` - - TTS 使用 script 字段(口播旁白) - - 检查字幕准确、BGM 不盖配音 +4. 参数:画幅、生图模型、(B 模式)视频模型 — 优先从 account.json 继承 ``` -> 命令语法见下方「CLI 参考」,不在此处重复。 +→ 5 项确认后,输出执行计划让用户最终确认。用户说"开始"才进入 Step 0。 -### CLI 参考 +### 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 按模板输出分镜表 JSON: + +```json +[{"id":1,"shotDesc":"英文画面描述","script":"中文口播文案","duration":5,"directorRef":"tarantino","keyword":"权力"}] +``` + +**主 Agent 审查**:时长合理?隐性动势完整(视频模式)?directorRef 已填?视频模式 script 拼接校验通过? + +→ 展示给用户确认。确认后**分镜表锁定为脊骨契约**,下游禁止增减 shot。 + +### Step 2-A: 图片提示词(子 Agent 执行) + +- 主 Agent 传**完整分镜表 JSON**(不传原始文案)+ 图片提示词模板路径给子 Agent +- 子 Agent 为每个 shot 追加 `imagePrompt` 字段: + - 入参(来自分镜表):shotDesc + script + directorRef + keyword + - 出参:分镜表 JSON + imagePrompt +- **硬约束:输出 shot 数量 == 输入 shot 数量** + +**主 Agent 审查**:① 数量对得上?② shotDesc 内容完整保留?③ 光影策略对应 directorRef? + +### Step 2-B: 生图 + Manifest 初始化 ```bash -# 创建账号(Step 0:首次使用时) +node scripts/pipeline.js init --account --mode \ + --items '[{"shotDesc":"...","script":"...","duration":5,"imagePrompt":"...","directorRef":"tarantino","keyword":"权力"}]' +``` + +- items 不含 videoPrompt,后续 Step 3-A 补充 +- 脚本从 account.json 继承:imageModel、videoModel、format、references +- 首尾帧模式:每个 item 必须有 `lastFramePrompt` + +```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 传分镜表 JSON(含已确认分镜图路径)+ 视频提示词模板路径给子 Agent +- 子 Agent 为每个 shot 生成 `videoPrompt`: + - 入参:shotDesc + directorRef + 已确认分镜图 + 目标模型 + - 出参:videoPrompt(描述镜头运动,非画面内容) +- **硬约束:输出数量 == 分镜表 shot 数量** +- Agent 按 id 对齐回写 manifest.json + +**主 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(Step 2-B 使用,AI 只提供创意内容,不含 videoPrompt) +# 初始化 manifest node scripts/pipeline.js init --account --mode \ - --items '[{"shotDesc":"...","script":"...","duration":5,"imagePrompt":"...","directorRef":"tarantino","keyword":"权力"}]' -# 也可从文件读取 items(适合大量数据) + --items '[{...}]' node scripts/pipeline.js init --account --mode single --items-file ./items.json -# 校验 manifest 完整性 +# 校验 manifest node scripts/pipeline.js validate --manifest -# 人工确认分镜图(Step 2-C,可选:跳过时 Agent 批量设置 confirmed=true) -node scripts/pipeline.js confirm --manifest --all - # 跑指定阶段 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 -# 断点续跑(跳过已完成阶段和 item) +# 断点续跑 node scripts/pipeline.js run --manifest --resume +# 确认分镜图 +node scripts/pipeline.js confirm --manifest --all + # 查看进度 node scripts/pipeline.js status --manifest ``` -**阶段**: `images` → `upload` → `videos` → `tts` → `assemble` +**阶段顺序**: `images` → `upload` → `videos` → `tts` → `assemble` -**Manifest item 状态**: `pending` → `generating` → `done` / `failed`。无 status 字段视为 pending。 +**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 读取字幕风格配置 + +--- + +## 参考:视频模式 ### 单图模式 -```dot -digraph single_image { - rankdir=LR - node [shape=box, style=filled, fillcolor="#f5f5f5", fontsize=11] - - img [label="一张图", shape=oval] - prompt [label="videoPrompt"] - grok [label="Grok\n6s 视频", fillcolor="#fff3e0"] - veo [label="VEO\n6-8s 视频", fillcolor="#e8f5e9"] - kling [label="Kling\n6s 视频", fillcolor="#e1f5fe"] - result [label="视频输出", shape=oval, fillcolor="#e3f2fd"] - - img -> prompt - prompt -> grok - prompt -> veo - prompt -> kling - grok -> result - veo -> result - kling -> result -} -``` - -- 每条文案生成 1 张图 + 1 个 videoPrompt -- Grok、VEO 和 Kling 都支持 -- 提示词描述运动:"slow zoom in on subject" +每条文案生成 1 张图 + 1 个 videoPrompt。Grok、VEO、Kling 都支持。提示词描述运动如 "slow zoom in on subject"。 ### 首尾帧模式 -```dot -digraph frame_pair { - rankdir=LR - node [shape=box, style=filled, fillcolor="#f5f5f5", fontsize=11] - - first [label="起始帧"] - last [label="结束帧"] - prompt [label="videoPrompt"] - veo [label="VEO\n6-8s 过渡视频", fillcolor="#e8f5e9"] - kling [label="Kling\n6s 过渡视频", fillcolor="#e1f5fe"] - result [label="视频输出", shape=oval, fillcolor="#e3f2fd"] - - first -> veo - last -> veo - prompt -> veo - first -> kling - last -> kling - prompt -> kling - veo -> result - kling -> result -} -``` - -- 每条文案生成 **2 张图**(firstFrame + lastFrame)+ 1 个 videoPrompt -- **VEO 和 Kling 支持**(images 数组传两张图) -- 起始帧和结束帧必须是**同一场景的不同状态** -- 提示词描述过渡:"transition from idle machines to active production" +每条文案生成 **2 张图**(firstFrame + lastFrame)+ 1 个 videoPrompt。仅 VEO、Kling 支持。两帧必须是同一场景的不同状态,提示词描述过渡如 "transition from A to B"。 | 对比 | 单图模式 | 首尾帧模式 | |------|---------|-----------| @@ -280,9 +255,7 @@ digraph frame_pair { --- -## 视频模型与执行策略 - -### 视频模型选择 +## 参考:视频模型与降级 | 模型 | 时长 | 画幅 | 单图 | 首尾帧 | 特点 | API | |------|------|------|------|--------|------|-----| @@ -291,113 +264,22 @@ digraph frame_pair { | Veo3-fast-frames | ~8s | 16:9, 9:16 | ✅ | ✅ | 多帧、质量最高 | jimmyai.cn | | Kling | 6s | 任意 | ✅ | ✅ | 快、首尾帧支持 | yunwu.ai | -### 视频生成注意事项 - -- **并行执行**:先同时提交所有任务(并发 3),再并行轮询结果 -- 单个视频生成耗时 60-300 秒 -- 脚本内置 3 次重试,每次自动简化提示词 +**注意事项**: +- 并行提交(并发 3),再并行轮询。单视频 60-300 秒,脚本内置 3 次重试 - VEO 独有:`enhance_prompt=true` 中文增强,`enable_upsample=true` 超分 -- 配置在 `config.json` +- 同批次同模型,画幅统一跟随 manifest.format +- 个别 item 降级时在 manifest 标记 `videoModel` 以便追踪 -### 视频大小一致性 - -- **同批次同模型**,不混合 Grok(720P/6s)、VEO(超分/8s)和 Kling(6s) -- 画幅统一跟随 manifest 顶层 `format`(默认 `9:16`) -- 个别 item 降级到备用模型时,在 manifest 中标记 `"videoModel"` 以便追踪 - -### 视频生成失败降级 - -**降级链**: `Grok ↔ VEO ↔ Kling` - -**触发**: 同一 item 重试 5 次仍失败 → 用备用模型单独补生成 - -```bash -# Grok 失败 → VEO/Kling 补 -node veo-video-generator.js --image --prompt -o ./videos -node kling-video-generator.js --image --prompt -o ./videos - -# VEO 失败 → Grok/Kling 补 -node grok-video-generator.js --image --prompt -o ./videos -node kling-video-generator.js --image --prompt -o ./videos -``` - -**规则**: 逐 item 降级,不卡整批次。补完后上传 OSS,回写 `videoUrl`,继续 `tts → assemble`。 - ---- - -## 目录规范 - -所有批次的输出遵循统一目录结构。完整规范见 [batch-mode.md](../image-generator/references/batch-mode.md) 的"目录规范"章节。 - -**核心规则**: - -``` -output/{name}_{YYYYMMDD}_{NNN}/ -├── manifest.json # 主清单(贯穿全流程) -├── images/ # scene_{NN}_{slug}.jpeg(slug 从 script/shotDesc 派生,首尾帧加 _last 后缀) -├── videos/ # scene_{NN}_{slug}.mp4(与图片对应) -└── audio/ # seg_001.mp3(TTS 分句音频,多句时 seg_{id}_{j}.mp3) -``` - -**命名对应关系**:图片 `scene_01_觉醒.jpeg` → 视频 `scene_01_觉醒.mp4`;首尾帧尾帧 `scene_01_觉醒_last.jpeg`;MJ 候选 `scene_01_觉醒_cand1.jpeg` - ---- - -## manifest.json 格式 - -完整字段规范见 [manifest-schema.md](references/manifest-schema.md)(字段权重 P0/P1/P2、读写方、流转关系)。 - -**核心规则**: -- 脚本检测 `lastFrameUrl` → 首尾帧模式(传 images:[url, lastFrameUrl]);否则 → 单图模式(传 images:[url]) -- 顶层 `format` 自动传给 VEO/Grok/Kling 作为画幅比例 -- `account` 字段驱动 capcut_assemble 读取对应 account.json 的字幕风格配置 - ---- - -## 质量卡点(Agent 可执行) - -每个阶段完成后 Agent 自动校验,不通过的自动修复。需要人工视觉判断的(画质、动画、BGM等)由用户在人工审查步骤处理。 - -### 生图 卡点 - -| 检查项 | 标准 | 不通过处理 | -|--------|------|-----------| -| 图片分辨率 | 短边 >= 1024px | 重新生成 | -| 画幅比例 | 与 manifest.format 一致 | 重新生成 | -| 数量 | 与 items 数量匹配 | 补充生成失败项 | - -### 配音 卡点 - -| 检查项 | 标准 | 不通过处理 | -|--------|------|-----------| -| 音频时长 | 与素材总时长相近(±20%) | 调整语速或素材时长 | -| 音频数量 | 与 items 数量匹配 | 补充或裁剪 | - -### AI视频 卡点 - -| 检查项 | 标准 | 不通过处理 | -|--------|------|-----------| -| 视频数量 | 与 items 数量匹配 | 补充生成失败项 | - -### 成片输出 卡点 - -| 检查项 | 标准 | -|--------|------| -| 字幕准确 | 与原始文案一一对应 | - -**卡点不通过自动修复后再进入下一阶段。** +**降级链**: `Grok ↔ VEO ↔ Kling`。同一 item 重试 5 次仍失败 → 备用模型补生成 → 上传 OSS → 回写 `videoUrl` → 继续 tts+assemble --- ## 共享资源 -所有子技能共享以下资源(位于本目录): - -- `scripts/` — 共享脚本(生图、生视频、TTS、成片组装、同步剪映、OSS 上传等) -- `accounts/` — 账号配置(项目根目录,详见 [account-system.md](references/account-system.md)) +- `scripts/` — 生图、生视频、TTS、成片组装、OSS 上传等 +- `accounts/` — 账号配置(项目根目录) - `references/account-system.md` — 账号系统说明 - -配置统一在 `skills/config.json`(API密钥、路径)。 +- `skills/config.json` — API 密钥、路径配置 --- diff --git a/.claude/skills/video-from-script/scripts/lib/phase-images.js b/.claude/skills/video-from-script/scripts/lib/phase-images.js index 2273c13..fd3018f 100644 --- a/.claude/skills/video-from-script/scripts/lib/phase-images.js +++ b/.claude/skills/video-from-script/scripts/lib/phase-images.js @@ -49,7 +49,7 @@ async function phaseImages(manifest, manifestPath, options) { if (model === 'gemini') { result = await generateGemini(item, idx, dir, imagesDir, ratio, refs) } else if (model === 'mj') { - result = await generateMJ(item, idx, dir, imagesDir, ratio, refs, manifestPath) + result = await generateMJ(item, idx, dir, imagesDir, ratio, refs, manifest, manifestPath) } else if (model === 'kling') { result = await generateKling(item, idx, dir, imagesDir, ratio, refs) } else { @@ -116,7 +116,7 @@ async function generateGemini(item, idx, dir, imagesDir, ratio, refs) { return { file } } -async function generateMJ(item, idx, dir, imagesDir, ratio, refs, manifestPath) { +async function generateMJ(item, idx, dir, imagesDir, ratio, refs, manifest, manifestPath) { const { MJApi, ImageUtils } = require('../mj-image-generator') const referenceImages = refs.urls.length > 0 ? refs.urls : [] const styleWeight = 200 diff --git a/accounts/_template/prompts/通用分镜.md b/accounts/_template/prompts/通用分镜.md index 119736c..cca2060 100644 --- a/accounts/_template/prompts/通用分镜.md +++ b/accounts/_template/prompts/通用分镜.md @@ -82,9 +82,11 @@ source outside the frame begins its slow rotation ## 四、切割规则 -### 4.1 切割优先级 +切割分两层:第一层按语义场景做宏观切分(两种模式通用),第二层按气口做微观切分(视频成片专用)。 -以「语义场景单元」为第一切割依据,不按句号机械切割。 +### 4.1 第一层:语义场景切割(两种模式通用) + +以语义场景转折为切割依据,不按句号机械切割。 | 切割信号 | 判断标准 | |----------|---------| @@ -92,10 +94,57 @@ source outside the frame begins its slow rotation | 场景转换 | 叙述空间或时间发生变化 | | 主体变化 | 叙述对象或视角切换 | | 节奏重音 | 强调句、停顿感强、关键意象出现 | -| 语义完整 | 该段表达一个完整观点或例子 | -| 字数上限 | 视频成片每段 22 字左右;图文成片每段 50 字左右 | +| 语义完整(仅图文) | 该段表达一个完整观点或例子 | -### 4.2 时长控制 +### 4.2 第二层:气口切割(视频成片专用) + +**视频成片在完成语义场景切割后,必须在每个语义场景内部进行第二轮气口切割。** + +核心法则:以朗读时的自然换气停顿(气口)为切割点,将长句拆为多个连续 Shot。每个 Shot 的 `script` 是原文在该气口的**逐字截取片段**——不是摘要、不是改写、不是提炼。连续 Shot 的 `script` 拼接后必须完整还原原句,一字不落。 + +**气口即切割点:** +- 逗号(,)— 第一优先切割点 +- 自然停顿 — 朗读时逻辑换气处 +- 从句边界 — "当……的时候""不是……而是""因为……所以"的分界处 +- 禁止在词语中间切割 + +**字数约束:** +- 单段 8–22 字。目标 15–18 字(最舒适的朗读气口) +- 超过 22 字的从句,继续在下一个逗号处切开 +- 不足 8 字的碎片合并到相邻段 + +**连续关系处理:** +- 同属一个原句的连续 Shot,`directorRef` 保持同一位导演,画面构图持续递进 +- 连续从句 Shot 的 `keyword` 可选填,只在完整句的最后一个 Shot 必填,避免花字过密 +- 相邻帧允许同景别(视频运动本身提供变化) + +**示例——原文 52 字长句:** + +> 原文:「当你开始把别人的评价体系当作自己的坐标系,你已经把人生方向盘交给了后排乘客。」 + +正确切割: + +| Shot | script | 字数 | +|------|--------|------| +| N | 当你开始把别人的评价体系, | 12 | +| N+1 | 当作自己的坐标系, | 9 | +| N+2 | 你已经把人生方向盘交给了后排乘客。 | 16 | + +→ 三个 script 拼接 = 完整原文,连标点都不少。 + +**禁止行为:** +- ❌ 把 52 字原句摘要成一句 22 字的改写 +- ❌ 丢弃原文的论证、例子、细节来"节省字数" +- ❌ 跨语义场景合并——气口切割只在同一个语义场景内部进行 + +### 4.3 字数上限速查 + +| 模式 | 每段字数 | 说明 | +|------|---------|------| +| 图文成片 | 50 字左右 | 一帧讲透一个观点 | +| 视频成片 | 8–22 字 | 气口自然长度,长句必须拆为连续 Shot | + +### 4.4 时长控制 - **图文成片:** 每条 Shot 4-10 秒,跟随旁白节奏,完整表达一个观点 - **视频成片:** 每条 Shot 3-7 秒,目标 5 秒,匹配视频片段长度 @@ -325,7 +374,7 @@ undone ``` **字段说明**: -- `script`:该段的**完整原文逐字摘取,一字不改**。原文怎么写就怎么贴,禁止改写、提炼、摘要、概括、换词 +- `script`:该段的**原文逐字摘取,一字不改**。原文怎么写就怎么贴,禁止改写、提炼、摘要、概括、换词。**视频模式:长句必须拆为 N 个连续 Shot,每个 Shot 的 script 是该句在该气口的逐字片段——所有连续 Shot 的 script 按顺序拼接后,必须等于原始口播文案的完整句,连标点符号都不能少一个。** - `keyword`:该段的**氛围关键词**(可选),2-6 个字,以花字效果叠加在画面中央增强冲击力。提炼该段最核心的意象/概念,偏向名词或动名词,有画面感。无合适关键词时省略该字段 ## 九、启动指令与自检 @@ -347,8 +396,13 @@ undone > 如果这帧图片喂给视频模型,它知道往哪个方向动吗? > 答案是「不知道」→ **重写** +**视频成片文本完整性自检(输出完整 JSON 后必做):** + +> 把所有 shot 的 `script` 按 id 顺序拼接,等于原始口播文案吗? +> 答案是「不等于」→ **重做气口切割,禁止摘要** + **其他规则:** - `directorRef` 必须填写,不得为空,下游依赖此字段执行风格 -- 按语义单元切割,每段表达一个完整观点或例子 +- **视频成片:每个 shot 不要求表达完整观点,气口片段即可;连续 shot 拼接后才构成完整语义** - 若用户未提供完整口播文案,提示补充,不得凭空生成 diff --git a/accounts/军事账号/prompts/分镜.md b/accounts/军事账号/prompts/分镜.md index 760074e..2efc6e0 100644 --- a/accounts/军事账号/prompts/分镜.md +++ b/accounts/军事账号/prompts/分镜.md @@ -186,9 +186,11 @@ the geometry did. ## 七、切割规则 -### 6.1 切割优先级 +切割分两层:第一层按语义场景做宏观切分(两种模式通用),第二层按气口做微观切分(视频成片专用)。 -以「语义场景单元」为第一切割依据,不按句号机械切割。 +### 7.1 第一层:语义场景切割(两种模式通用) + +以语义场景转折为切割依据,不按句号机械切割。 | 切割信号 | 判断标准 | |---------|---------| @@ -196,10 +198,57 @@ the geometry did. | 场景转换 | 叙述空间或时间发生变化 | | 主体变化 | 叙述对象或视角切换 | | 节奏重音 | 强调句、停顿感强、关键意象出现 | -| 语义完整 | 该段表达一个完整观点或例子 | -| 字数上限 | 视频成片每段 22 字左右;图文成片每段 50 字左右 | +| 语义完整(仅图文) | 该段表达一个完整观点或例子 | -### 6.2 时长控制 +### 7.2 第二层:气口切割(视频成片专用) + +**视频成片在完成语义场景切割后,必须在每个语义场景内部进行第二轮气口切割。** + +核心法则:以朗读时的自然换气停顿(气口)为切割点,将长句拆为多个连续 Shot。每个 Shot 的 `script` 是原文在该气口的**逐字截取片段**——不是摘要、不是改写、不是提炼。连续 Shot 的 `script` 拼接后必须完整还原原句,一字不落。 + +**气口即切割点:** +- 逗号(,)— 第一优先切割点 +- 自然停顿 — 朗读时逻辑换气处 +- 从句边界 — "当……的时候""不是……而是""因为……所以"的分界处 +- 禁止在词语中间切割 + +**字数约束:** +- 单段 8–22 字。目标 15–18 字(最舒适的朗读气口) +- 超过 22 字的从句,继续在下一个逗号处切开 +- 不足 8 字的碎片合并到相邻段 + +**连续关系处理:** +- 同属一个原句的连续 Shot,`directorRef` 保持同一位导演,画面构图持续递进 +- 连续从句 Shot 的 `keyword` 可选填,只在完整句的最后一个 Shot 必填,避免花字过密 +- 相邻帧允许同景别(视频运动本身提供变化) + +**示例——原文 52 字长句:** + +> 原文:「当你开始把别人的评价体系当作自己的坐标系,你已经把人生方向盘交给了后排乘客。」 + +不对。正确切割: + +| Shot | script | 字数 | +|------|--------|------| +| N | 当你开始把别人的评价体系, | 12 | +| N+1 | 当作自己的坐标系, | 9 | +| N+2 | 你已经把人生方向盘交给了后排乘客。 | 16 | + +→ 三个 script 拼接 = 完整原文,连标点都不少。 + +**禁止行为:** +- ❌ 把 52 字原句摘要成一句 22 字的改写 +- ❌ 丢弃原文的论证、例子、细节来"节省字数" +- ❌ 跨语义场景合并——气口切割只在同一个语义场景内部进行 + +### 7.3 字数上限速查 + +| 模式 | 每段字数 | 说明 | +|------|---------|------| +| 图文成片 | 50 字左右 | 一帧讲透一个观点 | +| 视频成片 | 8–22 字 | 气口自然长度,长句必须拆为连续 Shot | + +### 7.4 时长控制 - **图文成片:** 每条 Shot 4-10 秒,跟随旁白节奏,完整表达一个观点 - **视频成片:** 每条 Shot 3-7 秒,目标 5 秒,匹配视频片段长度 @@ -352,7 +401,7 @@ something that cannot be undone ``` **字段说明**: -- `script`:该段的**完整原文逐字摘取,一字不改**。原文怎么写就怎么贴,禁止改写、提炼、摘要、概括、换词。包含论证、例子、细节,不是金句 +- `script`:该段的**原文逐字摘取,一字不改**。原文怎么写就怎么贴,禁止改写、提炼、摘要、概括、换词。包含论证、例子、细节,不是金句。**视频模式:长句必须拆为 N 个连续 Shot,每个 Shot 的 script 是该句在该气口的逐字片段——所有连续 Shot 的 script 按顺序拼接后,必须等于原始口播文案的完整句,连标点符号都不能少一个。** - `keyword`:该段的**氛围关键词**,2-6 个字,以花字效果叠加在画面中央增强冲击力。规则: - 提炼该段最核心的意象/概念,不是复述文案 - 偏向名词或动名词,有画面感:"权力""沉默""位置""逐帧拆""审视" @@ -476,5 +525,10 @@ something that cannot be undone > 如果这帧图片喂给视频模型,它知道往哪个方向动吗? > 答案是「不知道」→ **重写** +**视频成片文本完整性自检(输出完整 JSON 后必做):** + +> 把所有 shot 的 `script` 按 id 顺序拼接,等于原始口播文案吗? +> 答案是「不等于」→ **重做气口切割,禁止摘要** + directorRef 必须填写,不得为空,下游依赖此字段执行风格 -按语义单元切割,每段表达一个完整观点或例子 +**视频成片:每个 shot 不要求表达完整观点,气口片段即可;连续 shot 拼接后才构成完整语义**