Get started with Live API

L'API Live permet des interactions vocales et vidéo en temps réel et à faible latence avec Gemini. Il traite les flux continus d'audio, de vidéo ou de texte pour fournir des réponses vocales immédiates et semblables à celles d'un humain, créant ainsi une expérience conversationnelle naturelle pour vos utilisateurs.

Présentation de l'API Live

L'API Live propose un ensemble complet de fonctionnalités telles que la détection de l'activité vocale, l'utilisation d'outils et l'appel de fonctions, la gestion des sessions (pour gérer les conversations de longue durée) et les jetons éphémères (pour une authentification sécurisée côté client).

Cette page vous permet de vous familiariser avec des exemples et des exemples de code de base.

Exemples d'applications

Consultez les exemples d'applications suivants qui illustrent l'utilisation de l'API Live pour des cas d'utilisation de bout en bout :

  • Application de démarrage audio en direct sur AI Studio, utilisant des bibliothèques JavaScript pour se connecter à l'API Live et diffuser de l'audio bidirectionnel via votre micro et vos haut-parleurs.
  • Cookbook Python de l'API Live utilisant Pyaudio pour se connecter à l'API Live.

Intégration de partenaires

Si vous préférez un processus de développement plus simple, vous pouvez utiliser Daily, LiveKit ou Voximplant. Il s'agit de plates-formes partenaires tierces qui ont déjà intégré l'API Gemini Live via le protocole WebRTC pour simplifier le développement d'applications audio et vidéo en temps réel.

Avant de commencer à créer

Avant de commencer à créer des applications avec l'API Live, vous devez prendre deux décisions importantes : choisir un modèle et choisir une approche d'implémentation.

Choisir une architecture de génération audio

