テキスト読み上げ生成(TTS)

Gemini API は、Gemini のテキスト読み上げ(TTS)生成機能を使用して、テキスト入力を単一話者または複数話者の音声に変換できます。テキスト読み上げの生成は制御可能です。つまり、構造化されたターン メタデータ(speech_metadata)とインライン音声タグを組み合わせて、音声のスタイル、アクセント、ペース、トーンを制御できます。

TTS 機能は、Live API を介して提供される音声生成とは異なります。Live API は、インタラクティブな非構造化音声、マルチモーダル入力と出力用に設計されています。Live API は動的な会話コンテキストに優れていますが、Gemini API を介した TTS は、ポッドキャストやオーディオブックの生成など、スタイルやサウンドを細かく制御して正確なテキスト朗読が必要なシナリオ向けに調整されています。

このガイドでは、Gemini 3.8 Flash TTS(gemini-3.8-flash-tts)と Gemini 3.8 Flash-Lite TTS(gemini-3.8-flash-lite-tts)を使用して、テキストから単一話者と複数話者の音声を生成する方法について説明します。

始める前に

サポートされているモデル セクションに記載されている Gemini TTS モデルを使用し、最新の Google GenAI SDK(Python の場合は google-genai >= 2.25.0、JavaScript/TypeScript の場合は @google/genai >= 2.24.0)にアップグレードするか、REST API を使用してください。最適な結果を得るには、どのモデルをいつ使用するかを確認して、ワークロードに最適なモデルを選択してください。

構築を開始する前に、AI Studio で Gemini TTS モデルをテストすることをおすすめします。

単一話者 TTS

Gemini 3.8 TTS モデルを使用してテキストを単一話者の音声に変換するには、input で逐語的な文字変換を渡し、speech_metadata アノテーションを使用してターンレベルのスタイル設定を適用し、generation_config.speech_config で音声を構成します。音声は、事前構築済みの音声オプション、拡張音声ライブラリ(GET /v1beta/voices)、カスタム音声デザイン ID(voice_...)、ボイス レプリケーション ID(voice_...、またはオプションのステートレス voicekey_...)から選択できます。

次の例では、モデルからのデフォルトの WAV 出力音声(audio/wav)をファイルに直接保存します。

Python

import base64
from google import genai

client = genai.Client()

interaction = client.interactions.create(
    model="gemini-3.8-flash-tts",
    input=[{
        "type": "user_input",
        "content": [{
            "type": "text",
            "text": "Have a wonderful day!",
            "annotations": [{
                "type": "speech_metadata",
                "style": "cheerful and friendly",
            }],
        }],
    }],
    response_format={"type": "audio"},
    generation_config={
        "speech_config": [
            {"voice": "Kore"},
        ]
    },
)

with open("out.wav", "wb") as f:
    f.write(base64.b64decode(interaction.output_audio.data))

JavaScript

import * as fs from 'node:fs';
import {GoogleGenAI} from '@google/genai';

async function main() {
   const client = new GoogleGenAI({});

   const interaction = await client.interactions.create({
      model: 'gemini-3.8-flash-tts',
      input: [{
         type: 'user_input',
         content: [{
            type: 'text',
            text: 'Have a wonderful day!',
            annotations: [{
               type: 'speech_metadata',
               style: 'cheerful and friendly',
            }],
         }],
      }],
      response_format: { type: 'audio' },
      generation_config: {
         speech_config: [
            { voice: 'Kore' },
         ],
      },
   });

   const audioBuffer = Buffer.from(interaction.output_audio.data, 'base64');
   fs.writeFileSync('out.wav', audioBuffer);
}
await main();

REST

curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3.8-flash-tts",
    "input": [{
      "type": "user_input",
      "content": [{
        "type": "text",
        "text": "Have a wonderful day!",
        "annotations": [{
          "type": "speech_metadata",
          "style": "cheerful and friendly"
        }]
      }]
    }],
    "response_format": {
      "type": "audio"
    },
    "generation_config": {
      "speech_config": [
        { "voice": "Kore" }
      ]
    }
  }' | jq -r '[.steps[] | select(.type=="model_output") | .content[] | select(.type=="audio")] | last | .data' | base64 --decode > out.wav

Python と JavaScript SDK では、interaction.output_audio コンビニエンス プロパティを使用して生成された音声データを取得できます。このプロパティは、最後に生成された音声ブロックを返します(未加工の REST JSON レスポンスでは、base64 でエンコードされた音声が steps[].content[].data に保存されます)。コンビニエンス プロパティの詳細については、インタラクションの概要をご覧ください。

マルチスピーカー TTS

複数の話者による会話の場合は、speech_config.speakers で 2 人の話者を構成し、各ターンを speaker とオプションのターンレベルの style を指定する speech_metadata アノテーションを含む個別のテキスト アイテムとして渡します。speech_config は、単一話者生成の場合は配列([{"voice": "..."}])を受け取り、複数話者生成の場合はオブジェクト({"speakers": [...]})を受け取ります。

Python

import base64
from google import genai

client = genai.Client()

interaction = client.interactions.create(
    model="gemini-3.8-flash-tts",
    input=[{
        "type": "user_input",
        "content": [
            {
                "type": "text",
                "text": "How's it going today Jane?",
                "annotations": [{
                    "type": "speech_metadata",
                    "speaker": "Joe",
                    "style": "cheerful and friendly",
                }],
            },
            {
                "type": "text",
                "text": "Not too bad, how about you? Ready to test these new voices?",
                "annotations": [{
                    "type": "speech_metadata",
                    "speaker": "Jane",
                    "style": "calm and relaxed",
                }],
            },
        ],
    }],
    response_format={"type": "audio"},
    generation_config={
        "speech_config": {
            "speakers": [
                {"speaker": "Joe", "voice": "Puck"},
                {"speaker": "Jane", "voice": "Kore"},
            ],
        }
    },
)

