
前回インストールとAIエージェントを使ってロゴ作成までやりました。

今回は画像4枚で音声に合わせた口パク、瞬きを作ってみます。
YMM4みたいなGUIの動画ソフトは使わず、AIにコードを書いて貰って、音声に合わせて自動で口パク・瞬きさせる方法です。
インストールまだの人は上記の記事参考にしてみてください。
Remotionとは?
Remotionは、Reactでプログラム的に動画を作れるフレームワークです。
画面の要素をReactのコンポーネントとして書いて、フレームごとの状態をコードで制御することで動画を組み立てます。
音声や画像を読み込んでフレーム単位で表示を切り替えられるので、今回みたいに音声に合わせて立ち絵を口パクさせる処理と相性がいいみたいです。
タイムラインを手で並べる動画編集ソフトと違って、動きをロジックで書けるのが特徴です。
主な特徴
- Reactで動画をプログラム的に作れる
- フレーム単位で表示や動きを制御できる
- 音声・画像・動画を読み込んで合成できる
- コードで書けるのでAIに実装を任せやすい
- CLIでmp4などに書き出せる

作れるもの
Remotionで口パクさせるのに必要なもの
- FFmpeg
- 立ち絵画像4枚
- 音声
FFmpeg
音声解析して口パクさせてるのでFFmpegが必要です。
windowsならpowershellでインストールできます。
winget install --id Gyan.FFmpeg -e手動で設定する場合は以下の手順でパスも通せます。
- https://www.gyan.dev/ffmpeg/builds/を開く
- release builds の ffmpeg-release-essentials.zip をダウンロード
- ZIPを解凍する
- 解凍したフォルダを任意のパスに置く 例)C:\ffmpeg
- C:\ffmpeg\bin\ffmpeg.exe があることを確認
- Windowsの検索で 環境変数 と入力
- システム環境変数の編集 を開く
- 環境変数 をクリック
- 上側の ユーザー環境変数 から Path を選択
- 編集 → 新規 をクリック
- 以下を追加
C:\ffmpeg\bin- OKで閉じる
- コマンドプロンプトを開き直して確認
ffmpeg -versionこれでバージョンが表示されればFFmpegは使えます。

立ち絵画像4枚
立ち絵は以下の4枚を用意します。
- 目開・口閉
- 目開・口開
- 目閉・口開
- 目閉・口閉
これはろてじんさんが紹介しているPromptをお借りしました。

元になる画像を入れて、そのまま記事にあるPromptを入力すれば表情差分を作って貰えます。
Gemini、grok、ChatGPTどれでも作れました。
元画像:

・grok(1024×1024)

・Gemini(2048×2048)

・ChatGPT(1254×1254)

若干位置や距離感変わっちゃってるんですが、Geminiが一番解像度高くて綺麗に出せてました。
これを4分割します。
分割だけできればいいので今回はオンラインツール使います。
画像取り込んで縦横調整→画像を分割でzipがダウンロードできます。

解凍すると中に4分割された画像があるので、それぞれ以下のような名前にして指定のパスに置きます。

my-video/
public/
character/
avatar-eyes-open-mouth-closed.png
avatar-eyes-open-mouth-open.png
avatar-eyes-closed-mouth-closed.png
avatar-eyes-closed-mouth-open.pngImageMagickインストールしている方ならコマンドでも分割可能です。
magick input.png -crop 1024x1024 +repage output_%02d.png一応canvaでもImage Splitterというツールを使えばできます。

ただ無料期間はあるもののリサイズが有料みたいなので、分割だけなら上記のツールかコマンドの方が無難だと思います。
音声
音声は生成するならIrodori-TTSがおすすめです。

