Files
MediaCrawler/mac-agent-os-main/PLANS/AUDIO_LIPSYNC_PLAN.md
T
butubb 2112c1a870
Deploy VitePress site to Pages / build (push) Canceled after 0s
Deploy VitePress site to Pages / Deploy (push) Canceled after 0s
feat(monitor): 抖音 Web 接口客户端 —— 绕开爬虫子进程,直接发 HTTP
移植自 mac-agent-os 的 mediacrawler_adapter:不起子进程、不开页面,用浏览器里那份
登录态直接调抖音 Web 接口。产物键名照抄 store/douyin,所以 ingest 那条链路一个字不用改。

**目前能用的(真环境实测,非推断)**:

    profile/other : 200, 7075 字节  —— 博主主页指标(粉丝/获赞/作品数/昵称)
    aweme/detail  : 200, 45425 字节 —— 单条作品详情(含点赞/评论/收藏/分享)

**目前不能用的:作品列表 `aweme/post`。** 两个互相独立的原因:
  1. 这个接口被抖音单独升级成了真校验:不带 x-tt-argus 回 403「Uifid Not Found」,
     带上 dummy 值回 200 + **空 body**。也就是说「头在不在」骗得过,「真校验」过不了。
     同一套头打 profile/other 和 aweme/detail 都是通的 —— 抖音是挑着接口加保护的,
     挑中的恰好是「批量拉作品列表」这个最敏感的动作。
  2. 改走页面截获也不行:CDP 浏览器打开博主主页会落到「验证码中间页」(当天大量探测的
     代价,过几小时要重测)。

  所以现在的边界是:**已知作品的指标刷新能做,自动发现新作品做不了**。

**排查中控住变量后得到的两条事实**(都写进注释了):
  · `Accept` / `Accept-Language` / `Referer` 才是主页接口能返回真数据的原因 —— 只有
    UA+client hints+Cookie 时是 200 但仅 121 字节的空壳,补上这三个头变 7074 字节。
    (我先前猜的 sec-ch-ua 不是关键。)
  · 因此 UA 与 client hints 必须**成套地取自同一个浏览器**,所以 BrowserIdentity 一次
    从 CDP 取齐 cookie + UA + hints,而不是各自写死。

「200 + 空 body 必须当场报错」也是刻意写死的:放过去它会在下游变成「这个博主没作品」,
把一次失败伪装成一条正常结果 —— 爬虫那条路正是这么栽的,还被翻译成「账号被封」。

测试 +11:cookie 解析、请求头成套性(含 uifid 缺失/回退)、产物键名与 store 对齐、
以及 _get 的三条失败路径(空 body / 403 带网关原话 / 正常返回)。
2026-10-10 17:12:25 +08:00

6.3 KiB
Raw Blame History

声音 / 口型 完整方案(v1 草案)

建立:2026-10-03 · 状态:待用户最终确认后实施 关联:composer/dubbing.py(配音引擎·已上线)、composer/lipsync.py(待改造为可灵版)


一、目标

让成片的声音完整、口型对得上、节奏跟得上:

  1. 主角出镜说台词的镜头 → 口型同步
  2. 旁白 / 空镜 → 正常配音(不做口型)
  3. 同一角色音色全片一致(不管画面怎么变)
  4. 台词时长决定镜头时长(画面跟着声音走)

二、用户已确认的决策

# 决策 说明
1 只对有台词的镜头做口型 成本最低;其余镜头不做
2 音色必须一致 一个角色 = 一个固定 voice_id;音色库管理
3 音频先行 先 TTS 得到真实音频时长 → 按它定镜头时长 → 再生成画面
4 旁白标记 = 混合(c) 默认自动判定(无出场人物=旁白),分镜卡片可手动改
5 一句话拆两镜 按语义停顿切分(先自动分,需要时手动调),每段独立 TTS + 对口型
6 对口型失败兜底 用原片段(不影响出片)
7 成本测试 改用 20 秒测试片:1 个空镜(素材库免费素材)+ 2 个 5 秒角色说话镜头(做口型)——"该省省,该花花"
8 双人同框对策 = 参数 正反打/过肩镜头做成本可控制的参数(默认关,未来有能力再启用,不影响创作)

二·五、待补充的基础能力(用户要求:补在基础层,其他流程可复用)

原则:补在基础能力层(capabilities/ / composer/),而非某个流程专属实现 —— 这样分镜、口播、混剪等流程都能复用。

