Génération de synthèse vocale

L'API Gemini peut transformer une entrée de texte en contenu audio à un ou plusieurs intervenants à l'aide des fonctionnalités de génération de synthèse vocale (TTS) de Gemini. La génération de synthèse vocale est contrôlable, ce qui signifie que vous pouvez combiner des métadonnées de tour structurées (speech_metadata) et des tags vocaux intégrés pour guider le style, l'accent, le rythme et le ton de l'audio.

La fonctionnalité TTS diffère de la génération vocale fournie par l'API Live, qui est conçue pour l'audio interactif et non structuré, ainsi que pour les entrées et sorties multimodales. Alors que l'API Live excelle dans les contextes conversationnels dynamiques, la synthèse vocale via l'API Gemini est conçue pour les scénarios qui nécessitent une récitation exacte du texte avec un contrôle précis du style et du son, comme la génération de podcasts ou de livres audio.

Ce guide vous explique comment générer de l'audio à une ou plusieurs voix à partir de texte à l'aide de Gemini 3.8 Flash TTS (gemini-3.8-flash-tts) et de Gemini 3.8 Flash-Lite TTS (gemini-3.8-flash-lite-tts).

Avant de commencer

Assurez-vous d'utiliser un modèle Gemini TTS listé dans la section Modèles compatibles, et passez à la dernière version du SDK Google GenAI (google-genai >= 2.25.0 pour Python ou @google/genai >= 2.24.0 pour JavaScript/TypeScript) ou utilisez l'API REST. Pour obtenir des résultats optimaux, consultez Quand utiliser tel ou tel modèle pour sélectionner le modèle le mieux adapté à votre charge de travail.

Il peut être utile de tester les modèles TTS Gemini dans AI Studio avant de commencer à créer.

TTS à locuteur unique

Pour convertir du texte en audio à un seul locuteur avec les modèles Gemini 3.8 TTS, transmettez la transcription textuelle dans input, associez un style au niveau du tour de parole à l'aide d'une annotation speech_metadata et configurez votre voix dans generation_config.speech_config. Vous pouvez choisir une voix parmi les options de voix prédéfinies, la bibliothèque de voix étendue (GET /v1beta/voices), un ID de conception de voix personnalisé (voice_...) ou un ID de réplication vocale (voice_... ou voicekey_... sans état facultatif).

Cet exemple enregistre la sortie audio WAV par défaut (audio/wav) du modèle directement dans un fichier :

Python

import base64
from google import genai

client = genai.Client()

interaction = client.interactions.create(
    model="gemini-3.8-flash-tts",
    input=[{
        "type": "user_input",
        "content": [{
            "type": "text",
            "text": "Have a wonderful day!",
            "annotations": [{
                "type": "speech_metadata",
                "style": "cheerful and friendly",
            }],
        }],
    }],
    response_format={"type": "audio"},
    generation_config={
        "speech_config": [
            {"voice": "Kore"},
        ]
    },
)

with open("out.wav", "wb") as f:
    f.write(base64.b64decode(interaction.output_audio.data))

JavaScript

import * as fs from 'node:fs';
import {GoogleGenAI} from '@google/genai';

async function main() {
   const client = new GoogleGenAI({});

   const interaction = await client.interactions.create({
      model: 'gemini-3.8-flash-tts',
      input: [{
         type: 'user_input',
         content: [{
            type: 'text',
            text: 'Have a wonderful day!',
            annotations: [{
               type: 'speech_metadata',
               style: 'cheerful and friendly',
            }],
         }],
      }],
      response_format: { type: 'audio' },
      generation_config: {
         speech_config: [
            { voice: 'Kore' },
         ],
      },
   });

   const audioBuffer = Buffer.from(interaction.output_audio.data, 'base64');
   fs.writeFileSync('out.wav', audioBuffer);
}
await main();

REST

curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3.8-flash-tts",
    "input": [{
      "type": "user_input",
      "content": [{
        "type": "text",
        "text": "Have a wonderful day!",
        "annotations": [{
          "type": "speech_metadata",
          "style": "cheerful and friendly"
        }]
      }]
    }],
    "response_format": {
      "type": "audio"
    },
    "generation_config": {
      "speech_config": [
        { "voice": "Kore" }
      ]
    }
  }' | jq -r '[.steps[] | select(.type=="model_output") | .content[] | select(.type=="audio")] | last | .data' | base64 --decode > out.wav

Dans les SDK Python et JavaScript, vous pouvez récupérer les données audio générées à l'aide de la propriété de commodité interaction.output_audio, qui renvoie le dernier bloc audio généré (dans les réponses JSON REST brutes, l'audio encodé en base64 est stocké dans steps[].content[].data). Pour en savoir plus sur les propriétés de commodité, consultez la présentation des interactions.

TTS multi-locuteur

Pour les dialogues à plusieurs locuteurs, configurez deux locuteurs dans speech_config.speakers et transmettez chaque tour de parole en tant qu'élément de texte distinct avec une annotation speech_metadata spécifiant speaker et style facultatif au niveau du tour de parole. Notez que speech_config accepte un tableau ([{"voice": "..."}]) pour la génération à une seule voix et un objet ({"speakers": [...]}) pour la génération à plusieurs voix :