とりあえず試すだけならフリー素材の音声でもOKです。
音声はaudioフォルダにnarration.wavとして置いときます。
my-video/
audio/
narration.wavAIエージェントに仕組みを作って貰う
あとはAIエージェント(Codex, Claudeなど)に指示して口パクする仕組みを作って貰います。
こんな感じで行けると思います。
Remotionで、用意済みの音声と4枚の立ち絵画像を使って、口パクと瞬きをする動画を作ってください。
画像は public/character にあります。
音声は public/audio/narration.wav にあります。
4枚の画像は、目開き口閉じ、目開き口開き、目閉じ口閉じ、目閉じ口開きの状態です。
音声に合わせて口が開閉するようにしてください。
瞬きも自然に入れてください。
画像や音声は新しく作らず、配置済みのファイルを使ってください。
必要なファイル構成を確認したうえで、Remotionで動く形に実装してください。
音声に合わせて口を動かすために必要なスクリプトと、動画側のTSXファイルも作ってください。
最後に、実行するコマンドと確認方法を教えてください。これでスクリプト実行コマンドなどを出してくれるのでそのまま実行してください。
分からなければAIに「やってください」って言えばやってくれます。
ただちょっと指示が雑なので、時間が掛かるのと、一発で成功するかわかりません。
もしうまく動作しなかったら、結果を報告して少しずつ修正していく必要があります。
具体的に指示する
一回作って貰った仕組みを見ると、
- 音声を解析する
- 音声ごとに閾値で開閉を指定したjson、またはtsファイルを作る
- tsxファイルでjsonと画像を紐づける
みたいなことをやってました。
なのでこの実装で良いなら、具体的に指示した方がスムーズです。
最後のコマンドとかは任意なので、不要なら削除してください。
Remotionプロジェクトに、4枚のPNG画像と1つの音声ファイルを使った口パク・瞬き機能を追加してください。
前提:
- プロジェクトルートは my-video
- キャラクター画像は public/character に配置済み
- 音声は public/audio/narration.wav に配置済み
- 画像と音声は変更しないでください
画像ファイル:
- public/character/avatar-eyes-open-mouth-closed.png
- public/character/avatar-eyes-open-mouth-open.png
- public/character/avatar-eyes-closed-mouth-closed.png
- public/character/avatar-eyes-closed-mouth-open.png
作ってほしいもの:
- scripts/generate-lipsync.mjs
- src/lipsync/mouth-cues.json
- src/Composition.tsx
- 必要なら src/Root.tsx
音声解析スクリプトの要件:
- public/audio/narration.wav を読み込む
- ffmpeg を使って音声を mono PCM に変換する
- fps は 30
- sampleRate は 16000
- 1フレームごとに音量を解析する
- 音量がしきい値以上なら 1、未満なら 0 にする
- src/lipsync/mouth-cues.json を生成する
- mouth-cues.json には fps、sampleRate、threshold、mouthByFrame を含める
- mouthByFrame は 0 / 1 の配列にする
Remotion側の要件:
- Composition.tsx で mouth-cues.json を読み込む
- useCurrentFrame() で現在フレームを取得する
- 音声開始からのフレーム番号で mouthByFrame を参照する
- mouthByFrame が 1 なら口開き画像、0 なら口閉じ画像を表示する
- 瞬きはComposition.tsx側で約5秒周期にする
- 瞬き中も口の開閉状態を維持する
- 通常時 + 0 は avatar-eyes-open-mouth-closed.png
- 通常時 + 1 は avatar-eyes-open-mouth-open.png
- 瞬き中 + 0 は avatar-eyes-closed-mouth-closed.png
- 瞬き中 + 1 は avatar-eyes-closed-mouth-open.png
- 音声は public/audio/narration.wav を Audio で再生する
- 画像は Img と staticFile() で読み込む
- キャラクターは画面右下に表示する
最後に:
- 生成した mouth-cues.json の意味を説明してください
- 実行コマンドを教えてください
- npm run dev で確認できる状態にしてください一気にやるのが不安ならスクリプトとtsxファイルの作成を分けると確認しやすくなります。
・音声解析スクリプト作成用Prompt
Remotionプロジェクト用に、音声から口パク用JSONを生成するNode.jsスクリプトを作ってください。
前提:
- プロジェクトルートは my-video
- 音声ファイルは public/audio/narration.wav
- 出力先は src/lipsync/mouth-cues.json
- キャラクター画像はすでに public/character に配置済みです
- 今回作るのは音声解析スクリプトだけです
- TSX側の実装は不要です
要件:
- scripts/generate-lipsync.mjs を作る
- ffmpegを使って narration.wav を mono PCM に変換する
- fps は 30
- sampleRate は 16000
- 1フレームごとに音量を解析する
- 音量がしきい値以上なら 1、未満なら 0 にする
- 出力JSONには fps、sampleRate、threshold、mouthByFrame を含める
- mouthByFrame は 0 / 1 の配列にする
- 0 は口閉じ、1 は口開きとして TSX 側で使う想定
- src/lipsync フォルダがなければ作成する
- 実行コマンドも教えてください
出力例:
{
"fps": 30,
"sampleRate": 16000,
"threshold": 0.05,
"mouthByFrame": [0, 1, 1, 0, 0, 1]
}これを実行するとmy-video\scriptsにgenerate-lipsync.mjsというファイルが作られます。
実行コマンドも出力してくれます。
node scripts/generate-lipsync.mjsこれを実行すると、音声を解析してsrc/lipsync/mouth-cues.jsonが作られます。
jsonはこんな感じになってて、音声解析→閾値で判定して0,1で開閉を指定しているようです。
{
"fps": 30,
"mouthByFrame": [0, 1, 1, 0, 0, 1]
}
# 0 = 口を閉じる
# 1 = 口を開く・tsxファイル作成用Prompt
Remotionプロジェクトに、口パクと瞬きを表示する Composition.tsx を作ってください。
前提:
- プロジェクトルートは my-video
- キャラクター画像4枚は public/character に配置済み
- 音声は public/audio/narration.wav に配置済み
- 口パク用JSONは src/lipsync/mouth-cues.json に生成済み
- 音声解析スクリプトはすでにあります
- 今回は TSX 側の実装だけ行ってください
画像ファイル:
- public/character/avatar-eyes-open-mouth-closed.png
- public/character/avatar-eyes-open-mouth-open.png
- public/character/avatar-eyes-closed-mouth-closed.png
- public/character/avatar-eyes-closed-mouth-open.png
実装要件:
- src/Composition.tsx を作成または更新する
- Remotion の AbsoluteFill, Audio, Img, Sequence, staticFile, useCurrentFrame を使う
- src/lipsync/mouth-cues.json を import する
- useCurrentFrame() で現在フレームを取得する
- 音声開始からのフレーム番号で mouthByFrame を参照する
- mouthByFrame が 1 なら口開き画像、0 なら口閉じ画像を表示する
- 瞬きは TSX 側で約5秒周期にする
- 瞬き中も口の開閉状態を維持する
- 通常時 + 0 は avatar-eyes-open-mouth-closed.png
- 通常時 + 1 は avatar-eyes-open-mouth-open.png
- 瞬き中 + 0 は avatar-eyes-closed-mouth-closed.png
- 瞬き中 + 1 は avatar-eyes-closed-mouth-open.png
- 音声は public/audio/narration.wav を Audio で再生する
- 画像は Img と staticFile() で読み込む
- キャラクターは画面右下に表示する
- Root.tsx の durationInFrames が短すぎる場合は、音声の長さに合わせやすいよう仮で長めに調整してください
- 音声解析スクリプトは変更しないでくださいこれでsrc/Composition.tsxが作成、または更新されます。
npm run devで起動すれば口パクの確認が可能です。

自然言語と具体的なPromptの両方で実装を試したんですが、キャラクターの配置はランダムだったりします。
あとAIに表情変える指示入れて4つ作って貰いましたが、人体のサイズも変わっていて外側がピクピクしてます。
なので手間はかかりますが、こういう部分もしっかりしたいなら、インペイントなどで一個ずつ表情作った方が良いです。
解像度もデフォルトだと1280×720なので、この辺り調整したい場合は別途AIに指示してみてください。
以上Remotionで口パクを実装する方法について紹介しました。
参考になれば幸いです。

