使用 Gemini TTS 生成語音

Gemini 文字轉語音 (TTS) 模型可將文字轉換為單人或多人音訊。您可以使用結構化對話中繼資料 (speech_metadata) 和內嵌語音標記,控制音訊的風格、口音、速度和語調。

本頁說明如何使用 Gemini Enterprise API 的 generateContent 和 streamGenerateContent 方法,透過下列模型生成語音:

TTS 模型專為精確朗讀文字而設計,可精細控制風格和聲音,例如旁白、有聲書和語音代理回覆。如要透過音訊輸入和輸出進行互動式即時對話,請改用 Live API。

如果您使用的是舊版 Gemini TTS 模型 (例如 gemini-3.1-flash-tts-preview),請參閱遷移指南。

支援的模型

模型 單一說話者 多位說話者 串流 語音設計 語音複製
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-3.1-flash-tts-preview)
Gemini 2.5 Pro TTS (gemini-2.5-pro-tts)
Gemini 2.5 Flash TTS (gemini-2.5-flash-tts)

本頁面的樣本和功能適用於 Gemini 3.8 TTS 模型。如需舊版模型,請參閱Cloud de Confiance by S3NS Text-to-Speech 說明文件中的 Gemini-TTS。

各模型的使用時機

兩個 Gemini 3.8 TTS 模型共用相同的要求結構定義和提示格式,因此只要變更模型 ID,即可切換模型:

  • 如果最重視音訊保真度、細膩的演繹和生動的控制,請使用 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 的建議替代方案,適用於大量批次製作、對話式語音代理串聯、朗讀功能、語音複製,以及主要語言的日常單一揚聲器語音。

事前準備

  1. 設定專案並啟用 Gemini Enterprise API。
  2. 為開發環境設定應用程式預設憑證。
  3. 如要使用 Python 範例,請安裝 2.25.0 以上版本的 Google Gen AI SDK:

    pip install --upgrade "google-genai>=2.25.0"
    

Gemini 3.8 TTS 模型適用於 global 位置。將要求傳送至 aiplatform.googleapis.com 端點。

單一說話者 TTS

如要將文字轉換成單一說話者的音訊,請在 parts[].text 中傳遞逐字稿、在 parts[].speech_metadata 中新增選用的語音層級樣式,並在 speechConfig.voiceConfig.voice 中設定語音。voice 欄位接受預建語音名稱、擴充語音庫語音 ID,或是設計或複製語音的 ID (voice_...),或選用的無狀態 voicekey_... 金鑰。

根據預設,一元要求會傳回完整的 WAV 檔案 (16 位元 PCM、24 kHz、單聲道),因此您可以直接將音訊位元組寫入 .wav 檔案。串流要求則會傳回原始 PCM 區塊。如需詳細資料和其他編碼方式,請參閱「音訊輸出格式」。

Python

from google import genai

client = genai.Client(enterprise=True, project="PROJECT_ID", location="global")

response = client.models.generate_content(
    model="gemini-3.8-flash-tts",
    contents=[{
        "role": "user",
        "parts": [{
            "text": "Have a wonderful day!",
            "speech_metadata": {"style": "cheerful and friendly"},
        }],
    }],
    config={
        "response_modalities": ["AUDIO"],
        "speech_config": {"voice_config": {"voice": "Kore"}},
    },
)

# The SDK has already decoded the base64 audio, so inline_data.data is a
# complete WAV file by default.
with open("out.wav", "wb") as f:
    f.write(response.candidates[0].content.parts[0].inline_data.data)

REST

curl -X POST \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json" \
  https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/publishers/google/models/gemini-3.8-flash-tts:generateContent \
  -d '{
    "contents": [{
      "role": "user",
      "parts": [{
        "text": "Have a wonderful day!",
        "speechMetadata": {"style": "cheerful and friendly"}
      }]
    }],
    "generationConfig": {
      "responseModalities": ["AUDIO"],
      "speechConfig": {
        "voiceConfig": {"voice": "Kore"}
      }
    }
  }' | jq -r '.candidates[0].content.parts[0].inlineData.data' | base64 --decode > out.wav

單一說話者串流文字轉語音

如要在模型合成語音時接收音訊,請使用 streamGenerateContent 方法。串流回應會傳回無標頭的原始 16 位元 PCM 區塊 (24 kHz,單聲道),因此您可以在每個區塊送達時,將其傳遞至播放器、通訊端或其他音訊管道。在下列 Python 範例中,emit_audio 函式代表該目的地。