Python

import base64
from google import genai

client = genai.Client()

interaction = client.interactions.create(
    model="gemini-3.8-flash-tts",
    input=[{
        "type": "user_input",
        "content": [
            {
                "type": "text",
                "text": "How's it going today Jane?",
                "annotations": [{
                    "type": "speech_metadata",
                    "speaker": "Joe",
                    "style": "cheerful and friendly",
                }],
            },
            {
                "type": "text",
                "text": "Not too bad, how about you? Ready to test these new voices?",
                "annotations": [{
                    "type": "speech_metadata",
                    "speaker": "Jane",
                    "style": "calm and relaxed",
                }],
            },
        ],
    }],
    response_format={"type": "audio"},
    generation_config={
        "speech_config": {
            "speakers": [
                {"speaker": "Joe", "voice": "Puck"},
                {"speaker": "Jane", "voice": "Kore"},
            ],
        }
    },
)

with open("out.wav", "wb") as f:
    f.write(base64.b64decode(interaction.output_audio.data))

JavaScript

import * as fs from 'node:fs';
import {GoogleGenAI} from '@google/genai';

async function main() {
   const client = new GoogleGenAI({});

   const interaction = await client.interactions.create({
      model: 'gemini-3.8-flash-tts',
      input: [{
         type: 'user_input',
         content: [
            {
               type: 'text',
               text: "How's it going today Jane?",
               annotations: [{
                  type: 'speech_metadata',
                  speaker: 'Joe',
                  style: 'cheerful and friendly',
               }],
            },
            {
               type: 'text',
               text: 'Not too bad, how about you? Ready to test these new voices?',
               annotations: [{
                  type: 'speech_metadata',
                  speaker: 'Jane',
                  style: 'calm and relaxed',
               }],
            },
         ],
      }],
      response_format: { type: 'audio' },
      generation_config: {
         speech_config: {
            speakers: [
               { speaker: 'Joe', voice: 'Puck' },
               { speaker: 'Jane', voice: 'Kore' },
            ],
         },
      },
   });

   const audioBuffer = Buffer.from(interaction.output_audio.data, 'base64');
   fs.writeFileSync('out.wav', audioBuffer);
}

await main();

REST

curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3.8-flash-tts",
    "input": [{
      "type": "user_input",
      "content": [
        {
          "type": "text",
          "text": "How'\''s it going today Jane?",
          "annotations": [{
            "type": "speech_metadata",
            "speaker": "Joe",
            "style": "cheerful and friendly"
          }]
        },
        {
          "type": "text",
          "text": "Not too bad, how about you? Ready to test these new voices?",
          "annotations": [{
            "type": "speech_metadata",
            "speaker": "Jane",
            "style": "calm and relaxed"
          }]
        }
      ]
    }],
    "response_format": {
      "type": "audio"
    },
    "generation_config": {
      "speech_config": {
        "mode": "conversational",
        "speakers": [
          { "speaker": "Joe", "voice": "Puck" },
          { "speaker": "Jane", "voice": "Kore" }
        ]
      }
    }
  }'

Contrôler le style de parole avec des métadonnées et des tags

Gemini 3.8 TTS traite le champ text strictement comme une transcription textuelle. Pour contrôler la diffusion sans que les indications scéniques soient lues à voix haute, séparez vos instructions par portée :

  • Diffusion soutenue au niveau du tour de parole (speech_metadata.style) : indiquez les émotions, le style de diffusion, la prosodie, le rythme et le volume qui s'appliquent à l'ensemble d'un tour de parole dans le champ style (par exemple, "style": "whispered urgently", "style": "out of breath" ou "style": "warm and enthusiastic").
  • Événements ponctuels (balises intégrées) : placez des pauses ou des sons vocaux non verbaux momentanés directement dans la transcription à l'aide de crochets (par exemple, "Wait... <short pause> did you hear that? <sigh>" ou "Excuse me <cough> as I was saying...").

Consultez le guide sur les prompts pour connaître toutes les bonnes pratiques.

Python

import base64
from google import genai

client = genai.Client()

interaction = client.interactions.create(
    model="gemini-3.8-flash-tts",
    input=[{
        "type": "user_input",
        "content": [
            {
                "type": "text",
                "text": "Wait... <short pause> look under that fallen log! Is that a blue-spotted salamander?",
                "annotations": [{
                    "type": "speech_metadata",
                    "speaker": "Dr. Anya",
                    "style": "whispered urgently",
                }],
            },
            {
                "type": "text",
                "text": "<gasp> No way! <laugh> We've been searching for this species all season!",
                "annotations": [{
                    "type": "speech_metadata",
                    "speaker": "Liam",
                    "style": "warm and enthusiastic",
                }],
            },
        ],
    }],
    response_format={"type": "audio"},
    generation_config={
        "speech_config": {
            "speakers": [
                {"speaker": "Dr. Anya", "voice": "Kore"},
                {"speaker": "Liam", "voice": "Puck"},
            ],
        }
    },
)