with open("out.wav", "wb") as f:
    f.write(base64.b64decode(interaction.output_audio.data))

JavaScript

import * as fs from 'node:fs';
import {GoogleGenAI} from '@google/genai';

async function main() {
   const client = new GoogleGenAI({});

   const interaction = await client.interactions.create({
      model: 'gemini-3.8-flash-tts',
      input: [{
         type: 'user_input',
         content: [
            {
               type: 'text',
               text: "How's it going today Jane?",
               annotations: [{
                  type: 'speech_metadata',
                  speaker: 'Joe',
                  style: 'cheerful and friendly',
               }],
            },
            {
               type: 'text',
               text: 'Not too bad, how about you? Ready to test these new voices?',
               annotations: [{
                  type: 'speech_metadata',
                  speaker: 'Jane',
                  style: 'calm and relaxed',
               }],
            },
         ],
      }],
      response_format: { type: 'audio' },
      generation_config: {
         speech_config: {
            speakers: [
               { speaker: 'Joe', voice: 'Puck' },
               { speaker: 'Jane', voice: 'Kore' },
            ],
         },
      },
   });

   const audioBuffer = Buffer.from(interaction.output_audio.data, 'base64');
   fs.writeFileSync('out.wav', audioBuffer);
}

await main();

REST

curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3.8-flash-tts",
    "input": [{
      "type": "user_input",
      "content": [
        {
          "type": "text",
          "text": "How'\''s it going today Jane?",
          "annotations": [{
            "type": "speech_metadata",
            "speaker": "Joe",
            "style": "cheerful and friendly"
          }]
        },
        {
          "type": "text",
          "text": "Not too bad, how about you? Ready to test these new voices?",
          "annotations": [{
            "type": "speech_metadata",
            "speaker": "Jane",
            "style": "calm and relaxed"
          }]
        }
      ]
    }],
    "response_format": {
      "type": "audio"
    },
    "generation_config": {
      "speech_config": {
        "mode": "conversational",
        "speakers": [
          { "speaker": "Joe", "voice": "Puck" },
          { "speaker": "Jane", "voice": "Kore" }
        ]
      }
    }
  }'

メタデータとタグを使用して音声スタイルを制御する

Gemini 3.8 TTS は、text フィールドを厳密に文字起こしとして扱います。ト書きを読み上げずに配信を制御するには、スコープごとに指示を分割します。

  • ターンレベルの持続的な配信(speech_metadata.style): ターン全体に適用される感情、配信スタイル、韻律、ペース、音量を style フィールドに入れます("style": "whispered urgently"、"style": "out of breath"、"style": "warm and enthusiastic" など)。
  • ポイントインタイム イベント(インラインタグ): 音声以外の瞬間的な発声や一時停止を、山かっこを使用して文字起こし内に直接配置します(例: "Wait... <short pause> did you hear that? <sigh>"、"Excuse me <cough> as I was saying...")。

包括的なベスト プラクティスについては、プロンプト ガイドをご覧ください。

Python

import base64
from google import genai

client = genai.Client()

interaction = client.interactions.create(
    model="gemini-3.8-flash-tts",
    input=[{
        "type": "user_input",
        "content": [
            {
                "type": "text",
                "text": "Wait... <short pause> look under that fallen log! Is that a blue-spotted salamander?",
                "annotations": [{
                    "type": "speech_metadata",
                    "speaker": "Dr. Anya",
                    "style": "whispered urgently",
                }],
            },
            {
                "type": "text",
                "text": "<gasp> No way! <laugh> We've been searching for this species all season!",
                "annotations": [{
                    "type": "speech_metadata",
                    "speaker": "Liam",
                    "style": "warm and enthusiastic",
                }],
            },
        ],
    }],
    response_format={"type": "audio"},
    generation_config={
        "speech_config": {
            "speakers": [
                {"speaker": "Dr. Anya", "voice": "Kore"},
                {"speaker": "Liam", "voice": "Puck"},
            ],
        }
    },
)

with open("out.wav", "wb") as f:
    f.write(base64.b64decode(interaction.output_audio.data))

JavaScript

import * as fs from 'node:fs';
import {GoogleGenAI} from '@google/genai';

async function main() {
   const client = new GoogleGenAI({});

   const interaction = await client.interactions.create({
      model: 'gemini-3.8-flash-tts',
      input: [{
         type: 'user_input',
         content: [
            {
               type: 'text',
               text: 'Wait... <short pause> look under that fallen log! Is that a blue-spotted salamander?',
               annotations: [{
                  type: 'speech_metadata',
                  speaker: 'Dr. Anya',
                  style: 'whispered urgently',
               }],
            },
            {
               type: 'text',
               text: "<gasp> No way! <laugh> We've been searching for this species all season!",
               annotations: [{
                  type: 'speech_metadata',
                  speaker: 'Liam',
                  style: 'warm and enthusiastic',
               }],
            },
         ],
      }],
      response_format: { type: 'audio' },
      generation_config: {
         speech_config: {
            speakers: [
               { speaker: 'Dr. Anya', voice: 'Kore' },
               { speaker: 'Liam', voice: 'Puck' },
            ],
         },
      },
   });

   if (interaction.output_audio?.data) {
      const audioBuffer = Buffer.from(interaction.output_audio.data, 'base64');
      fs.writeFileSync('out.wav', audioBuffer);
   }
}

