Get started with Live API

L'API Live permet des interactions vocales et vidéo en temps réel et à faible latence avec Gemini. Elle traite des flux audio, vidéo ou textuels continus pour fournir des réponses vocales immédiates et semblables à celles d'un humain, créant ainsi une expérience de conversation 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 d'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 aide à vous lancer avec des exemples et des exemples de code de base.

Exemples d'applications

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

Intégration de partenaires

Si vous préférez un processus de développement plus simple, vous pouvez utiliser Daily ou LiveKit. 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 avec l'API Live, vous devez prendre deux décisions importantes: choisir un modèle et 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 la plus réaliste, ainsi que de meilleures performances multilingues. Il permet également de bénéficier de fonctionnalités avancées telles que le dialogue affectif (sensible aux émotions), l'audio proactif (le modèle peut décider d'ignorer ou de répondre à certaines entrées) et la pensée. 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 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 en demi-cascade 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:

  • De 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 transfère ensuite à l'API Live.
  • Client-serveur: votre code 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 bon format et enregistre les données reçues au format WAV.

Vous pouvez envoyer des données audio en les convertissant au format PCM 16 bits, 16 kHz, mono, et vous pouvez les recevoir en définissant AUDIO comme modalité de réponse. La sortie utilise un taux 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