with open("out.wav", "wb") as f:
    f.write(base64.b64decode(interaction.output_audio.data))

JavaScript

import * as fs from 'node:fs';
import {GoogleGenAI} from '@google/genai';

async function main() {
   const client = new GoogleGenAI({});

   const interaction = await client.interactions.create({
      model: 'gemini-3.8-flash-tts',
      input: [{
         type: 'user_input',
         content: [
            {
               type: 'text',
               text: 'Wait... <short pause> look under that fallen log! Is that a blue-spotted salamander?',
               annotations: [{
                  type: 'speech_metadata',
                  speaker: 'Dr. Anya',
                  style: 'whispered urgently',
               }],
            },
            {
               type: 'text',
               text: "<gasp> No way! <laugh> We've been searching for this species all season!",
               annotations: [{
                  type: 'speech_metadata',
                  speaker: 'Liam',
                  style: 'warm and enthusiastic',
               }],
            },
         ],
      }],
      response_format: { type: 'audio' },
      generation_config: {
         speech_config: {
            speakers: [
               { speaker: 'Dr. Anya', voice: 'Kore' },
               { speaker: 'Liam', voice: 'Puck' },
            ],
         },
      },
   });

   if (interaction.output_audio?.data) {
      const audioBuffer = Buffer.from(interaction.output_audio.data, 'base64');
      fs.writeFileSync('out.wav', audioBuffer);
   }
}

await main();

REST

curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3.8-flash-tts",
    "input": [{
      "type": "user_input",
      "content": [
        {
          "type": "text",
          "text": "Wait... <short pause> look under that fallen log! Is that a blue-spotted salamander?",
          "annotations": [{
            "type": "speech_metadata",
            "speaker": "Dr. Anya",
            "style": "whispered urgently"
          }]
        },
        {
          "type": "text",
          "text": "<gasp> No way! <laugh> We'\''ve been searching for this species all season!",
          "annotations": [{
            "type": "speech_metadata",
            "speaker": "Liam",
            "style": "warm and enthusiastic"
          }]
        }
      ]
    }],
    "response_format": {
      "type": "audio"
    },
    "generation_config": {
      "speech_config": {
        "speakers": [
          { "speaker": "Dr. Anya", "voice": "Kore" },
          { "speaker": "Liam", "voice": "Puck" }
        ]
      }
    }
  }'

Génération de voix en streaming

Vous pouvez diffuser l'audio généré pendant sa synthèse en définissant stream: true. Contrairement aux requêtes unaires (qui renvoient un fichier WAV complet avec un en-tête RIFF), les requêtes de streaming renvoient par défaut des blocs bruts de PCM linéaire little-endian signé 16 bits sans en-tête (audio/l16, 24 kHz, mono). Les blocs audio peuvent ainsi être lus ou concaténés en continu sans en-tête de conteneur.

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
  }'

Formats de sortie audio

Les modèles TTS Gemini 3.8 utilisent différents formats audio par défaut selon que la requête est unaire ou en streaming :

  • Requêtes unaires (stream=False) : renvoient un fichier audio WAV (audio/wav) complet avec un en-tête RIFF standard (PCM 16 bits little-endian signé, mono, 24 kHz). Vous pouvez enregistrer les octets audio décodés directement dans un fichier .wav sans ajouter manuellement d'en-tête WAV.
  • Requêtes de flux (stream=True) : renvoient par défaut des blocs PCM linéaire brut sans en-tête (audio/l16) (PCM 24 kHz, mono, 16 bits signé little-endian). Les blocs peuvent ainsi être diffusés en streaming ou concaténés en continu sans en-tête de conteneur sur chaque bloc.

Pour demander un encodage audio ou un taux d'échantillonnage différent, configurez mime_type et éventuellement sample_rate dans response_format :

Format Valeur mime_type Description
WAV (valeur par défaut unaire) "audio/wav" Fichier WAV non compressé avec un en-tête RIFF (PCM 16 bits signé little-endian, mono, 24 kHz par défaut). Valeur par défaut pour les requêtes unaires.
PCM brut (L16) (paramètre par défaut pour le streaming) "audio/l16" Audio PCM linéaire 16 bits signé little-endian sans en-tête et non compressé (24 kHz, mono). Valeur par défaut pour les requêtes de streaming.
Mu-law "audio/mulaw" Audio encodé en G.711 mu-law 8 bits (couramment utilisé dans les systèmes de téléphonie/RVI nord-américains et japonais).
Loi A "audio/alaw" Audio encodé en G.711 loi A 8 bits (couramment utilisé dans les systèmes de téléphonie européens et internationaux).

Vous pouvez également spécifier sample_rate en Hertz (par exemple, 24000, 16000 ou 8000).

Python

import base64
from google import genai

client = genai.Client()

