Kamila 口播线 · 设计确认稿 · 2026-07-08

采访体话外音:不对口型,但时间轴严格对齐

画外有个提问的声音,Kamila 只在自己说话的段落对口型;记者问话时她在镜头前听。老的平文本口播原样保留,一行行为都不变。

2 种模式
老平文本 + 新采访体
1 个时钟
TTS 实测时长累加
0 回归
老路径代码不动
先 test
双模式真单验完再谈 prod

入口怎么分流

下单的东西(payload)里多一个可选的结构化台词字段。有它,走采访体;没有它,和今天一模一样。老模板、老单、存量行为零影响。

有 lines 只有 dialogue_ru 下单 payload 进来 shots[0].lines 有货? 分流 新 · 采访体 按 speaker 分段 vo=话外音 / kamila=本人 两种段两种拍法 vo=听镜 · kamila=对口型 详见下面时间轴图 老 · 平文本口播 现行路径,原样 整段 TTS→切窗→对口型 代码不改 行为一字不动 存量模板零回归 成片 LEGEND 新增(采访体) 现状(不动) 入口 · 出口

关键取舍:分流只发生在入口一处,老路径整块代码不碰。新模式出问题最多影响采访体订单,伤不到存量口播。

新字段长这样(和 hook 广告线已有的台词形状同构,上游好实现):

// 采访体下单(新,可选)
"shots": [{
  "scene": "冰场边的采访角,Kamila 坐在镜头前",
  "lines": [
    {"speaker": "vo",     "line_ru": "Камила, как вы это делаете?"},   // 记者,画外
    {"speaker": "kamila", "line_ru": "Честно говоря, всё просто..."},  // 本人,对口型
    {"speaker": "vo",     "line_ru": "..."},
    {"speaker": "kamila", "line_ru": "..."}
  ]
}]

// 老口播下单(完全不变)
"shots": [{ "scene": "...", "dialogue_ru": "整段平文本..." }]

时间轴怎么对齐 —— 一个钟推三条轨

你点的核心:话外音不对口型,但时间必须准。做法是延续这条线验证过的铁律 ——声音是主时钟。每段台词先做 TTS(她的声线 / 记者声线),量出真实时长,按顺序累加(段间留 0.4s 换气),这就是唯一的时间轴。音轨、画面、字幕三条轨都从同一个钟上取偏移,对齐是结构保证的,不存在"拼完再对"。

0s 5s 10s 15s 20s 25s t 同一偏移 12.6s 音轨 画面 字幕 记者声线 3.2s K宝声线(Fish) 8.6s 记者声线 2.6s K宝声线(Fish) 10.2s 听镜 · 闭嘴 无 lipsync 对口型窗(现有路径) Seedance + lipsync 听镜 生5s裁2.6s 对口型窗(现有路径) Seedance + lipsync [记者] … 0.0→3.2 [K宝] … 3.6→12.2 [记者] 12.6→15.2 [K宝] … 15.6→25.8 0.4s 0.4s 0.4s LEGEND Kamila 本人段(对口型) 话外音段(听镜,无 lipsync) SRT 字幕(带说话人)

看虚线:话外音第二问的起点 12.6s,在音轨、画面、字幕三条轨上是同一个数——因为它们都是从"前面各段实测时长 + 换气间隔"累加出来的,不是三条轨各算各的。口型崩那次的教训(duration 写死 ≠ TTS 时长)在这里天然不会复发。

话外音段的画面怎么拍

动什么,不动什么

改动说明
talking_head.py加采访体分支入口分流 + 分段 TTS + 听镜生成 + 时间轴铺轨;老分支代码不碰
prompts/新增 1 个听镜模板"她在听"的表演提示词;现有口播模板不动
recipe 资产加 1 个记者声线固定的沉稳画外音声线(Fish 参考),第一版不给用户选
workflow 定义声明 lines 可选字段发新 test snapshot,老字段不动
Mai 上游脚本层支持"谁说的"跟用户确认台词时标 speaker;方案你点头后我再去跟 mai-cc 对
不动老平文本路径、Fish/lipsync/拼接机制、hook 广告线、prod 别名(kvo=5fe8d649 冻结)

验收和发布路径

要你拍的两个小点(都有默认,不拍就按默认走):

  • 记者声线:默认配一个固定的沉稳声线,第一版不开放选择。
  • 话外音时的画面:默认"她在镜头前听"(采访标准拍法);要切空镜/B-roll 属于以后的加法。