await main();

REST

curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3.8-flash-tts",
    "input": [{
      "type": "user_input",
      "content": [
        {
          "type": "text",
          "text": "Wait... <short pause> look under that fallen log! Is that a blue-spotted salamander?",
          "annotations": [{
            "type": "speech_metadata",
            "speaker": "Dr. Anya",
            "style": "whispered urgently"
          }]
        },
        {
          "type": "text",
          "text": "<gasp> No way! <laugh> We'\''ve been searching for this species all season!",
          "annotations": [{
            "type": "speech_metadata",
            "speaker": "Liam",
            "style": "warm and enthusiastic"
          }]
        }
      ]
    }],
    "response_format": {
      "type": "audio"
    },
    "generation_config": {
      "speech_config": {
        "speakers": [
          { "speaker": "Dr. Anya", "voice": "Kore" },
          { "speaker": "Liam", "voice": "Puck" }
        ]
      }
    }
  }'

ストリーミング音声生成

stream: true を設定すると、生成された音声を合成しながらストリーミングできます。単項リクエスト(RIFF ヘッダーを含む完全な WAV ファイルを返す)とは異なり、ストリーミング リクエストはデフォルトでヘッダーなしの RAW 16 ビット符号付きリトル エンディアン リニア PCM(audio/l16、24 kHz、モノラル)チャンクを返すため、コンテナ ヘッダーなしでオーディオ チャンクを連続して再生または連結できます。

Python

import base64
from google import genai

client = genai.Client()

stream = client.interactions.create(
    model="gemini-3.8-flash-tts",
    input=[{
        "type": "user_input",
        "content": [{
            "type": "text",
            "text": "Have a wonderful day!",
            "annotations": [{
                "type": "speech_metadata",
                "style": "cheerful and friendly",
            }],
        }],
    }],
    response_format={"type": "audio"},
    generation_config={
        "speech_config": [
            {"voice": "Kore"},
        ]
    },
    stream=True,
)

for event in stream:
    if event.event_type == "step.delta":
        if event.delta.type == "audio":
            audio_data = base64.b64decode(event.delta.data)
            # Process the audio chunk (e.g. play it or write to a file)

JavaScript

import {GoogleGenAI} from '@google/genai';

async function main() {
   const client = new GoogleGenAI({});

   const stream = await client.interactions.create({
      model: 'gemini-3.8-flash-tts',
      input: [{
         type: 'user_input',
         content: [{
            type: 'text',
            text: 'Have a wonderful day!',
            annotations: [{
               type: 'speech_metadata',
               style: 'cheerful and friendly',
            }],
         }],
      }],
      response_format: { type: 'audio' },
      generation_config: {
         speech_config: [
            { voice: 'Kore' },
         ],
      },
      stream: true,
   });

   for await (const event of stream) {
      if (event.event_type === 'step.delta') {
         if (event.delta.type === 'audio') {
            const audioBuffer = Buffer.from(event.delta.data, 'base64');
            // Process the audio buffer
         }
      }
   }
}
await main();

REST

curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  -H "Content-Type: application/json" \
  --no-buffer \
  -d '{
    "model": "gemini-3.8-flash-tts",
    "input": [{
      "type": "user_input",
      "content": [{
        "type": "text",
        "text": "Have a wonderful day!",
        "annotations": [{
          "type": "speech_metadata",
          "style": "cheerful and friendly"
        }]
      }]
    }],
    "response_format": {
      "type": "audio"
    },
    "generation_config": {
      "speech_config": [
        { "voice": "Kore" }
      ]
    },
    "stream": true
  }'

音声出力形式

Gemini 3.8 TTS モデルでは、リクエストが単項かストリーミングかに応じて、異なるデフォルトの音声形式が使用されます。

  • 単項リクエスト(stream=False): 標準の RIFF ヘッダー(24 kHz、モノラル、16 ビット符号付きリトル エンディアン PCM)を含む完全な WAV(audio/wav)音声を返します。デコードされた音声バイトを .wav ファイルに直接保存できます。WAV ヘッダーを手動で追加する必要はありません。
  • ストリーミング リクエスト(stream=True): デフォルトでは、ヘッダーなしの未加工のリニア PCM(audio/l16)チャンク(24 kHz、モノラル、16 ビット符号付きリトル エンディアン PCM)を返します。これにより、各チャンクにコンテナ ヘッダーを付けることなく、チャンクを継続的にストリーミングまたは連結できます。

別の音声エンコードまたはサンプリング レートをリクエストするには、response_format 内で mime_type とオプションの sample_rate を構成します。

形式 mime_type 値 説明
WAV (単項デフォルト) "audio/wav" RIFF ヘッダー付きの非圧縮 WAV ファイル(16 ビット符号付きリトル エンディアン PCM、モノラル、デフォルトは 24 kHz)。単項リクエストのデフォルト。
Raw PCM(L16) (ストリーミングのデフォルト) "audio/l16" 非圧縮、ヘッダーレスの 16 ビット符号付きリトル エンディアン リニア PCM 音声(24 kHz、モノラル)。ストリーミング リクエストのデフォルト。
Mu-law "audio/mulaw" 8 ビットの G.711 mu-law エンコード オーディオ(北米と日本の電話/IVR システムで一般的に使用されています)。
A-law "audio/alaw" 8 ビット G.711 A-law エンコード オーディオ(ヨーロッパおよび国際電話システムで一般的に使用されます)。