interaction = client.interactions.create(
    model="gemini-3.8-flash-tts",
    input=[{
        "type": "user_input",
        "content": [{
            "type": "text",
            "text": "Have a wonderful day!",
            "annotations": [{
                "type": "speech_metadata",
                "style": "cheerful and friendly",
            }],
        }],
    }],
    response_format={
        "type": "audio",
        "mime_type": "audio/l16",  # "audio/wav" (default), "audio/l16", "audio/mulaw", or "audio/alaw"
        "sample_rate": 24000,
    },
    generation_config={
        "speech_config": [
            {"voice": "Kore"},
        ]
    },
)

with open("out.pcm", "wb") as f:
    f.write(base64.b64decode(interaction.output_audio.data))

JavaScript

import * as fs from 'node:fs';
import {GoogleGenAI} from '@google/genai';

async function main() {
   const client = new GoogleGenAI({});

   const interaction = await client.interactions.create({
      model: 'gemini-3.8-flash-tts',
      input: [{
         type: 'user_input',
         content: [{
            type: 'text',
            text: 'Have a wonderful day!',
            annotations: [{
               type: 'speech_metadata',
               style: 'cheerful and friendly',
            }],
         }],
      }],
      response_format: {
         type: 'audio',
         mime_type: 'audio/l16', // 'audio/wav' (default), 'audio/l16', 'audio/mulaw', or 'audio/alaw'
         sample_rate: 24000,
      },
      generation_config: {
         speech_config: [
            { voice: 'Kore' },
         ],
      },
   });

   const audioBuffer = Buffer.from(interaction.output_audio.data, 'base64');
   fs.writeFileSync('out.pcm', audioBuffer);
}
await main();

REST

curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3.8-flash-tts",
    "input": [{
      "type": "user_input",
      "content": [{
        "type": "text",
        "text": "Have a wonderful day!",
        "annotations": [{
          "type": "speech_metadata",
          "style": "cheerful and friendly"
        }]
      }]
    }],
    "response_format": {
      "type": "audio",
      "mime_type": "audio/l16",
      "sample_rate": 24000
    },
    "generation_config": {
      "speech_config": [
        { "voice": "Kore" }
      ]
    }
  }'

Options vocales

Gemini 3.8 TTS permet de sélectionner ou de créer des voix de quatre manières :

  1. Voix Studio prédéfinies : 30 voix sélectionnées, listées dans le tableau suivant.
  2. Bibliothèque vocale étendue : des centaines de voix supplémentaires dans différentes langues, avec différents accents et différents archétypes de personnages sont disponibles à l'aide de client.voices.list() (GET /v1beta/voices).
  3. Conception vocale : générez un personnage vocal personnalisé à partir d'une description en langage naturel dans Google AI Studio ou à l'aide de POST /v1beta/voices (type="prompted", qui renvoie un ID voice_... persistant et un aperçu WAV sample_audio dans CreateVoice et GetVoice).
  4. Réplication vocale : répliquez la voix d'un locuteur à partir d'un fichier audio de référence et de consentement dans Google AI Studio ou à l'aide de POST /v1beta/voices (type="replicated", store=True persistant par défaut ou store=False sans état facultatif).

Limites et TTL des voix personnalisées

Type de voix Mode de stockage Quota / Limite Conservation (TTL)
Voix avec état (voice_..., incitées ou répliquées) store=True 200 voix par projet (partagées entre les voix générées par prompt et les voix répliquées) 1 an à compter de la dernière utilisation*
Clés vocales sans état (voicekey_..., répliquées) store=False Géré par le client 7 jours

* Extension de la valeur TTL : la période de conservation d'un an est réinitialisée chaque fois que la voix est utilisée activement (soit en synthétisant la voix, soit en l'utilisant comme voix de base pour le remixage). Les voix qui n'ont pas été utilisées pendant un an sont automatiquement supprimées.

Voix prédéfinies

Zephyr -- Lumineux Puck : Upbeat Charon : informatif
Kore -- Ferme Fenrir -- Excitable Leda -- Jeune
Orus -- Entreprise Aoede -- Breezy Callirrhoe : tranquille
Autonoe : Lumineux Enceladus -- Breathy Iapetus : Effacer
Umbriel : facile à vivre Algieba -- Smooth Despina -- Lisse
Erinome -- Clair Algenib -- Gravelly Rasalgethi : Informations
Laomedeia : Upbeat Achernar -- Soft Alnilam -- Firm
Schedar -- Even Gacrux : Contenu réservé aux adultes Pulcherrima -- Forward
Achird : amical Zubenelgenubi -- Casual Vindemiatrix : Doux
Sadachbia -- Lively Sadaltager -- Knowledgeable Sulafat -- Chaude

Bibliothèque de voix étendue et filtrage

En plus des 30 voix de studio présentées dans le tableau précédent, la bibliothèque vocale étendue propose des centaines de voix supplémentaires dans différentes langues, avec des accents régionaux, des personnages et des domaines variés. Vous pouvez parcourir, filtrer et écouter l'intégralité de la bibliothèque de voix de manière interactive dans Google AI Studio, ou l'interroger de manière programmatique à l'aide de client.voices.list() (GET /v1beta/voices, à l'aide de google-genai 2.25.0+ / @google/genai 2.24.0+).

