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) w 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 zamiany tekstu na mowę Gemini 3.8, przekaż dosłowną transkrypcję w input, dołącz stylizację na poziomie wypowiedzi za pomocą adnotacji speech_metadata i skonfiguruj głos w generation_config.speech_config. Możesz wybrać głos z wbudowanych 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ślne dane wyjściowe audio w formacie WAV (audio/wav) z modelu są zapisywane 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();
Go
package main
import (
"context"
"encoding/base64"
"encoding/binary"
"log"
"os"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/interactions"
"google.golang.org/genai/interactions/models/operations"
)
func saveWaveFile(filename string, pcmData []byte) error {
f, err := os.Create(filename)
if err != nil {
return err
}
defer f.Close()
sampleRate := uint32(24000)
numChannels := uint16(1)
bitsPerSample := uint16(16)
byteRate := sampleRate * uint32(numChannels) * uint32(bitsPerSample/8)
blockAlign := numChannels * (bitsPerSample / 8)
dataSize := uint32(len(pcmData))
f.WriteString("RIFF")
binary.Write(f, binary.LittleEndian, uint32(36+dataSize))
f.WriteString("WAVEfmt ")
binary.Write(f, binary.LittleEndian, uint32(16))
binary.Write(f, binary.LittleEndian, uint16(1))
binary.Write(f, binary.LittleEndian, numChannels)
binary.Write(f, binary.LittleEndian, sampleRate)
binary.Write(f, binary.LittleEndian, byteRate)
binary.Write(f, binary.LittleEndian, blockAlign)
binary.Write(f, binary.LittleEndian, bitsPerSample)
f.WriteString("data")
binary.Write(f, binary.LittleEndian, dataSize)
_, err = f.Write(pcmData)
return err
}
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
generationConfig := &interactions.GenerationConfig{
SpeechConfig: genai.Ptr(interactions.NewSpeechConfigUnion([]interactions.SpeechConfig{
{Voice: genai.Ptr("Kore")},
})),
}
res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
Model: interactions.Model("gemini-3.1-flash-tts-preview"),
Input: interactions.NewInteractionsInput("Say cheerfully: Have a wonderful day!"),
ResponseFormat: genai.Ptr(interactions.NewCreateModelInteractionResponseFormat(
interactions.NewResponseFormat(interactions.AudioResponseFormat{}),
)),
GenerationConfig: generationConfig,
}),
})
if err != nil {
log.Fatal(err)
}
if res.Interaction.OutputAudio != nil && res.Interaction.OutputAudio.Data != nil {
pcmBytes, err := base64.StdEncoding.DecodeString(*res.Interaction.OutputAudio.Data)
if err != nil {
log.Fatal(err)
}
if err := saveWaveFile("out.wav", pcmBytes); err != nil {
log.Fatal(err)
}
}
}
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 w Pythonie i JavaScript możesz pobrać wygenerowane dane audio, korzystając z wygodnej właściwości interaction.output_audio, która zwraca ostatni wygenerowany blok audio (w surowych odpowiedziach REST JSON zakodowany w Base64 dźwięk jest przechowywany w steps[].content[].data). Więcej informacji o wygodnych właściwościach znajdziesz w omówieniu interakcji.
TTS z wieloma rozmówcami
W przypadku dialogu z udziałem wielu osób skonfiguruj 2 osoby w speech_config.speakers i przekaż każdą wypowiedź jako osobny element tekstowy z adnotacją speech_metadata określającą speaker i opcjonalny style na poziomie wypowiedzi. Używaj znaku
"mode": "conversational", aby zachować naturalny rytm rozmowy:
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": {
"mode": "conversational",
"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: {
mode: 'conversational',
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();
Go
package main
import (
"context"
"encoding/base64"
"encoding/binary"
"log"
"os"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/interactions"
"google.golang.org/genai/interactions/models/operations"
)
func saveWaveFile(filename string, pcmData []byte) error {
f, err := os.Create(filename)
if err != nil {
return err
}
defer f.Close()
sampleRate := uint32(24000)
numChannels := uint16(1)
bitsPerSample := uint16(16)
byteRate := sampleRate * uint32(numChannels) * uint32(bitsPerSample/8)
blockAlign := numChannels * (bitsPerSample / 8)
dataSize := uint32(len(pcmData))
f.WriteString("RIFF")
binary.Write(f, binary.LittleEndian, uint32(36+dataSize))
f.WriteString("WAVEfmt ")
binary.Write(f, binary.LittleEndian, uint32(16))
binary.Write(f, binary.LittleEndian, uint16(1))
binary.Write(f, binary.LittleEndian, numChannels)
binary.Write(f, binary.LittleEndian, sampleRate)
binary.Write(f, binary.LittleEndian, byteRate)
binary.Write(f, binary.LittleEndian, blockAlign)
binary.Write(f, binary.LittleEndian, bitsPerSample)
f.WriteString("data")
binary.Write(f, binary.LittleEndian, dataSize)
_, err = f.Write(pcmData)
return err
}
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
prompt := "TTS the following conversation between Joe and Jane:\n" +
"Joe: How's it going today Jane?\n" +
"Jane: Not too bad, how about you?"
generationConfig := &interactions.GenerationConfig{
SpeechConfig: genai.Ptr(interactions.NewSpeechConfigUnion([]interactions.SpeechConfig{
{Speaker: genai.Ptr("Joe"), Voice: genai.Ptr("Kore")},
{Speaker: genai.Ptr("Jane"), Voice: genai.Ptr("Puck")},
})),
}
res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
Model: interactions.Model("gemini-3.1-flash-tts-preview"),
Input: interactions.NewInteractionsInput(prompt),
ResponseFormat: genai.Ptr(interactions.NewCreateModelInteractionResponseFormat(
interactions.NewResponseFormat(interactions.AudioResponseFormat{}),
)),
GenerationConfig: generationConfig,
}),
})
if err != nil {
log.Fatal(err)
}
if res.Interaction.OutputAudio != nil && res.Interaction.OutputAudio.Data != nil {
pcmBytes, err := base64.StdEncoding.DecodeString(*res.Interaction.OutputAudio.Data)
if err != nil {
log.Fatal(err)
}
if err := saveWaveFile("out.wav", pcmBytes); err != nil {
log.Fatal(err)
}
}
}
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" }
]
}
}
}'
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, 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, 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 promptach.
Go
package main
import (
"context"
"log"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/interactions"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
transcriptRes, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
Model: interactions.Model("gemini-3.8-flash"),
Input: interactions.NewInteractionsInput(
"Generate a short transcript around 100 words that reads " +
"like it was clipped from a podcast by excited herpetologists. " +
"The hosts names are Dr. Anya and Liam.",
),
}),
})
if err != nil {
log.Fatal(err)
}
var transcript string
if transcriptRes.Interaction.OutputText != nil {
transcript = *transcriptRes.Interaction.OutputText
}
generationConfig := &interactions.GenerationConfig{
SpeechConfig: genai.Ptr(interactions.NewSpeechConfigUnion([]interactions.SpeechConfig{
{Speaker: genai.Ptr("Dr. Anya"), Voice: genai.Ptr("Kore")},
{Speaker: genai.Ptr("Liam"), Voice: genai.Ptr("Puck")},
})),
}
ttsRes, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
Model: interactions.Model("gemini-3.1-flash-tts-preview"),
Input: interactions.NewInteractionsInput(transcript),
ResponseFormat: genai.Ptr(interactions.NewCreateModelInteractionResponseFormat(
interactions.NewResponseFormat(interactions.AudioResponseFormat{}),
)),
GenerationConfig: generationConfig,
}),
})
if err != nil {
log.Fatal(err)
}
_ = ttsRes
}
Generowanie mowy strumieniowej
Możesz przesyłać strumieniowo wygenerowany dźwięk w trakcie jego syntezy, ustawiając parametr
stream: true. W przeciwieństwie do żądań binarnych (które zwracają kompletny plik WAV z nagłówkiem RIFF) żądania strumieniowe domyślnie zwracają fragmenty nieprzetworzonego 16-bitowego dźwięku PCM z podpisem w formacie little-endian bez nagłówka (audio/l16, 24 kHz, mono), dzięki czemu fragmenty dźwięku 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 unarne (
stream=False): zwracają kompletne dane audio w formacie WAV (audio/wav) z standardowym nagłówkiem RIFF (24 kHz, mono, 16-bitowy podpisany PCM w formacie little-endian). Zdekodowane bajty audio możesz zapisać bezpośrednio w pliku.wavbez ręcznego dodawania nagłówka WAV. - Żądania przesyłania strumieniowego (
stream=True): zwracaj domyślnie fragmenty surowego liniowego PCM bez nagłówka (audio/l16) (24 kHz, mono, 16-bitowy PCM ze znakiem 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 kontenerów w każdym fragmencie.
Aby poprosić o inne kodowanie audio lub częstotliwość próbkowania, skonfiguruj mime_type i opcjonalnie sample_rate wewnątrz response_format:
| Format | Wartość mime_type |
Opis |
|---|---|---|
| WAV (wartość domyślna) | "audio/wav" |
Nieskompresowany plik WAV z nagłówkiem RIFF (16-bitowy, podpisany, little-endian PCM, mono, domyślnie 24 kHz). Domyślne ustawienie w przypadku żądań binarnych. |
| Raw PCM (L16) (domyślny format transmisji strumieniowej) | "audio/l16" |
Nieskompresowany, bez nagłówka, 16-bitowy, podpisany, little-endian, liniowy dźwięk PCM (24 kHz, mono). Domyślna dla żądań strumieniowania. |
| Mu-law | "audio/mulaw" |
8-bitowy dźwięk zakodowany w formacie G.711 mu-law (powszechnie używany w systemach telefonicznych i 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();
Go
package main
import (
"context"
"encoding/base64"
"log"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/interactions"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
generationConfig := &interactions.GenerationConfig{
SpeechConfig: genai.Ptr(interactions.NewSpeechConfigUnion([]interactions.SpeechConfig{
{Voice: genai.Ptr("Kore")},
})),
}
res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
Model: interactions.Model("gemini-3.1-flash-tts-preview"),
Input: interactions.NewInteractionsInput("Say cheerfully: Have a wonderful day!"),
ResponseFormat: genai.Ptr(interactions.NewCreateModelInteractionResponseFormat(
interactions.NewResponseFormat(interactions.AudioResponseFormat{}),
)),
GenerationConfig: generationConfig,
Stream: genai.Ptr(true),
}),
})
if err != nil {
log.Fatal(err)
}
stream := res.InteractionSSEStreamEvent
defer stream.Close()
for stream.Next() {
event := stream.Value()
if stepDelta := event.GetDataStepDelta(); stepDelta != nil {
if audioDelta := stepDelta.GetDeltaAudio(); audioDelta != nil && audioDelta.Data != nil {
audioData, err := base64.StdEncoding.DecodeString(*audioDelta.Data)
if err != nil {
log.Fatal(err)
}
// Process the audio chunk (e.g. play it or write to a file)
_ = audioData
}
}
}
if err := stream.Err(); err != nil {
log.Fatal(err)
}
}
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
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: wygeneruj niestandardową osobowość głosową 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ądsample_audiow formacie WAV wCreateVoiceiGetVoice). - 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 |
Klucze głosowe bezstanowe (voicekey_..., replikowane) |
store=False |
Zarządzane przez klienta | 7 dni |
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 – Clear | Algenib – żwirowy | Rasalgethi – zawiera przydatne informacje |
| Laomedeia – Upbeat | 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 – wiedza | 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, 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 (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 | Wielu głośnikó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ą 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 przeprowadzasz migrację z modeli Gemini TTS w wersji gemini-3.1-flash-tts-preview lub starszej na Gemini 3.8 TTS:
- Przeniesienie wskazówek na poziomie zwrotu do
speech_metadata: zamiana tekstu na mowę w Gemini 3.8 traktuje tekst wejściowy jako dosłowny zapis. Przenieś instrukcje dotyczące ciągłego dostarczania (style– np."whispering","out of breath"lub"speaking slowly") i etykiety rozmówców (speaker) do strukturalnych adnotacjispeech_metadatazamiast osadzać wskazówki sceniczne w tekście transkrypcji. - Używaj tagów w nawiasach ostrych tylko w przypadku krótkotrwałych zdarzeń głosowych: zachowaj krótkotrwałe wokalizacje i pauzy w transkrypcji, używając nawiasów ostrych (np.
<laugh>,<sigh>,<cough>,<breath>lub<short pause>). Unikaj tagów efektów dźwiękowych (np. oklaski lub uderzenia) i umieszczaj style wypowiedzi w tagachspeech_metadata.style. - Określ
speakerw każdej turze w przypadku żądań z udziałem wielu osób: każda tura w żądaniu z udziałem wielu osób musi zawieraćspeakerwspeech_metadata, które odpowiada jednemu ze skonfigurowanych głośników. - Zaprojektuj persony z wyprzedzeniem za pomocą funkcji Projektowanie głosu: zastąp wielościeżkowe bloki
"Audio Profile"lub"Director's Notes"niestandardowym głosem utworzonym w funkcji Projektowanie głosu, a następnie przesyłaj identyfikatorvoice_...w żądaniach syntezy mowy z minimalnymi lub pustymi ciągami znakówstyle. - Uwzględnij domyślne wyjście WAV (
audio/wav) w przypadku żądań binarnych: w przeciwieństwie do modeli TTS w wersjigemini-3.1-flash-tts-previewi starszych (które domyślnie zwracały surowe dane PCM bez nagłówkaaudio/l16) model Gemini 3.8 TTS domyślnie zwraca dźwięk WAV (audio/wav) ze standardowym nagłówkiem RIFF 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 lubffmpeg), usuń ręczny wrapper nagłówka i zapisz zwrócone bajty bezpośrednio w pliku.wav. - Jeśli potok wymaga dźwięku PCM bez nagłówka, mu-law lub A-law, ustaw
response_formatna"audio/l16","audio/mulaw"lub"audio/alaw". 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 zapewnić stabilność postaci i jej zachowania w różnych sytuacjach, zaprojektuj osobowość 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 etapie projektowania głosu, aby wygenerować trwałą, niestandardową personęvoice_..., a następnie używaj tego identyfikatora głosu w wywołaniach TTS. - 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 Twojego 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 korekty dostawy, i ponownie używaj tego samego krótkiego ciągu znaków w kolejnych 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.
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 (
speech_config.speakers) 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ąaudio/wavz 44-bajtowym nagłówkiem RIFF, zażądaj surowego PCM ({"type": "audio", "mime_type": "audio/l16"}) lub usuń nagłówek WAV z każdej tury przed połączeniem klatek audio PCM o częstotliwości próbkowania 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.