🎬

AIで作る業務動画 Day 7|日本語音声でリップシンクJSONを生成する

に公開

今日のゴール

Rhubarb Lip Syncで日本語音声からリップシンクデータ(JSON)を生成して、実用レベルの精度が出るか検証する。


Day 6でRhubarbをインストールして英語音声では動いた。今日は本番環境で使う日本語音声で試す。

正直、Rhubarbは英語向けに作られているので、日本語でどこまで使えるか不安があった。

phonetic modeとは

Rhubarbには2つの認識エンジンがある。

エンジン 方式 対応言語
PocketSphinx 単語ベース 英語のみ
Phonetic 音素ベース 言語非依存

日本語音声にはphonetic modeを使う。

phonetic modeは「単語」ではなく「音素」(個々の発音)を認識する方式で、言語に依存しない。開発者によると、イタリア語などの非英語でも「英語の音素に似ている部分」を認識できるとのこと。

コマンドは-r phoneticオプションを付けるだけ。

rhubarb -r phonetic -f json -o output.json input.wav

前提条件

  • Rhubarb Lip Sync v1.14.0がインストール済み(Day 6)
  • Gemini TTSで生成した日本語音声ファイル(Day 3-5)

手順

Step 1: テスト用音声の準備

Day 3-5で生成した7つの音声ファイルをテストに使う。

ファイル 音声長 内容
keigo_01.wav 4.13秒 敬語テスト
kougo_01.wav 4.41秒 口語テスト
kanji_01.wav 2.45秒 漢字テスト
choubun_01.wav 15.01秒 長文テスト
voice_kore.wav 4.81秒 Koreボイス
day04_combined.wav 41.55秒 掛け合い音声
day05_combined.wav 41.07秒 統合スクリプト出力

Step 2: リップシンクJSON生成

phonetic modeで実行する。

rhubarb -r phonetic -f json -o keigo_01.json keigo_01.wav

出力例:

Application startup. Input file: keigo_01.wav
Progress: Processing audio file...
Progress: Done.

全7ファイルで実行した結果:

ファイル 音声長 キュー数 キュー/秒 使用Shape 結果
keigo_01 4.13秒 31 7.5 7種類 成功
kougo_01 4.41秒 32 7.3 6種類 成功
kanji_01 2.45秒 19 7.8 6種類 成功
choubun_01 15.01秒 106 7.1 9種類 成功
voice_kore 4.81秒 32 6.7 9種類 成功
day04_combined 41.55秒 279 6.7 9種類 成功
day05_combined 41.07秒 267 6.5 9種類 成功

全テスト成功率: 100%

キュー/秒は平均7前後。日本語の標準的な発話速度(6-8音素/秒)と概ね一致しており、口の動きが自然なペースで検出されている。

Step 3: JSONの構造確認

JSONが生成できたので、中身をサンプリングで確認した。

keigo_01.jsonの冒頭部分:

{ "start": 0.00, "end": 0.15, "value": "X" },  // 発話前の無音
{ "start": 0.15, "end": 0.26, "value": "A" },  // 開口
{ "start": 0.26, "end": 0.37, "value": "B" },  // 閉口
...
{ "start": 3.96, "end": 4.13, "value": "X" }   // 発話後の無音

確認できたこと:

観点 結果
start/endの連続性 ギャップなし、正常
無音区間の検出 先頭・末尾にX(無音)が出現
キュー密度 平均7キュー/秒(日本語の発話速度と一致)

実際に口パクが自然に見えるかは、動画を作成してから目視で確認する予定(Day 9の統合テストで実施)。

現時点での判断:

  • キュー密度が妥当なので、口の動きが速すぎ/遅すぎにはならないはず
  • 無音区間が適切に検出されているので、話していないときは口が閉じるはず
  • ただしRhubarbは英語音素ベースなので、日本語母音の厳密なマッピングは期待できない

アニメの口パクで重要なのは「口が動いているか」であって、言語学的な正確さではない。視覚的に違和感がなければ問題ないはずだが、これは動画を作ってから判断する。

Step 4: JSON出力仕様の確定

生成されたJSONを見ると、RhubarbはA〜H、Xの9種類の口形状を出力している。

{
  "metadata": {
    "soundFile": "keigo_01.wav",
    "duration": 4.13
  },
  "mouthCues": [
    { "start": 0.00, "end": 0.15, "value": "X" },
    { "start": 0.15, "end": 0.26, "value": "A" },
    { "start": 0.26, "end": 0.37, "value": "B" },
    ...
  ]
}

9種類のうち、G(歯を閉じた口)とH(舌を見せる口)は英語の"L"音などで使われる形で、日本語ではほぼ出現しない。Xは無音区間を示す。

そこで、口パク画像は基本の6種類(A〜F)だけ用意して、G・H・Xは近い形にマッピングする方針にした。

Rhubarb出力 使用する画像 理由
A〜F そのまま 基本形状
G B 閉じた口に近い
H C やや開いた口に近い
X A 無音なので閉じた口

Rhubarbの--extendedShapes ""オプションで出力を6種類に制限する方法もあるが、認識精度に影響する可能性があるため採用しなかった。生データを残しておいて、Remotion側で正規化する方が柔軟性がある。

動作確認チェックリスト

確認項目 結果
phonetic modeでJSONが生成される 達成
日本語音声でエラーが出ない 達成(7ファイル全て成功)
mouthCues配列にキューが含まれる 達成
キュー密度が妥当(6-8/秒) 達成(平均7/秒)
視覚的に自然か Day 9で確認予定

うまくいかない場合

症状 原因 対処
「Cannot read audio file」 対応形式外 WAV/OGG形式に変換
キューがほぼ「X」のみ 無音が多い/音量が小さい 音声ファイルを確認
処理が終わらない ファイルが大きすぎる --threadsオプションで並列化

今日の成果物

  • 日本語音声7ファイルのリップシンクJSON(全て正常生成)
  • JSON構造の確認完了(キュー密度、無音検出が妥当)
  • JSON出力仕様: 9形状 → 6形状にフォールバック

検証環境

項目 バージョン
OS Windows 11 Pro
Rhubarb Lip Sync 1.14.0
テスト音声 Gemini TTS生成(Day 3-5)
検証日 2026-01-07

明日のテーマ: Rhubarbの口パクデータ(mouthCues)が何を意味するか深掘りする。A〜Xの各形状が日本語のどの発音に対応するかをまとめて、Remotionで使えるマッピング表を作成する。


シリーズを追いかける

→ 著者ページ(Zenn)

Discussion