remotion_docker_devcontainer / voicevox-remotion-template /
@Syuji Syuji authored 5 hours ago
..
public 立ち絵素材を追加 6 hours ago
scripts 音声同期口パク機能を実装 18 hours ago
src 立ち絵セットにデフォルトの説明を追加 5 hours ago
.eslintrc.cjs 音声同期口パク機能を実装 18 hours ago
AGENTS.MD プロジェクト作業方針を追加する 7 days ago
README.md 立ち絵差し替え手順を追記 5 hours ago
package-lock.json Remotion依存関係を更新 1 day ago
package.json 音声同期口パク機能を実装 18 hours ago
tsconfig.json Remotionプロジェクト設定を追加する 8 days ago
README.md

Remotion x VOICEVOX ゆっくり解説テンプレート

Remotion と VOICEVOX を組み合わせて、複数キャラクターが時系列で登場・発話する動画テンプレートです。 サンプルテーマは「ネコミミはなぜかわいいのか?」です。

使い方

1. 依存関係をインストール

npm install

2. VOICEVOX エンジンを起動

VOICEVOX のエンジンを起動してください。既定では http://host.docker.internal:50021 を参照します。 詳細は公式リポジトリを参照してください。

https://github.com/VOICEVOX/voicevox_engine

3. 脚本を編集

src/data/script.tscharacterstimeline を編集します。

show("sayo", {caption: "ネコミミ代表として、小夜が登場!"});
say("sayo-001", "sayo", "小夜です。ネコミミ代表として、耳のかわいさを証明しに来ました。");
say("zunda-005", "zundamon", "それじゃあ、また次回なのだ!");
  • characters: 表示名、VOICEVOX の speakerName / styleName、立ち絵設定を定義します。
  • initialVisibleCharacters: 動画開始時から表示するキャラクターを定義します。
  • show(...): キャラクターを画面に登場させ、任意の説明字幕を出します。
  • say(...): キャラクターに読み上げさせ、字幕と音声を同期します。
  • 行ごとにスタイルを変える場合は say(..., {voicevox: {styleName: "スタイル名"}}) を使います。

4. 音声を生成

npm run voice:generate