Python

from google import genai

client = genai.Client(enterprise=True, project="PROJECT_ID", location="global")

def emit_audio(pcm: bytes) -> None:
    """Sends a chunk of raw 16-bit PCM audio (24 kHz, mono) downstream."""
    # Replace with your audio destination, such as a player, a WebSocket,
    # or a telephony stream.
    print(f"Received {len(pcm)} bytes of audio")

response_stream = client.models.generate_content_stream(
    model="gemini-3.8-flash-lite-tts",
    contents=[{
        "role": "user",
        "parts": [{
            "text": "Have a wonderful day!",
            "speech_metadata": {"style": "cheerful and friendly"},
        }],
    }],
    config={
        "response_modalities": ["AUDIO"],
        "speech_config": {"voice_config": {"voice": "Kore"}},
    },
)

for chunk in response_stream:
    if not chunk.candidates or not chunk.candidates[0].content:
        continue
    for part in chunk.candidates[0].content.parts or []:
        if part.inline_data and part.inline_data.data:
            emit_audio(part.inline_data.data)

REST

curl -N -X POST \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json" \
  "https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/publishers/google/models/gemini-3.8-flash-lite-tts:streamGenerateContent?alt=sse" \
  -d '{
    "contents": [{
      "role": "user",
      "parts": [{
        "text": "Have a wonderful day!",
        "speechMetadata": {"style": "cheerful and friendly"}
      }]
    }],
    "generationConfig": {
      "responseModalities": ["AUDIO"],
      "speechConfig": {
        "voiceConfig": {"voice": "Kore"}
      }
    }
  }' | sed -n 's/^data: //p' \
    | jq -r '.candidates[0].content.parts[0].inlineData.data // empty' \
    | while read -r chunk; do echo "$chunk" | base64 --decode; done > streamed.pcm

streamed.pcm 檔案包含原始 16 位元 PCM 音訊,頻率為 24 kHz,單聲道。

多位說話者 TTS

如要設定兩位說話者之間的對話,請在 speechConfig.multiSpeakerVoiceConfig.speakerVoiceConfigs 中設定這兩位說話者。然後將每個輪流發言的內容做為個別的 part 傳遞,並將每個輪流發言的 speech_metadata.speaker 設為已設定的其中一個說話者名稱,以及新增選用的輪流發言層級 style。

多位說話者要求必須恰好有兩位說話者。

Python

from google import genai

client = genai.Client(enterprise=True, project="PROJECT_ID", location="global")

response = client.models.generate_content(
    model="gemini-3.8-flash-tts",
    contents=[{
        "role": "user",
        "parts": [
            {
                "text": "How's it going today, Jane?",
                "speech_metadata": {"speaker": "Joe", "style": "cheerful and friendly"},
            },
            {
                "text": "Not too bad, how about you? Ready to test these new voices?",
                "speech_metadata": {"speaker": "Jane", "style": "calm and relaxed"},
            },
        ],
    }],
    config={
        "response_modalities": ["AUDIO"],
        "speech_config": {
            "multi_speaker_voice_config": {
                "speaker_voice_configs": [
                    {"speaker": "Joe", "voice_config": {"voice": "Puck"}},
                    {"speaker": "Jane", "voice_config": {"voice": "Kore"}},
                ]
            }
        },
    },
)

with open("dialogue.wav", "wb") as f:
    f.write(response.candidates[0].content.parts[0].inline_data.data)

REST

curl -X POST \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json" \
  https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/publishers/google/models/gemini-3.8-flash-tts:generateContent \
  -d '{
    "contents": [{
      "role": "user",
      "parts": [
        {
          "text": "How'\''s it going today, Jane?",
          "speechMetadata": {"speaker": "Joe", "style": "cheerful and friendly"}
        },
        {
          "text": "Not too bad, how about you? Ready to test these new voices?",
          "speechMetadata": {"speaker": "Jane", "style": "calm and relaxed"}
        }
      ]
    }],
    "generationConfig": {
      "responseModalities": ["AUDIO"],
      "speechConfig": {
        "multiSpeakerVoiceConfig": {
          "speakerVoiceConfigs": [
            {"speaker": "Joe", "voiceConfig": {"voice": "Puck"}},
            {"speaker": "Jane", "voiceConfig": {"voice": "Kore"}}
          ]
        }
      }
    }
  }' | jq -r '.candidates[0].content.parts[0].inlineData.data' | base64 --decode > dialogue.wav

多位說話者串流 TTS

