Interfejs Gemini API może przekształcać tekst na mowę jednego lub wielu rozmówców, korzystając z funkcji zamiany tekstu na mowę (TTS) w Gemini.
Generowanie zamiany 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 jednym lub wieloma mówcami 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
Upewnij się, że używasz modelu Gemini TTS wymienionego w sekcji Obsługiwane modele, i przejdź na najnowszą wersję pakietu Google GenAI SDK (google-genai >= 2.25.0 w przypadku Pythona lub @google/genai >= 2.24.0 w przypadku JavaScriptu/TypeScriptu) lub użyj interfejsu REST API.
Aby uzyskać optymalne wyniki, zapoznaj się z artykułem Kiedy używać którego modelu, aby wybrać najlepszy model dla swojego zadania.
Zanim zaczniesz tworzyć, warto przetestować modele Gemini TTS w AI Studio.
TTS z jednym głosem
Aby przekonwertować tekst na dźwięk z jednym rozmówcą za pomocą modeli TTS Gemini 3.8, przekaż dosłowną transkrypcję w input, dołącz styl na poziomie tury za pomocą adnotacji speech_metadata i skonfiguruj głos w generation_config.speech_config. Możesz wybrać głos z gotowych opcji głosu, rozszerzonej biblioteki głosów (GET /v1beta/voices), niestandardowego identyfikatora projektu głosu (voice_...) lub identyfikatora replikacji głosu (voice_... lub opcjonalnie bezstanowego voicekey_...).
W tym przykładzie domyślny plik audio WAV (audio/wav) z modelu jest zapisywany bezpośrednio w pliku:
Python
import base64
from google import genai
client = genai.Client()
interaction = client.interactions.create(
model="gemini-3.8-flash-tts",
input=[{
"type": "user_input",
"content": [{
"type": "text",
"text": "Have a wonderful day!",
"annotations": [{
"type": "speech_metadata",
"style": "cheerful and friendly",
}],
}],
}],
response_format={"type": "audio"},
generation_config={
"speech_config": [
{"voice": "Kore"},
]
},
)
with open("out.wav", "wb") as f:
f.write(base64.b64decode(interaction.output_audio.data))
JavaScript
import * as fs from 'node:fs';
import {GoogleGenAI} from '@google/genai';
async function main() {
const client = new GoogleGenAI({});
const interaction = await client.interactions.create({
model: 'gemini-3.8-flash-tts',
input: [{
type: 'user_input',
content: [{
type: 'text',
text: 'Have a wonderful day!',
annotations: [{
type: 'speech_metadata',
style: 'cheerful and friendly',
}],
}],
}],
response_format: { type: 'audio' },
generation_config: {
speech_config: [
{ voice: 'Kore' },
],
},
});
const audioBuffer = Buffer.from(interaction.output_audio.data, 'base64');
fs.writeFileSync('out.wav', audioBuffer);
}
await main();
REST
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3.8-flash-tts",
"input": [{
"type": "user_input",
"content": [{
"type": "text",
"text": "Have a wonderful day!",
"annotations": [{
"type": "speech_metadata",
"style": "cheerful and friendly"
}]
}]
}],
"response_format": {
"type": "audio"
},
"generation_config": {
"speech_config": [
{ "voice": "Kore" }
]
}
}' | jq -r '[.steps[] | select(.type=="model_output") | .content[] | select(.type=="audio")] | last | .data' | base64 --decode > out.wav
W pakietach SDK dla Pythona i pakietach JavaScript SDK możesz pobrać wygenerowane dane audio, korzystając z właściwości interaction.output_audio, która zwraca ostatni wygenerowany blok audio (w nieprzetworzonych odpowiedziach REST JSON zakodowany w base64 dźwięk jest przechowywany w steps[].content[].data). Szczegółowe informacje o właściwościach znajdziesz w omówieniu interakcji.
Zamiana tekstu na mowę z wieloma rozmówcami
W przypadku dialogu z wieloma rozmówcami skonfiguruj 2 rozmówców w speech_config.speakers i przekaż każdą wypowiedź jako osobny element tekstowy z adnotacją speech_metadata określającą speaker i opcjonalną style na poziomie wypowiedzi. Zwróć uwagę, że speech_config akceptuje tablicę ([{"voice": "..."}]) w przypadku generowania głosu jednego rozmówcy i obiekt ({"speakers": [...]}) w przypadku generowania głosów wielu rozmówców:
Python
import base64
from google import genai
client = genai.Client()
interaction = client.interactions.create(
model="gemini-3.8-flash-tts",
input=[{
"type": "user_input",
"content": [
{
"type": "text",
"text": "How's it going today Jane?",
"annotations": [{
"type": "speech_metadata",
"speaker": "Joe",
"style": "cheerful and friendly",
}],
},
{
"type": "text",
"text": "Not too bad, how about you? Ready to test these new voices?",
"annotations": [{
"type": "speech_metadata",
"speaker": "Jane",
"style": "calm and relaxed",
}],
},
],
}],
response_format={"type": "audio"},
generation_config={
"speech_config": {
"speakers": [
{"speaker": "Joe", "voice": "Puck"},
{"speaker": "Jane", "voice": "Kore"},
],
}
},
)
with open("out.wav", "wb") as f:
f.write(base64.b64decode(interaction.output_audio.data))
JavaScript
import * as fs from 'node:fs';
import {GoogleGenAI} from '@google/genai';
async function main() {
const client = new GoogleGenAI({});
const interaction = await client.interactions.create({
model: 'gemini-3.8-flash-tts',
input: [{
type: 'user_input',
content: [
{
type: 'text',
text: "How's it going today Jane?",
annotations: [{
type: 'speech_metadata',
speaker: 'Joe',
style: 'cheerful and friendly',
}],
},
{
type: 'text',
text: 'Not too bad, how about you? Ready to test these new voices?',
annotations: [{
type: 'speech_metadata',
speaker: 'Jane',
style: 'calm and relaxed',
}],
},
],
}],
response_format: { type: 'audio' },
generation_config: {
speech_config: {
speakers: [
{ speaker: 'Joe', voice: 'Puck' },
{ speaker: 'Jane', voice: 'Kore' },
],
},
},
});
const audioBuffer = Buffer.from(interaction.output_audio.data, 'base64');
fs.writeFileSync('out.wav', audioBuffer);
}
await main();
REST
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3.8-flash-tts",
"input": [{
"type": "user_input",
"content": [
{
"type": "text",
"text": "How'\''s it going today Jane?",
"annotations": [{
"type": "speech_metadata",
"speaker": "Joe",
"style": "cheerful and friendly"
}]
},
{
"type": "text",
"text": "Not too bad, how about you? Ready to test these new voices?",
"annotations": [{
"type": "speech_metadata",
"speaker": "Jane",
"style": "calm and relaxed"
}]
}
]
}],
"response_format": {
"type": "audio"
},
"generation_config": {
"speech_config": {
"mode": "conversational",
"speakers": [
{ "speaker": "Joe", "voice": "Puck" },
{ "speaker": "Jane", "voice": "Kore" }
]
}
}
}'
Kontrolowanie stylu mowy za pomocą metadanych i tagów
Gemini 3.8 TTS traktuje pole text ściśle jako dosłowną transkrypcję. Aby kontrolować sposób odczytywania bez odczytywania na głos wskazówek scenicznych, podziel instrukcje według zakresu:
- Stałe dostarczanie na poziomie tury (
speech_metadata.style): umieść emocje, styl dostarczania, prozodię, tempo i głośność, które mają zastosowanie w całej turze, w polustyle(np."style": "whispered urgently","style": "out of breath"lub"style": "warm and enthusiastic"). - Zdarzenia w określonym momencie (tagi wbudowane): umieść krótkie dźwięki inne niż mowa lub pauzy 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 promptach.
Python
import base64
from google import genai
client = genai.Client()
interaction = client.interactions.create(
model="gemini-3.8-flash-tts",
input=[{
"type": "user_input",
"content": [
{
"type": "text",
"text": "Wait... <short pause> look under that fallen log! Is that a blue-spotted salamander?",
"annotations": [{
"type": "speech_metadata",
"speaker": "Dr. Anya",
"style": "whispered urgently",
}],
},
{
"type": "text",
"text": "<gasp> No way! <laugh> We've been searching for this species all season!",
"annotations": [{
"type": "speech_metadata",
"speaker": "Liam",
"style": "warm and enthusiastic",
}],
},
],
}],
response_format={"type": "audio"},
generation_config={
"speech_config": {
"speakers": [
{"speaker": "Dr. Anya", "voice": "Kore"},
{"speaker": "Liam", "voice": "Puck"},
],
}
},
)
with open("out.wav", "wb") as f:
f.write(base64.b64decode(interaction.output_audio.data))
JavaScript
import * as fs from 'node:fs';
import {GoogleGenAI} from '@google/genai';
async function main() {
const client = new GoogleGenAI({});
const interaction = await client.interactions.create({
model: 'gemini-3.8-flash-tts',
input: [{
type: 'user_input',
content: [
{
type: 'text',
text: 'Wait... <short pause> look under that fallen log! Is that a blue-spotted salamander?',
annotations: [{
type: 'speech_metadata',
speaker: 'Dr. Anya',
style: 'whispered urgently',
}],
},
{
type: 'text',
text: "<gasp> No way! <laugh> We've been searching for this species all season!",
annotations: [{
type: 'speech_metadata',
speaker: 'Liam',
style: 'warm and enthusiastic',
}],
},
],
}],
response_format: { type: 'audio' },
generation_config: {
speech_config: {
speakers: [
{ speaker: 'Dr. Anya', voice: 'Kore' },
{ speaker: 'Liam', voice: 'Puck' },
],
},
},
});
if (interaction.output_audio?.data) {
const audioBuffer = Buffer.from(interaction.output_audio.data, 'base64');
fs.writeFileSync('out.wav', audioBuffer);
}
}
await main();
REST
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3.8-flash-tts",
"input": [{
"type": "user_input",
"content": [
{
"type": "text",
"text": "Wait... <short pause> look under that fallen log! Is that a blue-spotted salamander?",
"annotations": [{
"type": "speech_metadata",
"speaker": "Dr. Anya",
"style": "whispered urgently"
}]
},
{
"type": "text",
"text": "<gasp> No way! <laugh> We'\''ve been searching for this species all season!",
"annotations": [{
"type": "speech_metadata",
"speaker": "Liam",
"style": "warm and enthusiastic"
}]
}
]
}],
"response_format": {
"type": "audio"
},
"generation_config": {
"speech_config": {
"speakers": [
{ "speaker": "Dr. Anya", "voice": "Kore" },
{ "speaker": "Liam", "voice": "Puck" }
]
}
}
}'
Generowanie mowy strumieniowej
Możesz przesyłać strumieniowo wygenerowany dźwięk podczas jego syntezy, ustawiając stream: true. W przeciwieństwie do żądań jednoargumentowych (które zwracają kompletny plik WAV z nagłówkiem RIFF) żądania strumieniowe domyślnie zwracają fragmenty nieprzetworzonego 16-bitowego liniowego PCM ze znakiem w formacie little-endian (audio/l16, 24 kHz, mono) bez nagłówka, dzięki czemu fragmenty audio można odtwarzać lub łączyć w sposób ciągły bez nagłówków kontenera.
Python
import base64
from google import genai
client = genai.Client()
stream = client.interactions.create(
model="gemini-3.8-flash-tts",
input=[{
"type": "user_input",
"content": [{
"type": "text",
"text": "Have a wonderful day!",
"annotations": [{
"type": "speech_metadata",
"style": "cheerful and friendly",
}],
}],
}],
response_format={"type": "audio"},
generation_config={
"speech_config": [
{"voice": "Kore"},
]
},
stream=True,
)
for event in stream:
if event.event_type == "step.delta":
if event.delta.type == "audio":
audio_data = base64.b64decode(event.delta.data)
# Process the audio chunk (e.g. play it or write to a file)
JavaScript
import {GoogleGenAI} from '@google/genai';
async function main() {
const client = new GoogleGenAI({});
const stream = await client.interactions.create({
model: 'gemini-3.8-flash-tts',
input: [{
type: 'user_input',
content: [{
type: 'text',
text: 'Have a wonderful day!',
annotations: [{
type: 'speech_metadata',
style: 'cheerful and friendly',
}],
}],
}],
response_format: { type: 'audio' },
generation_config: {
speech_config: [
{ voice: 'Kore' },
],
},
stream: true,
});
for await (const event of stream) {
if (event.event_type === 'step.delta') {
if (event.delta.type === 'audio') {
const audioBuffer = Buffer.from(event.delta.data, 'base64');
// Process the audio buffer
}
}
}
}
await main();
REST
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
--no-buffer \
-d '{
"model": "gemini-3.8-flash-tts",
"input": [{
"type": "user_input",
"content": [{
"type": "text",
"text": "Have a wonderful day!",
"annotations": [{
"type": "speech_metadata",
"style": "cheerful and friendly"
}]
}]
}],
"response_format": {
"type": "audio"
},
"generation_config": {
"speech_config": [
{ "voice": "Kore" }
]
},
"stream": true
}'
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 jednoargumentowe (
stream=False): zwracają pełny dźwięk WAV (audio/wav) ze standardowym nagłówkiem RIFF (24 kHz, mono, 16-bitowy, ze znakiem, little-endian PCM). Możesz zapisać zdekodowane bajty audio bezpośrednio w pliku.wavbez ręcznego dodawania nagłówka WAV. - Żądania strumieniowe (
stream=True): domyślnie zwracają nieprzetworzone fragmenty Linear PCM bez nagłówka (audio/l16) (24 kHz, mono, 16-bitowy PCM ze znakiem, little-endian), dzięki czemu fragmenty mogą być przesyłane strumieniowo lub łączone w sposób ciągły bez nagłówków kontenera w każdym fragmencie.
Aby poprosić o inne kodowanie dźwięku lub inną częstotliwość próbkowania, skonfiguruj mime_type i opcjonalnie sample_rate w response_format:
| Format | Wartość mime_type |
Opis |
|---|---|---|
| WAV (domyślny format jednoargumentowy) | "audio/wav" |
Nieskompresowany plik WAV z nagłówkiem RIFF (16-bitowy, podpisany, PCM w formacie little-endian, mono, domyślnie 24 kHz). Domyślna wartość dla żądań jednoargumentowych. |
| Raw PCM (L16) (domyślny format strumieniowania) | "audio/l16" |
Nieskompresowany, bez nagłówka, 16-bitowy, ze znakiem, little-endian, liniowy dźwięk PCM (24 kHz, mono). Domyślna wartość dla żądań strumieniowania. |
| Mu-law | "audio/mulaw" |
8-bitowy dźwięk zakodowany w standardzie G.711 mu-law (powszechnie używany w systemach telefonicznych/IVR w Ameryce Północnej i Japonii). |
| A-law | "audio/alaw" |
8-bitowy dźwięk zakodowany za pomocą kodeka G.711 A-law (powszechnie używany w europejskich i międzynarodowych systemach telefonicznych). |
Możesz też podać wartość sample_rate w hercach (np. 24000, 16000 lub 8000).
Python
import base64
from google import genai
client = genai.Client()
interaction = client.interactions.create(
model="gemini-3.8-flash-tts",
input=[{
"type": "user_input",
"content": [{
"type": "text",
"text": "Have a wonderful day!",
"annotations": [{
"type": "speech_metadata",
"style": "cheerful and friendly",
}],
}],
}],
response_format={
"type": "audio",
"mime_type": "audio/l16", # "audio/wav" (default), "audio/l16", "audio/mulaw", or "audio/alaw"
"sample_rate": 24000,
},
generation_config={
"speech_config": [
{"voice": "Kore"},
]
},
)
with open("out.pcm", "wb") as f:
f.write(base64.b64decode(interaction.output_audio.data))
JavaScript
import * as fs from 'node:fs';
import {GoogleGenAI} from '@google/genai';
async function main() {
const client = new GoogleGenAI({});
const interaction = await client.interactions.create({
model: 'gemini-3.8-flash-tts',
input: [{
type: 'user_input',
content: [{
type: 'text',
text: 'Have a wonderful day!',
annotations: [{
type: 'speech_metadata',
style: 'cheerful and friendly',
}],
}],
}],
response_format: {
type: 'audio',
mime_type: 'audio/l16', // 'audio/wav' (default), 'audio/l16', 'audio/mulaw', or 'audio/alaw'
sample_rate: 24000,
},
generation_config: {
speech_config: [
{ voice: 'Kore' },
],
},
});
const audioBuffer = Buffer.from(interaction.output_audio.data, 'base64');
fs.writeFileSync('out.pcm', audioBuffer);
}
await main();
REST
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3.8-flash-tts",
"input": [{
"type": "user_input",
"content": [{
"type": "text",
"text": "Have a wonderful day!",
"annotations": [{
"type": "speech_metadata",
"style": "cheerful and friendly"
}]
}]
}],
"response_format": {
"type": "audio",
"mime_type": "audio/l16",
"sample_rate": 24000
},
"generation_config": {
"speech_config": [
{ "voice": "Kore" }
]
}
}'
Opcje głosowe
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, z różnymi akcentami i archetypami postaci, które są dostępne za pomocą
client.voices.list()(GET /v1beta/voices). - Projektowanie głosu: wygeneruj niestandardową osobowość głosową na podstawie opisu w języku naturalnym w Google AI Studio lub za pomocą
POST /v1beta/voices(type="prompted", która zwraca trwały identyfikatorvoice_...i podgląd WAVsample_audiowCreateVoiceiGetVoice). - Replikacja głosu: Replikacja głosu mówcy na podstawie dźwięku referencyjnego i dźwięku, na którego wykorzystanie uzyskano zgodę, w Google AI Studio lub za pomocą
POST /v1beta/voices(type="replicated", domyślnie trwałestore=Truelub opcjonalne bezstanowestore=False).
Limity i TTL głosów niestandardowych
| Rodzaj głosu | Tryb przechowywania | Limit | Przechowywanie (TTL) |
|---|---|---|---|
Głosy stanowe (voice_..., wygenerowane na podstawie promptu lub replikowane) |
store=True |
200 głosów na projekt (współdzielonych między głosami wygenerowanymi na podstawie promptów i głosami replikowanymi). | 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 TTL: 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 – młodzieńczy |
| Orus – Firm | Aoede – Breezy | Callirrhoe – Easy-going |
| Autonoe – jasny | Enceladus -- Breathy | Iapetus – Clear |
| Umbriel – spokojny | Algieba – gładki | Despina – gładki |
| Erinome – Clear | Algenib – żwirowy | Rasalgethi – Zawiera przydatne informacje |
| Laomedeia – optymistyczny | Achernar – Soft | Alnilam – Firm |
| Schedar – Even | Gacrux – Mature | Pulcherrima – Przekaż dalej |
| Achird – przyjazny | Zubenelgenubi – zwykły | Vindemiatrix – delikatny |
| Sadachbia – Lively | Sadaltager – kompetentny | Sulafat – ciepły |
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, postaciami i domenami. Możesz przeglądać, filtrować i odsłuchiwać całą bibliotekę głosów interaktywnie 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 niestandardowe zapisane głosy (uporządkowane od najnowszych), a następnie głosy z gotowego katalogu, które pasują 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, wielkość liter nie jest rozróżniana. |
region_code |
list[str] |
Kod regionu w formacie ISO 3166-1 alfa-2 lub UN M.49 (np. ["US", "GB"]). |
accent |
list[str] |
Deskryptory akcentu regionalnego (np. ["American", "British"]). |
gender |
list[str] |
Postrzegana płeć ("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] |
Optymalna domena 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 podłańcucha w dowolnym tekście bez rozróżniania wielkości liter w polach 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, aby pobrać następną stronę 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 tradycyjne) | ✔️ | ✔️ |
| 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 | ✔️ | ✔️ |
| chałcha-mongolski | ✔️ | ✔️ |
| hausa | ✔️ | ✔️ |
| hebrajski | ✔️ | ✔️ |
| hindi | ✔️ | ✔️ |
| węgierski | ✔️ | ✔️ |
| islandzki | ✔️ | ✔️ |
| igbo | ✔️ | – |
| iloko | ✔️ | ✔️ |
| indonezyjski | ✔️ | ✔️ |
| perski (Iran) | ✔️ | ✔️ |
| włoski | ✔️ | ✔️ |
| japoński | ✔️ | ✔️ |
| jawajski | ✔️ | ✔️ |
| Kabyle | ✔️ | – |
| kamba | ✔️ | ✔️ |
| kannada | ✔️ | ✔️ |
| kaszmirski (alfabet arabski), | ✔️ | ✔️ |
| kaszmirski (pismo 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 (język) | ✔️ | ✔️ |
| fulfulde (Nigeria) | ✔️ | ✔️ |
| północnoazerbejdżański | ✔️ | ✔️ |
| sotho północny | ✔️ | ✔️ |
| uzbecki (północny) | ✔️ | ✔️ |
| norweski bokmål | ✔️ | ✔️ |
| norweski (Nynorsk) | ✔️ | ✔️ |
| njandża | ✔️ | ✔️ |
| oksytański | ✔️ | – |
| orija (język indywidualny) | ✔️ | ✔️ |
| 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 | ✔️ | ✔️ |
| standardowy arabski (pismo arabskie) | ✔️ | ✔️ |
| standardowy arabski (alfabet łaciński) | ✔️ | ✔️ |
| standardowy łotewski, | ✔️ | ✔️ |
| standardowy malajski | ✔️ | ✔️ |
| suahili (język) | ✔️ | – |
| suazi | ✔️ | – |
| szwedzki | ✔️ | – |
| tadżycki | ✔️ | – |
| tamilski | ✔️ | ✔️ |
| telugu | ✔️ | ✔️ |
| tajski | ✔️ | – |
| tigrinia | ✔️ | – |
| albański (toskijski) | ✔️ | – |
| turecki | ✔️ | ✔️ |
| ujgurski | ✔️ | – |
| wietnamski | ✔️ | ✔️ |
Obsługiwane modele
| Model | Pojedynczy rozmówca | Wielu rozmówców | 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ą ten sam schemat interfejsu API i format promptów, co pozwala na przełączanie się między nimi przez zmianę jednego parametru:
- Używaj Gemini 3.8 Flash TTS (
gemini-3.8-flash-tts), gdy najważniejsza jest maksymalna wierność akustyczna, niuansowana gra i ekspresyjna kontrola. Idealnie nadaje się do pracy kreatywnej na poziomie studyjnym, złożonych dialogów z wieloma rozmówcami, trudnych tagów wokalnych, trudnej wymowy, dialektów regionalnych lub mniejszościowych oraz długich narracji wymagających stabilnego głosu i tonu pomieszczenia. - 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 masowej produkcji, kaskad agentów głosowych, funkcji czytania na głos, niezawodnej replikacji głosu i codziennej mowy jednego rozmówcy w głównych językach.
Przewodnik po migracji
Jeśli przechodzisz z modelu gemini-3.1-flash-tts-preview lub wcześniejszych modeli Gemini TTS na Gemini 3.8 TTS:
- Przenieś wskazówki dojazdu do
speech_metadata: Gemini 3.8 TTS traktuje tekst wejściowy ściśle jako transkrypcję dosłowną. Przenieś instrukcje dotyczące sposobu wypowiedzi (style– np."whispering","out of breath"lub"speaking slowly") i etykiety rozmówców (speaker) do uporządkowanych adnotacjispeech_metadata, zamiast umieszczać didaskalia w tekście transkrypcji. - Używaj tagów w nawiasach ostrokątnych tylko w przypadku zdarzeń głosowych w danym momencie: zachowaj chwilowe wokalizacje i pauzy w transkrypcji, używając nawiasów ostrokątnych (np.
<laugh>,<sigh>,<cough>,<breath>lub<short pause>). Unikaj tagów efektów dźwiękowych (takich jak oklaski lub uderzenia) i umieszczaj style dostawy wspeech_metadata.style. - Określ
speakerw każdej turze w żądaniach z wieloma rozmówcami: każda tura w żądaniu z wieloma rozmówcami musi wyraźnie zawieraćspeakerwewnątrzspeech_metadata, pasujący do jednego ze skonfigurowanych rozmówców. - Zaprojektuj persony z wyprzedzeniem za pomocą funkcji Voice design: zastąp wieloakapitowe bloki
"Audio Profile"lub"Director's Notes"niestandardowym głosem utworzonym w Voice design, a następnie przekaż ten identyfikatorvoice_...w żądaniach TTS z minimalnymi lub pustymi ciągami znakówstyle. - Uwzględnij domyślne dane wyjściowe WAV (
audio/wav) w przypadku żądań jednoargumentowych: w przeciwieństwie do modeli TTSgemini-3.1-flash-tts-previewi wcześniejszych (które domyślnie zwracały nieprzetworzone dane PCMaudio/l16bez nagłówka) Gemini 3.8 TTS domyślnie zwraca dźwięk WAV (audio/wav) ze standardowym nagłówkiem RIFF w przypadku żądań jednoargumentowych.- Jeśli Twój kod wcześniej opakowywał surowe bajty PCM w nagłówek WAV (np. za pomocą modułu
wavew Pythonie lubffmpeg), usuń ręczny wrapper nagłówka i zapisz zwrócone bajty bezpośrednio w pliku.wav. - Jeśli Twój potok wymaga dźwięku PCM bez nagłówka, mu-law lub A-law, ustaw parametr
response_format.mime_typena"audio/l16","audio/mulaw"lub"audio/alaw"(np.{"response_format": {"type": "audio", "mime_type": "audio/l16"}}w interfejsie Interactions API lubAUDIO_L16wgenerateContent). Więcej informacji znajdziesz w sekcji 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 TTS Gemini 3.8 traktują tekst wejściowy ściśle jako dosłowną transkrypcję.
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 ciągłe wskazówki na poziomie tury (speech_metadata) od wbudowanych tagów głosowych.
Pole stylu a tagi wbudowane
Podziel instrukcje dotyczące wydajności według zakresu:
- Sposób wypowiedzi na poziomie tury (
speech_metadata.style): umieść atrybuty sposobu wypowiedzi, takie jak emocje, prozodia, ogólne tempo lub styl wypowiedzi (np."whispering","out of breath","muttering"lub"sarcastic"), w polustyleobiektuspeech_metadata. Aby stworzyć stabilną postać i zachować spójność między turami, zaprojektuj ją z wyprzedzeniem w sekcji Projekt głosu, a parametrstylewykorzystuj tylko do opcjonalnych poprawek 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 niewokalnych 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 przy konkretnym słowie). | Wbudowane w text (<...>) |
"<cough> Thank you all for coming tonight! <throat-clearing> As I was saying..." |
Tempo i przerwy
Rytm i ciszę możesz kontrolować na 3 poziomach szczegółowości:
- Interpunkcja i wielokropki: używaj przecinków, myślników (
--) i wielokropków (...), aby uzyskać naturalne wahanie w rozmowie. - Wbudowane tagi pauzy: wstaw
<short pause>lub<long pause>w dokładnych miejscach w skrypcie, w których lektor 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ć tempo mowy w całej turze.
Prozodia i ton
Używaj parametru speech_metadata.style, aby kontrolować prozodię, wysokość głosu i fleksję w trakcie 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 w naturalny sposób 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
Wstawiaj w tekście niewerbalne dźwięki wydawane przez ludzi, używając nawiasów ostrych (<...>) w dokładnym miejscu, w którym powinien pojawić się dźwięk. Zalecane tagi wokalne:
<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> |
Potwierdzenia i nakładające się wypowiedzi
W dialogach z wieloma mówcami umieść reakcje słuchaczy w znakach potoku (|reaction|) w wypowiedzi mówcy, aby utworzyć naturalne kanały zwrotne lub nakładające się wypowiedzi bez dzielenia ich na osobne wypowiedzi dla każdej reakcji.
- Krótkie reakcje: dodaj krótkie reakcje słuchacza (
|oh hmm|,|oh really?|,|absolutely|) w trakcie wypowiedzi aktywnego rozmówcy:- Turn 1 (Speaker A):
"So the launch is Thursday |oh hmm| Are we actually ready?" - Turn 2 (Speaker B):
"Ready enough |oh really?| The last blocker cleared this morning." - Turn 3 (Speaker A):
"Then let's ship it |absolutely| and watch the dashboards."
- Turn 1 (Speaker 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 potem"one. two. three. |happy| happy |birthday| birthday!" - Pełne nakładanie się wypowiedzi:
"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 generowanymi treściami i czego unikać
Aby zachować stabilność tożsamości głosowej w różnych turach, postępuj zgodnie z tymi wytycznymi:
- Zaprojektuj persony z wyprzedzeniem w ramach projektowania głosu, zamiast używać długich bloków stylu:
długie akapity
"Audio Profile"i wypunktowania"Director's Notes"przeniesione z wcześniejszych modeli są najczęstszą przyczyną dryfu głosu. Wykorzystaj tę samą intuicję twórczą w projektowaniu głosu, aby wygenerować trwałą niestandardową postaćvoice_..., a następnie używaj tego identyfikatora głosu w wywołaniach TTS. - Polegaj na stabilności głosu referencyjnego (pomiń metainstrukcje): modele Gemini 3.8 TTS są trenowane tak, aby najpierw zakotwiczyć się na nagraniu referencyjnym.
Nie dołączaj 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 dryf. Usuń niepotrzebne instrukcje dotyczące stylu i pozwól modelowi na naturalne zmiany wokół stabilnego punktu zapewnianego przez odniesienie głosowe. - Nie próbuj zmieniać niezmiennych cech rozmówcy w tagu
style: unikaj umieszczania w taguspeech_metadata.stylewieku, płci, imion i nazwisk ani trwałych zmian akcentu. Zamiast tego wybierz głos regionalny z rozszerzonej biblioteki głosów lub utwórz go za pomocą funkcji Projektowanie głosu.
Zalecany przepływ pracy
- Utwórz postać raz: utwórz postać w Voice design lub wybierz głos regionalny z rozszerzonej biblioteki głosów, który pasuje do wybranego języka i osobowości.
- Twórz naturalne transkrypcje mówione z elementami niepłynności: aby uzyskać maksymalną naturalność, zapisuj
textjako prawdziwą transkrypcję mówioną, w tym naturalne elementy niepłynności i wahania (np."Oh uh yeah I think... hm, so that's interesting"). - Najpierw przetestuj zwykły TTS: najpierw dokonaj syntezy transkrypcji 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 1 wywołanie TTS na turę, gdy docierają fragmenty tekstu z LLM.
- Niech skonfigurowany
voice(gotowy, zaprojektowanyvoice_...lub zreplikowanyvoice_.../voicekey_...) przenosi tożsamość rozmówcy między turami – nigdy nie wysyłaj ponownie długiej persony w każdej turze. - Pozostaw pole
stylepuste lub wyślij jeden krótki ciąg stały (np."casual, friendly") dla całej rozmowy. - Podziel długie odpowiedzi agenta na krótsze tury, zamiast używać bardziej rygorystycznych promptów dotyczących stylu.
Ograniczenia
- Modele TTS akceptują tylko tekstowe dane wejściowe i generują tylko dźwiękowe dane wyjściowe.
- Generowanie wielu rozmówców w ramach jednego żądania (
speech_config.speakers) obsługuje maksymalnie 2 rozmówców korzystających z gotowych głosów. Aby połączyć niestandardowe (voice_...) lub replikowane (voice_.../voicekey_...) głosy w dialogu z wieloma postaciami, zsyntetyzuj wypowiedź każdego rozmówcy osobno. Żądania jednoargumentowe domyślnie zwracająaudio/wavz 44-bajtowym nagłówkiem RIFF, dlatego przed połączeniem ramek audio PCM 24 kHz poproś o nieprzetworzony format PCM ({"type": "audio", "mime_type": "audio/l16"}) lub usuń nagłówek WAV z każdej tury. - Limity miejsca na dane i TTL w przypadku głosu niestandardowego:
- Głosy z zachowaniem stanu (
store=True, na podstawie promptu lub replikowane): maksymalnie 200 głosów na projekt z rocznym czasem życia danych (TTL). - Bezstanowe klucze głosowe (
store=False,voicekey_...): 7-dniowy TTL (czas życia danych).
- Głosy z zachowaniem stanu (
- W sekcji Obsługiwane języki znajdziesz informacje o zakresie językowym.
Co dalej?
- Twórz niestandardowe postacie głosowe na podstawie języka naturalnego za pomocą projektowania głosu.
- Odtwórz głos istniejącego rozmó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.