sample_rate をヘルツ単位で指定することもできます(例: 24000、16000、8000)。

Python

import base64
from google import genai

client = genai.Client()

interaction = client.interactions.create(
    model="gemini-3.8-flash-tts",
    input=[{
        "type": "user_input",
        "content": [{
            "type": "text",
            "text": "Have a wonderful day!",
            "annotations": [{
                "type": "speech_metadata",
                "style": "cheerful and friendly",
            }],
        }],
    }],
    response_format={
        "type": "audio",
        "mime_type": "audio/l16",  # "audio/wav" (default), "audio/l16", "audio/mulaw", or "audio/alaw"
        "sample_rate": 24000,
    },
    generation_config={
        "speech_config": [
            {"voice": "Kore"},
        ]
    },
)

with open("out.pcm", "wb") as f:
    f.write(base64.b64decode(interaction.output_audio.data))

JavaScript

import * as fs from 'node:fs';
import {GoogleGenAI} from '@google/genai';

async function main() {
   const client = new GoogleGenAI({});

   const interaction = await client.interactions.create({
      model: 'gemini-3.8-flash-tts',
      input: [{
         type: 'user_input',
         content: [{
            type: 'text',
            text: 'Have a wonderful day!',
            annotations: [{
               type: 'speech_metadata',
               style: 'cheerful and friendly',
            }],
         }],
      }],
      response_format: {
         type: 'audio',
         mime_type: 'audio/l16', // 'audio/wav' (default), 'audio/l16', 'audio/mulaw', or 'audio/alaw'
         sample_rate: 24000,
      },
      generation_config: {
         speech_config: [
            { voice: 'Kore' },
         ],
      },
   });

   const audioBuffer = Buffer.from(interaction.output_audio.data, 'base64');
   fs.writeFileSync('out.pcm', audioBuffer);
}
await main();

REST

curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3.8-flash-tts",
    "input": [{
      "type": "user_input",
      "content": [{
        "type": "text",
        "text": "Have a wonderful day!",
        "annotations": [{
          "type": "speech_metadata",
          "style": "cheerful and friendly"
        }]
      }]
    }],
    "response_format": {
      "type": "audio",
      "mime_type": "audio/l16",
      "sample_rate": 24000
    },
    "generation_config": {
      "speech_config": [
        { "voice": "Kore" }
      ]
    }
  }'

音声オプション

Gemini 3.8 TTS は、音声を選択または作成する 4 つの方法をサポートしています。

  1. 事前構築済みのスタジオ音声: 次の表に示す 30 種類の厳選された音声。
  2. 拡張音声ライブラリ: client.voices.list()(GET /v1beta/voices)を使用してアクセスできる、言語、アクセント、キャラクターのアーキタイプにわたる数百もの追加の音声。
  3. 音声設計: Google AI Studio の自然言語の説明から、または POST /v1beta/voices(type="prompted"、永続的な voice_... ID と CreateVoice と GetVoice の sample_audio WAV プレビューを返します)を使用して、カスタム音声ペルソナを生成します。
  4. ボイス レプリケーション: Google AI Studio の参照音声と同意音声から、または POST /v1beta/voices(デフォルトでは type="replicated"、永続的な store=True、またはオプションのステートレス store=False)を使用して、話者の音声を複製します。

カスタム音声の上限と TTL

音声タイプ ストレージ モード 割り当て / 上限 保持(TTL)
ステートフル音声(voice_...、プロンプトまたは複製) store=True プロジェクトあたり 200 個の音声(プロンプト音声と複製音声で共有) 最終使用日から 1 年間*
ステートレス音声キー(voicekey_...、レプリケート済み) store=False クライアント管理 7 日

* TTL の延長: 音声がアクティブに使用される(音声で音声を合成するか、リミックスのベース音声として使用する)たびに、1 年間の保持期間がリセットされます。1 年間アクティビティがない音声は自動的に削除されます。

事前構築済みの音声

Zephyr -- Bright Puck -- Upbeat Charon -- 情報提供
Kore -- Firm Fenrir -- 興奮しやすい Leda -- 若々しい
Orus -- Firm Aoede -- Breezy Callirrhoe -- おおらか
Autonoe -- Bright Enceladus -- Breathy Iapetus -- Clear
Umbriel -- Easy-going Algieba -- Smooth Despina -- Smooth
Erinome -- クリア Algenib -- 砂利 Rasalgethi -- 情報が豊富
Laomedeia -- アップビート Achernar -- Soft Alnilam -- Firm
シェダル -- 偶数 Gacrux -- 成熟 Pulcherrima -- Forward
Achird -- フレンドリー Zubenelgenubi -- Casual Vindemiatrix -- Gentle
Sadachbia -- Lively Sadaltager -- 知識が豊富 スラファト -- 暖かい

拡張された音声ライブラリとフィルタリング

上の表に記載されている 30 種類の注目のスタジオ音声に加えて、拡張音声ライブラリには、言語、地域アクセント、キャラクター ペルソナ、ドメインにわたる数百種類の音声が用意されています。Google AI Studio で、音声ライブラリ全体をインタラクティブに閲覧、フィルタリング、試聴できます。また、client.voices.list()(GET /v1beta/voices、google-genai 2.25.0+ / @google/genai 2.24.0+ を使用)を使用してプログラムでクエリすることもできます。