ListVoices renvoie vos voix stockées personnalisées (de la plus récente à la plus ancienne), suivies des voix du catalogue prédéfini correspondant à vos critères de filtrage. Lorsque plusieurs valeurs sont transmises pour un filtre de liste, les voix correspondant à n'importe quelle valeur de ce filtre sont renvoyées (OR), tandis que les paramètres de filtre distincts se combinent avec AND :

Paramètre Type Description
language_code list[str] Balise(s) de langue BCP-47 (par exemple, ["en-US", "en-GB"]). Correspondance exacte non sensible à la casse.
region_code list[str] Code(s) de région ISO 3166-1 alpha-2 ou UN M.49 (par exemple, ["US", "GB"]).
accent list[str] Descripteur(s) d'accent régional (par exemple, ["American", "British"]).
gender list[str] Présentation du genre perçu ("female", "male" ou "neutral").
pitch list[str] Classification de la hauteur de la voix ("low", "medium" ou "high").
persona list[str] Persona vocal ou archétype de personnage (par exemple, ["Warm, Friendly"], ["Narrator"]).
contexts (context dans REST) list[str] Domaine d'utilisation optimal (par exemple, ["Audiobook", "Conversational", "News"]).
type (type_ en Python) list[str] Filtrer par source vocale : "prebuilt", "prompted" (Conception de voix) ou "replicated" (Réplication de voix).
search str Recherche de sous-chaîne en texte libre, non sensible à la casse, sur display_name et description.
page_size int Nombre maximal de voix renvoyées par page (par défaut 50, maximum 1000).
page_token str Jeton de response.next_page_token permettant d'extraire la page de résultats suivante.

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"

Langues disponibles

Les modèles TTS détectent automatiquement la langue de saisie. Gemini 3.8 Flash TTS (gemini-3.8-flash-tts) est compatible avec plus de 130 langues, et Gemini 3.8 Flash-Lite TTS (gemini-3.8-flash-lite-tts) est compatible avec plus de 100 langues :

Langue Gemini 3.8 Flash TTS Gemini 3.8 Flash-Lite TTS
Aceh (écriture arabe) ✔️ ✔️
Afrikaans ✔️ ✔️
Akan ✔️ ✔️
Amharique ✔️ ✔️
Arménien ✔️ ✔️
Assamais ✔️ ✔️
Awadhi ✔️ ✔️
Balinais ✔️ ✔️
Bengali ✔️ ✔️
Banjar (écriture arabe) ✔️ —
Banjar (alphabet latin) ✔️ ✔️
Bachkir ✔️ —
Basque ✔️ ✔️
Belarusian ✔️ ✔️
Bemba ✔️ —
Bhodjpouri ✔️ ✔️
Bosniaque ✔️ ✔️
Bouguis ✔️ ✔️
Bulgare ✔️ ✔️
Birman ✔️ —
Cantonais ✔️ ✔️
Catalan ✔️ ✔️
Cebuano ✔️ ✔️
Sorani ✔️ ✔️
Chhattisgarhi ✔️ ✔️
Chinois (écriture hans) ✔️ ✔️
Chinois (écriture Hant) ✔️ ✔️
Tatar de Crimée ✔️ —
Croate ✔️ ✔️
Tchèque ✔️ ✔️
Danois ✔️ ✔️
Néerlandais ✔️ ✔️
Dioula ✔️ —
Dzongkha ✔️ —
Arabe (Égypte) ✔️ ✔️
Anglais ✔️ ✔️
Estonien ✔️ ✔️
Tagalog ✔️ ✔️
Finnois ✔️ —
Français ✔️ ✔️
Galicien ✔️ ✔️
Ganda ✔️ ✔️
Géorgien ✔️ ✔️
Allemand ✔️ ✔️
Grec ✔️ ✔️
Guarani ✔️ —
Gujarati ✔️ ✔️
Créole haïtien ✔️ ✔️
Mongol khalkha ✔️ ✔️
Haoussa ✔️ ✔️
Hébreu ✔️ ✔️
Hindi ✔️ ✔️
Hongrois ✔️ ✔️
Islandais ✔️ ✔️
Igbo ✔️ —
Ilocano ✔️ ✔️
Indonésien ✔️ ✔️
Persan (Iran) ✔️ ✔️
Italien ✔️ ✔️
Japonais ✔️ ✔️
Javanais ✔️ ✔️
Kabyle ✔️ —
Kamba ✔️ ✔️
Kannada ✔️ ✔️
Cachemiri (alphabet arabe) ✔️ ✔️
Cachemiri (écriture Deva) ✔️ ✔️
Kazakh ✔️ ✔️
Khmer ✔️ ✔️
Kikuyu ✔️ ✔️
Kinyarwanda ✔️ ✔️
Kongo ✔️ ✔️
Coréen ✔️ ✔️
Kirghiz ✔️ ✔️
Laotien ✔️ ✔️
Latgalien ✔️ —
Lingala ✔️ ✔️
Lituanien ✔️ —
Luxembourgeois ✔️ —
Macédonien ✔️ ✔️
Magahi ✔️ ✔️
Maithili ✔️ ✔️
Malayalam ✔️ ✔️
Maltais ✔️ ✔️
Manipuri ✔️ ✔️
Marathi ✔️ ✔️
Minangkabau (écriture arabe) ✔️ ✔️
Minangkabau (alphabet latin) ✔️ —
Mizo ✔️ ✔️
Népalais (langue individuelle) ✔️ ✔️
Peul du Nigeria ✔️ ✔️
Azéri du Nord ✔️ ✔️
Sotho du Nord ✔️ ✔️
Ouzbek du Nord ✔️ ✔️
Norvégien bokmål ✔️ ✔️
Nynorsk (norvégien) ✔️ ✔️
Chichewa ✔️ ✔️
Occitan ✔️ —
Odia (langue individuelle) ✔️ ✔️
Pangasinan ✔️ —
Perse (Afghanistan) ✔️ ✔️
Polonais ✔️ ✔️
Portugais ✔️ ✔️
Panjabi ✔️ ✔️
Roumain ✔️ ✔️
Russe ✔️ ✔️
Santali ✔️ ✔️
Serbe ✔️ ✔️
Sindhî ✔️ —
Cingalais ✔️ ✔️
Slovaque ✔️ ✔️
Slovène ✔️ —
Somali ✔️ —
Azéri ✔️ ✔️
Pachto du Sud ✔️ ✔️
Sotho du Sud ✔️ —
Espagnol ✔️ ✔️
Arabe standard (écriture arabe) ✔️ ✔️
Arabe standard (alphabet latin) ✔️ ✔️
Letton standard ✔️ ✔️
Malais standard ✔️ ✔️
Swahili (langue individuelle) ✔️ —
Swati ✔️ —
Suédois ✔️ —
Tadjik ✔️ —
Tamoul ✔️ ✔️
Telugu ✔️ ✔️
Thaï ✔️ —
Tigrinya ✔️ —
Tosque albanais ✔️ —
Turc ✔️ ✔️
Ouïghour ✔️ —
Vietnamien ✔️ ✔️