Si vous créez un cas d'utilisation basé sur l'audio, le modèle que vous choisissez détermine l'architecture de génération audio utilisée pour créer la réponse audio :

  • Audio natif : cette option offre la voix la plus naturelle et réaliste, ainsi que de meilleures performances multilingues. Il permet également d'utiliser des fonctionnalités avancées telles que le dialogue affectif (sensible aux émotions), l'audio proactif (où le modèle peut décider d'ignorer ou de répondre à certaines entrées) et la "réflexion". L'audio natif est compatible avec les modèles audio natifs suivants :
    • gemini-2.5-flash-preview-native-audio-dialog
    • gemini-2.5-flash-exp-native-audio-thinking-dialog
  • Audio en demi-cascade : cette option utilise une architecture de modèle en cascade (entrée audio native et sortie de synthèse vocale). Il offre de meilleures performances et une meilleure fiabilité dans les environnements de production, en particulier avec l'utilisation d'outils. L'audio semi-cascadé est compatible avec les modèles suivants :
    • gemini-live-2.5-flash-preview
    • gemini-2.0-flash-live-001

Choisir une approche d'implémentation

Lorsque vous intégrez l'API Live, vous devez choisir l'une des approches d'implémentation suivantes :

  • Serveur à serveur : votre backend se connecte à l'API Live à l'aide de WebSockets. En règle générale, votre client envoie des données de flux (audio, vidéo, texte) à votre serveur, qui les transmet ensuite à l'API Live.
  • Client vers serveur : votre code de frontend se connecte directement à l'API Live à l'aide de WebSockets pour diffuser des données, en contournant votre backend.

Commencer

Cet exemple lit un fichier WAV, l'envoie au format approprié et enregistre les données reçues en tant que fichier WAV.

Vous pouvez envoyer de l'audio en le convertissant au format PCM 16 bits, 16 kHz, mono. Vous pouvez recevoir de l'audio en définissant AUDIO comme modalité de réponse. La sortie utilise une fréquence d'échantillonnage de 24 kHz.

Python

# Test file: https://storage.googleapis.com/generativeai-downloads/data/16000.wav
# Install helpers for converting files: pip install librosa soundfile
import asyncio
import io
from pathlib import Path
import wave
from google import genai
from google.genai import types
import soundfile as sf
import librosa

client = genai.Client()

# Half cascade model:
# model = "gemini-live-2.5-flash-preview"

# Native audio output model:
model = "gemini-2.5-flash-preview-native-audio-dialog"

config = {
  "response_modalities": ["AUDIO"],
  "system_instruction": "You are a helpful assistant and answer in a friendly tone.",
}

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:

        buffer = io.BytesIO()
        y, sr = librosa.load("sample.wav", sr=16000)
        sf.write(buffer, y, sr, format='RAW', subtype='PCM_16')
        buffer.seek(0)
        audio_bytes = buffer.read()

        # If already in correct format, you can use this:
        # audio_bytes = Path("sample.pcm").read_bytes()

        await session.send_realtime_input(
            audio=types.Blob(data=audio_bytes, mime_type="audio/pcm;rate=16000")
        )

        wf = wave.open("audio.wav", "wb")
        wf.setnchannels(1)
        wf.setsampwidth(2)
        wf.setframerate(24000)  # Output is 24kHz

        async for response in session.receive():
            if response.data is not None:
                wf.writeframes(response.data)

            # Un-comment this code to print audio data info
            # if response.server_content.model_turn is not None:
            #      print(response.server_content.model_turn.parts[0].inline_data.mime_type)

        wf.close()

if __name__ == "__main__":
    asyncio.run(main())

JavaScript

// Test file: https://storage.googleapis.com/generativeai-downloads/data/16000.wav
import { GoogleGenAI, Modality } from '@google/genai';
import * as fs from "node:fs";
import pkg from 'wavefile';  // npm install wavefile
const { WaveFile } = pkg;

const ai = new GoogleGenAI({});
// WARNING: Do not use API keys in client-side (browser based) applications
// Consider using Ephemeral Tokens instead
// More information at: https://ai.google.dev/gemini-api/docs/ephemeral-tokens

// Half cascade model:
// const model = "gemini-live-2.5-flash-preview"

// Native audio output model:
const model = "gemini-2.5-flash-preview-native-audio-dialog"

const config = {
  responseModalities: [Modality.AUDIO], 
  systemInstruction: "You are a helpful assistant and answer in a friendly tone."
};

async function live() {
    const responseQueue = [];

    async function waitMessage() {
        let done = false;
        let message = undefined;
        while (!done) {
            message = responseQueue.shift();
            if (message) {
                done = true;
            } else {
                await new Promise((resolve) => setTimeout(resolve, 100));
            }
        }
        return message;
    }

    async function handleTurn() {
        const turns = [];
        let done = false;
        while (!done) {
            const message = await waitMessage();
            turns.push(message);
            if (message.serverContent && message.serverContent.turnComplete) {
                done = true;
            }
        }
        return turns;
    }

    const session = await ai.live.connect({
        model: model,
        callbacks: {
            onopen: function () {
                console.debug('Opened');
            },
            onmessage: function (message) {
                responseQueue.push(message);
            },
            onerror: function (e) {
                console.debug('Error:', e.message);
            },
            onclose: function (e) {
                console.debug('Close:', e.reason);
            },
        },
        config: config,
    });

    // Send Audio Chunk
    const fileBuffer = fs.readFileSync("sample.wav");

    // Ensure audio conforms to API requirements (16-bit PCM, 16kHz, mono)
    const wav = new WaveFile();
    wav.fromBuffer(fileBuffer);
    wav.toSampleRate(16000);
    wav.toBitDepth("16");
    const base64Audio = wav.toBase64();

    // If already in correct format, you can use this:
    // const fileBuffer = fs.readFileSync("sample.pcm");
    // const base64Audio = Buffer.from(fileBuffer).toString('base64');

    session.sendRealtimeInput(
        {
            audio: {
                data: base64Audio,
                mimeType: "audio/pcm;rate=16000"
            }
        }

    );

    const turns = await handleTurn();

    // Combine audio data strings and save as wave file
    const combinedAudio = turns.reduce((acc, turn) => {
        if (turn.data) {
            const buffer = Buffer.from(turn.data, 'base64');
            const intArray = new Int16Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / Int16Array.BYTES_PER_ELEMENT);
            return acc.concat(Array.from(intArray));
        }
        return acc;
    }, []);

    const audioBuffer = new Int16Array(combinedAudio);

    const wf = new WaveFile();
    wf.fromScratch(1, 24000, '16', audioBuffer);  // output is 24kHz
    fs.writeFileSync('audio.wav', wf.toBuffer());

    session.close();
}

async function main() {
    await live().catch((e) => console.error('got error', e));
}

main();

Étape suivante