# 25 秒竖屏对口型唱歌视频 — 调研结论与实施方案

> 生成日期：2026-09-04 ｜ 任务文件夹：`dl-hub/用户上传/25S任务/`
> 素材：人物三视图（1792×1008 横向）+ 参考视频（720×1280 竖屏，25.33s，H.264+AAC 44.1kHz 立体声）

---

## 一、任务理解

| 需求 | 说明 |
|---|---|
| 成片规格 | 竖屏（9:16）25s 对口型唱歌视频 |
| 音频 | 只取参考视频的音频（**audio-only**），音频不做任何改动 |
| 人物 | 三视图角色，全程**怼脸直拍**（close-up） |
| 表情 | 全程**哀怨忧伤**，有美感的忧伤感，不是死皱着眉头 |
| 动作 | 身体和头部随音乐**轻微晃动**，简单即可 |
| 技术限制 | MiniMax H3 超 15s 会严重漂移 → 分 **12s + 13s** 两段生成后拼接 |
| 拼接保真 | 需要把第一段视频的**末尾二十多帧**作为第二段输入，保障画面不脱节 |

---

## 二、调研结论（关键事实，全部已核实）

### 2.1 两个 "MiniMaxH3Director" 不是同一个类（回答疑问）

GPU 机上装了**两个包，各自内嵌了不同的 Director 实现**，同名注册冲突才需要别名区分：

| 包 | 注册名 | 指向类 | 行数 | 说明 |
|---|---|---|---|---|
| `ComfyUI-DaSiWa-Nodes`（DaSiWa，V18 用的） | `MiniMaxH3Director` + `DaSiWaMiniMaxH3DirectorLegacy` | 自己的 `nodes/nodes_minimax_h3_director.py` | 227 | **支持 video/audio timeline items**，`media_mode` 三态 |
| `ComfyUI_MiniMaxH3_Director`（官方 AIMixer 多段版） | `MiniMaxH3Director` + `ComfyMiniMaxH3Director` | 自己的 `nodes/director.py` | 291 + 多模块 | 多段 timeline、内建段间引导 |

- 同名 `MiniMaxH3Director` 由两个包都注册，ComfyUI 按加载顺序后注册者覆盖；所以各自都留了**别名**保住自己的实现：DaSiWa 用 `DaSiWaMiniMaxH3DirectorLegacy`，官方用 `ComfyMiniMaxH3Director`。
- **V18 模板（`v18_api_template.json`）里 2730 节点的 class_type 正是 `DaSiWaMiniMaxH3DirectorLegacy`** —— 即 V18 实际调用的是 **DaSiWa 版（227 行）**。它已支持：
  - REF2VA 模式，timeline_data items 支持 `type: image / video / audio`
  - 视频 item 的 `media_mode` 三态：`video`（只要画面帧）/ `audio`（**只取内嵌音轨，不要画面帧 = audio-only**）/ `video_audio`（两者都要）
  - 参考限制：图 ≤9、视频 ≤3、音频 ≤3、共 ≤12 文件；**视频参考总时长 ≤15s、音频参考总时长 ≤15s**；纯音频必须有图/视频伴随

### 2.2 用户的三个关键技术点都有对应机制

| 需求 | 机制（已核实源码） |
|---|---|
| **audio-only**（只用参考视频的音频） | DaSiWa Director timeline item：`type:"video", media_mode:"audio"` 即只解码内嵌音轨（`load_embedded_video_audio`），或独立 `type:"audio"` item（`load_audio`）。原生节点 `MiniMaxH3ReferenceToVideo` 的 `ref_audios` 输入承接 |
| **末帧续接**（第一段末 20 多帧作为第二段输入） | 原生 `MiniMaxH3ReferenceToVideo` 支持 `ref_videos`（2-15s 视频参考帧，解码为 24fps 帧批传给模型）。把第一段输出视频（或其末段 ~1-2s 裁剪）作为第二段的 `<Video 1>` 参考，模型据此延续画面。**这即是"导演台"末帧续接在 V18 上的等价实现** |
| **分段硬约束** | ① H3 单次生成训练范围 124-362 帧 ≈ **5-15s**（12s/13s 分段正确）；② 音频参考总时长 **≤15s** —— 25s 音频一次传不完，**12+13 分段天然满足**每段音频参考 ≤15s；③ 每段参考视频 2-15s 内 |

### 2.3 官方多段版（用户记忆中的"导演台"）现状