Modèles compatibles

Modèle Locuteur unique Plusieurs locuteurs Conception vocale Réplication vocale
Gemini 3.8 Flash TTS (gemini-3.8-flash-tts) ✔️ ✔️ ✔️ ✔️
Gemini 3.8 Flash-Lite TTS (gemini-3.8-flash-lite-tts) ✔️ ✔️ ✔️ ✔️
Preview Gemini 3.1 Flash TTS ✔️ ✔️ — —
Gemini 2.5 Pro Preview TTS ✔️ ✔️ — —

Quand utiliser quel modèle

Les deux modèles Gemini 3.8 TTS partagent exactement le même schéma de l'API et le même format de requête, ce qui vous permet de passer de l'un à l'autre en modifiant un seul paramètre :

  • Utilisez Gemini 3.8 Flash TTS (gemini-3.8-flash-tts) lorsque la fidélité acoustique maximale, le jeu d'acteur nuancé et le contrôle expressif sont des priorités absolues. Il est idéal pour les travaux créatifs de qualité studio, les dialogues complexes entre plusieurs locuteurs, les tags d'éclats vocaux lourds, les prononciations difficiles, les dialectes régionaux ou minoritaires, et les narrations longues nécessitant une stabilité vocale et une tonalité de pièce solides.
  • Utilisez Gemini 3.8 Flash-Lite TTS (gemini-3.8-flash-lite-tts) comme solution rapide et économique pour remplacer gemini-3.1-flash-tts-preview. Il est optimisé pour la production en masse à grand volume, les cascades d'agents vocaux conversationnels, les fonctionnalités de lecture à voix haute, la réplication vocale fiable et la parole quotidienne à un seul locuteur dans les principales langues.

Guide de migration