多語者要求也支援串流。使用與多位說話者 TTS 相同的要求,並搭配 streamGenerateContent 方法。

Python

from google import genai

client = genai.Client(enterprise=True, project="PROJECT_ID", location="global")

def emit_audio(pcm: bytes) -> None:
    """Sends a chunk of raw 16-bit PCM audio (24 kHz, mono) downstream."""
    # Replace with your audio destination, such as a player, a WebSocket,
    # or a telephony stream.
    print(f"Received {len(pcm)} bytes of audio")

response_stream = client.models.generate_content_stream(
    model="gemini-3.8-flash-tts",
    contents=[{
        "role": "user",
        "parts": [
            {
                "text": "How's it going today, Jane?",
                "speech_metadata": {"speaker": "Joe", "style": "cheerful and friendly"},
            },
            {
                "text": "Not too bad, how about you? Ready to test these new voices?",
                "speech_metadata": {"speaker": "Jane", "style": "calm and relaxed"},
            },
        ],
    }],
    config={
        "response_modalities": ["AUDIO"],
        "speech_config": {
            "multi_speaker_voice_config": {
                "speaker_voice_configs": [
                    {"speaker": "Joe", "voice_config": {"voice": "Puck"}},
                    {"speaker": "Jane", "voice_config": {"voice": "Kore"}},
                ]
            }
        },
    },
)

for chunk in response_stream:
    if not chunk.candidates or not chunk.candidates[0].content:
        continue
    for part in chunk.candidates[0].content.parts or []:
        if part.inline_data and part.inline_data.data:
            emit_audio(part.inline_data.data)

REST

curl -N -X POST \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json" \
  "https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/publishers/google/models/gemini-3.8-flash-tts:streamGenerateContent?alt=sse" \
  -d '{
    "contents": [{
      "role": "user",
      "parts": [
        {
          "text": "How'\''s it going today, Jane?",
          "speechMetadata": {"speaker": "Joe", "style": "cheerful and friendly"}
        },
        {
          "text": "Not too bad, how about you? Ready to test these new voices?",
          "speechMetadata": {"speaker": "Jane", "style": "calm and relaxed"}
        }
      ]
    }],
    "generationConfig": {
      "responseModalities": ["AUDIO"],
      "speechConfig": {
        "multiSpeakerVoiceConfig": {
          "speakerVoiceConfigs": [
            {"speaker": "Joe", "voiceConfig": {"voice": "Puck"}},
            {"speaker": "Jane", "voiceConfig": {"voice": "Kore"}}
          ]
        }
      }
    }
  }' | sed -n 's/^data: //p' \
    | jq -r '.candidates[0].content.parts[0].inlineData.data // empty' \
    | while read -r chunk; do echo "$chunk" | base64 --decode; done > dialogue_streamed.pcm

dialogue_streamed.pcm 檔案包含原始 16 位元 PCM 音訊,頻率為 24 kHz,單聲道。

使用中繼資料和標記控制語音風格

Gemini 3.8 TTS 模型會將 text 欄位視為逐字稿。系統可能會朗讀文字中的指示,例如 "Say cheerfully: Hello!" 或 "Speaker 1: Hello!"。如要控管傳送,請依範圍拆分指令:

  • 持續性語音層級傳達方式 (speech_metadata.style):將適用於整個語音的情緒、傳達方式、韻律、語速和音量放入 speech_metadata.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..."。

如需更多指引,請參閱提示詞指南。

語音選項

