使用 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

单说话者流式 TTS

如需在模型仍在合成音频时接收音频,请使用 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 方法(在 Google Gen AI SDK 中为 client.voices.create(),或 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_... 密钥。

自定义语音限制和 TTL

语音类型 存储模式 管理 失效时间
存储的声音(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)。该方法会返回存储在项目中的自定义语音,然后返回预构建语音和扩展语音库语音。每个库语音都包含其 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) 会返回一个带有 RIFF 标头的完整 WAV 文件 (audio/wav):16 位 PCM、24 kHz、单声道。
  • 流式传输请求 (streamGenerateContent) 会返回无标头的原始 16 位有符号小端序 PCM 数据块 (audio/l16),采样率为 24 kHz,单声道。

如需请求其他编码,请将 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 μ 律 (audio/mulaw) G.711 μ-law 压扩音频(8 kHz,单声道),常用于北美和日本的电话系统。
AUDIO_ALAW A 律 (audio/alaw) G.711 A-law 压扩音频(8 kHz,单声道),常用于欧洲和国际电话。

模型会忽略 sampleRate 字段。线性 PCM 和 WAV 输出为 24 kHz,而 μ-law 和 A-law 输出为 8 kHz,无论响应 mimeType 中的速率是多少。如果您的流水线需要不同的采样率,请在客户端上对输出进行重新采样。

以下示例请求为电话流水线提供 μ-law 输出。Google Gen AI SDK for Python 不会在 GenerateContentConfig 中公开 responseFormat,因此 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 输出。

后续步骤