src/data/script.tssay(...) から public/audio/lines/*.wav を生成し、 src/data/voicevox-manifest.json に長さ・話者・スタイル情報を記録します。 音声が未生成の行は、プレビュー時にテキスト長から尺を推定します。

ピザ窯サンプルの音声を生成する場合は、次を実行します。

npm run voice:generate:pizza-kiln

5. 口パク指示データを生成

Rhubarb Lip Sync CLI を使い、VOICEVOX 音声から口形タイムラインを生成します。

npm run lipsync:generate

生成物は、Rhubarb の生 JSON が public/lipsync/raw/*.rhubarb.json、 Remotion 用に正規化した JSON が src/generated/lipsync/*.mouth.json、 プレビュー時に同期 import する集約 manifest が src/generated/lipsync/manifest.json です。

単体音声だけ再生成する場合は、次のように音声ファイルを指定できます。

npm run lipsync:generate -- public/audio/lines/zunda-001.wav

処理順は 1. npm run voice:generate2. npm run lipsync:generate3. npm run start です。音声を作り直したら、口パク指示データも再生成してください。

Rhubarb CLI は次の順で検出します。

  • RHUBARB_BIN に指定された実行ファイル
  • node_modules/.bin/rhubarb
  • tools/rhubarb/ または vendor/rhubarb/ 配下の実行ファイル
  • PATH 上の rhubarb

Windows / Linux / macOS で実行ファイル名が異なることがあります。 Dev Container で使う場合は Linux 版 Rhubarb を配置し、必要なら RHUBARB_BIN=/usr/local/bin/rhubarb のように指定してください。

日本語音声では Rhubarb の phonetic recognizer を使います。音声のみからの推定なので、 日本語の母音完全一致ではなく、動画用に自然に見える口パクを目的にしています。 Rhubarb 口形は次のように丸めます。

{
  X: "rest",
  A: "closed",
  B: "i",
  C: "e",
  D: "a",
  E: "o",
  F: "u",
  G: "i",
  H: "e",
}

6. プレビュー

npm run start

7. レンダリング

npm run render YukkuriZundamon out/video.mp4

編集ポイント

  • 時系列脚本: src/data/script.ts
  • 音声タイミング: src/data/voicevox-manifest.json (自動生成)
  • 口パクタイミング: src/generated/lipsync/manifest.json (自動生成)
  • 映像の構成: src/yukkuri-composition.tsx
  • 立ち絵セット: src/standee-sets.ts

字幕方針

本テンプレートは、短編 VOICEVOX ドラマ動画や、実写映像を背景にした解説動画での利用を主用途としています。

そのため、字幕は @remotion/captionsCaption 型 JSON による単語単位・時刻単位の正式な字幕データとしては扱わず、src/data/script.tssay(...) / show(...) に紐づく発話単位・シーン単位の表示テキストとして扱います。

say(...) の字幕は VOICEVOX で生成した音声尺、または未生成時の推定尺に同期して表示します。SRT/VTT 互換、単語単位ハイライト、自動文字起こし字幕が必要になった場合は、その時点で @remotion/captions の導入を検討します。

VOICEVOX設定

  • VOICEVOX_URL (既定: http://host.docker.internal:50021)
  • 話者とスタイルは src/data/script.tscharacters.*.voicevox で指定します。

立ち絵セットの追加・差し替え

立ち絵本体、口パク画像、通常表示時の基本レイアウトは src/standee-sets.tsstandeeSets にまとめています。 新しい立ち絵を追加する場合は、次の流れで修正します。

1. 画像素材を配置

public/image/ 配下に、立ち絵本体と口パク画像を配置します。imagePathmouthImageDir には public からの相対パスを指定します。

public/image/zundamon_ohnegus_ai_base.png
public/image/zundamon-ohnegus-ai-rhubarb-mouths/
  a.png
  i.png
  u.png
  e.png
  o.png
  closed.png
  rest.png

口パク画像は、立ち絵本体と同じキャンバス寸法・同じ位置合わせにしてください。 口だけが差分として重なる前提で、LipSyncedStandeeImage が本体画像の上に同じサイズで重ねます。

2. src/standee-sets.ts にセットを追加

standeeSets に、素材パスと基本レイアウトを追加します。

"zundamon_ohnegus_ai": {
  kind: "zundamon",
  imagePath: "image/zundamon_ohnegus_ai_base.png",
  mouthImageDir: "image/zundamon-ohnegus-ai-rhubarb-mouths",
  imageLayout: {
    width: 540,
    maxHeight: 730,
    translateY: 0,
    flipX: true,
  },
},
  • kind: キャラクター種別です。既存は "zundamon" / "sayo" です。
  • imagePath: 立ち絵本体のパスです。
  • mouthImageDir: a.png などの口パク画像を置いたディレクトリです。
  • imageLayout.width: 通常コンポジションでの表示幅です。
  • imageLayout.maxHeight: 通常コンポジションでの最大表示高さです。
  • imageLayout.translateY: 通常コンポジションで上下位置を微調整します。
  • imageLayout.flipX: 左右反転したい場合に true にします。

3. キャラクター定義で使うセットを選ぶ

通常コンポジションは src/data/script.ts、ピザ窯コンポジションは src/data/pizza-kiln/script.tscharacters.*.avatar で、使いたい立ち絵セットを展開します。 対象ファイルで getStandeeSet を import して使います。

avatar: {
  ...getStandeeSet("sayo_ohnegus_ai"),
  accentColor: "#6b5f83",
  nameplatePosition: "none",
  idleAnimationType: "none",
  speakingAnimationType: "rhubarbLipSync",
},

speakingAnimationType: "rhubarbLipSync" を指定すると、src/generated/lipsync/manifest.json の口形タイムラインに合わせて mouthImageDir の画像を切り替えます。

4. コンポジション固有の見栄えを調整

通常の全身表示は src/standee-sets.tsimageLayout で調整します。 コンポジションごとに特別な配置がある場合だけ、描画側を調整します。

  • 通常コンポジション: src/yukkuri-composition.tsxStage / CharacterAvatar
  • ピザ窯コンポジション: src/pizza-kiln-composition.tsxSayoStandee

ピザ窯コンポジションは、通常背景用の STAGE_STANDEE_* と、実写動画右下用の CORNER_* でサイズと切り抜き方を分けています。

5. 確認

変更後は、可能な範囲で次を実行します。

./node_modules/.bin/tsc --noEmit
npm run lint
./node_modules/.bin/remotion still src/index.ts YukkuriZundamon /tmp/yukkuri.png --frame=160
./node_modules/.bin/remotion still src/index.ts PizzaKilnSayo /tmp/pizza-kiln.png --frame=30

音声や say(...) を変更した場合は、npm run voice:generatenpm run lipsync:generate も実行してください。立ち絵画像だけを差し替える場合は、 口パクタイミングの再生成は不要です。

以前の public/audio/zundamon.txtsrc/data/script.json は互換用に残していますが、現在は参照しません。