生成文字轉語音檔案 (TTS)

Gemini API 可使用 Gemini 文字轉語音 (TTS) 生成功能,將文字輸入內容轉換為單人或多人音訊。文字轉語音生成功能可控,也就是說,您可以結合結構化對話中繼資料 (speech_metadata) 和內嵌語音標記,引導音訊的風格、口音、節奏和語調。

TTS 功能與透過 Live API 提供的語音生成功能不同,後者專為互動式非結構化音訊,以及多模態輸入和輸出內容而設計。Live API 擅長處理動態對話情境,而 Gemini API 的 TTS 則適用於需要精確朗讀文字,並細微控制風格和聲音的情境,例如生成 Podcast 或有聲書。

本指南說明如何使用 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 中設定兩位說話者,並將每個對話回合做為獨立文字項目傳遞,同時使用 speech_metadata 註解指定 speaker 和選用的回合層級 style。請注意,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 檔案,串流要求則預設會傳回不含標頭的原始 16 位元帶正負號 little-endian 線性 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 模型會根據要求是 unary 或串流,使用不同的預設音訊格式:

  • 一元要求 (stream=False):傳回完整的 WAV (audio/wav) 音訊,並附上標準 RIFF 標頭 (24 kHz、單聲道、16 位元帶正負號 little-endian PCM)。您可以直接將解碼後的音訊位元組儲存至 .wav 檔案,不必手動預先加入 WAV 標頭。
  • 串流要求 (stream=True):預設會傳回不含標頭的原始線性 PCM (audio/l16) 區塊 (24 kHz、單聲道、16 位元帶正負號 little-endian PCM),因此區塊可以連續串流或串連,每個區塊不含容器標頭。

如要要求不同的音訊編碼或取樣率,請在 response_format 中設定 mime_type 和選用的 sample_rate:

格式 mime_type值 說明
WAV (一元預設) "audio/wav" 未壓縮的 WAV 檔案,包含 RIFF 標頭 (16 位元帶正負號的小端序 PCM、單聲道、預設 24 kHz)。一元要求的預設值。
原始 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 支援四種選取或建立語音的方式:

  1. 預先建構的 Studio 語音:下表列出 30 種精選語音。
  2. 擴充語音庫:提供數百種其他語言、口音和角色原型,可使用 client.voices.list() (GET /v1beta/voices) 存取。
  3. 語音設計:在 Google AI Studio 中,透過自然語言描述生成自訂語音角色,或使用 POST /v1beta/voices (type="prompted",這會傳回持續性 voice_... ID 和 sample_audio WAV 預覽,位於 CreateVoice 和 GetVoice)。
  4. 語音複製:在 Google AI Studio 中,或使用 POST /v1beta/voices (type="replicated"、預設為永久 store=True,或選用無狀態 store=False),從參考和同意音訊複製說話者的聲音。

自訂語音限制和存留時間

語音類型 儲存模式 配額 / 限制 保留時間 (TTL)
有狀態語音 (voice_...、提示或複製) store=True 每個專案 200 個語音 (提示和複製語音共用) 上次使用後 1 年*
無狀態語音金鑰 (voicekey_...,已複製) store=False 由用戶端管理 7 天

* TTL 延長:每次主動使用語音 (透過語音合成語音,或將語音做為混音的基礎語音),1 年的保留期限就會重設。如果語音未活動滿 1 年,系統會自動刪除。

預先建立的聲音

Zephyr -- Bright Puck -- Upbeat Charon -- 資訊豐富
韓國 -- 公司 Fenrir - 興奮 Leda - 年輕
Orus -- Firm Aoede -- Breezy Callirrhoe - 隨和
Autonoe -- Bright 土衛二 -- Breathy Iapetus -- Clear
Umbriel -- 隨和 Algieba -- Smooth Despina -- Smooth
Erinome -- 清除 Algenib -- Gravelly Rasalgethi -- 資訊豐富
Laomedeia -- Upbeat Achernar -- 柔和 Alnilam -- Firm
Schedar -- Even Gacrux -- 成熟 Pulcherrima -- Forward
Achird -- 友善 Zubenelgenubi -- Casual Vindemiatrix - 溫和
Sadachbia -- Lively Sadaltager -- 博學多聞 Sulafat -- 微熱

擴充語音庫和篩選功能

除了上表列出的 30 種精選 Studio 語音外,擴充語音庫還提供數百種其他語音,涵蓋各種語言、地區口音、角色和領域。您可以在 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 架構和提示格式,只要變更一個參數,就能在兩者之間切換:

  • 如果最重視音訊保真度、細膩的演繹和生動的控制,請使用 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. 使用語音設計功能預先設計角色:使用語音設計功能建立自訂語音,取代多段 "Audio Profile" 或 "Director's Notes" 區塊,然後在 TTS 要求中加入該 voice_... ID,並盡量減少或不使用 style 字串。
  5. 單元要求預設會輸出 WAV (audio/wav) 格式:與 gemini-3.1-flash-tts-preview 和先前的 TTS 模型不同 (預設會傳回無標頭的原始 PCM audio/l16),Gemini 3.8 TTS 預設會傳回具有標準 RIFF 標頭的 WAV 音訊 (audio/wav),以供單元要求使用。
    • 如果您的程式碼先前將原始 PCM 位元組包裝在 WAV 標頭中 (例如使用 Python 的 wave 模組或 ffmpeg),請移除手動標頭包裝函式,並將傳回的位元組直接寫入 .wav 檔案。
    • 如果管道需要無標頭的原始 PCM、mu-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 欄位。如要建立穩定的角色和跨回合表現,請先在「Voice design」中設計角色,並僅使用 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..."

節奏和暫停

你可以透過三種精細程度控制節奏和靜音:

  • 標點符號和刪節號:使用逗號、破折號 (--) 和刪節號 (...),模擬自然對話中的猶豫。
  • 內嵌暫停標記:在腳本中說話者應暫停的確切位置插入 <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."
  • 重疊和交錯語音:使用多個管道片段,模擬兩位說話者同時或交錯說話 (搭配 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 文字區塊送達時,每回合進行一次 TTS 呼叫。
  • 讓已設定的 voice (預先建構、設計 voice_... 或複製 voice_... / voicekey_...) 在對話輪流進行時,持續傳達說話者的身分,不必在每一輪都重新傳送長篇的角色設定。
  • 將每回合的 style 欄位留空,或為整段對話傳送一個簡短的常數字串 (例如 "casual, friendly")。
  • 將代理的長篇回覆拆成較短的回覆,而不是使用更強烈的風格提示。

限制

  • TTS 模型接受純文字輸入,並生成純音訊輸出。
  • 單一要求多位說話者生成 (speech_config.speakers) 最多支援 2 位說話者使用預建語音。如要在多個角色的對話中,結合自訂設計 (voice_...) 或複製 (voice_... / voicekey_...) 的聲音,請分別合成每個講者的語音。一元要求預設會傳回含有 44 位元組 RIFF 標頭的 audio/wav,因此請要求原始 PCM ({"type": "audio", "mime_type": "audio/l16"}),或在串連 24kHz PCM 音訊影格前,先從每個回合中移除 WAV 標頭。
  • 自訂語音儲存空間限制和存留時間:
    • 有狀態的聲音 (store=True、提示或複製):每個專案最多 200 個聲音,存留時間為 1 年。
    • 無狀態語音金鑰 (store=False、voicekey_...): 7 天 TTL (存留時間)。
  • 如要瞭解支援的語言,請參閱「支援的語言」一節。

後續步驟