Interfejs Gemini API może przekształcać tekst na dźwięk z jednym lub wieloma mówcami za pomocą funkcji generowania tekstu na mowę (TTS) Gemini.
Generowanie tekstu na mowę jest kontrolowane, co oznacza, że możesz łączyć uporządkowane metadane tury (speech_metadata) i wbudowane tagi głosowe, aby określać styl, akcent, tempo i ton dźwięku.
Funkcja TTS różni się od generowania mowy za pomocą interfejsu Live API, który jest przeznaczony do interaktywnych, nieustrukturyzowanych danych audio oraz multimodalnych danych wejściowych i wyjściowych. Interfejs Live API sprawdza się w dynamicznych kontekstach konwersacyjnych, a TTS za pomocą interfejsu Gemini API jest dostosowany do scenariuszy, które wymagają dokładnego odczytania tekstu z precyzyjną kontrolą stylu i dźwięku, takich jak generowanie podcastów lub audiobooków.
Z tego przewodnika dowiesz się, jak generować dźwięk z jednego lub wielu głośników na podstawie tekstu za pomocą Gemini 3.8 Flash TTS (gemini-3.8-flash-tts) i Gemini 3.8 Flash-Lite TTS (gemini-3.8-flash-lite-tts).
Zanim zaczniesz
Użyj modelu Gemini TTS wymienionego w sekcji Obsługiwane modele. Aby uzyskać optymalne wyniki, zapoznaj się z artykułem Kiedy używać którego modelu, aby wybrać najlepszy model dla swojego zadania.
Przed rozpoczęciem tworzenia możesz przetestować modele Gemini TTS w AI Studio.
TTS z jednym głosem
Aby przekonwertować tekst na dźwięk z jednym mówcą za pomocą modeli TTS Gemini 3.8, przekaż dosłowną transkrypcję w parts[].text, dołącz stylizację na poziomie wypowiedzi w parts[].speech_metadata i skonfiguruj głos w speechConfig.voiceConfig. Możesz przekazać nazwę gotowego głosu, identyfikator rozszerzonej biblioteki głosów, identyfikator niestandardowego projektu głosu (voice_...) lub identyfikator replikacji głosu (voice_... lub opcjonalnie bezstanowy voicekey_...).
W tym przykładzie zapisujemy wyjściowy dźwięk z modelu w pliku WAV:
Python
from google import genai
client = genai.Client()
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"}
},
},
)
data = response.candidates[0].content.parts[0].inline_data.data
with open("out.wav", "wb") as f:
f.write(data)
JavaScript
import {GoogleGenAI} from '@google/genai';
import * as fs from 'node:fs';
async function main() {
const ai = new GoogleGenAI({});
const response = await ai.models.generateContent({
model: 'gemini-3.8-flash-tts',
contents: [{
role: 'user',
parts: [{
text: 'Have a wonderful day!',
speechMetadata: { style: 'cheerful and friendly' },
}],
}],
config: {
responseModalities: ['AUDIO'],
speechConfig: {
voiceConfig: { voice: 'Kore' },
},
},
});
const data = response.candidates?.[0]?.content?.parts?.[0]?.inlineData?.data;
const audioBuffer = Buffer.from(data, 'base64');
fs.writeFileSync('out.wav', audioBuffer);
}
await main();
REST
curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.8-flash-tts:generateContent" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-X POST \
-H "Content-Type: application/json" \
-d '{
"contents": [{
"role": "user",
"parts": [{
"text": "Have a wonderful day!",
"speech_metadata": {
"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 z wieloma rozmówcami
W przypadku dialogu z udziałem wielu mówców skonfiguruj 2 mówców w
multiSpeakerVoiceConfig.speakerVoiceConfigs za pomocą prebuiltVoiceConfig i
przekaż każdą turę dialogu jako osobny element part z parametrem speech_metadata określającym
zarówno speaker, jak i opcjonalny parametr style na poziomie tury:
Python
from google import genai
client = genai.Client()
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": {
"prebuilt_voice_config": {"voice_name": "Puck"}
},
},
{
"speaker": "Jane",
"voice_config": {
"prebuilt_voice_config": {"voice_name": "Kore"}
},
},
]
}
},
},
)
data = response.candidates[0].content.parts[0].inline_data.data
with open("out.wav", "wb") as f:
f.write(data)
JavaScript
import {GoogleGenAI} from '@google/genai';
import * as fs from 'node:fs';
async function main() {
const ai = new GoogleGenAI({});
const response = await ai.models.generateContent({
model: 'gemini-3.8-flash-tts',
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',
},
},
],
}],
config: {
responseModalities: ['AUDIO'],
speechConfig: {
multiSpeakerVoiceConfig: {
speakerVoiceConfigs: [
{
speaker: 'Joe',
voiceConfig: {
prebuiltVoiceConfig: { voiceName: 'Puck' },
},
},
{
speaker: 'Jane',
voiceConfig: {
prebuiltVoiceConfig: { voiceName: 'Kore' },
},
},
],
},
},
},
});
const data = response.candidates?.[0]?.content?.parts?.[0]?.inlineData?.data;
const audioBuffer = Buffer.from(data, 'base64');
fs.writeFileSync('out.wav', audioBuffer);
}
await main();
REST
curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.8-flash-tts:generateContent" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-X POST \
-H "Content-Type: application/json" \
-d '{
"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"
}
}
]
}],
"generationConfig": {
"responseModalities": ["AUDIO"],
"speechConfig": {
"multiSpeakerVoiceConfig": {
"speakerVoiceConfigs": [
{
"speaker": "Joe",
"voiceConfig": {
"prebuiltVoiceConfig": { "voiceName": "Puck" }
}
},
{
"speaker": "Jane",
"voiceConfig": {
"prebuiltVoiceConfig": { "voiceName": "Kore" }
}
}
]
}
}
}
}' | jq -r '.candidates[0].content.parts[0].inlineData.data' | \
base64 --decode > out.wav
Sterowanie stylem mowy za pomocą metadanych i tagów
Usługa Gemini 3.8 TTS traktuje pole text jako dosłowny zapis. Aby kontrolować odczytywanie bez odczytywania na głos wskazówek scenicznych, podziel instrukcje według zakresu:
- Stała dostawa na poziomie tury (
speech_metadata.style): umieść emocje, styl dostawy, prozodię, tempo i głośność, które mają zastosowanie w całej turze, wspeech_metadata.style(np."style": "whispered urgently","style": "out of breath"lub"style": "warm and enthusiastic"). - Zdarzenia w określonym momencie (tagi wbudowane): umieść krótkie, niewerbalne dźwięki lub przerwy bezpośrednio w transkrypcji, używając nawiasów ostrych (np.
"Wait... <short pause> did you hear that? <sigh>"lub"Excuse me <cough> as I was saying...").
Więcej sprawdzonych metod znajdziesz w przewodniku po tworzeniu promptów.
Opcje głosowe
Technologia Gemini 3.8 TTS obsługuje 4 sposoby wybierania lub tworzenia głosów:
- Gotowe głosy studyjne: 30 wyselekcjonowanych głosów wymienionych w tabeli poniżej.
- Rozszerzona biblioteka głosów: setki dodatkowych głosów w różnych językach, akcentach i archetypach postaci dostępnych za pomocą
client.voices.list()(GET /v1beta/voices). - Projektowanie głosu: generowanie spersonalizowanej osobowości głosowej na podstawie opisu w języku naturalnym w Google AI Studio lub za pomocą funkcji
POST /v1beta/voices(type="prompted", która zwraca trwały identyfikatorvoice_...i podgląd w formacie WAV wsample_audioiCreateVoice).GetVoice - Replikacja głosu:
Replikacja głosu mówcy na podstawie dźwięku referencyjnego i dźwięku z jego zgodą w Google AI Studio lub za pomocą
POST /v1beta/voices(type="replicated", domyślnie trwałestore=Truelub opcjonalne bezstanowestore=False).
Limity głosów niestandardowych i TTL
| Rodzaj głosu | Tryb przechowywania | Limit | Przechowywanie (TTL) |
|---|---|---|---|
Głosy z zachowaniem stanu (voice_..., wygenerowane na podstawie promptu lub sklonowane) |
store=True |
200 głosów na projekt (wspólnych dla głosów wygenerowanych na podstawie promptów i replikowanych) | 1 rok od ostatniego użycia* |
Klucze głosowe bezstanowe (voicekey_..., replikowane) |
store=False |
Zarządzane przez klienta | 7 dni |
* Przedłużenie okresu ważności: 1-roczny okres przechowywania jest resetowany za każdym razem, gdy głos jest aktywnie używany (do syntezy mowy lub jako głos bazowy do remiksowania). Głosy, które nie były używane przez rok, są automatycznie usuwane.
Gotowe głosy
| Zephyr – jasny | Puck – Upbeat | Charon – zawiera przydatne informacje |
| Kore – firma | Fenrir – pobudliwy | Leda -- Youthful |
| Orus – Firm | Aoede – Breezy | Callirrhoe – spokojny |
| Autonoe – jasny | Enceladus – Breathy | Iapetus – Clear |
| Umbriel – spokojny | Algieba – gładki | Despina – Smooth |
| Erinome – Wyczyść | Algenib – żwirowy | Rasalgethi – zawiera przydatne informacje |
| Laomedeia – optymistyczny | Achernar – Soft | Alnilam – Firm |
| Schedar – Równomierna | Gacrux – treści dla dorosłych | Pulcherrima – przekaż dalej |
| Achird – przyjazny | Zubenelgenubi – zwykłe | Vindemiatrix – delikatny |
| Sadachbia – Lively | Sadaltager – kompetentny | Sulafat – ciepła |
Rozszerzona biblioteka głosów i filtrowanie
Oprócz 30 głosów studyjnych wymienionych w tabeli powyżej rozszerzona biblioteka głosów zawiera setki dodatkowych głosów w różnych językach, z różnymi akcentami regionalnymi, o różnych osobowościach i w różnych domenach. Możesz przeglądać, filtrować i odsłuchiwać całą Bibliotekę głosów w interaktywny sposób w Google AI Studio lub wysyłać do niej zapytania programowo za pomocą client.voices.list() (GET /v1beta/voices, używając google-genai w wersji 2.25.0 lub nowszej / @google/genai w wersji 2.24.0 lub nowszej).
ListVoices zwraca zapisane głosy niestandardowe (w kolejności od najnowszych) oraz gotowe głosy z katalogu pasujące do kryteriów filtra. Jeśli w przypadku filtra listy przekazywanych jest kilka wartości, zwracane są głosy pasujące do dowolnej wartości w tym filtrze (OR), a różne parametry filtra są łączone za pomocą znaku AND:
| Parametr | Typ | Opis |
|---|---|---|
language_code |
list[str] |
Tagi języka BCP-47 (np. ["en-US", "en-GB"]). Dopasowanie ścisłe bez rozróżniania wielkości liter. |
region_code |
list[str] |
Kody regionów ISO 3166-1 alfa-2 lub UN M.49 (np. ["US", "GB"]). |
accent |
list[str] |
Opis akcentu regionalnego (np. ["American", "British"]). |
gender |
list[str] |
Postrzegana prezentacja płci ("female", "male" lub "neutral"). |
pitch |
list[str] |
Klasyfikacja wysokości głosu ("low", "medium" lub "high"). |
persona |
list[str] |
osobowość wokalna lub archetyp postaci (np. ["Warm, Friendly"], ["Narrator"]); |
contexts (context w REST) |
list[str] |
Domena optymalnego użytkowania (np. ["Audiobook", "Conversational", "News"]). |
type (type_ w Pythonie) |
list[str] |
Filtruj według źródła głosu: "prebuilt", "prompted" (projektowanie głosu) lub "replicated" (replikacja głosu). |
search |
str |
Wyszukiwanie podciągu tekstu dowolnego dopasowywane bez uwzględniania wielkości liter do display_name i description. |
page_size |
int |
Maksymalna liczba głosów zwracanych na stronę (domyślnie 50, maksymalnie 1000). |
page_token |
str |
Token z response.next_page_token do pobrania następnej strony wyników. |
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"
Obsługiwane języki
Modele TTS automatycznie wykrywają język wejściowy.
Gemini 3.8 Flash TTS
(gemini-3.8-flash-tts) obsługuje ponad 130 języków, a
Gemini 3.8 Flash-Lite TTS
(gemini-3.8-flash-lite-tts) obsługuje ponad 100 języków:
| Język | Gemini 3.8 Flash TTS | Gemini 3.8 Flash-Lite TTS |
|---|---|---|
| aceh (alfabet arabski), | ✔️ | ✔️ |
| afrikaans | ✔️ | ✔️ |
| akan | ✔️ | ✔️ |
| amharski | ✔️ | ✔️ |
| ormiański | ✔️ | ✔️ |
| asamski | ✔️ | ✔️ |
| awadhi | ✔️ | ✔️ |
| balijski | ✔️ | ✔️ |
| bengalski | ✔️ | ✔️ |
| banjar (alfabet arabski) | ✔️ | – |
| banjar (alfabet łaciński) | ✔️ | ✔️ |
| baszkirski | ✔️ | – |
| baskijski | ✔️ | ✔️ |
| białoruski | ✔️ | ✔️ |
| bemba | ✔️ | – |
| bhodźpuri | ✔️ | ✔️ |
| bośniacki | ✔️ | ✔️ |
| Bugiński | ✔️ | ✔️ |
| bułgarski | ✔️ | ✔️ |
| birmański | ✔️ | – |
| kantoński | ✔️ | ✔️ |
| kataloński | ✔️ | ✔️ |
| cebuański | ✔️ | ✔️ |
| centralny kurdyjski | ✔️ | ✔️ |
| ćhattisgarhi | ✔️ | ✔️ |
| chiński (pismo han) | ✔️ | ✔️ |
| chiński (pismo Hant), | ✔️ | ✔️ |
| krymsko-tatarski | ✔️ | – |
| chorwacki | ✔️ | ✔️ |
| czeski | ✔️ | ✔️ |
| duński | ✔️ | ✔️ |
| niderlandzki | ✔️ | ✔️ |
| diula | ✔️ | – |
| dzongkha | ✔️ | – |
| arabski egipski | ✔️ | ✔️ |
| angielski | ✔️ | ✔️ |
| estoński | ✔️ | ✔️ |
| filipiński | ✔️ | ✔️ |
| fiński | ✔️ | – |
| francuski | ✔️ | ✔️ |
| galicyjski | ✔️ | ✔️ |
| luganda | ✔️ | ✔️ |
| gruziński | ✔️ | ✔️ |
| niemiecki | ✔️ | ✔️ |
| grecki | ✔️ | ✔️ |
| guarani | ✔️ | – |
| gudżarati | ✔️ | ✔️ |
| kreolski haitański | ✔️ | ✔️ |
| mongolski chałchaski, | ✔️ | ✔️ |
| hausa | ✔️ | ✔️ |
| hebrajski | ✔️ | ✔️ |
| hindi | ✔️ | ✔️ |
| węgierski | ✔️ | ✔️ |
| islandzki | ✔️ | ✔️ |
| igbo | ✔️ | – |
| iloko | ✔️ | ✔️ |
| indonezyjski | ✔️ | ✔️ |
| perski irański, | ✔️ | ✔️ |
| włoski | ✔️ | ✔️ |
| japoński | ✔️ | ✔️ |
| jawajski | ✔️ | ✔️ |
| kabylski, | ✔️ | – |
| kamba | ✔️ | ✔️ |
| kannada | ✔️ | ✔️ |
| kaszmirski (alfabet arabski) | ✔️ | ✔️ |
| kaszmirski (dewanagari) | ✔️ | ✔️ |
| kazachski | ✔️ | ✔️ |
| khmerski | ✔️ | ✔️ |
| kikuyu | ✔️ | ✔️ |
| ruanda-rundi | ✔️ | ✔️ |
| kongo | ✔️ | ✔️ |
| koreański | ✔️ | ✔️ |
| kirgiski | ✔️ | ✔️ |
| laotański | ✔️ | ✔️ |
| łatgalski | ✔️ | – |
| lingala | ✔️ | ✔️ |
| litewski | ✔️ | – |
| luksemburski | ✔️ | – |
| macedoński | ✔️ | ✔️ |
| magahi | ✔️ | ✔️ |
| maithili | ✔️ | ✔️ |
| malajalam | ✔️ | ✔️ |
| maltański | ✔️ | ✔️ |
| manipuri, | ✔️ | ✔️ |
| marathi | ✔️ | ✔️ |
| Minangkabau (pismo arabskie) | ✔️ | ✔️ |
| minangkabau (alfabet łaciński) | ✔️ | – |
| mizo | ✔️ | ✔️ |
| nepalski (osobny język), | ✔️ | ✔️ |
| ful nigeryjski | ✔️ | ✔️ |
| północnoazerski, | ✔️ | ✔️ |
| sotho północny | ✔️ | ✔️ |
| północny uzbecki, | ✔️ | ✔️ |
| norweski bokmål | ✔️ | ✔️ |
| norweski (Nynorsk) | ✔️ | ✔️ |
| njandża | ✔️ | ✔️ |
| oksytański | ✔️ | – |
| Odia (pojedynczy język) | ✔️ | ✔️ |
| pangasinan | ✔️ | – |
| perski (Afganistan) | ✔️ | ✔️ |
| polski | ✔️ | ✔️ |
| portugalski | ✔️ | ✔️ |
| pendżabski | ✔️ | ✔️ |
| rumuński | ✔️ | ✔️ |
| rosyjski | ✔️ | ✔️ |
| santali | ✔️ | ✔️ |
| serbski | ✔️ | ✔️ |
| sindhi | ✔️ | – |
| syngaleski | ✔️ | ✔️ |
| słowacki | ✔️ | ✔️ |
| słoweński | ✔️ | – |
| somalijski | ✔️ | – |
| południowoazerski, | ✔️ | ✔️ |
| paszto południowy, | ✔️ | ✔️ |
| sotho południowy | ✔️ | – |
| hiszpański | ✔️ | ✔️ |
| arabski standardowy (alfabet arabski), | ✔️ | ✔️ |
| arabski standardowy (alfabet łaciński), | ✔️ | ✔️ |
| standardowy łotewski, | ✔️ | ✔️ |
| malajski standardowy, | ✔️ | ✔️ |
| suahili (język) | ✔️ | – |
| suazi | ✔️ | – |
| szwedzki | ✔️ | – |
| tadżycki | ✔️ | – |
| tamilski | ✔️ | ✔️ |
| telugu | ✔️ | ✔️ |
| tajski | ✔️ | – |
| tigrinia | ✔️ | – |
| albański (toskijski) | ✔️ | – |
| turecki | ✔️ | ✔️ |
| ujgurski | ✔️ | – |
| wietnamski | ✔️ | ✔️ |
Obsługiwane modele
| Model | Pojedynczy rozmówca | Wielogłośnikowy | Projektowanie głosu | Replikacja głosu |
|---|---|---|---|---|
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 (wersja testowa) | ✔️ | ✔️ | – | – |
| Wersja testowa Gemini 2.5 Pro TTS | ✔️ | ✔️ | – | – |
Kiedy używać którego modelu
Oba modele Gemini 3.8 TTS mają identyczny schemat interfejsu API i format promptów, dzięki czemu możesz się między nimi przełączać, zmieniając tylko jeden parametr:
- Używaj Gemini 3.8 Flash TTS (
gemini-3.8-flash-tts), gdy najważniejsza jest maksymalna wierność akustyczna, niuanse w interpretacji i ekspresyjna kontrola. Jest idealny do pracy twórczej w studiu, złożonych dialogów z udziałem wielu osób, tagów z intensywnymi wybuchami głosu, trudnych wymówień, regionalnych lub mniejszościowych dialektów oraz długich narracji wymagających stabilności głosu i dźwięku otoczenia. - Używaj Gemini 3.8 Flash-Lite TTS
(
gemini-3.8-flash-lite-tts) jako szybkiego i ekonomicznego zamiennikagemini-3.1-flash-tts-preview. Jest zoptymalizowany pod kątem produkcji masowej o dużej skali, kaskad konwersacyjnych agentów głosowych, funkcji odczytywania na głos, niezawodnej replikacji głosu i codziennego odtwarzania mowy przez pojedynczy głośnik w najpopularniejszych językach.
Przewodnik po migracji
Jeśli przechodzisz z wcześniejszych modeli w wersji podglądowej (gemini-3.1-flash-tts-preview lub gemini-2.5-pro-preview-tts) na Gemini 3.8 TTS (gemini-3.8-flash-tts lub gemini-3.8-flash-lite-tts), zapoznaj się z tymi 5 kluczowymi zmianami:
- Oddzielenie stylu od transkrypcji: przenieś instrukcje dotyczące ciągłej gry aktorskiej, tonu, prozodii i tempa (np.
"whispering","out of breath"lub"speaking slowly") z tekstu zwykłego dospeech_metadata.style. W przypadkutextnależy podać dosłowną transkrypcję z tagami wokalnymi w tekście. - Zaprojektuj persony z wyprzedzeniem za pomocą funkcji projektowania głosu: zastąp wielozdaniowe bloki
"Audio Profile"lub"Director's Notes"niestandardowym głosem utworzonym w funkcji projektowania głosu, a następnie przekaż identyfikatorvoice_...w żądaniach syntezy mowy z minimalnymi lub pustymi ciągamistyle. - Używaj strukturalnych wypowiedzi w dialogu: w przypadku dialogu z wieloma mówcami przekaż jeden
partna wypowiedź mówcy z użyciemspeech_metadata.speakerzamiast osadzaćSpeaker: ...prefiksy w jednym bloku tekstu. - Używaj nawiasów ostrych w przypadku tagów wokalnych wstawianych w tekście: używaj nawiasów ostrych (
<laugh>,<sigh>,<cough>,<breath>,<short pause>) w przypadku ludzkich wokalizacji i przerw w określonym momencie. Unikaj tagów efektów dźwiękowych, które nie są związane z głosem (np. brawa lub uderzenia). - Uwzględnij domyślne wyjście WAV (
AUDIO_WAV) w przypadku żądań binarnych: w przeciwieństwie dogemini-3.1-flash-tts-preview(który domyślnie zwracał surowe dane PCM bez nagłówka)AUDIO_L16modele TTS Gemini 3.8 zwracają kompletne dane audio WAV (AUDIO_WAV) z nagłówkiem RIFF (24 kHz, mono, 16-bit PCM) w przypadku żądań binarnych:- Jeśli Twój kod wcześniej opakowywał surowe bajty PCM w nagłówek WAV (np. za pomocą modułu
wavew Pythonie lub pakietuwavw Node.js), usuń ręczny wrapper nagłówka i zapisz zdekodowane bajty audio bezpośrednio w pliku.wav. - Jeśli Twój obecny potok wymaga nieprzetworzonego dźwięku PCM bez nagłówka, mu-law lub A-law, ustaw wyraźnie
response_format.audio.mime_typena"AUDIO_L16","AUDIO_MULAW"lub"AUDIO_ALAW"(np.{"response_format": {"audio": {"mime_type": "AUDIO_L16"}}}wgenerateContentlub{"response_format": {"type": "audio", "mime_type": "audio/l16"}}w interfejsie Interactions API). Zobacz Formaty wyjściowe audio.
- Jeśli Twój kod wcześniej opakowywał surowe bajty PCM w nagłówek WAV (np. za pomocą modułu
Przewodnik po promptach
Modele Gemini 3.8 TTS traktują tekst wejściowy ściśle jako dosłowny zapis.
W przeciwieństwie do wcześniejszych modeli podglądu, w których wskazówki sceniczne były osadzone w zwykłym tekście, Gemini 3.8 TTS oddziela wskazówki dotyczące ciągłych zmian na poziomie tury (speech_metadata) od wbudowanych tagów głosowych.
Pole stylu a tagi w tekście
Podziel instrukcje dotyczące skuteczności według zakresu:
- Dostarczanie na poziomie wypowiedzi (
speech_metadata.style): umieść atrybuty ciągłego dostarczania, takie jak emocje, prozodia, ogólne tempo lub styl dostarczania (np."whispering","out of breath","muttering"lub"sarcastic"), w polustyleelementuspeech_metadata. Aby stworzyć stabilną postać i zapewnić spójność w kolejnych turach, zaprojektuj personę z wyprzedzeniem w sekcji Projektowanie głosu i używajstyletylko do opcjonalnych zmian na poziomie tury. - Zdarzenia w określonym momencie (tagi wbudowane): umieszczaj krótkie, niewerbalne dźwięki wokalne, oddechy lub przerwy w transkrypcji za pomocą nawiasów ostrych (
<cough>,<breath>,<sigh>,<short pause>). Używaj nawiasów ostrych (<...>) w przypadku najwyższej jakości dźwięku i skup się na ludzkich dźwiękach wokalnych, a nie na efektach dźwiękowych.
| Zakres | Gdzie umieścić | Przykłady |
|---|---|---|
| Na poziomie tury (utrzymywany przez całą turę) | speech_metadata.style |
"angry tone", "speaking rapidly", "out of breath", "whispers", "sarcastic" |
| W określonym momencie (występuje w określonym słowie) | Wstawiony w text (<...>) |
"<cough> Thank you all for coming tonight! <throat-clearing> As I was saying..." |
Tempo i pauzy
Możesz kontrolować rytm i ciszę na 3 poziomach szczegółowości:
- Znaki interpunkcyjne i wielokropki: używaj przecinków, myślników (
--) i wielokropków (...), aby uzyskać naturalne wahanie w rozmowie. - Tagi pauzy w tekście: wstaw tagi
<short pause>lub<long pause>w dokładnych miejscach skryptu, w których mówca powinien zrobić przerwę:text Hold on, let me think... <short pause> Alright, I've got it. - Tempo na poziomie tury: ustaw
"style": "speaking rapidly"lub"style": "speaking slowly"wspeech_metadata, aby kontrolować szybkość mówienia w całej turze.
Prozodia i ton
Użyj speech_metadata.style, aby kontrolować prozodię, wysokość głosu i intonację w ramach wypowiedzi (np. "style": "high pitch, cheerful and excited inflection" lub "style": "monotone and flat"). Jeśli emocje lub prozodia zmieniają się w trakcie dialogu, podziel skrypt na osobne wypowiedzi z różnymi wartościami style dla każdej z nich.
Wyróżnienie
Używaj wielkich liter w przypadku konkretnych słów w transkrypcji w połączeniu ze znakami interpunkcyjnymi i tagami wokalnymi w tekście, aby naturalnie podkreślać kluczowe słowa:
This is a VERY important point!
It was a VERY long day <sigh> ... nobody listens anymore.
Wykrzyknienia i dźwięki inne niż mowa
Umieść wtrącenia w postaci dźwięków wydawanych przez człowieka, które nie są mową, w tekście, używając nawiasów ostrych (<...>) w dokładnym miejscu, w którym powinien pojawić się dźwięk. Zalecane tagi głosowe to:
<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> |
Kanały zwrotne i nakładające się wypowiedzi
W dialogach z wieloma mówcami reakcje słuchaczy umieszczaj w znakach potoku (|reaction|) w wypowiedzi mówcy, aby tworzyć naturalne kanały zwrotne lub nakładające się wypowiedzi bez dzielenia ich na osobne wypowiedzi dla każdej reakcji.
- Krótkie wymiany informacji w kanale zwrotnym: włącz krótkie reakcje słuchacza (
|oh hmm|,|oh really?|,|absolutely|) w wypowiedź aktywnego mówcy:- Tura 1 (osoba mówiąca A):
"So the launch is Thursday |oh hmm| Are we actually ready?" - Tura 2 (osoba B):
"Ready enough |oh really?| The last blocker cleared this morning." - Tura 3 (mówca A):
"Then let's ship it |absolutely| and watch the dashboards."
- Tura 1 (osoba mówiąca A):
- Nakładające się i przeplatające się wypowiedzi: użyj wielu segmentów z kreską pionową, aby symulować jednoczesne lub przeplatające się wypowiedzi 2 osób (najlepiej działa z
gemini-3.8-flash-tts):- Jednoczesne odliczanie i refren:
"Let's surprise him on three |ok| ready?", a następnie"one. two. three. |happy| happy |birthday| birthday!" - Pełne nakładanie się głośników:
"Hello |oh| there |my| it |goodness| must |gracious| be |would| almost |you| time |look| for |at that| dinner"
- Jednoczesne odliczanie i refren:
Spójność między generacjami i czego unikać
Aby zachować stabilność tożsamości głosowej w różnych turach, postępuj zgodnie z tymi wytycznymi:
- Zamiast długich bloków stylu projektuj persony z wyprzedzeniem w projektowaniu głosowym:
długie akapity
"Audio Profile"i wielopunktowe listy"Director's Notes"przeniesione z wcześniejszych modeli są najczęstszą przyczyną odchyleń w głosie. Wykorzystaj tę samą intuicję twórczą na początku projektowania głosu, aby wygenerować trwałą, niestandardowąvoice_...personę, a następnie używaj tego identyfikatora głosu w wywołaniach funkcji zamiany tekstu na mowę. - Polegaj na głosie referencyjnym, aby zapewnić stabilność (pomijaj meta-instrukcje): modele TTS Gemini 3.8 są trenowane tak, aby najpierw opierać się na dźwięku referencyjnym.
Nie umieszczaj instrukcji, które nakazują modelowi utrzymywanie stałego głosu (np.
"do not switch speaker identity"lub"maintain identical timbre") – dodatkowy tekst prompta zwiększa dryfowanie. Zrezygnuj z niepotrzebnych instrukcji dotyczących stylu i pozwól modelowi naturalnie zmieniać się w okolicach stabilnego punktu wyznaczonego przez referencyjny głos. - Nie próbuj zmieniać niezmiennych cech mówcy w
style: unikaj umieszczania wspeech_metadata.styleinformacji o wieku, płci, imionach i nazwiskach oraz trwałych zmianach akcentu. Zamiast tego wybierz głos regionalny z rozszerzonej biblioteki głosów lub utwórz własny za pomocą projektowania głosu.
Zalecany przepływ pracy
- Stwórz postać tylko raz: utwórz postać w projektowaniu głosu lub wybierz głos regionalny z rozszerzonej biblioteki głosów, który pasuje do języka docelowego i osobowości.
- Twórz naturalne transkrypcje mówione z niepłynnościami: aby uzyskać maksymalną naturalność, zapisz
textjako prawdziwą transkrypcję mówioną – z naturalnymi niepłynnościami i wahaniami w rozmowie (np."Oh uh yeah I think... hm, so that's interesting"). - Najpierw przetestuj zwykły TTS: najpierw zsyntetyzuj transkrypcję za pomocą pustego pola
style. Większość żądań nie wymaga żadnych instrukcjistyle. - Dodawaj krótkie prompty
styletylko w przypadku drobnych zmian: dodawaj zwięzły ciąg znakówstyle(np."casual, friendly"lub"muttering, then reassuring") tylko w przypadku tur, które wymagają konkretnej zmiany w dostarczaniu, i używaj tego samego krótkiego ciągu znaków w różnych turach, gdy chcesz uzyskać spójną wartość bazową.
Rozmowy wieloetapowe i agenty głosowe
Podczas tworzenia agentów głosowych działających w czasie rzeczywistym lub aplikacji wieloetapowych:
- Wykonuj jedno połączenie TTS na turę, gdy pojawiają się fragmenty tekstu LLM.
- Pozwól skonfigurowanemu
voice(gotowemu, zaprojektowanemuvoice_...lub sklonowanemuvoice_.../voicekey_...) przenosić tożsamość mówcy między turami – nigdy nie wysyłaj ponownie długiej persony postaci w każdej turze. - Pozostaw pole
stylepuste lub wyślij jeden krótki stały ciąg znaków (np."casual, friendly") dla całej rozmowy. - Dziel długie odpowiedzi agenta na krótsze, zamiast używać bardziej złożonych promptów dotyczących stylu.
Generowanie mowy strumieniowej
Możesz przesyłać strumieniowo wygenerowany dźwięk w trakcie jego syntezy przez model. W przeciwieństwie do żądań binarnych (które zwracają kompletny plik WAV z nagłówkiem RIFF) żądania przesyłania strumieniowego domyślnie zwracają fragmenty surowego 16-bitowego liniowego PCM ze znakiem w formacie little-endian bez nagłówka (AUDIO_L16 / audio/L16;codec=pcm;rate=24000, 24 kHz, mono), dzięki czemu fragmenty audio można odtwarzać lub łączyć w sposób ciągły bez nagłówków kontenera:
Python
from google import genai
client = genai.Client()
response_stream = client.models.generate_content_stream(
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"}
},
},
)
for chunk in response_stream:
try:
data = chunk.candidates[0].content.parts[0].inline_data.data
# data contains raw PCM bytes (24kHz, 1-channel, 16-bit)
except (IndexError, AttributeError):
pass
JavaScript
import {GoogleGenAI} from '@google/genai';
async function main() {
const ai = new GoogleGenAI({});
const responseStream = await ai.models.generateContentStream({
model: 'gemini-3.8-flash-tts',
contents: [{
role: 'user',
parts: [{
text: 'Have a wonderful day!',
speechMetadata: { style: 'cheerful and friendly' },
}],
}],
config: {
responseModalities: ['AUDIO'],
speechConfig: {
voiceConfig: { voice: 'Kore' },
},
},
});
for await (const chunk of responseStream) {
const data = chunk.candidates?.[0]?.content?.parts?.[0]?.inlineData?.data;
if (data) {
const audioBuffer = Buffer.from(data, 'base64');
// Process the audio buffer
}
}
}
await main();
REST
curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.8-flash-tts:streamGenerateContent" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-X POST \
-H "Content-Type: application/json" \
-d '{
"contents": [{
"role": "user",
"parts": [{
"text": "Have a wonderful day!",
"speech_metadata": {
"style": "cheerful and friendly"
}
}]
}],
"generationConfig": {
"responseModalities": ["AUDIO"],
"speechConfig": {
"voiceConfig": {
"voice": "Kore"
}
}
}
}'
Formaty wyjścia audio
Modele Gemini 3.8 TTS używają różnych domyślnych formatów audio w zależności od tego, czy żądanie jest jednorazowe czy strumieniowe:
- Żądania unarne (
models.generate_content): zwracają kompletny dźwięk WAV (AUDIO_WAV) z nagłówkiem RIFF (24 kHz, mono, 16-bitowy PCM ze znakiem w formacie little-endian). Możesz zapisać zdekodowane bajty audio bezpośrednio w pliku.wavbez ręcznego dodawania kontenera WAV. - Żądania przesyłania strumieniowego (
models.generate_content_stream/streamGenerateContent): domyślnie zwracaj niezawierające nagłówka surowe fragmenty Linear PCM (AUDIO_L16) (24 kHz, mono, 16-bitowy podpisany PCM w formacie little-endian), aby można było przesyłać strumieniowo lub łączyć fragmenty w sposób ciągły bez nagłówków kontenera w każdym fragmencie.
Możesz zastąpić kodowanie dźwięku wyjściowego i częstotliwość próbkowania za pomocą parametru generationConfig.responseFormat.audio:
Wartość mimeType |
Format | Opis |
|---|---|---|
"AUDIO_WAV" (domyślna wartość jednoargumentowa) |
WAV (audio/wav) |
Pełny plik WAV z nagłówkiem RIFF (24 kHz, mono, 16-bitowy PCM). |
"AUDIO_L16" (domyślne ustawienie strumieniowania) |
Linear PCM (audio/l16) |
Surowy 16-bitowy liniowy PCM bez nagłówka, ze znakiem, w formacie little-endian. Najlepsze do przesyłania strumieniowego, niestandardowych potoków audio lub łączenia klipów wieloetapowych. |
"AUDIO_MULAW" |
μ-law (audio/basic / audio/mulaw) |
Skompresowany dźwięk G.711 μ-law. Powszechnie używany w telefonii w Ameryce Północnej i Japonii (8 kHz). |
"AUDIO_ALAW" |
A-law (audio/alaw) |
Skonwertowany dźwięk G.711 A-law. Powszechnie używany w europejskiej i międzynarodowej telefonii (8 kHz). |
Opcjonalnie możesz też określić sampleRate (np. 24000, 16000 lub 8000 Hz; domyślnie 24000 Hz).
W tym przykładzie wysyłamy żądanie surowego 16-bitowego formatu PCM bez nagłówka (AUDIO_L16) przy częstotliwości 24 kHz:
Python
from google import genai
client = genai.Client()
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"],
"response_format": {
"audio": {
"mime_type": "AUDIO_L16",
"sample_rate": 24000,
}
},
"speech_config": {
"voice_config": {"voice": "Kore"}
},
},
)
data = response.candidates[0].content.parts[0].inline_data.data
with open("out.pcm", "wb") as f:
f.write(data)
JavaScript
import {GoogleGenAI} from '@google/genai';
import * as fs from 'node:fs';
async function main() {
const ai = new GoogleGenAI({});
const response = await ai.models.generateContent({
model: 'gemini-3.8-flash-tts',
contents: [{
role: 'user',
parts: [{
text: 'Have a wonderful day!',
speechMetadata: { style: 'cheerful and friendly' },
}],
}],
config: {
responseModalities: ['AUDIO'],
responseFormat: {
audio: {
mimeType: 'AUDIO_L16',
sampleRate: 24000,
},
},
speechConfig: {
voiceConfig: { voice: 'Kore' },
},
},
});
const data = response.candidates?.[0]?.content?.parts?.[0]?.inlineData?.data;
const audioBuffer = Buffer.from(data, 'base64');
fs.writeFileSync('out.pcm', audioBuffer);
}
await main();
REST
curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.8-flash-tts:generateContent" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-X POST \
-H "Content-Type: application/json" \
-d '{
"contents": [{
"role": "user",
"parts": [{
"text": "Have a wonderful day!",
"speech_metadata": {
"style": "cheerful and friendly"
}
}]
}],
"generationConfig": {
"responseModalities": ["AUDIO"],
"responseFormat": {
"audio": {
"mimeType": "AUDIO_L16",
"sampleRate": 24000
}
},
"speechConfig": {
"voiceConfig": {
"voice": "Kore"
}
}
}
}' | jq -r '.candidates[0].content.parts[0].inlineData.data' | \
base64 --decode > out.pcm
Ograniczenia
- Modele TTS akceptują dane wejściowe w postaci tekstu i generują dane wyjściowe w postaci dźwięku.
- Generowanie mowy dla wielu rozmówców w ramach jednego żądania (
multiSpeakerVoiceConfig) obsługuje maksymalnie 2 rozmówców, którzy używają gotowych głosów. Aby połączyć zaprojektowane (voice_...) lub sklonowane (voice_.../voicekey_...) głosy w dialogu z udziałem wielu postaci, zsyntetyzuj wypowiedź każdej z nich osobno. Ponieważ żądania unarne domyślnie zwracają wartośćaudio/wavz 44-bajtowym nagłówkiem RIFF, zażądaj surowego PCM (AUDIO_L16) lub usuń nagłówek WAV z każdej tury przed połączeniem klatek audio PCM o częstotliwości 24 kHz. - Limity miejsca na dane i wartości TTL w przypadku głosu niestandardowego:
- Głosy stanowe (
store=True, na podstawie prompta lub replikowane): maksymalnie 200 głosów na projekt z rocznym czasem życia danych. - Klucze głosowe bezstanowe (
store=False,voicekey_...): 7-dniowy czas życia danych (TTL).
- Głosy stanowe (
- Więcej informacji o obsługiwanych językach znajdziesz w sekcji Obsługiwane języki.
Co dalej?
- Twórz niestandardowe persony głosowe w języku naturalnym za pomocą projektowania głosu.
- Skopiuj głos istniejącego mówcy w replikacji głosu.
- Porównaj specyfikacje modeli na stronach Gemini 3.8 Flash TTS i Gemini 3.8 Flash-Lite TTS.
- Poznaj interaktywny dwukierunkowy dźwięk dzięki interfejsowi Live API.