Communitygithub.com

shaharsha/動画クリップ生成

静止画像、イラスト、コミックパネル、キャラクターアートから短いアニメーションクリップ(画像から動画へ)を生成し、キャラクターの口元を既存の台詞音声に同期させるためのスキルです。

動画クリップ生成 とは?

このスキルは、静止画像から短い動画クリップ(4~9秒)を生成し、必要に応じてキャラクターの口元を台詞音声にリップシンクするためのワークフローを提供します。主に画像から動画への変換モデルとしてGoogleのGemini Omni Flash 1.1を標準で使用し、その他Veo、Seedance、ElevenLabs Flowsなどのモデルも選択可能です。リップシンクにはfal.ai上のSync 3がデフォルトで使用され、動画全体の動きを保持しながら口元のみを再タイミングします。このスキルは、生成されたクリップをフレーム抽出シートで確認し、プロップの重複や不自然な動きなどのアーティファクトを検出するプロセスを含みます。また、複数話者のクリップをライン単位で分割し、話者の顔を指定して正確なリップシンクを実現する機能も備えています。主にターミナルベースのツール(Pythonスクリプトとffmpeg)で動作し、環境変数によるAPIキー管理が必要です。

対応~Claude Code~Codex CLI~Cursor✓Gemini CLI
npx skills add https://github.com/shaharsha/claude-skills/tree/HEAD/skills/generating-video-clips

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

動画クリップ生成(静止画からクリップ、そしてリップシンク)

概要

完成した静止画は、画像から動画へのモデルによって4~9秒のクリップになります。その後、画面上のキャラクターが喋る場合、リップシンクモデルがその口元をあなたの台詞に合わせて再調整します。結果を直接見ることはできません。抽出されたフレーム(scripts/take_sheet.py と viewing-videos スキルを使用)からすべてのクリップを評価し、最終的な判断は人間に委ねてください。

必要条件: Python 3(標準ライブラリのみ)、ffmpeg/ffprobe。APIキーは環境変数で設定します: 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キーデフォルト。イラスト、アニメ、漫画の静止画向け。写実的な静止画でも動作した(1テスト)画風と顔を保持。任意の入力アスペクト比(2:3の静止画でも9:16に綺麗に変換されるため、事前の外描きやクロップは不要)。720p、9:16または16:9。同期的、クリップあたり約25~35秒。独自のオーディオを追加するのでミュートすること
Veo 3.1 / Veo 3.1 FastGemini API、画像を開始フレームとして写実的な静止画当スキルの実行では未使用。使用前に最新ドキュメントを確認すること
Seedance 2.5ElevenLabs Flows、またはByteDance直接代替の見た目試用時はアカウント承認が必要だった
ElevenLabs Flows内の任意のモデルElevenLabs API1つのキーで全てをカバー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-3s] 赤いジャケットの女性が電話を手に取り、興奮して話す。[3-6s] 緑のパーカーの友達がソファに寄りかかって笑う。ゆっくりカメラが押し込まれる。"}}}

プロンプトの書き方(完全なガイドと例は references/gemini-omni.md):

  • 秒単位のタイムライン。各ブラケットが1ビート。クリップの長さはタイムラインとほぼ同じになります。
  • 人物は服装で識別し、名前では決して呼ばないでください。モデルは「ダナ」が誰かを知りません。
  • 「話す」と指定してください。リップシンク対象のキャラクターの口がすでに動くようにするためです。
  • 変更してはいけないことを固定します。「カメラは静止」、「左壁に窓は1つだけ」、「フードの人物はちょうど1人」、「彼女の手はテーブルの上に平らに置いたまま」。各固定方法は 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

シートを読み取ります。行がテイク、列が時間です。プロップの重複、ドアや人物の出現、手が体を横切る、顔がずれる、ジェスチャーが2回行われるなどを探します。問題の正確な秒数を特定してください。修正方法はその位置に依存するためです。

ハードカットはサンプリングされたフレームの間で見逃しやすいです。直接リストアップします。出力がなければワンカット連続撮影です。

ffmpeg -i clips/S09_t1.mp4 -vf "select='gt(scene,0.3)',showinfo" -an -f null - 2>&1 | grep pts_time

クリップをショットに合わせる

編集では、クリップがそのショットを正確に満たし、編集のフレームレートに合っている必要があります。

問題修正
開始が悪い(台詞の前にジェスチャーが行われる、最初の1秒でプロップが重複する)開始を遅らせる: --off 1.5
トリミング後に短すぎる--speed 1.22 で速度を落とす(最大約1.25まで問題なく読み取られる)。最終フレームが保持される
中盤が悪いショットを分割する。問題のある部分をフレーム外に保つクロップで最初の台詞を再生し、その後カットバックする
修正不可能(ドアが現れる、第二の人物が入ってくる)固定プロンプトで再生成し、2~3テイク、シートで選択する

