通过语音设计创建自定义语音

您可以使用语音设计功能,根据自然语言描述创建自定义语音。您无需选择预建的语音或录制参考音频,只需描述角色的年龄、音色、口音和基准发音,即可创建语音。Voices API 会将语音存储在您的项目中,并返回一个可重复使用的 voice_... ID,您可以在语音生成请求中传递该 ID。

设计的声音可与 Gemini 3.8 Flash TTS (gemini-3.8-flash-tts) 和 Gemini 3.8 Flash-Lite TTS (gemini-3.8-flash-lite-tts) 搭配使用。

语音设计的工作原理

  1. 创建提示语音:调用 Voices API create 方法,并将 voice.type 设置为 VOICE_TYPE_PROMPTED,将 store 设置为 true。
  2. 接收语音 ID 和示例:Voices API 会生成语音,将其存储在您的项目中,并在 id 字段中返回其 ID(例如 voice_abc123...),并在 sample_audio 字段中返回语音示例。
  3. 生成语音:调用 generateContent 或 streamGenerateContent 时,在 speechConfig.voiceConfig.voice 中传递语音 ID。

准备工作

完成 Gemini TTS 页面上的准备工作中的步骤。Voices API 可通过 v1beta1 API 版本在 global 位置使用。

创建设计的语音

在请求中设置以下字段:

  • store:必须为 true。设计的语音始终存储在您的项目中。
  • voice.type:VOICE_TYPE_PROMPTED。
  • voice.prompted.input:语音的自然语言说明。
  • voice.display_name、voice.gender、voice.language_code:语音的可选元数据。

不设置 voice.model。如果请求同时设置了模型和 store: true,则会失败并显示 INVALID_ARGUMENT 错误。

设计声音可能需要几秒钟的时间。Python 示例将请求超时时间设置为 60 秒。

响应包含以下字段:

  • id:新语音的 ID。
  • sample_audio:语音样本。data 字段包含采用 base64 编码的音频,mime_type 字段则指明了其编码。例如,audio/l16; rate=24000; channels=1 是无标头的 16 位 PCM,采样率为 24 kHz,单声道。
  • usage:请求使用的 token 数量。如需了解详情,请参阅价格。

Python

import base64
import wave

from google import genai

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

voice = client.voices.create(
    store=True,
    voice={
        "type": "VOICE_TYPE_PROMPTED",
        "display_name": "Warm British Astronomer",
        "gender": "male",
        "language_code": "en-GB",
        "prompted": {
            "input": (
                "A warm, thoughtful astronomer in his late 60s with a gentle"
                " British accent, speaking with quiet wonder."
            )
        },
    },
    timeout=60,
)

print(f"Created voice ID: {voice.id}")

# Save the voice sample. The SDK returns sample_audio.data as a base64
# string. Raw 16-bit PCM (audio/l16) needs a WAV header.
sample = base64.b64decode(voice.sample_audio.data)
if voice.sample_audio.mime_type.lower().startswith("audio/l16"):
    with wave.open("voice_sample.wav", "wb") as wf:
        wf.setnchannels(1)
        wf.setsampwidth(2)
        wf.setframerate(24000)
        wf.writeframes(sample)
else:
    with open("voice_sample.wav", "wb") as f:
        f.write(sample)

REST

curl -X POST \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json" \
  https://aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/global/voices \
  -d '{
    "store": true,
    "voice": {
      "type": "VOICE_TYPE_PROMPTED",
      "displayName": "Warm British Astronomer",
      "gender": "male",
      "languageCode": "en-GB",
      "prompted": {
        "input": "A warm, thoughtful astronomer in his late 60s with a gentle British accent, speaking with quiet wonder."
      }
    }
  }' > created_voice.json

# Print the voice ID and the encoding of the voice sample.
jq -r '.id, .sample_audio.mime_type' created_voice.json

# Decode the voice sample.
jq -r '.sample_audio.data' created_voice.json | base64 --decode > voice_sample.pcm