ListVoices は、カスタムの保存済み音声(新しい順)を返し、その後にフィルタ条件に一致する事前構築済みのカタログ音声を返します。リストフィルタに複数の値が渡されると、そのフィルタのいずれかの値に一致する音声が返されます(OR)。一方、異なるフィルタ パラメータは AND と組み合わされます。

パラメータ 型 説明
language_code list[str] BCP-47 言語タグ(例: ["en-US", "en-GB"])。大文字と小文字を区別しない完全一致。
region_code list[str] ISO 3166-1 alpha-2 または UN M.49 形式の地域コード(例: ["US", "GB"])。
accent list[str] 地域アクセント記述子(["American", "British"] など)。
gender list[str] 認識された性別表現("female"、"male"、"neutral")。
pitch list[str] 声のピッチの分類("low"、"medium"、"high")。
persona list[str] 音声のペルソナまたはキャラクターのアーキタイプ(例: ["Warm, Friendly"]、["Narrator"])。
contexts(REST の context) list[str] 最適な使用量ドメイン(["Audiobook", "Conversational", "News"] など)。
type(Python の場合は type_) list[str] 音声ソースでフィルタ: "prebuilt"、"prompted"(音声デザイン)、"replicated"(ボイス レプリケーション)。
search str フリーテキストの部分文字列検索では、display_name と description の両方に対して大文字と小文字を区別せずに照合が行われました。
page_size int ページごとに返される音声の最大数(デフォルトは 50、最大は 1000)。
page_token str response.next_page_token からのトークン。結果の次のページを取得します。

Python

from google import genai

client = genai.Client()

# Filter the Voice Library by language, gender, pitch, domain context, and keyword
response = client.voices.list(
    language_code=["en-US", "en-GB"],
    gender=["female"],
    pitch=["medium", "low"],
    contexts=["Audiobook", "Conversational"],
    type_=["prebuilt"],
    search="warm",
    page_size=50,
)

for voice in response.voices or []:
    print(
        f"{voice.id} | {voice.display_name} ({voice.language_code},"
        f" {voice.accent}, {voice.gender}, pitch={voice.pitch}):"
        f" {voice.description}"
    )

JavaScript

import { GoogleGenAI } from "@google/genai";

const ai = new GoogleGenAI();

// Filter the Voice Library by language, gender, pitch, domain context, and keyword
const response = await ai.voices.list({
  language_code: ["en-US", "en-GB"],
  gender: ["female"],
  pitch: ["medium", "low"],
  contexts: ["Audiobook", "Conversational"],
  type: ["prebuilt"],
  search: "warm",
  page_size: 50,
});

for (const voice of response.voices ?? []) {
  console.log(
    `${voice.id} | ${voice.display_name} (${voice.language_code}, ${voice.accent}, ${voice.gender}, pitch=${voice.pitch}): ${voice.description}`
  );
}

REST

curl -G "https://generativelanguage.googleapis.com/v1beta/voices" \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  --data-urlencode "language_code=en-US" \
  --data-urlencode "language_code=en-GB" \
  --data-urlencode "gender=female" \
  --data-urlencode "pitch=medium" \
  --data-urlencode "context=Audiobook" \
  --data-urlencode "type=prebuilt" \
  --data-urlencode "search=warm" \
  --data-urlencode "page_size=50"

サポートされている言語

TTS モデルは入力言語を自動的に検出します。Gemini 3.8 Flash TTS(gemini-3.8-flash-tts)は 130 以上の言語に対応し、Gemini 3.8 Flash-Lite TTS(gemini-3.8-flash-lite-tts)は 100 以上の言語に対応しています。