`ComfyUI_MiniMaxH3_Director`（官方多段版）确实内建了真正的**段间引导**：
- `director/h3_motion_context.py`：`DEFAULT_CONTEXT_FRAMES = 22`（正是"二十多帧"），`CONTEXT_FRAME_CHOICES = (5, 22, 39, 56)`
- `director/segment_continuity.py`：将上一段 AV 尾部 pin 进下一段 conditioning，再 trim 前缀
- 官方工作流已放 GPU 机：`minimax_h3_director_rv2v.json` / `v2v.json` / `r2v.json` 等（2026-09-02 放入 workflows 目录），timeline v4 含 `segments` 数组、`continuityEnabled` / `continuityOverlapFrames` 字段

**但注意**：官方包是否在 GPU 机上完整跑通**尚未验证**（history 目录无官方版节点记录、无该包输出样例）。直接上官方多段版有风险，需要先冒烟测试。

### 2.4 V18 模板现状

- 节点 2730（`DaSiWaMiniMaxH3DirectorLegacy`）：`mode=REF2VA`、`width=736`、`height=1280`（竖屏）、`duration=12`
- `timeline_data` 目前只填 image items → **需扩展支持 video/audio items**（改动点见下）
- 输出链 `DaSiWa_EnhancedVideoCombine` 带 `audio` 输入（1512:2675），输出 `xxx_audio.mp4`

---

## 三、推荐方案：V18 管线两段生成 + ffmpeg 拼接（路线 A）

在已跑通的 V18 管线上做最小扩展，风险最低、链路全部已验证。

### 3.1 总体流程

```
素材准备
 ├─ 三视图 → h3-turnaround-autoprep 裁正面视图（Picture 1）+ 完整三视图（Picture 2）
 ├─ 参考视频 → 上传 GPU 机 input（视频本身作为音频源，media_mode=audio）
 └─ 音频切分：0-12s（第一段）、12-25s（第二段）—— 由 timeline item 的 trim 实现，音频本体不改动

第一段生成（12s，REF2VA）
 ├─ 参考：Picture 1（正面）+ Picture 2（三视图）+ Audio 1（参考视频音轨 0-12s，media_mode=audio）
 ├─ 分辨率 736×1280（竖屏）｜时长 12s｜seed 固定记录
 └─ 输出：seg1.mp4

拼接准备
 └─ 从 seg1.mp4 裁剪末段（如最后 1-2s，24-48 帧）→ tail.mp4（作为第二段的 <Video 1> 视觉参考）
    （也可直接用整个 seg1.mp4 作为参考，12s ≤ 15s 合规；末段裁剪更省算力）

第二段生成（13s，REF2VA）
 ├─ 参考：Picture 1 + Picture 2 + Video 1（tail.mp4，media_mode=video）+ Audio 1（音轨 12-25s，media_mode=audio）
 ├─ 提示词：`[video continuation]` 前缀 + "continue from the end of <Video 1>，keep the same camera、face、expression"
 ├─ 分辨率 736×1280｜时长 13s｜seed 固定记录
 └─ 输出：seg2.mp4

拼接（ffmpeg）
 └─ concat seg1 + seg2（同分辨率同帧率）→ final 25s.mp4
```

### 3.2 代码改动点（`~/Downloads/dasiwa-h3-research/v18_pipeline.py`）

在 `build_v18_prompt()` 里扩展 timeline_data 构造，支持三种 item：

```python
# 图片 item（现有）
{"type": "image", "value": "<input目录文件名>", "slot": i, "order": i, ...}

# 视频 item（含 audio-only 与纯视觉两种用法）
{
  "type": "video",
  "value": "<上传到input的mp4文件名>",
  "media_mode": "audio",          # audio=只取音轨（audio-only）| video=只要帧 | video_audio=都要
  "trim_start": 0.0, "trim_end": 12.0,   # 音频/视频裁剪区间
  "duration": 12.0,
  "order": n, "slot": n,
}

# 音频 item（可选，独立音频文件时用）
{"type": "audio", "value": "audio_seg.wav", "trim_start": 0.0, "trim_end": 12.0, ...}
```

- 第一段 timeline items：`[Picture1, Picture2, 视频item(media_mode=audio, 0-12s)]`
- 第二段 timeline items：`[Picture1, Picture2, 视频item(media_mode=video, tail.mp4), 视频item(media_mode=audio, 12-25s)]`（注意顺序，Audio 编号按类型时间线顺序）
- `validate_reference_limits` 要求"有音频必须有图/视频伴随"——两段都有 Picture，合规
- 每段音频参考 ≤15s、视频参考 ≤15s，全部合规

### 3.3 提示词要点（六段式 REF2VA，按 h3-prompt-writer 规范）

