Generowanie tekstu na mowę (TTS)

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 polu style (np. "style": "whispered urgently", "style": "out of breath" lub "style": "warm and enthusiastic").
  • Zdarzenia w określonym momencie (tagi wbudowane): umieść krótkie, niewerbalne dźwięki lub przerwy bezpośrednio w transkrypcji, używając nawiasów ostrych (np. "Wait... <short pause> did you hear that? <sigh>" lub "Excuse me <cough> as I was saying...").

Więcej sprawdzonych metod znajdziesz w przewodniku po 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 .wav bez 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:

  1. Gotowe głosy studyjne: 30 wyselekcjonowanych głosów wymienionych w tabeli poniżej.
  2. 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).
  3. 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 identyfikator voice_... i podgląd sample_audio w formacie WAV w CreateVoice i GetVoice).
  4. 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łe store=True lub opcjonalne bezstanowe store=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 zamiennika gemini-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:

  1. 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 adnotacji speech_metadata zamiast osadzać wskazówki sceniczne w tekście transkrypcji.
  2. 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 tagach speech_metadata.style.
  3. Określ speaker w 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ć speaker w speech_metadata, które odpowiada jednemu ze skonfigurowanych głośników.
  4. 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 identyfikator voice_... w żądaniach syntezy mowy z minimalnymi lub pustymi ciągami znaków style.
  5. Uwzględnij domyślne wyjście WAV (audio/wav) w przypadku żądań binarnych: w przeciwieństwie do modeli TTS w wersji gemini-3.1-flash-tts-preview i starszych (które domyślnie zwracały surowe dane PCM bez nagłówka audio/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 wave w Pythonie lub ffmpeg), 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_format na "audio/l16", "audio/mulaw" lub "audio/alaw". Zobacz Formaty wyjściowe audio.

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 polu style elementu speech_metadata. Aby zapewnić stabilność postaci i jej zachowania w różnych sytuacjach, zaprojektuj osobowość z wyprzedzeniem w sekcji Projektowanie głosu i używaj style tylko 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" w speech_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."
  • 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"

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 w speech_metadata.style informacji 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.
  1. 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.
  2. Twórz naturalne transkrypcje mówione z niepłynnościami: aby uzyskać maksymalną naturalność, zapisz text jako prawdziwą transkrypcję mówioną – z naturalnymi niepłynnościami i wahaniami w rozmowie (np. "Oh uh yeah I think... hm, so that's interesting").
  3. Najpierw przetestuj zwykły TTS: najpierw zsyntetyzuj transkrypcję za pomocą pustego pola style. Większość żądań nie wymaga żadnych instrukcji style.
  4. Dodawaj krótkie prompty style tylko w przypadku drobnych zmian: dodawaj zwięzły ciąg znaków style (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, zaprojektowanemu voice_... 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 style puste 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/wav z 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).
  • Więcej informacji o obsługiwanych językach znajdziesz w sekcji Obsługiwane języki.

Co dalej?