言語 Gemini 3.8 Flash TTS Gemini 3.8 Flash-Lite TTS
アチェ語(アラビア文字) ✔️ ✔️
アフリカーンス語 ✔️ ✔️
アカン語 ✔️ ✔️
アムハラ語 ✔️ ✔️
アルメニア語 ✔️ ✔️
アッサム語 ✔️ ✔️
アワディー語 ✔️ ✔️
バリ文字 ✔️ ✔️
ベンガル語 ✔️ ✔️
バンジャール語(アラビア文字) ✔️ —
バンジャール語(ラテン文字) ✔️ ✔️
バシキール語 ✔️ —
バスク語 ✔️ ✔️
ベラルーシ語 ✔️ ✔️
ベンバ語 ✔️ —
ボージュプリー語 ✔️ ✔️
ボスニア語 ✔️ ✔️
ブギス文字 ✔️ ✔️
ブルガリア語 ✔️ ✔️
ビルマ語 ✔️ —
広東語 ✔️ ✔️
カタルーニャ語 ✔️ ✔️
セブアノ語 ✔️ ✔️
中央クルド語 ✔️ ✔️
チャッティースガリー語 ✔️ ✔️
中国語(簡体字) ✔️ ✔️
中国語(繁体字) ✔️ ✔️
クリミア タタール語 ✔️ —
クロアチア語 ✔️ ✔️
チェコ語 ✔️ ✔️
デンマーク語 ✔️ ✔️
オランダ語 ✔️ ✔️
ジュラ語 ✔️ —
ゾンカ語 ✔️ —
エジプト アラビア語 ✔️ ✔️
英語 ✔️ ✔️
エストニア語 ✔️ ✔️
フィリピン語 ✔️ ✔️
フィンランド語 ✔️ —
フランス語 ✔️ ✔️
ガリシア語 ✔️ ✔️
ガンダ語 ✔️ ✔️
ジョージア語 ✔️ ✔️
ドイツ語 ✔️ ✔️
ギリシャ語 ✔️ ✔️
グアラニ語 ✔️ —
グジャラート語 ✔️ ✔️
ハイチ語 ✔️ ✔️
ハルハ モンゴル語 ✔️ ✔️
ハウサ語 ✔️ ✔️
ヘブライ語 ✔️ ✔️
ヒンディー語 ✔️ ✔️
ハンガリー語 ✔️ ✔️
アイスランド語 ✔️ ✔️
イボ語 ✔️ —
イロカノ語 ✔️ ✔️
インドネシア語 ✔️ ✔️
イランペルシア語 ✔️ ✔️
イタリア語 ✔️ ✔️
日本語 ✔️ ✔️
ジャワ語 ✔️ ✔️
カビル語 ✔️ —
カンバ語 ✔️ ✔️
カンナダ語 ✔️ ✔️
カシミール語(アラビア文字) ✔️ ✔️
カシミール語(デーヴァナーガリー文字) ✔️ ✔️
カザフ語 ✔️ ✔️
クメール語 ✔️ ✔️
キクユ語 ✔️ ✔️
キニヤルワンダ語 ✔️ ✔️
コンゴ語 ✔️ ✔️
韓国語 ✔️ ✔️
キルギス語 ✔️ ✔️
ラオ語 ✔️ ✔️
ラトガリア語 ✔️ —
リンガラ語 ✔️ ✔️
リトアニア語 ✔️ —
ルクセンブルク語 ✔️ —
マケドニア語 ✔️ ✔️
マガヒー語 ✔️ ✔️
マイティリー語 ✔️ ✔️
マラヤーラム語 ✔️ ✔️
マルタ語 ✔️ ✔️
マニプリ語 ✔️ ✔️
マラーティー語 ✔️ ✔️
ミナンカバウ語(アラビア文字) ✔️ ✔️
ミナンカバウ語(ラテン文字) ✔️ —
ミゾ語 ✔️ ✔️
ネパール語(個別の言語) ✔️ ✔️
フルフルディ語(ナイジェリア) ✔️ ✔️
北アゼルバイジャン語 ✔️ ✔️
北ソト語 ✔️ ✔️
北ウズベク語 ✔️ ✔️
ノルウェー語(ブークモール) ✔️ ✔️
ノルウェー語(ニーノシク) ✔️ ✔️
ニャンジャ語 ✔️ ✔️
オック語 ✔️ —
オディア語(個別の言語) ✔️ ✔️
パンガシナン語 ✔️ —
ペルシャ語(アフガニスタン) ✔️ ✔️
ポーランド語 ✔️ ✔️
ポルトガル語 ✔️ ✔️
パンジャブ語 ✔️ ✔️
ルーマニア語 ✔️ ✔️
ロシア語 ✔️ ✔️
サンタル語 ✔️ ✔️
セルビア語 ✔️ ✔️
シンド語 ✔️ —
シンハラ語 ✔️ ✔️
スロバキア語 ✔️ ✔️
スロベニア語 ✔️ —
ソマリ語 ✔️ —
南アゼルバイジャン語 ✔️ ✔️
南部パシュト語 ✔️ ✔️
南ソト語 ✔️ —
スペイン語 ✔️ ✔️
標準アラビア語(アラビア文字) ✔️ ✔️
標準アラビア語(ラテン文字) ✔️ ✔️
標準ラトビア語 ✔️ ✔️
標準マレー語 ✔️ ✔️
スワヒリ語(個別の言語) ✔️ —
スワート語 ✔️ —
スウェーデン語 ✔️ —
タジク語 ✔️ —
タミル語 ✔️ ✔️
テルグ語 ✔️ ✔️
タイ語 ✔️ —
ティグリニャ語 ✔️ —
トスク アルバニア語 ✔️ —
トルコ語 ✔️ ✔️
ウイグル語 ✔️ —
ベトナム語 ✔️ ✔️

サポートされているモデル

モデル 単一話者 マルチスピーカー 音声デザイン ボイス レプリケーション
Gemini 3.8 Flash TTS(gemini-3.8-flash-tts) ✔️ ✔️ ✔️ ✔️
Gemini 3.8 Flash-Lite TTS(gemini-3.8-flash-lite-tts) ✔️ ✔️ ✔️ ✔️
Gemini 3.1 Flash TTS プレビュー ✔️ ✔️ — —
Gemini 2.5 Pro プレビュー TTS ✔️ ✔️ — —

どのモデルをいつ使用するか

Gemini 3.8 TTS モデルはどちらも同じ API スキーマとプロンプト形式を共有しているため、1 つのパラメータを変更するだけで切り替えることができます。

  • Gemini 3.8 Flash TTS(gemini-3.8-flash-tts)を使用する: 音響の忠実度、ニュアンスのある演技、表現力豊かなコントロールが最優先事項である場合。スタジオ品質のクリエイティブな作業、複数の話者による複雑な会話、重いボーカルバースト タグ、難しい発音、地域や少数派の方言、安定した音声とルームトーンの安定性を必要とする長文のナレーションに最適です。
  • Gemini 3.8 Flash-Lite TTS(gemini-3.8-flash-lite-tts)を、gemini-3.1-flash-tts-preview の高速で費用対効果の高い代替として使用します。大量の一括処理、会話型音声エージェントのカスケード、読み上げ機能、信頼性の高いボイス レプリケーション、主要言語での日常的な単一話者の音声に最適化されています。

移行ガイド

