Tobatsu 2.0 · 查实更正版
先认错:上一版我说"查无此名"是错的——我查的是 Tobatsu 1.0 和本地仓,而它活在 Tobatsu 2.0。它是真 workflow(v5),task 34413dfd 今天刚 done。真机制是:Fish TTS 出声 → Seedance Omni 出画 → 对口型,声音不是 Seedance 也不是 ElevenLabs。
tobatsu-api.fpai.io + 本地 repo)上查的,作废。这版全部来自 tobatsu2 控制面的真实数据:WORKFLOW.md 源 + 真机 task 产物。K宝口播 / Kamila voice-over。Mai 先生成并让用户确认一张 GPT-image 首帧,把 first_frame_url 交给 Tobatsu;Tobatsu 跑 Seedance Omni 5-15 秒的对口型窗口、对口型、再拼接成片。
aspect_ratio 只能 9:16,shots 恰好 1 段,带 dialogue_ru(俄语台词)。kamila-assets / kamila-hook-recipe(打包 runner) / fish-tts-prompting / unified-media-generation / omni-handler / lipsync-align / rendi-ffmpeg / mai-platform-delivery。digital-human-omnihuman/OmniHuman,也不准跑老的 kamila_hook story runner。tobatsu2 GET /workflows/kamila_voice_over/source (v5, len 8546)
voiceover_align、combo 那套(voiceover_digital_human_pip_subtitle_mai)是不同的工作流。这条是 Seedance Omni 对口型,不是 ElevenLabs 对齐源视频,也不是 OmniHuman 数字人。打包 runner 是 kamila-hook-recipe/scripts/talking_head.py,WORKFLOW.md 里把音频路径写得很死:
[friendly][confident])。ref_audio_url —— 让 Seedance 拿到对的嘴型节奏。lipsync-align --anchor audio --fish <window_fish.wav> 让画面嘴型跟着 Fish 走。Seedance 自带音轨只用于背景提取和嘴型时序参考,交付的声音是 Fish。win 顺序拼接,重编码 1080×1920 / 30fps / yuv420p / AAC。Fish 整轨 17.74s → 切 2 窗(0–11.60s、11.60–17.74s)→ 各自 win*.seedance.mp4 + win*.fish.wav + win*.aligned.mp4 → 拼成 18.09s 成片。timestamp_source = scribe_word_timestamps,两窗 lipsync_ok=true。产物里能看到 media/full_tts.wav、win0.seedance.audio.wav(Seedance 自带音,被弃用)、win0.aligned.mp4(对口型后)。
tobatsu2 GET /tasks/34413dfd/outputs + outputs/runner/result.json
用的是 Seedance Omni,请求类型 any2video,走 unified 生成 API(UNIFIED_GENERATION_API_URL = unified-generation-api.adtech-videogen.workers.dev/generate)。它就是用 ref_audio_url 这条任意输入能力,把音频喂进去驱动画面。
| 来源 | omni 模型 id | type |
|---|---|---|
omni-handler skill(omni 专用,rev1) | ultra-seedance-2-omni | any2video |
unified-media-generation skill 示例清单(rev2) | funpub-seedance-2-omni | any2video |
ultra-seedance-2-omni vs funpub-seedance-2-omni)。最终发哪个,字面烧在 runner 脚本 talking_head.py 里 —— 该 .py 在 skill package 内,API 的 GET /skills 只回 SKILL.md、取不到脚本,所以这里没法 100% 断言。omni 专用的 omni-handler 明写 ultra-seedance-2-omni,以它为准的可能性更大。要钉死就得读 package 里的 .py。tobatsu2 GET /skills/omni-handler · /skills/unified-media-generation
用了。它不是叫 "unified-api",在 2.0 里就叫 unified-media-generation —— 这就是 unified 生成 API 的客户端/契约 skill,是 kamila_voice_over 八个 skill 之一。再加 omni-handler 专门教怎么写 Seedance Omni 的 any2video 引用 prompt(@audio1 映射 ref_audio_url 等)。
# unified-media-generation 里的请求形(any2video / omni)
{
"type": "any2video",
"models": ["…-seedance-2-omni"], // 数组,不是单数 model
"input": {
"prompt": ...,
"ref_image_url": [首帧],
"ref_audio_url": [该窗 Fish 片段], // ← 口播对齐的关键
"duration": "11"
}
}
runtime_env 要 UNIFIED_GENERATION_API_URL / _AUTH_KEY / _BILLING_EMAIL 三个(unified)+ FAL_KEY(lipsync-align 那一步走 FAL)。
Fish TTS 出整条俄语配音 → 按词级时间戳切 5–15s 窗 → 每窗喂 Seedance Omni(any2video,该窗 Fish 当 ref_audio_url)生成对口型画面 → lipsync-align(FAL)把嘴型锚到 Fish → 拼接 1080×1920。声音=Fish,画面=Seedance,对齐靠 ref_audio + lipsync。
Seedance Omni · any2video,经 unified 生成 API。模型 id:omni-handler 写 ultra-seedance-2-omni,unified-media-generation 示例写 funpub-seedance-2-omni —— 两份文档不一致,最终字面在 runner 的 .py 里(API 取不到)。
有 —— 2.0 里叫 unified-media-generation(unified API 客户端),配 omni-handler(omni prompt 规则)。runtime_env 依赖 UNIFIED_GENERATION_* 三件。lipsync 那步另走 FAL_KEY。