Si vous migrez de gemini-3.1-flash-tts-preview ou de modèles Gemini TTS antérieurs vers Gemini 3.8 TTS :

  1. Déplacez les instructions au niveau du tour de parole vers speech_metadata : Gemini 3.8 TTS traite le texte d'entrée strictement comme une transcription textuelle. Déplacez les instructions de diffusion continue (style, comme "whispering", "out of breath" ou "speaking slowly") et les identifiants des intervenants (speaker) dans des annotations speech_metadata structurées au lieu d'intégrer les indications scéniques dans le texte de la transcription.
  2. Utilisez des balises intégrées entre crochets uniquement pour les événements vocaux ponctuels : conservez les vocalisations et les pauses momentanées non vocales dans la transcription à l'aide de crochets (par exemple, <laugh>, <sigh>, <cough>, <breath> ou <short pause>). Évitez les balises d'effets sonores (comme les applaudissements ou les bruits sourds) et placez les styles de diffusion dans speech_metadata.style.
  3. Spécifiez speaker à chaque tour de parole dans les requêtes à plusieurs locuteurs : chaque tour de parole d'une requête à plusieurs locuteurs doit inclure explicitement speaker dans speech_metadata correspondant à l'un des locuteurs configurés.
  4. Concevez des personas à l'avance avec la conception vocale : remplacez les blocs "Audio Profile" ou "Director's Notes" de plusieurs paragraphes par une voix personnalisée créée dans Conception vocale, puis transmettez cet ID voice_... dans vos requêtes TTS avec des chaînes style minimales ou vides.
  5. Tenir compte de la sortie WAV (audio/wav) par défaut pour les requêtes unaires : contrairement aux modèles TTS gemini-3.1-flash-tts-preview et antérieurs (qui renvoyaient par défaut un PCM brut audio/l16 sans en-tête), Gemini 3.8 TTS renvoie par défaut un fichier audio WAV (audio/wav) avec un en-tête RIFF standard pour les requêtes unaires.
    • Si votre code encapsulait auparavant des octets PCM bruts dans un en-tête WAV (par exemple, à l'aide du module wave ou de ffmpeg de Python), supprimez l'encapsulation manuelle de l'en-tête et écrivez les octets renvoyés directement dans un fichier .wav.
    • Si votre pipeline nécessite un fichier audio PCM brut, mu-law ou A-law sans en-tête, définissez explicitement response_format.mime_type sur "audio/l16", "audio/mulaw" ou "audio/alaw" (par exemple, {"response_format": {"type": "audio", "mime_type": "audio/l16"}} dans l'API Interactions ou AUDIO_L16 dans generateContent). Consultez la section Formats de sortie audio.

Guide sur les prompts

Les modèles Gemini 3.8 TTS traitent le texte saisi strictement comme une transcription mot pour mot. Contrairement aux modèles d'aperçu précédents, où les indications scéniques étaient intégrées en texte brut, Gemini 3.8 TTS sépare les indications durables au niveau du tour de parole (speech_metadata) des balises vocales intégrées ponctuelles.

Champ "Style" et balises intégrées

Répartissez vos instructions de performances par champ d'application :

  • Informations sur le débit au niveau du tour de parole (speech_metadata.style) : placez les attributs de débit soutenu (comme l'émotion, la prosodie, le rythme général ou le style de débit, comme "whispering", "out of breath", "muttering" ou "sarcastic") dans le champ style de speech_metadata. Pour créer un personnage et une performance stables tout au long des tours, concevez la persona à l'avance dans Conception de la voix et utilisez style uniquement pour les ajustements facultatifs au niveau du tour.
  • Événements ponctuels (balises intégrées) : insérez des bruits vocaux momentanés non parlés, des respirations ou des pauses dans la transcription à l'aide de crochets (<cough>, <breath>, <sigh>, <short pause>). Utilisez des crochets (<...>) pour une qualité audio optimale et tenez-vous-en aux vocalisations humaines plutôt qu'aux effets sonores non vocaux.
Champ d'application Où placer Exemples
Au niveau du tour (maintenu pendant le tour) speech_metadata.style "angry tone", "speaking rapidly", "out of breath", "whispers", "sarcastic"
À un moment précis (se produit à un mot spécifique) En ligne dans text (<...>) "<cough> Thank you all for coming tonight! <throat-clearing> As I was saying..."

Rythme et pauses

Vous pouvez contrôler le rythme et le silence à trois niveaux de précision :

  • Ponctuation et points de suspension : utilisez des virgules, des tirets (--) et des points de suspension (...) pour imiter les hésitations naturelles d'une conversation.
  • Balises de pause intégrées : insérez <short pause> ou <long pause> aux endroits exacts du script où un locuteur doit faire une pause : text Hold on, let me think... <short pause> Alright, I've got it.
  • Rythme au niveau du tour : définissez "style": "speaking rapidly" ou "style": "speaking slowly" dans speech_metadata pour contrôler le débit de parole sur l'ensemble du tour.

Prosodie et ton

Utilisez speech_metadata.style pour contrôler la prosodie, la hauteur et l'inflexion de la voix tout au long d'un tour de parole (par exemple, "style": "high pitch, cheerful and excited inflection" ou "style": "monotone and flat"). Si l'émotion ou la prosodie changent au milieu du dialogue, divisez le script en tours de parole distincts avec des valeurs style différentes pour chacun d'eux.

Mise en valeur

Mettez en majuscules certains mots de la transcription, en les combinant avec la ponctuation et les balises vocales intégrées, pour mettre l'accent sur les mots clés :

This is a VERY important point!
It was a VERY long day <sigh> ... nobody listens anymore.

Exclamations et sons non verbaux

Placez les vocalisations humaines non verbales sur la même ligne que le texte, en utilisant des chevrons (<...>) à l'endroit exact où le son doit se produire. Voici quelques exemples de tags vocaux recommandés :

<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>

Réponses minimales et chevauchement des voix

Dans un dialogue à plusieurs locuteurs, placez les réactions des auditeurs entre des barres verticales (|reaction|) au cours du tour de parole d'un locuteur pour créer des réactions naturelles ou des chevauchements de parole sans avoir à créer un tour de parole distinct pour chaque réaction.

  • Courts échanges en canal secondaire : superposez de brèves réactions de l'auditeur (|oh hmm|, |oh really?|, |absolutely|) pendant le tour de parole du participant actif :
    • Tour 1 (Locuteur A) : "So the launch is Thursday |oh hmm| Are we actually ready?"
    • Tour 2 (Intervenant B) : "Ready enough |oh really?| The last blocker cleared this morning."
    • Tour 3 (Intervenant A) : "Then let's ship it |absolutely| and watch the dashboards."
  • Discours qui se chevauchent et s'entrelacent : utilisez plusieurs segments de barre verticale pour simuler un discours simultané ou entrelacé entre deux locuteurs (fonctionne mieux avec gemini-3.8-flash-tts) :
    • Compte à rebours/refrain simultanés : "Let's surprise him on three |ok| ready?" suivi de "one. two. three. |happy| happy |birthday| birthday!"
    • Chevauchement complet des intervenants : "Hello |oh| there |my| it |goodness| must |gracious| be |would| almost |you| time |look| for |at that| dinner"

Cohérence entre les générations et ce qu'il faut éviter

Suivez ces consignes pour que l'identité vocale reste stable d'un tour à l'autre :

  • Concevez des personas en amont dans la conception vocale au lieu d'utiliser de longs blocs de style : Les longs paragraphes "Audio Profile" et les listes à puces "Director's Notes" hérités des modèles précédents sont la cause la plus fréquente de dérive vocale. Utilisez cette même intuition créative en amont dans la conception vocale pour générer une personnalité voice_... personnalisée persistante, puis transmettez cet ID vocal à vos appels TTS.
  • S'appuyer sur la référence vocale pour la stabilité (omettre les méta-instructions) : Les modèles Gemini 3.8 TTS sont entraînés à s'ancrer d'abord sur la référence audio. N'incluez pas d'instructions demandant au modèle de maintenir la voix stable (comme "do not switch speaker identity" ou "maintain identical timbre"). Un texte de requête supplémentaire augmente la dérive. Supprimez les instructions de style inutiles et laissez le modèle varier naturellement autour du point stable fourni par la référence vocale.
  • N'essayez pas de modifier les caractéristiques immuables du locuteur dans style : évitez d'indiquer l'âge, le genre, les noms ou les changements d'accent permanents dans speech_metadata.style. Choisissez plutôt une voix régionale dans la bibliothèque vocale étendue ou créez-en une avec Conception de voix.
  1. Créez le personnage une seule fois : créez votre personnage dans Voice Design ou sélectionnez une voix régionale dans la bibliothèque de voix étendue qui correspond à votre langue cible et à votre persona.
  2. Rédigez des transcriptions vocales naturelles avec des disfluences : pour un maximum de naturel, rédigez le text comme une transcription vocale réelle, y compris les disfluences et les hésitations naturelles de la conversation (par exemple, "Oh uh yeah I think... hm, so that's interesting").
  3. Testez d'abord la synthèse vocale simple : synthétisez votre transcription avec un champ style vide. La plupart des requêtes n'ont pas besoin d'instruction style.
  4. Ajoutez des prompts style courts uniquement pour les ajustements : ajoutez une chaîne style concise (comme "casual, friendly" ou "muttering, then reassuring") uniquement pour les tours qui nécessitent un ajustement de diffusion spécifique, et réutilisez cette chaîne courte exacte d'un tour à l'autre lorsque vous souhaitez une référence cohérente.

Agents vocaux et de dialogue multitours

Lorsque vous créez des agents vocaux conversationnels en temps réel ou des applications multitours :

  • Effectuez un appel TTS par tour à mesure que les fragments de texte du LLM arrivent.
  • Laissez le voice configuré (prédéfini, voice_... conçu ou voice_... / voicekey_... répliqué) porter l'identité du locuteur d'un tour à l'autre. Ne renvoyez jamais un long persona de caractères à chaque tour.
  • Laissez le champ style par tour vide ou envoyez une chaîne constante courte (telle que "casual, friendly") pour l'ensemble de la conversation.
  • Divisez les longues réponses des agents en tours plus courts au lieu d'utiliser des invites de style plus fortes.

Limites

  • Les modèles TTS acceptent les entrées textuelles uniquement et génèrent des sorties audio uniquement.
  • La génération multilocuteur à requête unique (speech_config.speakers) est compatible avec un maximum de deux locuteurs utilisant des voix prédéfinies. Pour combiner des voix personnalisées (voice_...) ou répliquées (voice_... / voicekey_...) dans un dialogue à plusieurs personnages, synthétisez le tour de parole de chaque locuteur individuellement. Étant donné que les requêtes unaires renvoient audio/wav avec un en-tête RIFF de 44 octets par défaut, demandez du PCM brut ({"type": "audio", "mime_type": "audio/l16"}) ou supprimez l'en-tête WAV de chaque tour avant de concaténer les images audio PCM de 24 kHz.
  • Limites de stockage et TTL des voix personnalisées :
    • Voix avec état (store=True, guidées ou répliquées) : maximum de 200 voix par projet avec une valeur TTL d'un an (Time To Live).
    • Clés vocales sans état (store=False, voicekey_...) : TTL de 7 jours (Time To Live).
  • Consultez la section Langues acceptées pour connaître les langues disponibles.

Étape suivante