- **subject_definitions**：`<Subject 1>` 是三视图里的同一人（声明三视图是一个人的三个角度）；`<Picture 1>` 正面身份锚定；`<Picture 2>` 外观补充
- **summary**：`[video continuation] + [audio reuse]` 前缀
- **detailed_description**：怼脸直拍（extreme close-up, face filling the frame from the very start）、哀怨忧伤（a melancholic, sorrowful-yet-beautiful expression；**gentle sadness, not frowning hard, not exaggerated**）、随乐轻晃（subtle, gentle swaying of head and upper body in rhythm with the music）、对口型（lip-sync singing along with the audio）
- **retention_analysis**：Picture 1/2 `fully_preserved`；Video 1 `weak_reference`（camera/continuity）；Audio 1 `fully_copy`（音色与口型对齐）
- 禁止项：no camera movement / fixed camera（怼脸机位钉死）、no extra person

### 3.4 拼接细节（ffmpeg）

```bash
# 两段同参数生成（736×1280, 24fps）→ concat
ffmpeg -f concat -safe 0 -i list.txt -c copy final_25s.mp4
# 若 codec 不一致（Auto→AV1 或 H.264），先统一转 H.264 再 concat
```
音频随视频一起拼接即可（每段 EnhancedVideoCombine 已带音频输出），25s 音频首尾连续。

---

## 四、备选方案：官方多段 Director（路线 B，段间引导更彻底）

用户记忆中的"导演台将第一段最后二十多帧作为第二段输入"——官方包 `ComfyUI_MiniMaxH3_Director` 的**段间引导**（默认 22 帧 motion-context pin）是原生实现，比路线 A 的"参考视频续接"更稳（latent 级 pin，而非模型参考）。

但启用前必须先冒烟测试：
1. 用 `H3Director官方-20260903/minimax_h3_director_rv2v.json`（或 r2v）在 GPU 机跑一次单段 5s 验证官方包链路完整（模型加载、timeline v4、输出）
2. 验证通过后再构造两段 timeline（segments 数组，`continuityEnabled: true, continuityOverlapFrames: 22`）
3. 音频参考走官方版 timeline 的 refs（同样支持 audio-only）

**风险**：官方包未在本机验证过；timeline v4 的 API 展开需从 history 提取新模板（类似 V18 模板的做法）；与 DaSiWa 包同名节点注册冲突需用 `ComfyMiniMaxH3Director` 别名区分。

**决策建议**：先走路线 A（改动小、全链路已验证、预计 1-2 小时内可出第一版），路线 B 作为"画面脱节仍明显"时的升级手段。

---

## 五、执行清单

- [ ] 1. 三视图预处理：`turnaround_prep.py` 裁正面（Picture 1）+ 完整三视图（Picture 2）
- [ ] 2. 参考视频上传 GPU 机 input（`_upload_file_to_comfy` 已支持 mp4）
- [ ] 3. 扩展 `build_v18_prompt()` 支持 video/audio timeline items（见 3.2）
- [ ] 4. 写六段式提示词（h3-prompt-writer 流程，见 3.3）
- [ ] 5. 生成第一段 12s（audio-only 0-12s），下载 seg1.mp4
- [ ] 6. 裁剪 seg1 末段 1-2s 为 tail.mp4，上传
- [ ] 7. 生成第二段 13s（Video 1=tail + audio-only 12-25s）
- [ ] 8. ffmpeg 拼接 → 25s 成片，发布到下载中心
- [ ] 9. 检查拼接缝：表情/机位/口型是否脱节；必要时调 tail 长度（22/39/56 帧）或 seed
- [ ] （可选）10. 若脱节明显 → 评估官方多段版（路线 B）冒烟测试

---

## 六、风险与对策

| 风险 | 对策 |
|---|---|
| 拼接缝处画面跳变 | 第二段用 tail 视频参考 + `[video continuation]` 强声明；tail 取 22-56 帧（1-2.3s）；必要时两段 seed 与机位措辞完全一致 |
| 表情漂移成"死皱眉头" | 提示词明确 "gentle melancholy, soft sorrowful gaze, relaxed brows, not frowning"；参考图正面裁图兜底 |
| 怼脸直拍失效（拉到中景） | detailed_description 每 shot 都写 "extreme close-up / face fills the frame"；加 "camera locked, no push-out" |
| 音频参考超 15s 被拒 | 分段后每段 12s/13s ≤ 15s，天然合规（`validate_reference_limits` 已核实） |
| 官方多段版不可用 | 先走路线 A，官方版仅作升级备选 |
| AV1 输出 concat 失败 | 生成时 `force_h264=True`（pipeline 已有参数），统一 H.264 再 concat |
