対象読者: Three.js / Next.js でVRMアバターを動かしたい開発者、AIを使ってYouTube動画やバーチャルキャラクターを作りたい方
前提知識: TypeScript / Python の基礎知識、REST APIの概念
はじめに
「アバターの口を音声に合わせて動かしたい」——バーチャルYouTuber、AIキャラクター、自動生成動画など、リップシンクの需要は急速に高まっています。
本記事では、実際に6つの日本語TTSプロバイダーを検証した経験をもとに、以下を解説します。
- VRMアバターにリップシンクさせる仕組みと実装方法
- MeCab・WhisperX など必要なツールの役割を初心者向けに解説
- TTSプロバイダー6社の特徴・APIオプション・ルビ対応・品質の比較
- オープンソースエンジンをクラウド(GCP・AWS)にデプロイする方法
- 著者による最終推奨プロバイダー
VRMとリップシンクの基礎知識
VRMとは
VRM(Virtual Reality Model)は、Pixiv が策定した3Dアバター向けのオープンファイルフォーマットです。Unity・Unreal Engine・ブラウザ(Three.js)などで広く使われており、@pixiv/three-vrm ライブラリを使えばブラウザ上でも表示・制御できます。
参考: VRM公式サイト
ブレンドシェイプ(Blend Shape)とは
VRMファイルには、顔の表情を制御するためのブレンドシェイプというパラメータが内蔵されています。「顔の変形レシピ」のようなもので、0.0(全閉じ)〜1.0(全開き)の数値で口や目の形を連続的に変化させます。
リップシンクには、日本語の5母音に対応した以下の5パラメータを使います。
| パラメータ名 | 対応する母音 | 代表的な音 | 口の形のイメージ |
|---|---|---|---|
aa(A) |
あ段 | か・さ・た・な… | 大きく縦に開く |
ih(I) |
い段 | き・し・ち・に… | 横に引いて薄く開く |
ou(U) |
う段 | く・す・つ・ぬ… | 前にすぼめる |
ee(E) |
え段 | け・せ・て・ね… | 中程度に開く |
oh(O) |
お段 | こ・そ・と・の… | 丸く開く |
これらを音声の発音タイミングに合わせてリアルタイムで動かすのがリップシンクです。
// three-vrm でリップシンク値を適用する例
vrm.expressionManager.setValue('aa', 0.9) // 「か」の口
vrm.expressionManager.setValue('ih', 0.0)
vrm.expressionManager.setValue('ou', 0.0)
vrm.expressionManager.setValue('ee', 0.0)
vrm.expressionManager.setValue('oh', 0.0)
vrm.expressionManager.update(delta)
リップシンクの基本フロー
① テキスト → TTS(音声合成)
↓
② 文字単位タイムスタンプ取得
(例: "き" → 0ms〜80ms、"か" → 80ms〜160ms)
↓
③ 文字 → 母音クラスへ変換
(例: "き" → 母音 i → ブレンドシェイプ I)
↓
④ タイムライン上にキーフレーム生成
↓
⑤ 再生中に補間しながら VRM に適用
②のタイムスタンプ取得が最大の難所です。TTSプロバイダーによって取り方が全く異なります。
日本語リップシンク特有の難しさ
問題1: 漢字タイムスタンプは口の形に変換できない
TTSのAPIが「漢字のまま」文字ごとのタイムスタンプを返してくる場合があります。
TTSが返すタイムスタンプ:
"機" → 0〜80ms, "械" → 80〜160ms ...
ブレンドシェイプへの変換を試みると:
charToVowel('機') = null ← 漢字は母音変換テーブルにない
→ 口の形が計算できない → リップシンクが動かない
問題2: 英語略語・漢字の誤読
「AI」「API」などをそのまま渡すとエンジンによっては「アイ」「アピ」と読まれます。また「今日」「行列」などの同形異音語も誤読の原因になります。
問題3: 拗音(きょ・しゅ等)の扱い
「きょ」は1モーラ(発音単位)ですが、文字としては「き」と「ょ」の2文字です。別々のタイムスタンプとして扱うと口の形の切り替えが不自然になります。
必要なツールの詳細解説
ツール1: MeCab(形態素解析器)
MeCabとは
MeCab(和布蕪)は、奈良先端科学技術大学院大学の工藤拓氏が開発した日本語形態素解析器です。オープンソース(BSD/GPL v2/LGPLv2)で無料で使えます。
参考: MeCab GitHub
「形態素解析」と聞くと難しそうですが、要するに**「日本語の文章を単語に区切って、各単語の読み方を教えてくれるツール」**です。
入力: "今日の生成AIについて解説します"
MeCab の出力:
今日 → 読み: きょう モーラ: [きょ, う]
の → 読み: の
生成 → 読み: せいせい モーラ: [せい, せい]
AI → 読み: エーアイ
について → モーラ: [に, つい, て]
解説 → 読み: かいせつ モーラ: [かい, せつ]
リップシンクでの役割
漢字のタイムスタンプをモーラ(発音の最小単位)ごとのタイムスタンプに変換します。
TTSが返したタイムスタンプ:
"機" 0-80ms, "械" 80-160ms ← 漢字のまま
MeCab で変換:
"機械" → モーラ [き, かい] に160msを均等分割
き 0- 53ms → 母音 i → ブレンドシェイプ I
か 53-107ms → 母音 a → ブレンドシェイプ A
い 107-160ms → 母音 i → ブレンドシェイプ I
セットアップ
MeCab はローカルにインストールして使います。FastAPI でサーバー化すると Next.js などから HTTP API として呼び出せます。
# macOS でのインストール
brew install mecab mecab-ipadic
# FastAPI で MeCab をAPIサーバー化する例
from fastapi import FastAPI
import MeCab
app = FastAPI()
tagger = MeCab.Tagger()
@app.post("/analyze")
def analyze(req: dict):
node = tagger.parseToNode(req["text"])
morphemes = []
while node:
if node.surface:
features = node.feature.split(",")
reading = features[7] if len(features) > 7 else node.surface
morphemes.append({"surface": node.surface, "reading": reading})
node = node.next
return {"morphemes": morphemes}
ツール2: WhisperX(音声アライメント)
WhisperXとは
WhisperX は、OpenAI の音声認識モデル「Whisper」を拡張したオープンソースツールです。Max Bain らが開発し、INTERSPEECH 2023 に論文が掲載されています。
参考: WhisperX GitHub
WhisperX には2つのモードがあります。
| モード | 機能 | テキスト |
|---|---|---|
文字起こし (transcribe) |
音声 → テキストを生成 | 不要 |
強制アライメント (align) |
「このテキストがこの音声のどこで発音されているか」を計算 | 必須 |
リップシンクで使うのは強制アライメントのみです。TTS が音声データだけ返してタイムスタンプを返さない場合(Fish Audio S2・Google Chirp3-HD など)に、このツールで後付けタイムスタンプを取得します。
# 起動時に1回だけアライメントモデルを読み込む
align_model, align_metadata = whisperx.load_align_model(
language_code="ja", device="cuda" # CPU のみなら "cpu"
)
# 音声ファイルとテキストを渡して強制アライメント
segments = [{"text": "きょうのないようについてかいせつします", "start": 0.0, "end": 5.0}]
result = whisperx.align(segments, align_model, align_metadata, audio, device,
return_char_alignments=True)
# → {"char": "き", "start": 0.10, "end": 0.18} のような文字ごとのタイムスタンプが得られる
重要ポイント
- テキストは必須: テキストなしでは
align()は動きません - かな表記が高精度: 漢字よりひらがな表記の方が精度が上がります
- GPU推奨: NVIDIA GPU があると高速ですが、CPU のみでも動作します
ツール3: three-vrm(VRM表示ライブラリ)
@pixiv/three-vrm は Pixiv が開発したブラウザ向けVRM表示ライブラリです。
npm install @pixiv/three-vrm three
import { VRMLoaderPlugin } from '@pixiv/three-vrm'
const loader = new GLTFLoader()
loader.register(parser => new VRMLoaderPlugin(parser))
const gltf = await loader.loadAsync('/avatar.vrm')
const vrm = gltf.userData.vrm
// リップシンクの適用(毎フレーム実行)
vrm.expressionManager.setValue('aa', blendshapeA)
vrm.expressionManager.update(deltaTime)
TTSプロバイダー 詳細解説
1. VOICEVOX
| 項目 | 内容 |
|---|---|
| 種別 | オープンソース(無料) |
| 動作形態 | ローカルアプリ / ローカルAPIサーバー |
| 開発者 | ヒホ氏(個人開発) |
| 価格 | 無料 |
| 公式サイト | https://voicevox.hiroshiba.jp/ |
| APIドキュメント | https://voicevox.github.io/voicevox_engine/api/ |
VOICEVOX は日本語特化の無料音声合成エンジンです。「ずんだもん」「四国めたん」などのキャラクターボイスが用意されており、ゲーム・動画制作の現場で広く使われています。クラウドAPIではなく、ローカルで起動して使います。
audio_query のレスポンスにモーラ(発音単位)ごとの時間情報が含まれるため、MeCab・WhisperX なしでリップシンクが実現できます。
制約: キャラクターボイスは固定で、話者のボイスクローンには対応していません。
利用可能なAPIパラメータ
POST /audio_query で合成パラメータを取得し、POST /synthesis で音声を生成します。
| パラメータ | 範囲 | デフォルト | 説明 |
|---|---|---|---|
speedScale |
0.5〜2.0 | 1.0 | 話速の倍率 |
pitchScale |
-0.15〜0.15 | 0.0 | ピッチの調整 |
intonationScale |
0.0〜2.0 | 1.0 | イントネーション強度 |
volumeScale |
0.0〜2.0 | 1.0 | 音量の倍率 |
prePhonemeLength |
— | — | 発話前の無音長 |
postPhonemeLength |
— | — | 発話後の無音長 |
outputSamplingRate |
— | 24000 | 出力サンプリングレート |
# Docker で起動
docker run --rm -p 50021:50021 voicevox/voicevox_engine:cpu-ubuntu20.04-latest
# 利用例
query = requests.post(
"http://localhost:50021/audio_query",
params={"text": "こんにちは", "speaker": 1}
).json()
query["speedScale"] = 0.9
query["intonationScale"] = 1.2
audio = requests.post(
"http://localhost:50021/synthesis",
params={"speaker": 1},
json=query
).content
ルビ・読み指定: SSML 非対応。 accent_phrases の各モーラの moras[].text や pitch を直接操作することでアクセントの調整は可能ですが、外部から読みを指定する仕組みはありません。
日本語品質: 評価では英語の外来語・ローン語の発音が不自然になりやすく、イントネーションやアクセントに違和感が残る場面があります。
2. AivisSpeech
| 項目 | 内容 |
|---|---|
| 種別 | オープンソース(無料) |
| 動作形態 | ローカルアプリ / ローカルAPIサーバー / Docker |
| 開発者 | Aivis Project |
| 価格 | 無料 |
| GitHub | https://github.com/Aivis-Project/AivisSpeech-Engine |
| APIドキュメント | https://aivis-project.github.io/AivisSpeech-Engine/api/ |
AivisSpeech は VOICEVOX 互換の API を持つ日本語特化TTS エンジンです。Style-Bert-VITS2 と OpenJTalk を組み合わせたアーキテクチャにより、VOICEVOX よりも自然な日本語イントネーションを実現しています。
利用可能なAPIパラメータ
VOICEVOX と同じ audio_query / synthesis 構造ですが、AivisSpeech 独自の拡張があります。
| パラメータ | 範囲 | デフォルト | 説明 |
|---|---|---|---|
speedScale |
0.5〜2.0 | 1.0 | 話速 |
pitchScale |
-0.15〜0.15 | 0.0 | ピッチ |
intonationScale |
0.0〜2.0 | 1.0 | イントネーション強度(感情の強さに相当) |
volumeScale |
0.0〜2.0 | 1.0 | 音量 |
prePhonemeLength |
— | — | 発話前の無音長 |
postPhonemeLength |
— | — | 発話後の無音長 |
また AivisSpeech は /synthesis_timed というモーラ単位の正確なタイムスタンプ付き音声合成エンドポイントも提供しており、リップシンク精度を高められます。
# Docker で起動(公式イメージ)
# CPU のみ
docker run -p 10101:10101 ghcr.io/aivis-project/aivisspeech-engine:cpu-latest
# GPU 搭載(NVIDIA)
docker run --gpus all -p 10101:10101 ghcr.io/aivis-project/aivisspeech-engine:nvidia-latest
# AivisSpeech の利用例(VOICEVOX と同じコードが動く)
query = requests.post(
"http://localhost:10101/audio_query",
params={"text": "こんにちは", "speaker": 888753760} # スピーカーID
).json()
query["speedScale"] = 0.95
query["intonationScale"] = 1.3 # 感情の強さを上げる
audio = requests.post(
"http://localhost:10101/synthesis",
params={"speaker": 888753760},
json=query
).content
ルビ・読み指定: SSML 非対応。audio_query の accent_phrases を操作することで読みや音程を制御できますが、外部から直接ルビを指定する仕組みは持っていません。
カスタムボイスについて: .aivm 形式のカスタム音声モデルを作成・追加することでオリジナルボイスに対応できますが、モデル作成には専門的な工数が必要です。
日本語品質: VOICEVOX よりも自然ですが、実際の検証ではアクセントに違和感が残る場面があります。
クラウド(GCP・AWS)へのデプロイ
AivisSpeech・VOICEVOX はどちらもDocker イメージが提供されているため、ローカル専用ではなくクラウドサービスとして運用できます。
Google Cloud Run へのデプロイ例
# cloudbuild.yaml 抜粋
steps:
- name: 'gcr.io/cloud-builders/docker'
args: ['pull', 'ghcr.io/aivis-project/aivisspeech-engine:cpu-latest']
- name: 'gcr.io/cloud-builders/docker'
args: ['tag', 'ghcr.io/aivis-project/aivisspeech-engine:cpu-latest',
'gcr.io/$PROJECT_ID/aivisspeech']
- name: 'gcr.io/cloud-builders/docker'
args: ['push', 'gcr.io/$PROJECT_ID/aivisspeech']
# Cloud Run にデプロイ
gcloud run deploy aivisspeech \
--image gcr.io/$PROJECT_ID/aivisspeech \
--port 10101 \
--memory 2Gi \
--region asia-northeast1
AWS ECS / Fargate へのデプロイ例
# ECR にイメージをプッシュ
aws ecr get-login-password | docker login --username AWS --password-stdin $ECR_URI
docker pull ghcr.io/aivis-project/aivisspeech-engine:cpu-latest
docker tag ghcr.io/aivis-project/aivisspeech-engine:cpu-latest $ECR_URI/aivisspeech:latest
docker push $ECR_URI/aivisspeech:latest
# ECS タスク定義で PORT=10101 を環境変数に設定してデプロイ
注意: モデルファイル(
.aivm)はコンテナ起動時にマウントするか、GCS / S3 からダウンロードする仕組みを用意する必要があります。Cloud Run の場合はステートレスなので、起動時に GCS からモデルを取得するスクリプトを Dockerfile に組み込むのが一般的です。
3. ElevenLabs
| 項目 | 内容 |
|---|---|
| 種別 | クラウドAPI(有料・無料枠あり) |
| 動作形態 | クラウドAPI |
| 開発者 | ElevenLabs |
| 価格 | Pro プラン $99/月〜 |
| 公式サイト | https://elevenlabs.io/ |
多言語対応の音声合成APIです。英語では非常に高品質で、音声クローンが比較的簡単に作成できます。API がタイムスタンプを直接返すため WhisperX なしでリップシンクに対応できます。
利用可能なAPIパラメータ
| パラメータ | 範囲 | 説明 |
|---|---|---|
stability |
0.0〜1.0 | 安定性。低いほど感情豊かになるが不安定。高いほど単調だが一貫性がある |
similarity_boost |
0.0〜1.0 | クローン声の忠実度。高いほど元の声に近い |
style |
0.0〜1.0 | スタイル誇張度(感情の強さ)。高いほど大げさな表現になる |
speed |
0.7〜1.2 | 話速 |
use_speaker_boost |
boolean | 話者の明瞭さを強化する |
モデルの選択肢
| モデルID | 特徴 |
|---|---|
eleven_v3 |
最新・最高品質・タイムスタンプ対応 |
eleven_multilingual_v2 |
多言語安定版 |
eleven_turbo_v2_5 |
高速版 |
eleven_flash_v2_5 |
最速・最安 |
// ElevenLabs API 呼び出し例
const response = await fetch(
`https://api.elevenlabs.io/v1/text-to-speech/${voiceId}/with-timestamps`,
{
method: "POST",
headers: { "xi-api-key": API_KEY, "Content-Type": "application/json" },
body: JSON.stringify({
text: "こんにちは、動画の説明を始めます。",
model_id: "eleven_v3",
voice_settings: {
stability: 0.5,
similarity_boost: 0.75,
style: 0.3,
speed: 1.0
}
})
}
)
// レスポンスに alignment.characters[] と alignment.character_start_times_seconds[] が含まれる
ルビ・読み指定: SSML <phoneme> タグは英語モデルのみ対応で日本語には使えません。かな変換テキストを渡すと日本語として不自然な発音になることがあります。
4. Inworld TTS
| 項目 | 内容 |
|---|---|
| 種別 | クラウドAPI(有料) |
| 動作形態 | クラウドAPI(REST / WebSocket) |
| 開発者 | Inworld AI |
| 価格 | $25 / 100万文字(TTS-2)、$5 / 100万文字(TTS-1.5 Mini) |
| 公式サイト | https://inworld.ai/tts-api |
リアルタイム対話向けの低遅延TTS APIです(200ms 以下)。API がタイムスタンプを直接返すため WhisperX は不要です。
利用可能なAPIパラメータ
| パラメータ | 範囲・値 | 説明 |
|---|---|---|
deliveryMode |
STABLE / BALANCED / CREATIVE |
発話スタイル。STABLEは一貫性重視、CREATIVEは表現豊か |
speakingRate |
0.5〜1.5 | 話速 |
temperature |
0.0〜2.0 | 表現の多様性(TTS-2のみ)。高いほど豊かで予測不能な表現 |
deliveryMode の目安(stability 値から変換)
| stability | deliveryMode |
|---|---|
| 0.65 以上 | STABLE(安定・一貫性) |
| 0.35〜0.64 | BALANCED(バランス) |
| 0.35 未満 | CREATIVE(表現豊か・不安定) |
モデルの選択肢
| モデルID | 特徴 |
|---|---|
inworld-tts-2 |
最新・最高品質 |
inworld-tts-1.5-max |
高品質・高速 |
inworld-tts-1.5-mini |
超高速・低コスト |
// Inworld TTS API 呼び出し例
const response = await fetch("https://api.inworld.ai/tts/v1alpha/text:synthesize", {
method: "POST",
headers: { "Authorization": `Bearer ${API_KEY}` },
body: JSON.stringify({
text: "こんにちは、解説を始めます。",
voice: { name: voiceId },
audioConfig: { speakingRate: 1.0 },
deliveryMode: "BALANCED",
temperature: 0.5, // inworld-tts-2 のみ
model: "inworld-tts-2"
})
})
ルビ・読み指定: カスタム発音機能が存在しますが英語 IPA のみ対応で日本語には使えません。ElevenLabs と同様に、かな変換テキストを渡すと不自然な発音になる場合があります。
5. Fish Audio S2
| 項目 | 内容 |
|---|---|
| 種別 | クラウドAPI(オープンソースモデルも公開) |
| 動作形態 | クラウドAPI |
| 開発者 | Fish Audio |
| 価格 | $15 / 100万 UTF-8バイト(無料枠あり) |
| 公式サイト | https://fish.audio/ |
| APIドキュメント | https://docs.fish.audio/ |
「TTS Arena」の日本語部門で高評価を獲得している音声合成APIです。15〜45秒の音声サンプルをアップロードするだけで話者クローンが作成できます。
利用可能なAPIパラメータ
| パラメータ | 範囲・値 | デフォルト | 説明 |
|---|---|---|---|
prosody.speed |
0.5〜2.0 | 1.0 | 話速 |
prosody.volume |
-20.0〜20.0 dB | 0.0 | 音量(dB) |
temperature |
0.0〜1.0 | 0.7 | 表現の多様性。低いほど安定、高いほど表現豊か |
top_p |
0.0〜1.0 | 0.7 | サンプリング多様性 |
chunk_length |
100〜300 | 200 | 一度に処理するテキストの文字数。小さいと自然な間が増える |
format |
mp3/wav/pcm/opus |
mp3 |
出力フォーマット |
mp3_bitrate |
64/128/192 | 128 | MP3 ビットレート |
normalize |
boolean | true | テキストの正規化(数字・記号の読み変換) |
latency |
normal/balanced |
normal |
生成モード。balanced は品質と速度のバランス |
プロソディ制御タグ(テキスト内に埋め込む)
Fish Audio S2 はテキスト中に自然言語タグを埋め込むことで、笑いや咳などの感情表現を制御できます。これは SSML ではなく Fish Audio 独自の形式です。
| タグ | 効果 |
|---|---|
[laugh] |
笑い声を挿入 |
[cough] |
咳払いを挿入 |
[pitch up] |
ピッチを上げる |
[whisper in small voice] |
ささやき声にする |
[professional broadcast tone] |
アナウンサー口調にする |
# Fish Audio S2 API 呼び出し例
response = requests.post(
"https://api.fish.audio/v1/tts",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"text": "[laugh]それは面白いですね。 エーアイ が動画を セーセイ しました。",
"reference_id": "your-voice-clone-id",
"format": "mp3",
"mp3_bitrate": 128,
"normalize": True,
"latency": "normal",
"prosody": {
"speed": 0.9, # やや遅めに
"volume": 0.0
},
"temperature": 0.7,
"top_p": 0.7,
"chunk_length": 200
}
)
ルビ・読み指定: SSML や発音辞書には非対応です。Fish Audio の公式ブログ(2026年1月)では以下のように明記されています。
「発音辞書やSSMLのような高度なコントロールには対応していません。読み間違いが発生した場合は、テキストを少し編集(ひらがな・カタカナ化など)するか、細かく文を区切ることで大半のエラーは解決できます」
— Fish Audio 公式ブログ
ElevenLabs・Inworld と異なり、Fish Audio S2 はひらがな・カタカナのテキストを渡しても日本語として自然な発音を維持します。かな変換しても不自然にならないのが大きな強みです。
6. Google Cloud TTS(Neural2 / WaveNet / Chirp3-HD)
| 項目 | 内容 |
|---|---|
| 種別 | クラウドAPI(有料・無料枠あり) |
| 開発者 | |
| 価格 | Neural2: $16 / 100万文字、Chirp3-HD: $30 / 100万文字。無料枠: 毎月100万文字 |
| 公式サイト | https://cloud.google.com/text-to-speech |
Google Cloud TTS は複数のモデル世代を提供しており、モデルによって特性が大きく異なります。
モデル比較
| モデル | 日本語品質 | タイムスタンプ | SSML | 価格 |
|---|---|---|---|---|
| WaveNet | △ | ◎ SSML mark で取得 | ○ | $16/100万文字 |
| Neural2 | △ | ◎ SSML mark で取得 | ○ | $16/100万文字 |
| Chirp3-HD | ○ | ✗ 非対応(WhisperX必須) | ✗ 非対応 | $30/100万文字 |
Neural2 / WaveNet は Chirp3-HD と比べると日本語の自然さ・イントネーションに劣ります。タイムスタンプを直接取れる点は便利ですが、音声品質のトレードオフがあります。
利用可能なAPIパラメータ(audioConfig)
| パラメータ | 範囲 | 説明 |
|---|---|---|
speakingRate |
0.25〜2.0 | 話速 |
pitch |
-20.0〜20.0 半音 | ピッチ調整(Chirp3-HD は非対応) |
volumeGainDb |
— | 音量調整(dB) |
sampleRateHertz |
— | サンプリングレート |
⚠️ Chirp3-HD では
speakingRate・pitchは適用されません。 SSML も非対応です。
// Google Cloud TTS(Chirp3-HD)利用例
const [response] = await client.synthesizeSpeech({
input: { ssml: `<speak>${text}</speak>` },
voice: { languageCode: "ja-JP", name: "ja-JP-Chirp3-HD-Aoede" },
audioConfig: {
audioEncoding: "MP3",
speakingRate: 1.0, // Chirp3-HD では無視される
sampleRateHertz: 24000,
}
})
// Google Cloud TTS(Neural2)利用例 ── SSML mark でタイムスタンプ取得
const [response] = await client.synthesizeSpeech({
input: {
ssml: `<speak>
<phoneme alphabet="yomigana" ph="せいせい">生成</phoneme>
<phoneme alphabet="yomigana" ph="えーあい">AI</phoneme>について
<mark name="ch_0"/>解説<mark name="ch_1"/>します。
</speak>`
},
voice: { languageCode: "ja-JP", name: "ja-JP-Neural2-B" },
audioConfig: { audioEncoding: "MP3", speakingRate: 1.0 },
enableTimePointing: [1] // SSML_MARK
})
// response.timepoints に各 mark の発話タイムスタンプが含まれる
ルビ・読み指定: <phoneme alphabet="yomigana"> タグで漢字の読みを明示的に指定できます(Neural2 / WaveNet のみ。Chirp3-HD は SSML 非対応)。
音声クローン(Custom Voice): Google への申請と審査(Google の AI 原則に基づく同意確認・倫理審査)が必要な許可制機能です。
TTSプロバイダー 比較表
| プロバイダー | 日本語品質 | 音声の自然さ | タイムスタンプ | ルビ・読み指定 | 音声クローン | 費用 | MeCab | WhisperX |
|---|---|---|---|---|---|---|---|---|
| VOICEVOX | △ ※1 | △ | audio_query から直接 ◎ | 非対応 | × | 無料 | 不要 | 不要 |
| AivisSpeech | ○ | △ | audio_query から直接 ◎ | 非対応 | △ ※2 | 無料 | 不要 | 不要 |
| ElevenLabs | △ | △ | API が直接返す ◎ | 非対応(英語のみ) | ○ | $99/月〜 | 必要 | 不要 |
| Inworld | △ | △ | API が直接返す ◎ | 非対応(英語IPAのみ) | ○ | $25/100万文字 | 必要 | 不要 |
| Google Neural2 | △ | △ | SSML mark で直接 ◎ | 対応(yomigana) | △ ※3 | $16/100万文字 | 必要 | 不要 |
| Fish Audio S2 | ○ | ○ | WhisperX で後付け | 非対応(テキスト編集で対処) | ○ | $15/100万バイト | 推奨 ※4 | 必要 |
| Google Chirp3-HD | ○ | ○ | WhisperX で後付け | 非対応(SSML不可) | △ ※3 | $30/100万文字 | 不要 | 必要 |
※1 評価をひらがなテキストで実施
※2 カスタム音声モデル(.aivm)の作成に専門知識と工数が必要
※3 Google への申請・審査が必要(許可制)
※4 WhisperX の精度向上のためひらがな変換用に使用(必須ではない)
ルビ・読み指定の重要性と対処法
「どのプロバイダーを選ぶか」と同じくらい重要なのが、誤読をどう防ぐかという問題です。
プロバイダー別の対処方針
| プロバイダー | 誤読対処法 | 注意点 |
|---|---|---|
| Google Neural2 | SSML <phoneme yomigana> でルビ指定 |
最も確実。LLMにセグメント生成を任せると自動化できる |
| Fish Audio S2 | テキストをひらがな/カタカナ + スペース区切りに編集 | かな変換しても自然。公式推奨の方法 |
| AivisSpeech / VOICEVOX | audio_query の accent_phrases を操作 | API経由での細かな制御は限定的 |
| ElevenLabs / Inworld | かな変換は可能だが非推奨 | かな変換するとイントネーションが不自然になりやすい |
| Google Chirp3-HD | SSML 非対応のためテキスト編集のみ | Chirp3-HD は日本語の地力が高いので誤読は少ない |
Google Cloud TTS のルビ指定(Neural2のみ)
<speak>
今日の<phoneme alphabet="yomigana" ph="せいせい">生成</phoneme>
<phoneme alphabet="yomigana" ph="えーあい">AI</phoneme>の使い方を解説します。
</speak>
Fish Audio S2 の推奨テキスト編集方法
// API呼び出し直前に正規表現でカタカナ語の前後にスペースを自動挿入
function addSpacesAroundKatakana(text: string): string {
return text
.replace(/([^\s])([ァ-ヶー]{2,})/g, '$1 $2')
.replace(/([ァ-ヶー]{2,})([^\s])/g, '$1 $2')
.replace(/\s{2,}/g, ' ')
.trim()
}
// 使用例
addSpacesAroundKatakana("エーアイが動画をセーセイした")
// → " エーアイ が動画を セーセイ した"
プロバイダー別のリップシンク実装アプローチ
パターンA: audio_query のモーラ情報を直接使う(VOICEVOX・AivisSpeech)
外部ツール不要で最もシンプルです。
テキスト → audio_query API → モーラ+時間情報取得
→ synthesis API → 音声データ生成
→ モーラタイムライン → キーフレーム生成 → VRM 適用
パターンB: API が直接タイムスタンプを返す(ElevenLabs・Inworld・Google Neural2)
WhisperX は不要ですが、漢字タイムスタンプを MeCab でモーラに変換する処理が必要です。
テキスト(誤読対策済み)→ TTS API
→ 音声データ + 文字タイムスタンプ(漢字のまま)
→ MeCab で漢字 → モーラ変換
→ キーフレーム生成 → VRM 適用
パターンC: WhisperX で後付けアライメント(Fish Audio S2・Google Chirp3-HD)
TTS の音声品質は最高クラスですが、パイプラインが増えます。
テキスト
→ MeCab でひらがな変換(WhisperX 参照テキスト用)
→ カタカナ語にスペース区切り追加
→ TTS API → 音声データのみ(タイムスタンプなし)
→ WhisperX /align に「音声 + かな読みテキスト」送信
→ 文字単位タイムスタンプ(かな文字)取得
→ 拗音統合 → キーフレーム生成 → VRM 適用
詰まりやすいポイント
1. 漢字のまま WhisperX に渡すと精度が落ちる
// NG: 漢字テキストをそのまま渡す
whisperx.align(audio, "動画の内容を自動生成します")
// OK: ひらがなに変換してから渡す(MeCab を使用)
whisperx.align(audio, "どうがのないようをじどうせいせいします")
2. ElevenLabs・Inworld でかな変換テキストを送ると不自然になる
これらのプロバイダーは英語ベースのモデルのため、ひらがな・カタカナの羅列を自然な日本語イントネーションで読むことが苦手です。Fish Audio S2 は日本語ネイティブモデルのため、かな変換しても自然な発音を保てる点が大きな違いです。
3. 拗音(きょ・しゅ等)は1モーラとして統合する
WhisperX は「き」と「ょ」を別々の文字として返すため、1モーラに統合します。
const SMALL_KANA = new Set('ぁぃぅぇぉゃゅょァィゥェォャュョ')
function mergeSmallKana(timestamps: TimestampItem[]): MoraEntry[] {
const result: MoraEntry[] = []
for (let i = 0; i < timestamps.length; i++) {
const ts = timestamps[i]
if (i + 1 < timestamps.length && SMALL_KANA.has(timestamps[i + 1].char)) {
result.push({ mora: ts.char + timestamps[i+1].char,
startMs: ts.startMs, endMs: timestamps[i+1].endMs })
i++
} else {
result.push({ mora: ts.char, startMs: ts.startMs, endMs: ts.endMs })
}
}
return result
}
最終的なおすすめ
日本語の音声品質とリップシンクの両立を目指すなら、以下の2択を推奨します。
第1推奨: Fish Audio S2 + WhisperX
理由:
✓ 日本語の自然さが最高クラス(TTS-Arena 日本語部門上位)
✓ 15〜45秒のサンプルから話者クローンを簡単に作成
✓ かな変換テキストでも自然(ElevenLabs との大きな違い)
✓ プロソディタグ([laugh] など)で感情表現も制御可能
✓ 価格が安い($15/100万バイト)
✓ オープンソースモデルが公開されておりセルフホストも可能
構成:
Fish Audio S2 + MeCab(かな変換) + WhisperX(アライメント)
第2推奨: Google Chirp3-HD + WhisperX
理由:
✓ 日本語の自然さが Fish Audio S2 と並び最高クラス
✓ Google Cloud インフラとの統合が容易(ADC認証・追加設定不要)
✓ 無料枠あり(毎月100万文字)
✓ Neural2 に切り替えれば SSML yomigana ルビ指定も使える
構成:
Google Chirp3-HD + WhisperX(アライメント)
注意:
△ タイムスタンプ非対応(WhisperX が必須)
△ 音声クローンは申請・審査が必要(許可制)
△ SSML・rate・pitch パラメータが Chirp3-HD では使えない
ツール構成サマリー
| 優先事項 | 推奨構成 | 必要ツール |
|---|---|---|
| 音声品質・クローン精度を最大化 | Fish Audio S2 | MeCab + WhisperX |
| Google Cloud 統合・スケーラビリティ | Chirp3-HD | WhisperX |
| シンプル・追加ツール不要 | AivisSpeech | なし(クラウドデプロイ可) |
| ローカル完結・無料・クローン不要 | VOICEVOX | なし |
参考リンク
- VRM公式サイト
- @pixiv/three-vrm GitHub
- VOICEVOX 公式 / VOICEVOX API ドキュメント
- AivisSpeech GitHub / AivisSpeech API ドキュメント
- AivisSpeech Docker イメージ
- Fish Audio 公式 / Fish Audio API ドキュメント
- Google Cloud TTS ドキュメント
- Google Cloud TTS 料金
- Google Cloud TTS 日本語音素(yomigana)
- Google Cloud Custom Voice
- ElevenLabs SSML サポート
- Inworld カスタム発音
- MeCab GitHub
- WhisperX GitHub