使用語音設計建立自訂語音

您可以使用語音設計功能,透過自然語言描述建立自訂語音。不必選擇預建語音或錄製參考音訊,只要描述角色的年齡、音色、口音和基本語調,就能建立語音。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 位於global位置,可透過 v1beta1 API 版本存取。

建立設計的聲音

在要求中設定下列欄位:

  • 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 是 24 kHz 的單聲道 16 位元 PCM,沒有標頭。
  • usage:要求使用的權杖數量。詳情請參閱「定價」。

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 檔案包含 24 kHz 的無標頭 16 位元 PCM 音訊 (單聲道)。

如要聆聽以自己文字生成的語音,請按照下一節的說明生成語音。

使用設計的聲音生成語音

在 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 的費率,以文字輸入和音訊輸出詞元計費。音訊輸出權杖涵蓋 Voices API 生成的語音樣本。create 回應中的 usage 欄位會同時回報這兩項計數。舉例來說,建立樣本中的一句說明大約會使用 220 個輸入權杖,以及 1,100 個輸出權杖。

系統不會針對 get、list 和 delete 方法收費。使用設計的聲音生成的語音,會按照您呼叫的模型費率計費。

如要瞭解權杖費率,請參閱 Gemini Enterprise 定價。

提示最佳做法

  • 在語音描述中加入永久特徵:建立語音時,請定義年齡、性別、音色、音質和地域口音,而非在 speech_metadata.style 中定義。
  • 使用 speech_metadata.style 呈現當下情緒:建立語音後,使用 style 等簡短值 (例如 "whispered urgently" 或 "cheerful and energetic") 指導每輪對話,但不會變更說話者的身分。
  • 具體簡潔:清楚的一兩句話描述,例如「30 多歲的體育賽事播報員,聲音清脆有活力,帶有中西部口音」,比冗長或矛盾的段落更能產生一致的結果。

後續步驟