gemini-3.1-flash-tts-preview 以前の Gemini TTS モデルから Gemini 3.8 TTS に移行する場合:

  1. ターンレベルの指示を speech_metadata に移動: Gemini 3.8 TTS は、入力テキストを厳密に逐語記録として扱います。持続的な配信指示(style - "whispering"、"out of breath"、"speaking slowly" など)と話者ラベル(speaker)を、台本テキストに舞台指示を埋め込むのではなく、構造化された speech_metadata アノテーションに移動します。
  2. 山かっこインラインタグは、特定の時点の音声イベントにのみ使用します。瞬間的な非音声発話や一時停止は、山かっこ(<laugh>、<sigh>、<cough>、<breath>、<short pause> など)を使用して、文字起こしにインラインで保持します。効果音タグ(拍手やドスンという音など)は避け、配信スタイルを speech_metadata.style に配置します。
  3. 複数話者のリクエストのすべてのターンで speaker を指定する: 複数話者のリクエストのすべてのターンで、構成された話者のいずれかに一致する speech_metadata 内に speaker を明示的に含める必要があります。
  4. Voice Design でペルソナを事前に設計する: 複数段落の "Audio Profile" ブロックまたは "Director's Notes" ブロックを、Voice Design で作成したカスタム音声に置き換えます。その後、最小限の 文字列または空の style 文字列を使用して、TTS リクエスト全体でその voice_... ID を使用します。
  5. 単項リクエストのデフォルトの WAV(audio/wav)出力を考慮する: gemini-3.1-flash-tts-preview 以前の TTS モデル(デフォルトでヘッダーなしの未加工 PCM audio/l16 を返した)とは異なり、Gemini 3.8 TTS は、単項リクエストに対してデフォルトで標準の RIFF ヘッダーを含む WAV 音声(audio/wav)を返します。
    • 以前のコードで、WAV ヘッダーに未加工の PCM バイトをラップしていた場合(たとえば、Python の wave モジュールや ffmpeg を使用していた場合)、手動のヘッダー ラッパーを削除し、返されたバイトを .wav ファイルに直接書き込みます。
    • パイプラインでヘッダーレスの生の PCM、μ-law、A-law のオーディオが必要な場合は、response_format.mime_type を "audio/l16"、"audio/mulaw"、"audio/alaw" に明示的に設定します(たとえば、Interactions API の {"response_format": {"type": "audio", "mime_type": "audio/l16"}} や generateContent の AUDIO_L16 など)。オーディオ出力形式をご覧ください。

プロンプト ガイド

Gemini 3.8 TTS モデルは、入力テキストを逐語的な音声文字変換として厳密に扱います。ステージ指示が書式なしテキストに埋め込まれていた以前のプレビュー モデルとは異なり、Gemini 3.8 TTS では、持続的なターンレベルの指示(speech_metadata)と、特定の時点のインライン音声タグが分離されています。

スタイル フィールドとインライン タグ

パフォーマンスに関する指示をスコープごとに分割します。

  • ターンレベルの配信(speech_metadata.style): 感情、韻律、全体的なペース、配信スタイル("whispering"、"out of breath"、"muttering"、"sarcastic" など)などの持続的な配信属性を speech_metadata の style フィールドに入れます。ターン間で安定したキャラクターとパフォーマンスを実現するには、音声デザインでペルソナを事前に設計し、style はオプションのターンレベルの調整にのみ使用します。
  • 特定の時点のイベント(インラインタグ): 音声以外の瞬間的な発声、呼吸、一時停止を、山かっこ(<cough>、<breath>、<sigh>、<short pause>)を使用して文字起こしにインラインで挿入します。山かっこ(<...>)を使用して、最高の音質を得るために、音声以外の効果音ではなく、人間の発声にこだわります。
スコープ 設置場所 例
ターンレベル(ターン全体で維持される) speech_metadata.style "angry tone"、"speaking rapidly"、"out of breath"、"whispers"、"sarcastic"
ポイントインタイム(特定の単語で発生) text(<...>)のインライン "<cough> Thank you all for coming tonight! <throat-clearing> As I was saying..."

ペースと一時停止

リズムと無音は、次の 3 つのレベルで制御できます。

  • 句読点と省略記号: カンマ、ダッシュ(--)、省略記号(...)を使用して、自然な会話の躊躇を表現します。
  • インライン一時停止タグ: 話者が一時停止するスクリプトの正確な位置に <short pause> または <long pause> を挿入します。 text Hold on, let me think... <short pause> Alright, I've got it.
  • ターンレベルのペース: speech_metadata で "style": "speaking rapidly" または "style": "speaking slowly" を設定して、ターン全体の発話速度を制御します。

韻律とピッチ

speech_metadata.style を使用して、ターン全体の韻律、ピッチ、抑揚を制御します(例: "style": "high pitch, cheerful and excited inflection"、"style": "monotone and flat")。会話の途中で感情や韻律が変化する場合は、スクリプトを個別のターンに分割し、ターンごとに異なる style 値を設定します。

強調

文字起こしで特定の単語を大文字にし、句読点とインライン音声タグを組み合わせて、キーワードに自然な音声ストレスを配置します。

This is a VERY important point!
It was a VERY long day <sigh> ... nobody listens anymore.

ボーカル バーストと非音声

音声以外の人の発声は、音が鳴る正確な位置に山かっこ(<...>)を使用してインラインで配置します。推奨されるボーカルタグは次のとおりです。

