生成影片片段(靜態圖 → 片段,然後口型同步)
概述
完成的靜態圖透過圖像轉影片模型變成 4-9 秒的片段。接著,如果角色在畫面中說話,口型同步模型會根據你的對話音訊重新調整其嘴巴的時序。你無法觀看結果:必須從擷取的影格(使用 scripts/take_sheet.py 與 viewing-videos 技能)判斷每個片段,並讓人類對動作有最終決定權。
需求: Python 3(僅標準函式庫)與 ffmpeg/ffprobe。金鑰需設為環境變數:GEMINI_API_KEY(Google AI Studio 金鑰;影像專用金鑰也可用,且 GEMINI_IMAGE_API_KEY 會作為備用讀取)用於 Omni,以及 FAL_KEY(與 fal 顯示的完整金鑰完全相同)用於口型同步。切勿列印它們。
選擇模型
| 模型 | 透過何者存取 | 用途 | 備註 |
|---|---|---|---|
Gemini Omni Flash 1.1 (gemini-omni-1.1-flash) | Google Interactions API, AI Studio 金鑰 | 預設用於插畫、動漫與卡通靜態圖;也曾在一次測試中用於寫實靜態圖 | 保留藝術風格與臉部;任何輸入比例(2:3 的靜態圖會回傳乾淨的 9:16,因此無需先擴繪或裁切);720p 9:16 或 16:9;同步,約 25-35 秒/片段;會加上自己的音訊(請將其靜音) |
| Veo 3.1 / Veo 3.1 Fast | Gemini API,圖片作為起始影格 | 寫實靜態圖 | 我們的執行中未使用;使用前請先查閱最新文件 |
| Seedance 2.5 | ElevenLabs Flows,或直接透過 ByteDance | 替代風格 | 嘗試時需要帳戶核准 |
| ElevenLabs Flows 內的任何模型 | ElevenLabs API | 一把金鑰搞定所有事情 | API 存取需要 Pro 方案 (402 paid_plan_required) 且金鑰需擁有 image_video_generation 權限(沒有權限則回傳 401);那裡的 Omni 僅限應用程式 |
對於口型同步,fal 上的 Sync 3 (fal-ai/sync-lipsync/v3) 是預設選擇。它採用影片轉影片的方式,因此保留片段的動作,僅重新調整嘴巴的時序。比較與價格:請參閱 references/providers.md。
為靜態圖製作動畫
python3 <this-skill-dir>/scripts/omni_generate.py jobs.json clips/ [--takes 3] [--only S05]
{"base": "原封不動地讓這張靜態圖活起來:相同的藝術風格、色調、光線與佈局,且每個角色都保留其臉部、頭髮、身形與穿著。自然流暢的動作。畫面上不要有任何文字、不要對話框、不要出現新人物,一個連續的鏡頭。",
"jobs": {"S05": {"image": "panels/p05.png",
"prompt": "[0-3秒] 穿著紅色夾克的女人拿起手機說話,興奮的樣子。[3-6秒] 穿著綠色帽T的朋友向後靠在沙發上大笑。鏡頭緩慢推進。"}}}
如何撰寫提示詞(完整指南與範例請參閱 references/gemini-omni.md):
- 一個每秒的時間線,每個中括號一個節拍。片段的長度大約等於時間線的長度。
- 根據穿著來稱呼人物,絕對不要用名字:模型不知道「Dana」是誰。
- 對任何將進行口型同步的角色加上「說話」,這樣嘴巴才會先動起來。
- 固定不可改變的部分:「鏡頭保持靜止」、「左牆上只有一扇窗」、「剛好一個穿連帽衫的人物」、「她的雙手平放在桌上」。每個固定點都來自
references/failure-modes.md中的實際失敗案例。
在使用每個生成結果前先審查
python3 <this-skill-dir>/scripts/take_sheet.py sheet review/S09.jpg clips/S09_t1.mp4 clips/S09_t2.mp4 clips/S09_t3.mp4 --times 0.3,1,2,3,4,5,6
讀取表格:橫列是生成結果,直欄是時間點。檢查是否有道具重複、門或人物出現、手穿過身體、臉部偏移,以及動作重複。精確指出每個問題發生的秒數,因為修復方式取決於問題位置。
在抽樣影格之間容易遺漏硬切。直接列出它們;沒有輸出表示是連續鏡頭:
ffmpeg -i clips/S09_t1.mp4 -vf "select='gt(scene,0.3)',showinfo" -an -f null - 2>&1 | grep pts_time
將片段匹配到它的鏡頭
剪輯需要一個能完全填滿其鏡頭、且符合剪輯影格率的片段:
| 問題 | 修復方式 |
|---|---|
| 開頭不佳(台詞前先出現動作、第一秒內有重複道具) | 延後開始:--off 1.5。 |
| 修剪後太短 | 放慢速度:--speed 1.22(最多約 1.25 倍仍可接受);最後一個影格會維持住。 |
| 中間不佳 | 分割鏡頭:先播放第一句台詞時,裁切掉問題區域使其不在畫面內,然後再切回來。 |
| 無法修復(一扇門出現、第二個人走進來) | 使用固定提示詞重新生成,產出 2-3 個結果,並在表格中挑選。 |
lipsync_parts.py normalize clip.mp4 shot.mp4 --frames N --off S --speed K 可以一次性完成偏移、速度、影格率、縮放(填滿並中心裁切,絕不拉伸)以及最後影格維持,並且總是回傳正好 N 個影格。
口型同步對話
- 標準化片段到鏡頭:
python3 <this-skill-dir>/scripts/lipsync_parts.py normalize clip.mp4 shot.mp4 --frames 132 --off 1.5 --speed 1.22。 - 分割在台詞邊界,使每個部分只有一個說話者。
- 撰寫
shot.json:每句台詞包含其在鏡頭中的開始/結束時間(秒)與說話者;frames等於你標準化時使用的--frames。如果說話者從背後看到、在畫面外,或是群眾呼喊,請加上"skip": true:{"id": "S05", "video": "shot.mp4", "fps": 24, "frames": 132, "lines": [{"id": "05-1", "audio": "lines/05-1.mp3", "start": 0.72, "end": 2.31, "speaker": "maya"}, {"id": "05-2", "audio": "lines/05-2.mp3", "start": 2.43, "end": 4.10, "speaker": "ido"}]} - 執行
lipsync_parts.py split shot.json parts/。除了分割出的部分之外,它還會寫入parts/S05_lipsync_jobs.json:每個非跳過的部分一個條目,使用絕對路徑,out已命名為 join 預期的方式(synced/S05_<k>.mp4),且face: null。
- 撰寫
- 指向每個部分中的說話者,並將其寫入該 jobs 檔案中的
"face": "x,y@<mid>"(mid在每個條目中)。- 在該部分的中間影格上,選取說話者臉部上的一個畫素。
- 確認它:
take_sheet.py point parts/S05_1.mp4 check.jpg --frame 30 --xy 410,560,然後檢視圖片。 - 臉部偵測器在手繪臉部上不可靠,因此請用肉眼挑選並確認。只有當畫面中只有一張臉時,才保留為
null。
- 同步:
lipsync_fal.py --jobs parts/S05_lipsync_jobs.json。預計約 $0.13/秒,每個部分約 70-150 秒;6 個平行執行。現有的輸出會被跳過。若要在修正臉部後重新處理某個部分,請單獨執行該部分:lipsync_fal.py parts/S05_1.mp4 parts/S05_1.wav synced/S05_1.mp4 --face 410,560@30 --force(搭配--jobs使用--force會重新處理每個部分)。 - 合併:
lipsync_parts.py join parts/S05_plan.json synced/ final/S05.mp4。每個部分會被強制設定為其精確的影格數,跳過的部分保留其原始影格,沒有同步檔案的部分會回報(--strict會使其變成錯誤),並會檢查總影格數。
詳細資訊、模型選擇與失敗案例:請參閱 references/lipsync.md。
成本與時間(2026-10 測量)
| 步驟 | 計費單位 | 成本 | 時間 |
|---|---|---|---|
| Omni 片段 | 每輸出影片秒數(一個 6 秒片段約 $0.60;預計每個鏡頭約需 1.5 次重拍) | ~$0.10 | 每次呼叫約 30 秒,4 個平行執行 |
| Sync 3 口型同步 | 每輸出秒數(一個部分通常為 3-6 秒) | ~$0.13 | 每個部分約 70-150 秒,6 個平行執行 |
常見錯誤
| 錯誤 | 結果 | 修復方式 |
|---|---|---|
| 在影片提示詞中使用角色名稱 | 錯誤的人物移動 | 用穿著描述他們 |
| 保留 Omni 的音訊 | 在你的對話下出現虛構的聲音與音樂 | 將其靜音 (-an) |
| 未使用表格就採用生成結果 | 重複的道具與新的門出現 | 每個生成結果都要用表格審查 |
| 為了修正糟糕的第一秒而重新生成整個片段 | 其他地方出現新問題 | 偏移加上放慢速度 |
| 對整個雙人對話鏡頭進行口型同步 | 一個嘴巴同時動兩句台詞 | 在台詞邊界分割,每個部分一個說話者 |
| 讓模型自己選擇說話者 | 錯誤的臉在說話 | 指定 --face X,Y@FRAME |
| 縮短 fal 金鑰 | 401 錯誤 | 傳遞與 fal 顯示的完全相同的金鑰 |
| 未修正影格數就合併部分 | 鏡頭與剪輯不同步 | 使用 lipsync_parts.py join |
相關技能
- image-generation:靜態圖(角色卡、漫畫格)。
- elevenlabs-tts:嘴巴要同步的對話音訊。
- viewing-videos:用於審查片段的影格擷取。
- producing-animated-episodes:使用這些片段的完整集數工作流程。