lipsync_parts.py normalize clip.mp4 shot.mp4 --frames N --off S --speed K は、オフセット、速度、fps、スケール(カバー&センタークロップ、ストレッチはしない)、最終フレーム保持を1ステップで行い、常に正確にNフレームを返します。

台詞にリップシンク

  1. クリップをショットに正規化する: python3 <this-skill-dir>/scripts/lipsync_parts.py normalize clip.mp4 shot.mp4 --frames 132 --off 1.5 --speed 1.22
  2. ライン境界で分割し、各部分に1人の話者がいるようにする。
    • 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 を書き出す。各 非スキップ パートに1エントリで、絶対パス、out はjoinが期待する名前(synced/S05_<k>.mp4)で既に命名され、face: null が設定される。
  3. 各パートで話者を指定し、そのjobsファイルに "face": "x,y@<mid>" として書き込む(mid は各エントリにある)。
    • パートの中間フレームで、話者の顔のピクセルを1つ選ぶ。
    • 確認する: take_sheet.py point parts/S05_1.mp4 check.jpg --frame 30 --xy 410,560 を実行し、画像を読む。
    • 顔検出器は描かれた顔では信頼性が低いため、目視で選択・確認する。顔が1つだけ表示されている場合のみ null のままにする。
  4. 同期: lipsync_fal.py --jobs parts/S05_lipsync_jobs.json を実行する。予想コストは1秒あたり約$0.13、1パートあたり約70~150秒。6つが並列実行される。既存の出力はスキップされる。顔を修正した後に1パートだけやり直すには、そのパート単独で実行する: lipsync_fal.py parts/S05_1.mp4 parts/S05_1.wav synced/S05_1.mp4 --face 410,560@30 --force(--jobs と --force を一緒に使うとすべてのパートをやり直すことになるので注意)。
  5. 結合: lipsync_parts.py join parts/S05_plan.json synced/ final/S05.mp4 を実行する。各パートは正確なフレーム数に強制され、スキップされたパートは元のフレームを保持し、同期ファイルがないパートは報告される(--strict でエラーになる)。総フレーム数もチェックされる。

詳細、モデル選択、失敗事例: references/lipsync.md

コストと時間(2026年10月測定)

ステップ計量単位コスト時間
Omniクリップ出力動画1秒あたり(6秒クリップで約$0.60。リテイク込みでショットあたり約1.5回呼び出しを見込む)約$0.101呼び出し約30秒、4並列
Sync 3 リップシンク出力1秒あたり(パートは通常3~6秒)約$0.131パート約70~150秒、6並列

よくある間違い

間違い結果修正
動画プロンプトでキャラクターを名前で呼ぶ別の人物が動く服装で説明する
Omniのオーディオをそのまま使う台詞の下に作り物の声や音楽が流れるミュートする(-an)
シートを使わずにテイクを使用するプロップの重複や新しいドアがそのまま使われるすべてのテイクをシートで確認する
最初の1秒が悪いだけでクリップ全体を再生成する別の場所に新しい問題が発生するオフセットとスローダウンで対応する
2人の話者がいるショット全体をリップシンクする1つの口が両方の台詞で動くライン境界で分割し、パートごとに1人の話者にする
モデルに話者を任せる間違った顔が話す--face X,Y@FRAME で指定する
falキーを短縮する401エラーfalが表示する通りのキーをそのまま渡す
フレーム数を修正せずにパートを結合するショットが編集との同期からずれるlipsync_parts.py join を使用する

関連スキル

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

shaharsha/deck-to-video

Use when turning a slide deck plus per-slide narration audio into an mp4 video — a self-playing/self-presenting deck video, "slides to video", "presentation to mp4", a shareable WhatsApp/Slack/Drive video of a narrated deck, or when a slide video needs a per-slide progress bar / countdown / slide counter. Also use when a slide video should highlight, glow or spotlight the element being talked about in time with the voice, or when narration and on-screen animation need syncing. Also use when...

shaharsha/image-generation

Generate logos, icons, UI mockups, hero images, product shots, and other design assets using OpenAI GPT Image 2.5 (Sunburst, Flare) or Google Gemini (Nano Banana 2, Nano Banana Pro, Nano Banana 2 Lite). Use whenever the user asks to create, design, generate, mock up, render, or illustrate a visual asset, needs a transparent PNG, or asks for image prompt engineering. Picks the right model and quality for the job, writes a model-specific prompt following the official prompting rules of each...

shaharsha/producing-animated-episodes

Use when making a narrated or voiced animated video with recurring characters - an anime, cartoon or comic episode, a short for a group chat, a story video about friends, family, a class or a team - from photos, a chat export, a story idea or a script, in any visual style, Hebrew/RTL or English. Also use when such a video has subtitles or cards too fast to read, music stopping early, the ending cut off, lines buried under music, mouths out of sync, a gesture before its line, or one face...

関連スキル