はじめに
GoogleのGemini 2.5 Flash Preview TTSを使うと、REST APIだけで自然な日本語ナレーション音声を生成できます。従来のGoogle Cloud TTSと比べて、原稿のトーンを自動で読み取り、感情豊かな音声を出力してくれるのが特徴です。
この記事では、APIキーの取得からcurlでの音声生成、Node.jsでのWAVファイル変換、さらに感情を込めた音声を作るコツまでを解説します。
Gemini 2.5 Flash TTS とは
Gemini 2.5 Flash Preview TTSは、Googleが提供するテキスト読み上げ(Text-to-Speech)モデルです。
従来のCloud TTSとの違い:
- テキストの感情やトーンを自動で検出し、抑揚のある音声を生成
-
response_modalities: ["AUDIO"]を指定するだけで音声レスポンスを取得 - 複数の声質(Zephyr、Kore、Aoede等)から選択可能
- Gemini APIキーだけで利用可能(Cloud TTSの別契約不要)
モデル名は gemini-2.5-flash-preview-tts です。
環境準備とAPIキーの取得
必要なもの
- Googleアカウント
- Gemini APIキー(Google AI Studio で取得)
- curl または Node.js 環境
APIキーの取得手順
- Google AI Studio にアクセス
- 左メニューから「Get API key」をクリック
- 「Create API key」でキーを生成
- 環境変数に設定:
export GEMINI_API_KEY="your-api-key-here"
curlでナレーション音声を生成してみる
まずはcurlで動作確認してみましょう。
curl -s \
"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-preview-tts:generateContent?key=${GEMINI_API_KEY}" \
-H 'Content-Type: application/json' \
-d '{
"contents": [
{
"parts": [
{
"text": "こんにちは!今日はGemini TTSの使い方を解説します。APIひとつで、こんなに自然な音声が作れるんです。"
}
]
}
],
"generationConfig": {
"response_modalities": ["AUDIO"],
"speech_config": {
"voice_config": {
"prebuilt_voice_config": {
"voice_name": "Zephyr"
}
}
}
}
}' -o response.json
レスポンスはJSON形式で、candidates[0].content.parts[0].inlineData.data にBase64エンコードされた音声データが入っています。音声フォーマットは PCM Linear16、サンプリングレート24kHz です。
レスポンスの確認
# Base64データの先頭を確認
cat response.json | jq -r '.candidates[0].content.parts[0].inlineData.mimeType'
# → "audio/L16;rate=24000"
Node.jsでWAVファイルに変換する
APIレスポンスのPCMデータをそのまま再生することはできないので、WAVヘッダーを付与してファイルに保存します。
// decode-audio.js
const fs = require('fs');
const response = JSON.parse(fs.readFileSync('response.json', 'utf-8'));
const base64Audio = response.candidates[0].content.parts[0].inlineData.data;
const pcmBuffer = Buffer.from(base64Audio, 'base64');
// WAVヘッダーを作成(PCM L16, 24kHz, mono)
const sampleRate = 24000;
const bitsPerSample = 16;
const numChannels = 1;
const byteRate = sampleRate * numChannels * (bitsPerSample / 8);
const blockAlign = numChannels * (bitsPerSample / 8);
const dataSize = pcmBuffer.length;
const header = Buffer.alloc(44);
header.write('RIFF', 0);
header.writeUInt32LE(36 + dataSize, 4);
header.write('WAVE', 8);
header.write('fmt ', 12);
header.writeUInt32LE(16, 16); // fmt chunk size
header.writeUInt16LE(1, 20); // PCM format
header.writeUInt16LE(numChannels, 22);
header.writeUInt32LE(sampleRate, 24);
header.writeUInt32LE(byteRate, 28);
header.writeUInt16LE(blockAlign, 32);
header.writeUInt16LE(bitsPerSample, 34);
header.write('data', 36);
header.writeUInt32LE(dataSize, 40);
const wavBuffer = Buffer.concat([header, pcmBuffer]);
fs.writeFileSync('output.wav', wavBuffer);
console.log(`WAV file saved: ${(wavBuffer.length / 1024).toFixed(1)} KB`);
node decode-audio.js
# → WAV file saved: 158.3 KB
生成された output.wav を再生すると、自然な日本語ナレーションが聞けるはずです。
感情豊かな音声を作るコツ
Gemini TTS 2.5は原稿のトーンを自動で読み取って抑揚を変えるという特徴があります。つまり、APIパラメータで感情を指定するのではなく、入力テキスト自体の書き方で音声の雰囲気が変わります。
明るくしたいとき
感嘆符やポジティブな表現を使います。
{
"text": "おめでとうございます!ついに完成しましたね!これは本当にすごいことです!"
}
落ち着いたトーンにしたいとき
句点で終わる解説調の文章にします。
{
"text": "それでは、設定ファイルの各項目について順番に見ていきましょう。まず最初に確認するのは、認証情報の設定です。"
}
盛り上げたいとき
締めくくりや感謝のメッセージを入れます。
{
"text": "いかがでしたか?ぜひ皆さんも試してみてください!きっと新しい可能性が広がるはずです!"
}
利用可能な音声
| 音声名 | 特徴 |
|---|---|
| Zephyr | 明るく親しみやすい。ナレーション向き |
| Kore | 落ち着いたビジネス調。解説向き |
| Aoede | 柔らかく優しい。ストーリー向き |
用途に合わせて voice_name を切り替えてみてください。
おまけ:Whisper APIで字幕も自動生成
生成した音声にタイムスタンプ付き字幕をつけたい場合、OpenAIのWhisper APIと組み合わせると便利です。
curl https://api.openai.com/v1/audio/transcriptions \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-F file=@output.wav \
-F model=whisper-1 \
-F response_format=srt \
-F language=ja \
-o subtitles.srt
これで動画のナレーション+字幕を完全にAPIだけで作ることができます。
まとめ
- Gemini 2.5 Flash TTSは、REST APIだけで自然な日本語音声を生成できる
- レスポンスはPCM L16(24kHz)のBase64データ → WAVヘッダーを付与して保存
- 感情表現はAPIパラメータではなく、入力テキストの書き方で制御する
- Whisper APIと組み合わせれば、ナレーション+字幕の自動生成パイプラインが作れる
実際に私はこの仕組みを使って、YouTube Shortsのナレーション音声を自動生成しています。ぜひ皆さんのプロジェクトでも活用してみてください。