# 能力 用途 现状
B1 首尾帧衔接 镜头间无缝续接 / 镜头内首尾帧控制 底层已具备(可灵 image_tail),上层未接通
B2 多参考图 多角色同框各保人脸 ❌ 可灵不支持;待专业方案(ComfyUI 多参考 / IP-Adapter)
B3 微表情 + 口型核对 生成后校验表情/口型是否符合预期(质量门) ❌ 无(可结合视觉模型做检测)

三、技术方案

3.1 声音分四轨

一条片子的声音 = 旁白轨 + 角色人声轨 + 环境音轨 + BGM轨

3.2 镜头按声音需求分三类

类型 特征 画面 声音
A 角色说话 有台词 + 有出场人物 图生视频(绑角色,保人脸) 角色音色 TTS + 对口型
B 旁白解说 有台词、无出场人物(或手动标旁白) 空镜 / 场景 旁白音色 TTS,不做口型
C 无台词 空镜 / 氛围 场景 环境音铺底(或静音)

3.3 工作流(音频先行)

① 分镜定稿(每镜:台词 + 出场人物 + 旁白标记)
        ↓
② 【音频先行】逐镜 TTS
   · A 类 → 该角色音色(voice_id 固定)
   · B 类 → 旁白音色
   · C 类 → 无
   → 得到每段**真实音频时长**
        ↓
③ 【画面跟随】按音频时长定镜头时长 → 生成画面
   · 绑角色 → 图生视频(保人脸一致性)← 2026-10-03 已修复
   · 未绑   → 文生视频
        ↓
④ 【对口型】仅 A 类镜头:
   镜头视频 + 台词音频 → 可灵 lip-sync → 替换片段(失败则用原片段)
        ↓
⑤ 【混流】人声轨 + 环境音 + BGM + 字幕

3.4 音色一致性机制

  • 一个角色 = 一个固定 voice_id(演员表 CastMember.voice_id 绑定)
  • 未指定 → 按角色代号 hash 从路人池稳定分配(同代号永远同音色)
  • CosyVoice 同一 voice_id 合成结果音色确定(仅语气/语速随文本微变)
  • 旁白与角色音色可以不同(解说员 vs 画面人物,观众接受且更自然)

3.5 可灵 lip-sync 接口(已实测探明,2026-10-03)

POST /v1/videos/lip-sync
{
  "input": {
    "mode": "audio2video",          // 或 text2video(需 voice_language)
    "video_url": "..." | "video_id": "...",   // 二选一(video_id 可用我们生成的镜头)
    "audio_type": "url",
    "audio_url": "..."
  }
}
GET  /v1/videos/lip-sync            ← 任务列表查询

✅ 用现有 kling key 即可,不需要 fal.ai(现有 lipsync.py 是 fal.ai 版 → 改造为可灵版) ⚠️ 单价未知(文档站为 SPA 抓不到)→ 按用户决策:先跑 1 个 5 秒镜头实测


四、实施步骤(建议顺序)

阶段 内容 依赖
P1 音频先行:出片流程加「先 TTS → 按音频时长定镜头时长」(音频存盘供混流复用,不重复 TTS) 无
P2 演员表音色绑定 + 旁白标记(前端 UI + schema) 无
P3 lipsync.py 改造为可灵版 + 接入出片流程(仅 A 类镜头,失败用原片段) P1
P4 20 秒测试片:1 空镜(免费素材)+ 2 个 5 秒角色说话 → 实测 lip-sync 单价 → 用户决定是否全量 P3
P5 首尾帧衔接(接通 image_tail)→ 补进基础能力层(B1) 独立
P6 双人同框 → 正反打参数(默认关,用户可控;未来 B2 到位后可启用) 独立
B 系列 基础能力补充:B1 首尾帧 / B2 多参考 / B3 微表情口型核对(补在基础层,全流程复用) 见二·五

五、成本估算(粗略,待实测)

项 单价 说明
TTS(CosyVoice) 极低(按字数) 几十字台词 ≈ 几分钱
可灵 lip-sync 待实测 参考 fal.ai 版注释 ¥0.1/秒
粗估 每部短片 23 个台词镜头 × 5 秒 ≈ **¥12/部** 月产 20 分钟 ≈ 十数量级

六、已知局限(诚实标注)

  1. 多角色同框:图生视频只能喂一张参考图 → 只保主角(替代:正反打 / 合成参考图 / 等专业能力)
  2. 跨镜头口型连贯:一句话拆两镜时,语气可能有轻微断裂(缓解:切分点落在语义停顿)
  3. 已生成素材:本方案只对新生成生效(旧镜头需重新出片)

七、待确认

  • 用户确认"按默认"(第 2/3/4 点)→ 即可开工 P1
  • 优先级:A 声音链先做(建议),B 一致性增强随后