<argh> <breath> <heavy breath> <exhales>
<cackle> <cheer> <chuckle> / <chuckles> <cough>
<cry> <gasp> <giggle> <groan>
<growl> <grunt> <grr> <hiss>
<laugh> / <laughter> <moan> <pant> <pff> / <phew>
<scream> <shout> <shriek> <sigh> / <sighs>
<sneeze> <snicker> <snort> <sob>
<throat-clearing> <tsk> <whimper> <whispers> / <whispering>
<yawn> <short pause> <long pause>

相づちと音声の重なり

複数話者の会話では、話者のターン内でリスナーの反応をパイプ文字(|reaction|)で囲み、反応ごとに別のターンに分割することなく、自然なバックチャネルや重複する発話を作成します。

  • 短いバックチャネルのやり取り: 発言中の参加者のターン中に、リスナーの短いリアクション(|oh hmm|、|oh really?|、|absolutely|)を重ねます。
    • ターン 1(話者 A): "So the launch is Thursday |oh hmm| Are we actually ready?"
    • ターン 2(話者 B): "Ready enough |oh really?| The last blocker cleared this morning."
    • ターン 3(スピーカー A): "Then let's ship it |absolutely| and watch the dashboards."
  • 重複する音声とインターリーブされた音声: 複数のパイプ セグメントを使用して、2 人の話者間の同時音声またはインターリーブされた音声をシミュレートします(gemini-3.8-flash-tts で最適に機能します)。
    • 同時カウントダウン/コーラス: "Let's surprise him on three |ok| ready?" の後に "one. two. three. |happy| happy |birthday| birthday!"
    • スピーカーの完全な重複: "Hello |oh| there |my| it |goodness| must |gracious| be |would| almost |you| time |look| for |at that| dinner"

世代間の整合性と避けるべきこと

ターン間で声のアイデンティティを安定させるには、次のガイドラインに沿ってください。

  • 長いスタイル ブロックではなく、音声設計でペルソナを事前に設計する: 以前のモデルから引き継がれた長い形式の "Audio Profile" 段落と複数の箇条書き "Director's Notes" は、音声のずれの最も一般的な原因です。音声デザインで同じクリエイティブな直感を使用して、永続的なカスタム voice_... ペルソナを生成し、TTS 呼び出しでその音声 ID を使用します。
  • 安定性のために音声リファレンスに依存する(メタ指示を省略): Gemini 3.8 TTS モデルは、最初に音声リファレンスにアンカーするようにトレーニングされています。モデルに音声を安定させるように指示する指示("do not switch speaker identity" や "maintain identical timbre" など)は含めないでください。プロンプト テキストを追加すると、ドリフトが増加します。不要なスタイル指示を削除し、音声参照によって提供される安定したポイントを中心にモデルが自然に変化するようにします。
  • style で不変の発話者の特徴を変更しようとしないでください。speech_metadata.style に年齢、性別、名前、永続的なアクセントの変更を入れないでください。代わりに、拡張音声ライブラリから地域音声を選択するか、音声デザインで作成します。
  1. キャラクターを一度作成する: 音声デザインでキャラクターを作成するか、ターゲット言語とペルソナに一致する地域音声を選択します。
  2. 自然な話し言葉の文字起こしを記述する: 自然さを最大限に高めるには、text を実際の話し言葉の文字起こしとして記述します。自然な会話の言い淀みやためらい("Oh uh yeah I think... hm, so that's interesting" など)を含めます。
  3. まずプレーン TTS をテストする: まず、空の style フィールドを使用して文字起こしを合成します。ほとんどのリクエストでは style 指示は必要ありません。
  4. 調整のみに短い style プロンプトを追加する: 特定の配信調整が必要なターンにのみ、簡潔な style 文字列("casual, friendly" や "muttering, then reassuring" など)を追加します。一貫したベースラインが必要な場合は、ターン間で同じ短い文字列を再利用します。

マルチターン会話と音声エージェント

リアルタイムの会話型音声エージェントまたはマルチターン アプリケーションを構築する場合:

  • LLM テキスト チャンクが到着するたびに、1 ターンに 1 回の TTS 呼び出しを行います。
  • 構成された voice(事前構築、設計された voice_...、複製された voice_... / voicekey_...)に、発言者の ID をターン間で保持させます。各ターンで長い文字のペルソナを再送信しないでください。
  • ターンごとの style フィールドを空のままにするか、会話全体に 1 つの短い定数文字列("casual, friendly" など)を送信します。
  • より強力なスタイル プロンプトを使用するのではなく、長いエージェント レスポンスを短いターンに分割します。

制限事項

  • TTS モデルは、テキストのみの入力を受け取り、音声のみの出力を生成します。
  • 単一リクエストの複数話者生成(speech_config.speakers)では、事前構築済みの音声を使用して最大 2 人の話者をサポートします。カスタム設計(voice_...)または複製(voice_... / voicekey_...)された音声を複数キャラクターの会話に組み合わせるには、各話者のターンを個別に合成します。単項リクエストはデフォルトで 44 バイトの RIFF ヘッダーを含む audio/wav を返すため、未加工の PCM({"type": "audio", "mime_type": "audio/l16"})をリクエストするか、各ターンから WAV ヘッダーを削除してから 24 kHz PCM 音声フレームを連結します。
  • カスタム音声の保存容量の上限と TTL:
    • ステートフル音声(store=True、プロンプトまたは複製): プロジェクトあたり最大 200 音声、1 年間の TTL(有効期間)。
    • ステートレス音声キー(store=False、voicekey_...): 7 日間の TTL(有効期間)。
  • 言語の対応状況については、サポートされている言語のセクションをご覧ください。

次のステップ