comfyui-shortdramav2 · diff
git:20260901.1507aac to git:20260911.70bf9bb
1 added, 1 removed. Audit A to A.
---
- name: comfyui-shortdrama
+ name: comfyui-shortdramav2
description: 通用短剧批量生成模板:用 ComfyUI + MiniMax H3 Ref2VA 把任意单元短剧剧本(markdown,每段英文 H3 提示词 + <Picture N>/<Audio N> 参考标签)批量转成 15 秒视频片段。任何人准备自己的角色图/声音、填一份 config.json 即可复用"解析 → 映射 → 建工作流 → 入队 → 轮询 → 收集"流水线。
---
# 短剧 Ref2VA 批量自动化(通用模板)
一套可复用的短剧自动化模板:把「分好段的短剧剧本」批量变成「15 秒视频片段」。只靠 ComfyUI HTTP API(`/prompt` + `/history` + `/view`),资产/地址/命名全部走 `config.json`,换剧不换代码。
> 先启动 ComfyUI,再运行脚本。此 Skill 不依赖 MCP,也不会注册或安装
> MCP;没有加载本 Skill 时,仍可用 NaibaChat 的通用 `http_request` 或
> `pwsh`/`comfy` CLI 直接调用 ComfyUI。
## 什么时候用
- 剧本是单元 markdown(`单元0X_*.md`),每段 `## 第N段 …(0–15 秒)`,含 `**H3 提示词**` 的 ` ```text ``` ` 代码块(中文或英文)和 `<Picture N>` / `<Audio N>` 参考标签。
- 要批量生成 15s 片段,且角色形象/音色跨段一致。
- 后端是 ComfyUI + MiniMax H3 Ref2VA。
## 剧本格式要求(脚本按此解析)
解析行为以 `scripts/generate_unit.py` 的 `parse_markdown()` 为准,写剧本时必须满足:
1. **提示词有效内容必须从 `subject_definitions:` 开始**。脚本只提取 ` ```text ` 代码块中从该字段开始到代码块结束的内容;即使代码块前面误放了上传前缀或说明文字,也不会把它们送进 ComfyUI。找不到该字段时会跳过该段。
2. **上传模板前缀(`|本段上传(按此顺序):…|`)必须写在代码块外面**。脚本把 ` ```text ` 块内全部内容原样送进 ComfyUI 提示词框,前缀一旦进块就成了提示词的一部分。
3. **`<Picture N>` / `<Audio N>` 标签必须出现在提示词正文中**(通常在 `subject_definitions` 的 `in <Picture N>` 与 `<Audio N> is …` 行)。脚本靠"标签是否出现在提示词里"决定是否挂载对应槽位;标签只写在前缀里会导致图片/音轨全部不挂载。
4. 段标题需能被识别为提示词段:`## 第N段 …`、`## 片段 NN|…`、`## P0X-N Ref2VA(English)`、`## 二、P0X Ref2VA 六字段版(英文 …)` 等。中文和英文版本都会解析;同一段同时存在两种语言时,运行脚本会让用户选择提交语言。代码块内容从 `subject_definitions:` 开始截取,代码块前或块内误放的“本段上传……”前缀不会送入 ComfyUI。
## 准备(新项目一次性)
1. ComfyUI + MiniMax H3 模型(Ref2VA 扩散模型、Qwen3VL 文本编码器、视频/音频 VAE)。
2. 导入模板 `assets/MiniMaxH3-1采TE加速.json`(脚本按 class_type / ref 槽位自动探测节点,不依赖固定节点 id)。**使用本 Skill 前,先询问用户是否有其他已经跑通的 MiniMaxH3 工作流可以提供;若有,优先以其为准(改用该工作流即可,脚本会自动适配,只需满足下方"换工作流的适配要求")。**
3. 角色定妆图/参考音放进 ComfyUI `input\`。
4. 复制 `config.example.json` → `config.json`,填地址、模板、前缀、图/音映射。
5. 写剧本 markdown(见下)。
## 参考标签 → 槽位映射(关键)
1-based 序号 → 0-based 槽位。**节点 id 不固定**:脚本按 class_type(`MiniMaxH3ReferenceToVideo` / `SaveVideo`)和 `ref_images.*` / `ref_audios.*` 槽位名自动探测模板节点,用户换工作流也能适配。
| 标签 | 槽位 |
|---|---|
| `<Picture 1>` | `ref_images.ref_image_0`("ref 00") |
| `<Picture 2>` | `ref_images.ref_image_1` |
| `<Picture 3>` | `ref_images.ref_image_2` |
| `<Picture 4>` | `ref_images.ref_image_3` |
| `<Picture 5>` | `ref_images.ref_image_4` |
| `<Picture 6>` | `ref_images.ref_image_5` |
| `<Picture 7>` | `ref_images.ref_image_6` |
| `<Picture 8>` | `ref_images.ref_image_7` |
| `<Picture 9>` | `ref_images.ref_image_8` |
| `<Audio 1>` | `ref_audios.ref_audio_0` |
| `<Audio 2>` | `ref_audios.ref_audio_1` |
| `<Audio 3>` | `ref_audios.ref_audio_2` |
自带模板 `assets/MiniMaxH3-1采TE加速.json` 已配好 **9 图槽 + 3 音槽**(`ref_image_0`–`ref_image_8`、`ref_audio_0`–`ref_audio_2`),节点 390–394 为占位图、395 为占位音,跑脚本时会被 config 里的文件名覆盖。
某段提示词出现 `<Picture N>` 且 config 配了文件名才挂对应槽位;没出现的槽位/节点删掉。台词/外貌描述逐字保留。
### 换工作流的适配要求(用户提供其他 MiniMaxH3 工作流时)
新工作流必须是 **API 格式**(`POST /prompt` 提交的 `{节点id: {class_type, inputs}}` JSON,即 ComfyUI「Export (API)」导出的格式),不是 UI 界面导出的 workflow 格式。脚本自动探测,但新工作流必须满足以下结构,否则会报错提示:
- 含 `MiniMaxH3ReferenceToVideo` 节点:提示词写它的 `prompt` 输入(内联字符串),或 `text` 槽位所连的上游文本节点;参考槽位按 `ref_images.ref_image_N` / `ref_audios.ref_audio_N` 命名,加载器(`LoadImage` / `LoadAudio`)直接连到槽位。
- 含 `SaveVideo` 节点:输出文件名前缀写它的 `filename_prefix`。
- 参考槽位数应 ≥ config 里实际用到的 `pictures` / `audios` 最大编号(自带模板 9 图 3 音;模板槽位不够时,超出部分不挂载)。
## config.json 字段
`comfyui_url`、`template_file`、`output_prefix`、`unit_glob`(剧本文件匹配,默认 `单元{unit:02d}_*.md`)、`pictures {"1".."9"}`、`audios {"1".."3"}`。空字符串 = 不启用该槽位。LoadAudio 支持 `.wav`/`.mp3`,文件名必须与 ComfyUI `input\` 一致。
### 按段覆盖映射(segment_pictures / segment_audios)
默认 `pictures`/`audios` 是**整单元一套全局映射**,前提是「角色/音色跨段一致」(同一个编号在每段都指同一资产)。若剧本是**每段各自重新编号**(例如 P05:Picture 3 在段1 是城堡场景、段2 是顾昊、段4 是江归;Audio 1 在段1 是秦西西、段3 是王婉),全局映射会挂错,需要用按段覆盖:
- `segment_pictures`:`{"段号": {"编号": "文件名"}}`,仅覆盖该段对应编号的图槽。
- `segment_audios`:同上,覆盖音槽。
- 未覆盖的编号回退到全局 `pictures` / `audios`。脚本 `seg_cfg()` 按段合并后挂载,build 与 submit 都生效。
示例(P05 实战配置,已实测五段全部挂载正确):
```json
{
"pictures": {
"1": "秦西西(第一套).png",
"2": "于闻闻(第一套).png",
"3": "顾昊(第一套).png",
"4": "王婉(第一章BOSS).png",
"5": "江归(第一套).png"
},
"audios": {
"1": "秦西西.mp3",
"2": "于闻闻.flac",
"3": "王婉.wav"
},
"segment_pictures": {
"1": { "3": "S2_哥特式副本集合大厅(夜).png" },
"2": { "4": "S3_哥特式离婚登记处(惨白) .png", "5": "王婉(第一章BOSS).png" },
"3": { "3": "S3_哥特式离婚登记处(惨白) .png", "4": "王婉(第一章BOSS).png" },
"4": { "3": "江归(第一套).png" },
"5": {}
},
"segment_audios": {
"1": { "1": "秦西西.mp3", "2": "于闻闻.flac" },
"2": {},
"3": { "1": "王婉.wav", "2": "于闻闻.flac" },
"4": { "1": "于闻闻.flac" },
"5": { "1": "秦西西.mp3" }
}
}
```
注意:文件名必须与 ComfyUI `input\` 里的实际文件名**逐字符一致**(含空格,如 `S3_哥特式离婚登记处(惨白) .png` 中 `.png` 前的空格)。
## 脚本(scripts/,先 `cp config.example.json config.json`)
- `generate_unit.py <单元号> [build|submit] [段号...]` — 解析→建 JSON→可选提交+轮询。`build` 只生成不提交。
- `submit_unit.py <单元号> [段号...]` — 读 `0X单元工作流\0X-*.json`,fire-all 入队 + 轮询。
- `fix_audio2.py <单元号> [音轨2文件名]` — 给含 `<Audio 2>` 的段补第二音轨(新脚本已内置,这是兜底)。
脚本与剧本 md、config.json、模板放同目录运行;先设 `PYTHONIOENCODING=utf-8`、`PYTHONUTF8=1`。
## 稳健性
- **先 fire-all 再轮询**:整单元先 POST 进队列再逐个 poll;会话中断/后台任务丢失不影响,ComfyUI 继续跑,恢复后重跑 `submit_unit.py` 或看 `/queue`、`/history`、输出目录。
- 每单元前缀隔离;提交前必查 `GET /system_stats`。
## 已知坑
- 资产缺失先问用户,别用别的音色顶替。
- `<Picture 1>` 必须进 `ref_image_0`("ref 00"),别贴错。
- **剧本若每段重编号(同名标签不同段指不同资产),必须用 `segment_pictures`/`segment_audios` 按段覆盖**,否则全局映射会挂错且不报错。
- 覆盖写 `.py` 可能报 `ReplaceFileW EACCES`;写新文件或对 JSON 后处理绕开。
- ComfyUI v0.33.1 `/models` 返回 list 不是 dict;模型存在性查文件系统。
- `Get-CimInstance Win32_Process` 可能被拒,用 `Get-Process`/`netstat`。
## 校验与交付
- ffprobe 校验时长 ≈ 15.08s、含音视频流。
- 复制到成品目录统一命名 `单元号-段号.mp4`,交付清单写清单元/段数/时长/第二音轨段。