Gemini 3.8 TTS 模型支援四種選取或建立語音的方式:

  1. 預先建立的語音:30 種精選語音。
  2. 擴充語音庫:超過 2,000 種精選預設語音,涵蓋多種語言、地區口音和角色。
  3. 語音設計: 使用 Voices API create 方法 (client.voices.create() (Google Gen AI SDK) 或 POST https://aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/global/voices),根據自然語言描述建立自訂語音。 將 type 設為 VOICE_TYPE_PROMPTED,並將 store 設為 true。回應會傳回儲存的 voice_... ID 和語音樣本。
  4. 語音複製:使用相同的 create 方法,從參考和同意聲明音訊複製說話者的語音。將 type 設為 VOICE_TYPE_REPLICATED。使用 store: true 時,回應會傳回儲存的 voice_... ID。使用 store: false 時,會傳回無狀態 voicekey_... 鍵。

自訂語音限制和存留時間

語音類型 儲存模式 管理 有效期限
儲存的語音 (voice_...,設計或複製) store: true Voices API list、get 和 delete 方法 上次使用後 1 年
語音複製金鑰 (voicekey_...) store: false 由應用程式管理。Google 不會保留金鑰。 建立後 7 天

使用儲存的語音生成語音時,會重新計算一年的保留期限,因此經常使用的語音不會過期。語音建立要求受限於每項專案每分鐘的配額。如果超過上限,create 方法會傳回 RESOURCE_EXHAUSTED 錯誤。詳情請參閱「配額與系統限制」。

資料儲存與保留

Google 會儲存您在建立儲存的語音時提供的輸入內容,以及從中衍生的語音構件,並與建立語音的Cloud de Confiance by S3NS 專案建立關聯。

當您根據說話者的錄音建立複製語音時,系統會儲存下列內容:

  • 參考音訊:要複製語音的說話者樣本。
  • 同意聲明音訊:說話者朗讀必要同意聲明。

當您在提示中使用語音的文字說明建立設計語音時,系統會儲存下列內容:

  • 您撰寫的文字提示詞,用來描述語音。
  • 模型會使用該提示生成的語音音訊做為語音參考。

設計的語音沒有同意聲明音訊,因為這是根據說明生成,而非根據真人錄音。

系統會儲存語音輸入內容,確保語音功能在模型更新後仍可正常運作。 基礎模型更新後,系統會根據儲存的輸入內容重新生成語音構件。如果找不到語音的儲存輸入內容,就無法重新生成構件,且語音會在模型更新後停止運作。接著必須再次建立語音。

儲存的輸入內容只會在模型更新時用於重新生成語音。這些資料會經過靜態資料加密,並與建立語音的專案隔離。

保留期限

自您上次使用語音合成語音起,語音和所有相關儲存資料最多會保留一年 (365 天)。語音建立後即開始計算時間,每次傳送使用該語音的合成要求時,時間都會重設。如果語音未在 365 天內使用,系統就會刪除該語音、儲存的輸入內容和衍生構件。

客戶刪除

您隨時可以使用 Voices API delete 方法刪除語音。刪除語音後,系統會一併刪除儲存的輸入內容和衍生成品。如果刪除擁有語音的 Cloud de Confiance by S3NS 專案,系統也會按照標準專案刪除程序刪除語音。

預先建立的聲音

下表列出每個預建語音的名稱和特徵:

  • Achernar:柔和
  • Achird:友善
  • Algenib:礫石
  • Algieba:平滑
  • Alnilam:堅定
  • Aoede:輕快
  • Autonoe:明快
  • Callirrhoe:隨和
  • Charon:充實
  • Despina:柔和
  • Enceladus:氣音
  • Erinome:清晰
  • Fenrir:激昂
  • Gacrux:成熟
  • Iapetus:清晰
  • Kore:堅定
  • Laomedeia:歡快
  • Leda:年輕
  • Orus:公司
  • Puck:歡樂
  • Pulcherrima:積極
  • Rasalgethi:充實
  • Sadachbia:活潑
  • Sadaltager:博學
  • Schedar:偶數
  • Sulafat:溫暖
  • Umbriel:隨和
  • Vindemiatrix:溫柔
  • Zephyr:明快
  • Zubenelgenubi:隨性

擴充語音資料庫

除了 30 種預先建立的語音,擴充語音庫還提供超過 2,000 種精選預設語音,涵蓋多種語言、地區口音、角色人物,以及有聲書、對話式代理和新聞等用途。如要使用語音庫中的語音,請在 speechConfig.voiceConfig.voice 中傳遞其 ID,方法與傳遞預建語音名稱相同。

如要瀏覽資料庫,請呼叫 Voices API list 方法 (ListVoices)。這會傳回專案中儲存的自訂語音,接著是預先建構和 Extended Voice Library 語音。每個程式庫語音都包含 id 和中繼資料,例如 language_code、accent、gender、pitch、persona 和 description。如要縮小結果範圍,請使用下列篩選器:

  • type:語音來源:預先建構和程式庫語音為 prebuilt,設計語音為 prompted,複製語音為 replicated。如果傳遞多個值,方法會傳回符合任一值的語音。
  • search:要比對的文字,不區分大小寫,會與每個語音的顯示名稱和說明進行比對。

以下範例會搜尋程式庫中的旁白聲音:

Python

from google import genai

client = genai.Client(enterprise=True, project="PROJECT_ID", location="global")

response = client.voices.list(type_=["prebuilt"], search="narrator", page_size=50)
for voice in response.voices or []:
    print(voice.id, voice.language_code, voice.gender, voice.description)

REST

curl -G \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  https://aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/global/voices \
  --data-urlencode "type=prebuilt" \
  --data-urlencode "search=narrator" \
  --data-urlencode "pageSize=50"

list 方法每頁最多傳回 50 個語音。如要取得下一頁,請將回應中的 next_page_token 值做為 page_token 參數傳遞。

音訊輸出格式

預設音訊編碼取決於方法:

  • 一元要求 (generateContent) 會傳回完整的 WAV 檔案 (audio/wav),並附上 RIFF 標頭:16 位元 PCM、24 kHz、單聲道。
  • 串流要求 (streamGenerateContent) 會以 24 kHz 單聲道傳回無標頭的原始 16 位元帶正負號小端序 PCM 區塊 (audio/l16)。

如要要求其他編碼方式,請將 generationConfig.responseFormat 設為音訊格式。Gemini 3.8 TTS 模型支援下列 mimeType 值:

mimeType 值 格式 說明
AUDIO_WAV (一元預設) WAV (audio/wav) 包含 RIFF 標頭的完整 WAV 檔案 (16 位元 PCM、24 kHz、單聲道)。
AUDIO_L16 (串流預設) 線性 PCM (audio/l16) 無標頭的原始 16 位元帶正負號小端序 PCM。適用於串流、自訂音訊管道,或串連多輪對話片段。
AUDIO_MULAW μ-law (audio/mulaw) G.711 μ-law 壓縮音訊 (8 kHz,單聲道),常用於北美和日本的電話系統。
AUDIO_ALAW A-law (audio/alaw) G.711 A-law 壓縮音訊 (8 kHz,單聲道),常用於歐洲和國際電話。

模型會忽略 sampleRate 欄位。無論回應 mimeType 中的速率為何,線性 PCM 和 WAV 輸出均為 24 kHz,μ-law 和 A-law 輸出則為 8 kHz。如果管道需要不同的取樣率,請在用戶端重新取樣輸出內容。

以下範例要求電話管道輸出 μ-law。Python 適用的 Google Gen AI SDK 不會公開 responseFormat 中的 GenerateContentConfig,因此 Python 範例會透過 http_options.extra_body 在要求主體中傳遞該值。

Python

from google import genai

client = genai.Client(enterprise=True, project="PROJECT_ID", location="global")

response = client.models.generate_content(
    model="gemini-3.8-flash-tts",
    contents=[{"role": "user", "parts": [{"text": "Have a wonderful day!"}]}],
    config={
        "response_modalities": ["AUDIO"],
        "speech_config": {"voice_config": {"voice": "Kore"}},
        "http_options": {
            "extra_body": {
                "generationConfig": {
                    "responseFormat": [{"audio": {"mimeType": "AUDIO_MULAW"}}]
                }
            }
        },
    },
)

# The response is headerless μ-law audio at 8 kHz, mono.
with open("out.mulaw", "wb") as f:
    f.write(response.candidates[0].content.parts[0].inline_data.data)

REST

curl -X POST \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json" \
  https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/publishers/google/models/gemini-3.8-flash-tts:generateContent \
  -d '{
    "contents": [{"role": "user", "parts": [{"text": "Have a wonderful day!"}]}],
    "generationConfig": {
      "responseModalities": ["AUDIO"],
      "responseFormat": [{"audio": {"mimeType": "AUDIO_MULAW"}}],
      "speechConfig": {
        "voiceConfig": {"voice": "Kore"}
      }
    }
  }' | jq -r '.candidates[0].content.parts[0].inlineData.data' | base64 --decode > out.mulaw

支援的語言

Gemini 3.8 TTS 模型會自動偵測輸入語言。Gemini 3.8 Flash TTS 支援 130 種語言,Gemini 3.8 Flash-Lite TTS 則支援 101 種語言:

限制

  • TTS 模型接受純文字輸入,並傳回純音訊輸出。
  • 多位說話者要求必須恰好有兩位說話者。如要在多角色對話中結合設計 (voice_...) 或複製 (voice_... 或 voicekey_...) 的語音,或使用兩個以上的說話者,請個別合成每位說話者的語音,然後串連音訊。請要求每個回合輸出 AUDIO_L16,或在串連片段前,先從每個片段中移除 WAV 標頭。
  • 這些模型僅適用於 global 地點。
  • 不支援系統指令。
  • 你無法設定輸出取樣率。不支援 MP3 和 Ogg Opus 輸出。

後續步驟