Gemini API dapat mengubah input teks menjadi audio satu atau beberapa pembicara menggunakan kemampuan pembuatan text-to-speech (TTS) Gemini.
Pembuatan text-to-speech dapat
dikontrol, yang berarti Anda
dapat menggabungkan metadata giliran terstruktur (speech_metadata) dan tag vokal inline
untuk memandu gaya, aksen, kecepatan, dan nada audio.
Kemampuan TTS berbeda dengan pembuatan ucapan yang disediakan melalui Live API, yang dirancang untuk audio interaktif dan tidak terstruktur, serta input dan output multimodal. Meskipun Live API unggul dalam konteks percakapan dinamis, TTS melalui Gemini API disesuaikan untuk skenario yang memerlukan pembacaan teks yang tepat dengan kontrol gaya dan suara yang cermat, seperti pembuatan podcast atau buku audio.
Panduan ini menunjukkan cara membuat audio satu penutur dan multi-penutur dari
teks menggunakan Gemini 3.8 Flash TTS
(gemini-3.8-flash-tts) dan
Gemini 3.8 Flash-Lite TTS
(gemini-3.8-flash-lite-tts).
Sebelum memulai
Pastikan Anda menggunakan model Gemini TTS yang tercantum di bagian Model yang didukung. Untuk hasil yang optimal, tinjau Kapan harus menggunakan model yang mana untuk memilih model terbaik untuk workload Anda.
Anda mungkin merasa berguna untuk menguji model Gemini TTS di AI Studio sebelum Anda mulai membangun.
TTS satu penutur
Untuk mengonversi teks menjadi audio satu penutur dengan model Gemini 3.8 TTS, teruskan transkrip kata demi kata dalam input, lampirkan gaya tingkat giliran menggunakan anotasi speech_metadata, dan konfigurasi suara Anda di generation_config.speech_config. Anda dapat memilih suara dari Opsi suara bawaan, Koleksi Suara yang Diperluas (GET /v1beta/voices), ID Desain suara kustom (voice_...), atau ID Replikasi suara (voice_..., atau voicekey_... tanpa status opsional).
Contoh ini menyimpan audio output WAV default (audio/wav) dari model langsung ke file:
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
Di SDK Python dan JavaScript, Anda dapat mengambil data audio yang dihasilkan dengan
menggunakan properti praktis interaction.output_audio, yang menampilkan
blok audio terakhir yang dihasilkan (dalam respons JSON REST mentah, audio berenkode base64
disimpan di steps[].content[].data). Untuk mengetahui detail properti praktis,
lihat
Ringkasan interaksi.
TTS multi-penutur
Untuk dialog multi-pembicara, konfigurasikan dua pembicara di speech_config.speakers
dan teruskan setiap giliran sebagai item teks terpisah dengan anotasi speech_metadata
yang menentukan speaker dan style tingkat giliran opsional. Gunakan
"mode": "conversational" untuk irama pergantian giliran yang alami:
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" }
]
}
}
}'
Mengontrol gaya ucapan dengan metadata dan tag
Gemini 3.8 TTS memperlakukan kolom text secara ketat sebagai transkrip kata demi kata. Untuk mengontrol penyampaian tanpa membacakan petunjuk panggung, pisahkan petunjuk Anda berdasarkan cakupan:
- Penyampaian tingkat giliran yang berkelanjutan (
speech_metadata.style): Masukkan emosi, gaya penyampaian, prosodi, kecepatan, dan volume yang berlaku di seluruh giliran dalam kolomstyle(misalnya,"style": "whispered urgently","style": "out of breath", atau"style": "warm and enthusiastic"). - Peristiwa pada titik waktu tertentu (tag inline): Tempatkan jeda atau letupan vokal non-ucapan sesaat langsung di dalam transkrip menggunakan tanda kurung sudut (misalnya,
"Wait... <short pause> did you hear that? <sigh>"atau"Excuse me <cough> as I was saying...").
Lihat Panduan perintah untuk mengetahui praktik terbaik yang komprehensif.
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
}
Pembuatan ucapan saat streaming
Anda dapat melakukan streaming audio yang dihasilkan saat disintesis dengan menetapkan
stream: true. Tidak seperti permintaan unary (yang menampilkan file WAV lengkap dengan header
RIFF), permintaan streaming menampilkan potongan PCM linear little-endian
16-bit bertanda tanpa header secara defaultaudio/l16 sehingga
potongan audio dapat diputar atau digabungkan secara terus-menerus tanpa header
container.
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
}'
Format output audio
Model TTS Gemini 3.8 menggunakan format audio default yang berbeda, bergantung pada apakah permintaan bersifat unary atau streaming:
- Permintaan unary (
stream=False): Menampilkan audio WAV (audio/wav) lengkap dengan header RIFF standar (24 kHz, mono, PCM little-endian bertanda 16-bit ). Anda dapat menyimpan byte audio yang didekode langsung ke file.wavtanpa menambahkan header WAV secara manual. - Permintaan streaming (
stream=True): Menampilkan potongan PCM Linear mentah tanpa header (audio/l16) (PCM little-endian bertanda 16-bit, mono, 24 kHz) secara default sehingga potongan dapat di-streaming atau digabungkan secara terus-menerus tanpa header penampung di setiap potongan.
Untuk meminta encoding atau frekuensi sampel audio yang berbeda, konfigurasi mime_type dan
sample_rate opsional di dalam response_format:
| Format | Nilai mime_type |
Deskripsi |
|---|---|---|
| WAV (default unary) | "audio/wav" |
File WAV tanpa kompresi dengan header RIFF (PCM little-endian bertanda 16-bit, mono, default 24 kHz). Default untuk permintaan unary. |
| PCM Mentah (L16) (default streaming) | "audio/l16" |
Audio PCM linear 16-bit bertanda little-endian tanpa kompresi dan tanpa header (24 kHz, mono). Default untuk permintaan streaming. |
| Mu-law | "audio/mulaw" |
Audio yang dienkode mu-law G.711 8-bit (umum digunakan dalam sistem telepon/IVR Amerika Utara dan Jepang). |
| A-law | "audio/alaw" |
Audio yang dienkode dengan hukum A G.711 8-bit (umumnya digunakan dalam sistem telepon Eropa dan internasional). |
Anda juga dapat menentukan sample_rate dalam Hertz (misalnya, 24000, 16000, atau
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" }
]
}
}'
Pilihan suara
Gemini 3.8 TTS mendukung empat cara untuk memilih atau membuat suara:
- Suara studio bawaan: 30 suara pilihan yang tercantum dalam tabel berikut.
- Perpustakaan Suara yang Diperluas: Ratusan suara tambahan dalam berbagai bahasa, aksen, dan arketipe karakter yang dapat diakses menggunakan
client.voices.list()(GET /v1beta/voices). - Desain suara: Buat persona vokal kustom
dari deskripsi bahasa alami di
Google AI Studio atau menggunakan
POST /v1beta/voices(type="prompted", yang menampilkan IDvoice_...persisten dan pratinjau WAVsample_audiodiCreateVoicedanGetVoice). - Replikasi suara: Mereplikasi suara penutur dari audio referensi dan audio yang telah disetujui di
Google AI Studio atau menggunakan
POST /v1beta/voices(type="replicated",store=Truepersisten secara default ataustore=Falsetanpa status opsional).
Batas suara kustom dan TTL
| Jenis suara | Mode penyimpanan | Kuota / batas | Retensi (TTL) |
|---|---|---|---|
Suara penting (voice_..., diminta atau direplikasi) |
store=True |
200 suara per project (dibagikan di seluruh suara yang diminta dan direplikasi) | 1 year |
Kunci suara tanpa status (voicekey_..., direplikasi) |
store=False |
Dikelola klien | 7 hari |
Suara bawaan
| Zephyr -- Bright | Puck -- Ceria | Charon -- Informatif |
| Kore -- Firm | Fenrir -- Mudah Terangsang (Excitable) | Leda -- Muda |
| Orus -- Firm | Aoede -- Breezy | Callirrhoe -- Santai |
| Autonoe -- Bright | Enceladus -- Breathy | Iapetus -- Clear |
| Umbriel -- Santai | Algieba -- Halus (Smooth) | Despina -- Smooth |
| Erinome -- Clear | Algenib -- Berbatu | Rasalgethi -- Informatif |
| Laomedeia -- Upbeat | Achernar -- Lembut | Alnilam -- Tegas (Firm) |
| Schedar -- Even | Gacrux -- Dewasa | Pulcherrima -- Meneruskan |
| Achird -- Ramah | Zubenelgenubi -- Kasual | Vindemiatrix -- Lembut (Gentle) |
| Sadachbia -- Lively | Sadaltager -- Berpengetahuan | Sulafat -- Hangat |
Library Suara yang Diperluas dan pemfilteran
Selain 30 suara studio unggulan dalam tabel sebelumnya, Pustaka Suara yang Diperluas menyediakan ratusan suara tambahan dalam berbagai bahasa, aksen regional, persona karakter, dan domain. Anda dapat menjelajahi, memfilter, dan
mendengarkan seluruh Library Suara secara interaktif di
Google AI Studio, atau mengkuerinya
secara terprogram menggunakan client.voices.list() (GET /v1beta/voices, menggunakan
google-genai 2.25.0+ / @google/genai 2.24.0+).
ListVoices menampilkan suara tersimpan kustom Anda (diurutkan dari yang terbaru terlebih dahulu), diikuti dengan suara katalog bawaan yang cocok dengan kriteria filter Anda. Jika beberapa nilai
diteruskan untuk filter daftar, suara yang cocok dengan nilai apa pun dalam filter tersebut akan
ditampilkan (OR), sementara parameter filter yang berbeda digabungkan dengan AND:
| Parameter | Jenis | Deskripsi |
|---|---|---|
language_code |
list[str] |
Tag bahasa BCP-47 (misalnya, ["en-US", "en-GB"]). Pencocokan persis yang tidak peka huruf besar/kecil. |
region_code |
list[str] |
Kode wilayah ISO 3166-1 alpha-2 atau UN M.49 (misalnya, ["US", "GB"]). |
accent |
list[str] |
Deskripsi aksen regional (misalnya, ["American", "British"]). |
gender |
list[str] |
Persepsi presentasi gender ("female", "male", atau "neutral"). |
pitch |
list[str] |
Klasifikasi nada suara ("low", "medium", atau "high"). |
persona |
list[str] |
Persona vokal atau arketipe karakter (misalnya, ["Warm, Friendly"], ["Narrator"]). |
contexts (context di REST) |
list[str] |
Domain penggunaan yang optimal (misalnya, ["Audiobook", "Conversational", "News"]). |
type (type_ di Python) |
list[str] |
Filter menurut sumber suara: "prebuilt", "prompted" (Desain suara), atau "replicated" (Replikasi suara). |
search |
str |
Penelusuran substring teks bebas dicocokkan tanpa peka huruf besar/kecil dengan display_name dan description. |
page_size |
int |
Jumlah maksimum suara yang ditampilkan per halaman (default 50, maksimum 1000). |
page_token |
str |
Token dari response.next_page_token untuk mengambil halaman hasil berikutnya. |
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"
Bahasa yang didukung
Model TTS mendeteksi bahasa input secara otomatis.
Gemini 3.8 Flash TTS
(gemini-3.8-flash-tts) mendukung lebih dari 130 bahasa, dan
Gemini 3.8 Flash-Lite TTS
(gemini-3.8-flash-lite-tts) mendukung lebih dari 100 bahasa:
| Language | Gemini 3.8 Flash TTS | Gemini 3.8 Flash-Lite TTS |
|---|---|---|
| Aceh (skrip Arab) | ✔️ | ✔️ |
| Afrika | ✔️ | ✔️ |
| Akan | ✔️ | ✔️ |
| Amharik | ✔️ | ✔️ |
| Armenia | ✔️ | ✔️ |
| Assam | ✔️ | ✔️ |
| Awadhi | ✔️ | ✔️ |
| Bali | ✔️ | ✔️ |
| Bangla | ✔️ | ✔️ |
| Banjar (skrip Arab) | ✔️ | — |
| Banjar (skrip Latn) | ✔️ | ✔️ |
| Bashkir | ✔️ | — |
| Basque | ✔️ | ✔️ |
| Belarusia | ✔️ | ✔️ |
| Bemba | ✔️ | — |
| Bhojpuri | ✔️ | ✔️ |
| Bosnia | ✔️ | ✔️ |
| Bugis | ✔️ | ✔️ |
| Bulgaria | ✔️ | ✔️ |
| Burma | ✔️ | — |
| Kanton | ✔️ | ✔️ |
| Katalan | ✔️ | ✔️ |
| Cebuano | ✔️ | ✔️ |
| Kurdi Tengah | ✔️ | ✔️ |
| Chhattisgarhi | ✔️ | ✔️ |
| China (skrip Hans) | ✔️ | ✔️ |
| China (skrip Hant) | ✔️ | ✔️ |
| Crimean Tatar | ✔️ | — |
| Kroasia | ✔️ | ✔️ |
| Ceko | ✔️ | ✔️ |
| Denmark | ✔️ | ✔️ |
| Belanda | ✔️ | ✔️ |
| Dyula | ✔️ | — |
| Dzongkha | ✔️ | — |
| Arab Mesir | ✔️ | ✔️ |
| Inggris | ✔️ | ✔️ |
| Estonia | ✔️ | ✔️ |
| Filipino | ✔️ | ✔️ |
| Finlandia | ✔️ | — |
| Prancis | ✔️ | ✔️ |
| Galisia | ✔️ | ✔️ |
| Ganda | ✔️ | ✔️ |
| Georgia | ✔️ | ✔️ |
| Jerman | ✔️ | ✔️ |
| Yunani | ✔️ | ✔️ |
| Guarani | ✔️ | — |
| Gujarat | ✔️ | ✔️ |
| Kreol Haiti | ✔️ | ✔️ |
| Halh Mongolia | ✔️ | ✔️ |
| Hausa | ✔️ | ✔️ |
| Ibrani | ✔️ | ✔️ |
| Hindi | ✔️ | ✔️ |
| Hungaria | ✔️ | ✔️ |
| Islandia | ✔️ | ✔️ |
| Igbo | ✔️ | — |
| Iloko | ✔️ | ✔️ |
| Indonesia | ✔️ | ✔️ |
| Persia Iran | ✔️ | ✔️ |
| Italia | ✔️ | ✔️ |
| Jepang | ✔️ | ✔️ |
| Jawa | ✔️ | ✔️ |
| Kabyle | ✔️ | — |
| Kamba | ✔️ | ✔️ |
| Kannada | ✔️ | ✔️ |
| Kashmir (skrip Arab) | ✔️ | ✔️ |
| Kashmir (skrip Deva) | ✔️ | ✔️ |
| Kazak | ✔️ | ✔️ |
| Khmer | ✔️ | ✔️ |
| Kikuyu | ✔️ | ✔️ |
| Kinyarwanda | ✔️ | ✔️ |
| Kongo | ✔️ | ✔️ |
| Korea | ✔️ | ✔️ |
| Kirgiz | ✔️ | ✔️ |
| Laos | ✔️ | ✔️ |
| Latgalia | ✔️ | — |
| Lingala | ✔️ | ✔️ |
| Lituania | ✔️ | — |
| Luksemburg | ✔️ | — |
| Makedonia | ✔️ | ✔️ |
| Magahi | ✔️ | ✔️ |
| Maithili | ✔️ | ✔️ |
| Malayalam | ✔️ | ✔️ |
| Malta | ✔️ | ✔️ |
| Manipuri | ✔️ | ✔️ |
| Marathi | ✔️ | ✔️ |
| Minangkabau (skrip Arab) | ✔️ | ✔️ |
| Minangkabau (skrip Latn) | ✔️ | — |
| Mizo | ✔️ | ✔️ |
| Nepali (bahasa individu) | ✔️ | ✔️ |
| Fulfulde Nigeria | ✔️ | ✔️ |
| Azerbaijan Utara | ✔️ | ✔️ |
| Sotho Utara | ✔️ | ✔️ |
| Uzbek Utara | ✔️ | ✔️ |
| Bokmål Norwegia | ✔️ | ✔️ |
| Nynorsk Norwegia | ✔️ | ✔️ |
| Nyanja | ✔️ | ✔️ |
| Occitan | ✔️ | — |
| Odia (bahasa individu) | ✔️ | ✔️ |
| Pangasinan | ✔️ | — |
| Persia (Afganistan) | ✔️ | ✔️ |
| Polandia | ✔️ | ✔️ |
| Portugis | ✔️ | ✔️ |
| Punjabi | ✔️ | ✔️ |
| Rumania | ✔️ | ✔️ |
| Rusia | ✔️ | ✔️ |
| Santali | ✔️ | ✔️ |
| Serbia | ✔️ | ✔️ |
| Sindhi | ✔️ | — |
| Sinhala | ✔️ | ✔️ |
| Slovakia | ✔️ | ✔️ |
| Slovenia | ✔️ | — |
| Somali | ✔️ | — |
| Azerbaijan Selatan | ✔️ | ✔️ |
| Pashto Selatan | ✔️ | ✔️ |
| Sotho Selatan | ✔️ | — |
| Spanyol | ✔️ | ✔️ |
| Arab Standar (skrip Arab) | ✔️ | ✔️ |
| Arab Standar (skrip Latn) | ✔️ | ✔️ |
| Latvia Standar | ✔️ | ✔️ |
| Melayu Standar | ✔️ | ✔️ |
| Swahili (bahasa individu) | ✔️ | — |
| Swati | ✔️ | — |
| Swedia | ✔️ | — |
| Tajik | ✔️ | — |
| Tamil | ✔️ | ✔️ |
| Telugu | ✔️ | ✔️ |
| Thai | ✔️ | — |
| Tigrinya | ✔️ | — |
| Tosk Albania | ✔️ | — |
| Turki | ✔️ | ✔️ |
| Uyghur | ✔️ | — |
| Vietnam | ✔️ | ✔️ |
Model yang didukung
| Model | Satu penutur | Multi-penutur | Desain suara | Replikasi suara |
|---|---|---|---|---|
Gemini 3.8 Flash TTS (gemini-3.8-flash-tts) |
✔️ | ✔️ | ✔️ | ✔️ |
Gemini 3.8 Flash-Lite TTS (gemini-3.8-flash-lite-tts) |
✔️ | ✔️ | ✔️ | ✔️ |
| Pratinjau Gemini 3.1 Flash TTS | ✔️ | ✔️ | — | — |
| Gemini 2.5 Pro Preview TTS | ✔️ | ✔️ | — | — |
Kapan model tertentu sebaiknya digunakan
Kedua model TTS Gemini 3.8 memiliki skema API dan format perintah yang sama persis, sehingga Anda dapat beralih di antara keduanya dengan satu perubahan parameter:
- Gunakan Gemini 3.8 Flash TTS
(
gemini-3.8-flash-tts) jika fidelitas akustik maksimum, akting yang bernuansa, dan kontrol ekspresif menjadi prioritas utama. Fitur ini ideal untuk karya kreatif berkualitas studio, dialog multi-pembicara yang kompleks, tag vocal-burst yang berat, pelafalan yang sulit, dialek regional atau minoritas, dan narasi panjang yang memerlukan stabilitas suara dan tone ruangan yang sangat solid. - Gunakan Gemini 3.8 Flash-Lite TTS
(
gemini-3.8-flash-lite-tts) sebagai penggantigemini-3.1-flash-tts-previewyang cepat dan hemat biaya. Model ini dioptimalkan untuk produksi massal bervolume tinggi, kaskade agen suara percakapan, fitur baca lisan, replikasi suara yang andal, dan ucapan satu penutur sehari-hari dalam bahasa utama.
Panduan migrasi
Jika Anda melakukan migrasi dari model Gemini TTS gemini-3.1-flash-tts-preview atau yang lebih lama ke Gemini 3.8 TTS:
- Memindahkan petunjuk tingkat belokan ke
speech_metadata: Gemini 3.8 TTS memperlakukan teks input secara ketat sebagai transkrip kata demi kata. Pindahkan petunjuk penayangan berkelanjutan (style—seperti"whispering","out of breath", atau"speaking slowly") dan label pembicara (speaker) ke anotasispeech_metadataterstruktur, bukan menyematkan petunjuk pementasan dalam teks transkrip. - Gunakan tag inline tanda kurung sudut hanya untuk peristiwa vokal pada satu titik waktu: Pertahankan
vokalisasi non-ucapan dan jeda sesaat dalam transkrip menggunakan
tanda kurung sudut (seperti
<laugh>,<sigh>,<cough>,<breath>, atau<short pause>). Hindari tag efek suara (seperti tepuk tangan atau bunyi gedebuk) dan masukkan gaya penyampaian dalamspeech_metadata.style. - Tentukan
speakerdi setiap giliran dalam permintaan multi-pembicara: Setiap giliran dalam permintaan multi-pembicara harus secara eksplisit menyertakanspeakerdi dalamspeech_metadatayang cocok dengan salah satu pembicara yang dikonfigurasi. - Desain persona di awal dengan desain Voice: Ganti blok multi-paragraf
"Audio Profile"atau"Director's Notes"dengan suara kustom yang dibuat di Desain Voice, lalu bawa IDvoice_...tersebut melalui permintaan TTS Anda dengan stringstyleminimal atau kosong. - Memperhitungkan output WAV (
audio/wav) default pada permintaan unary: Tidak seperti model TTSgemini-3.1-flash-tts-previewdan yang lebih lama (yang menampilkan PCM mentah tanpa headeraudio/l16secara default), Gemini 3.8 TTS menampilkan audio WAV (audio/wav) dengan header RIFF standar secara default untuk permintaan unary.- Jika kode Anda sebelumnya membungkus byte PCM mentah dalam header WAV (misalnya, menggunakan modul
wavePython atauffmpeg), hapus pembungkus header manual dan tulis byte yang ditampilkan langsung ke file.wav. - Jika pipeline Anda memerlukan audio PCM mentah tanpa header, mu-law, atau A-law,
tetapkan
response_formatke"audio/l16","audio/mulaw", atau"audio/alaw"secara eksplisit. Lihat Format output audio.
- Jika kode Anda sebelumnya membungkus byte PCM mentah dalam header WAV (misalnya, menggunakan modul
Panduan penulisan perintah
Model Gemini 3.8 TTS memperlakukan teks input secara ketat sebagai transkrip kata demi kata.
Tidak seperti model pratinjau sebelumnya yang menyematkan petunjuk pementasan dalam teks biasa, Gemini 3.8 TTS memisahkan petunjuk tingkat giliran yang berkelanjutan (speech_metadata) dari tag vokal inline point-in-time.
Kolom gaya versus tag inline
Pisahkan petunjuk performa Anda berdasarkan cakupan:
- Penayangan tingkat giliran (
speech_metadata.style): Masukkan atribut penayangan berkelanjutan—seperti emosi, prosodi, kecepatan keseluruhan, atau gaya penayangan (seperti"whispering","out of breath","muttering", atau"sarcastic")—ke dalam kolomstyledarispeech_metadata. Untuk membuat karakter dan performa yang stabil di setiap giliran, desain persona di awal dalam Desain suara dan gunakanstylehanya untuk penyesuaian tingkat giliran opsional. - Peristiwa pada satu titik waktu (tag inline): Masukkan letupan vokal non-ucapan sesaat, tarikan napas, atau jeda inline di dalam transkrip menggunakan tanda kurung sudut (
<cough>,<breath>,<sigh>,<short pause>). Gunakan tanda kurung sudut (<...>) untuk kualitas audio tertinggi, dan tetap gunakan vokalisasi manusia, bukan efek suara non-vokal.
| Cakupan | Tempatkan di | Contoh |
|---|---|---|
| Tingkat giliran (dipertahankan di seluruh giliran) | speech_metadata.style |
"angry tone", "speaking rapidly", "out of breath", "whispers", "sarcastic" |
| Point-in-time (terjadi pada kata tertentu) | Inline di text (<...>) |
"<cough> Thank you all for coming tonight! <throat-clearing> As I was saying..." |
Kecepatan dan jeda
Anda dapat mengontrol ritme dan keheningan pada tiga tingkat perincian:
- Tanda baca dan elipsis: Gunakan koma, tanda hubung (
--), dan elipsis (...) untuk keraguan percakapan yang alami. - Tag jeda inline: Sisipkan
<short pause>atau<long pause>di titik yang tepat dalam skrip tempat pembicara harus berhenti sejenak:text Hold on, let me think... <short pause> Alright, I've got it. - Kecepatan tingkat giliran: Tetapkan
"style": "speaking rapidly"atau"style": "speaking slowly"dispeech_metadatauntuk mengontrol kecepatan bicara di seluruh giliran.
Prosodi dan nada suara
Gunakan speech_metadata.style untuk mengontrol prosodi, nada, dan infleksi di seluruh
giliran bicara (misalnya, "style": "high pitch, cheerful and excited inflection" atau
"style": "monotone and flat"). Jika emosi atau prosodi berubah di tengah dialog,
pisahkan skrip menjadi giliran bicara terpisah dengan nilai style yang berbeda untuk setiap giliran bicara.
Penekanan
Gunakan huruf kapital pada kata tertentu dalam transkrip, yang dikombinasikan dengan tanda baca dan tag vokal inline, untuk memberikan tekanan vokal alami pada kata kunci:
This is a VERY important point!
It was a VERY long day <sigh> ... nobody listens anymore.
Ledakan vokal dan suara non-ucapan
Tempatkan vokalisasi manusia non-ucapan secara inline menggunakan tanda kurung sudut (<...>) pada
titik persis tempat suara harus terjadi. Tag vokal yang direkomendasikan meliputi:
<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> |
Saluran belakang dan ucapan yang tumpang-tindih
Dalam dialog multi-pembicara, sertakan reaksi pendengar dalam karakter pipa
(|reaction|) di dalam giliran pembicara untuk membuat saluran belakang yang alami atau
ucapan yang tumpang-tindih tanpa memecah menjadi giliran terpisah per reaksi.
- Pertukaran saluran belakang singkat: Susun reaksi singkat pendengar (
|oh hmm|,|oh really?|,|absolutely|) di dalam giliran pembicara aktif:- Giliran 1 (Pembicara A):
"So the launch is Thursday |oh hmm| Are we actually ready?" - Giliran 2 (Pembicara B):
"Ready enough |oh really?| The last blocker cleared this morning." - Giliran 3 (Pembicara A):
"Then let's ship it |absolutely| and watch the dashboards."
- Giliran 1 (Pembicara A):
- Ucapan yang tumpang-tindih dan berselang-seling: Gunakan beberapa segmen pipa untuk
mensimulasikan ucapan simultan atau berselang-seling antara dua penutur (berfungsi paling baik
dengan
gemini-3.8-flash-tts):- Hitung mundur/chorus serentak:
"Let's surprise him on three |ok| ready?"diikuti dengan"one. two. three. |happy| happy |birthday| birthday!" - Tumpang-tindih pembicara penuh:
"Hello |oh| there |my| it |goodness| must |gracious| be |would| almost |you| time |look| for |at that| dinner"
- Hitung mundur/chorus serentak:
Konsistensi di seluruh generasi dan hal yang harus dihindari
Ikuti panduan berikut untuk menjaga kestabilan identitas vokal di seluruh giliran:
- Merancang persona di awal dalam Desain suara, bukan blok gaya panjang:
Paragraf
"Audio Profile"panjang dan"Director's Notes"multi-butir yang dipertahankan dari model sebelumnya adalah penyebab paling umum terjadinya penyimpangan suara. Gunakan intuisi kreatif yang sama di awal dalam Desain suara untuk menghasilkan personavoice_...kustom yang persisten, lalu bawa ID suara tersebut melalui panggilan TTS Anda. - Mengandalkan referensi suara untuk stabilitas (menghilangkan meta-petunjuk):
Model TTS Gemini 3.8 dilatih untuk berfokus pada referensi audio terlebih dahulu.
Jangan sertakan petunjuk yang meminta model untuk menjaga kestabilan suara (seperti
"do not switch speaker identity"atau"maintain identical timbre")—teks perintah tambahan meningkatkan penyimpangan. Hapus petunjuk gaya yang tidak perlu dan biarkan model bervariasi secara alami di sekitar titik stabil yang disediakan oleh referensi suara. - Jangan mencoba mengubah karakteristik penutur yang tidak dapat diubah di
style: Hindari memasukkan perubahan usia, gender, nama, atau aksen permanen dispeech_metadata.style. Sebagai gantinya, pilih suara regional dari Extended Voice Library atau buat suara dengan Voice design.
Alur kerja yang direkomendasikan
- Buat karakter sekali saja: Buat karakter Anda di Desain suara atau pilih suara regional dari Koleksi Suara yang Diperluas yang cocok dengan bahasa target dan persona Anda.
- Tulis transkrip lisan alami dengan ketidaklancaran: Untuk mendapatkan kealamian
maksimal, tulis
textsebagai transkrip lisan yang nyata—termasuk ketidaklancaran dan keraguan percakapan alami (misalnya,"Oh uh yeah I think... hm, so that's interesting"). - Uji TTS biasa terlebih dahulu: Sintesiskan transkrip Anda dengan kolom
stylekosong terlebih dahulu—sebagian besar permintaan tidak memerlukan petunjukstylesama sekali. - Tambahkan perintah singkat
stylehanya untuk penyesuaian: Tambahkan stringstylesingkat (seperti"casual, friendly"atau"muttering, then reassuring") hanya untuk belokan yang memerlukan penyesuaian penayangan tertentu, dan gunakan kembali string singkat yang sama di seluruh belokan saat Anda menginginkan dasar pengukuran yang konsisten.
Dialog bolak-balik dan agen suara
Saat membangun agen suara percakapan real-time atau aplikasi multi-turn:
- Lakukan satu panggilan TTS per giliran saat potongan teks LLM tiba.
- Biarkan
voiceyang dikonfigurasi (bawaan,voice_...yang didesain, atauvoice_.../voicekey_...yang direplikasi) membawa identitas pembicara di setiap giliran—jangan pernah mengirim ulang persona karakter panjang di setiap giliran. - Biarkan kolom
styleper giliran kosong, atau kirim satu string konstan pendek (seperti"casual, friendly") untuk seluruh percakapan. - Membagi respons agen yang panjang menjadi giliran yang lebih pendek, bukan menggunakan perintah gaya yang lebih kuat.
Batasan
- Model TTS menerima input khusus teks dan menghasilkan output khusus audio.
- Pembuatan multi-penutur permintaan tunggal (
speech_config.speakers) mendukung hingga 2 penutur menggunakan suara bawaan. Untuk menggabungkan suara yang didesain khusus (voice_...) atau direplikasi (voice_.../voicekey_...) dalam dialog multi-karakter, sintesiskan setiap giliran bicara secara terpisah. Karena permintaan unary menampilkanaudio/wavdengan header RIFF 44 byte secara default, minta PCM mentah ({"type": "audio", "mime_type": "audio/l16"}) atau hapus header WAV dari setiap giliran sebelum menggabungkan frame audio PCM 24 kHz. - Batas penyimpanan suara kustom dan TTL:
- Suara dengan status (
store=True, dipicu atau direplikasi): Maksimum 200 suara per project dengan TTL 1 tahun (time-to-live). - Kunci suara stateless (
store=False,voicekey_...): TTL 7 hari (time-to-live).
- Suara dengan status (
- Tinjau bagian Bahasa yang didukung untuk mengetahui cakupan bahasa.
Langkah berikutnya
- Buat persona vokal kustom dari bahasa alami dengan Desain suara.
- Mereplikasi suara penutur yang ada di Replikasi suara.
- Bandingkan spesifikasi model di halaman model Gemini 3.8 Flash TTS dan Gemini 3.8 Flash-Lite TTS.
- Jelajahi audio dua arah interaktif dengan Live API.