如果 sample_audio.mime_type 为 audio/l16,则 voice_sample.pcm 文件包含无标头的 16 位 PCM 音频,采样率为 24 kHz,单声道。

如需使用自己的文本来试听该语音,请按照下一部分中的说明生成语音。

使用设计的语音生成语音

在 speechConfig.voiceConfig.voice 中传递语音 ID:

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": (
                "Look out past the rings of Saturn. Those faint photons left"
                " their source millions of years ago."
            ),
            "speech_metadata": {"style": "reflective and awe-inspired"},
        }],
    }],
    config={
        "response_modalities": ["AUDIO"],
        "speech_config": {"voice_config": {"voice": "VOICE_ID"}},
    },
)

# The SDK has already decoded the base64 audio, so inline_data.data is a
# complete WAV file by default.
with open("designed_voice.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": "Look out past the rings of Saturn. Those faint photons left their source millions of years ago.",
        "speechMetadata": {"style": "reflective and awe-inspired"}
      }]
    }],
    "generationConfig": {
      "responseModalities": ["AUDIO"],
      "speechConfig": {
        "voiceConfig": {"voice": "VOICE_ID"}
      }
    }
  }' | jq -r '.candidates[0].content.parts[0].inlineData.data' | base64 --decode > designed_voice.wav

将 VOICE_ID 替换为 create 方法返回的语音 ID。

管理已存储的语音

您可以列出、获取和删除项目中存储的声音,包括设计的声音和存储的复制声音。 list 方法会返回存储在项目中的语音,然后返回预构建的语音和扩展语音库语音。如需仅列出存储在项目中的声音,请将 type 过滤条件设置为 prompted 和 replicated,如以下示例所示。get 方法还会返回 sample_audio 字段中设计的语音样本。

Python

from google import genai

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

# List the voices stored in your project.
for voice in client.voices.list(type_=["prompted", "replicated"]).voices or []:
    print(voice.id, voice.display_name, voice.type)

# Get a voice by ID.
voice = client.voices.get(id="VOICE_ID")

# Delete a voice.
client.voices.delete(id="VOICE_ID")

REST

# List the voices stored in your project.
curl -G \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  https://aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/global/voices \
  --data-urlencode "type=prompted" \
  --data-urlencode "type=replicated"

# Get a voice by ID.
curl -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  https://aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/global/voices/VOICE_ID

# Delete a voice.
curl -X DELETE \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  https://aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/global/voices/VOICE_ID

限制

  • 存储的声音会在上次使用后一年过期。使用声音生成语音会重新开始此期限,因此您经常使用的声音不会过期。删除不再需要的语音。
  • 语音创建请求受每项目每分钟配额的限制。如果超出此限制,create 方法会返回 RESOURCE_EXHAUSTED 错误。请稍后再试。如需了解详情,请参阅配额和系统限制。

价格

创建设计的声音时,系统会按照 Gemini 3.8 Flash TTS 的费率,将文本输入 token 和音频输出 token 计入账单。音频输出 token 涵盖 Voices API 生成的语音样本。create 响应中的 usage 字段会报告这两个数量。例如,创建示例中的单句说明使用了大约 220 个输入 token 和大约 1,100 个输出 token。

get、list 和 delete 方法不收费。使用设计的语音生成的语音按您调用的模型的费率收费。

如需了解令牌费率,请参阅 Gemini Enterprise 价格。

提示撰写最佳实践

  • 在语音描述中添加永久性特征:创建语音时,请定义年龄、性别、音色、声音质感和地区口音,而不是在 speech_metadata.style 中定义。
  • 使用 speech_metadata.style 表示情境情绪:创建语音后,使用较短的 style 值(例如 "whispered urgently" 或 "cheerful and energetic")来指导每一轮对话,而不会改变说话者的身份。
  • 内容要具体且简洁:清晰的一两句话描述(例如“一位 30 多岁的体育播报员,声音清脆有力,略带中西部口音”)比冗长或矛盾的段落能生成更一致的结果。

后续步骤