Intégration LiveKit
Intégration LiveKit
Connectez une salle LiveKit à Speech Engine à l’aide d’un worker LiveKit Agents.
Ce guide explique comment utiliser ElevenLabs Speech Engine comme couche vocale pour une salle LiveKit. Un worker LiveKit Agents rejoint la salle en tant que participant, s’abonne à la piste audio de l’utilisateur, ouvre un WebSocket vers Speech Engine et publie l’audio synthétisé par Speech Engine dans la salle sous la forme de sa propre piste.
Architecture
Speech Engine accepte deux types de connexions WebSocket :
- Le WebSocket brain, auquel l’API ElevenLabs se connecte. Votre serveur l’exécute avec le SDK Speech Engine (
engine.serve()/engine.attach()) et reçoit les transcriptions auxquelles répondre. - Le WebSocket de conversation, auquel les clients se connectent. Les navigateurs se connectent via un jeton WebRTC ; les clients non basés sur un navigateur, comme un worker LiveKit Agents, se connectent via une URL signée et diffusent de l’audio PCM brut dans les deux sens.
Le worker LiveKit utilise la seconde connexion. Il agit comme un « client » de Speech Engine pour le compte des participants de la salle LiveKit.
Le serveur brain reste identique à celui du guide de démarrage rapide de Speech Engine, le worker LiveKit remplace le navigateur comme source audio, mais la logique LLM reste la même.
Quand utiliser ce modèle
Utilisez le pont LiveKit lorsque la salle fait elle-même partie de l’expérience :
- Sessions multiparticipants où les utilisateurs parlent avec l’agent en même temps
- Déploiements LiveKit existants pour lesquels changer de transport perturberait les clients
- Agents vocaux partageant une salle avec le partage d’écran, la vidéo ou le chat textuel
- Appels distribués de SIP vers LiveKit qui nécessitent un agent IA en ligne
Si vous avez uniquement besoin d’une boucle vocale entre le navigateur et Speech Engine, sans autres participants, le client WebRTC du guide de démarrage rapide de Speech Engine est plus simple : Speech Engine communique directement avec le navigateur via WebRTC, sans nécessiter de salle LiveKit.
Prérequis
- Un projet LiveKit, soit LiveKit Cloud, soit un serveur auto-hébergé. Le worker nécessite
LIVEKIT_URL,LIVEKIT_API_KEYetLIVEKIT_API_SECRET. - Un ElevenLabs Speech Engine. Suivez le guide de démarrage rapide de Speech Engine pour en créer un et exécuter le serveur brain.
- Python 3.9+ ou Node.js 18+.
Le worker de pont Node utilise
@livekit/rtc-node, actuellement disponible en
Developer Preview. Pour les déploiements en production, privilégiez le worker Python.
Configurer les formats audio de Speech Engine
AudioStream de LiveKit rééchantillonne les pistes Opus entrantes à la fréquence d’échantillonnage PCM demandée, ce qui vous permet de les faire correspondre directement à l’entrée de Speech Engine. Mettez à jour Speech Engine pour accepter du PCM 16 kHz en entrée ASR et produire du PCM 24 kHz en sortie TTS.
Le PCM de Speech Engine est partout au format 16 bits signé little-endian. Consultez la référence des formats audio pour connaître les autres fréquences prises en charge.
Créer le worker de pont
Le worker est un processus de longue durée qui se connecte à votre serveur LiveKit, attend les tâches, rejoint les salles attribuées et transfère l’audio entre la salle et Speech Engine.
Créer une URL signée Speech Engine
Le worker demande une URL signée de courte durée pour le WebSocket de conversation Speech Engine. L’URL signée intègre l’ID du moteur et une signature à usage unique, afin que le worker puisse ouvrir le WebSocket sans exposer votre clé API.
Définir le point d’entrée du worker
Chaque fois que le worker est envoyé dans une salle, son point d’entrée s’exécute. Le point d’entrée se connecte à la salle, ouvre un WebSocket de conversation Speech Engine et démarre deux ponts audio : l’un pour l’audio de l’appelant envoyé vers Speech Engine, l’autre pour l’audio synthétisé reçu en retour.
Le worker filtre son propre audio publié dans le gestionnaire track_subscribed en le comparant à l’identité du participant local. Sans cette vérification, le worker tenterait de renvoyer son propre audio synthétisé à Speech Engine.
Deux détails d’ordre sont importants pour garantir le bon fonctionnement :
- Moment d’enregistrement de l’écouteur :
TrackSubscribedest enregistré avantctx.connect(). LiveKit s’abonne automatiquement aux pistes existantes lors de la négociation de connexion, et un écouteur enregistré après peut manquer l’événement. La pompe audio attend uneFuture/Promisepour le WebSocket Speech Engine afin de pouvoir s’abonner immédiatement et transférer l’audio dès l’ouverture de la connexion. - TypeScript uniquement, sérialisation de la capture :
AudioSource.captureFramede@livekit/rtc-nodegénère une erreurInvalidStates’il est appelé simultanément. Le gestionnaire TypeScript sérialise les captures avec une chaîne de promesses. La boucle uniqueasync for el_to_roomde Python est naturellement séquentielle et n’en a pas besoin.
Envoyer le worker dans une salle
Puisque le worker possède un agent_name, il utilise un envoi explicite : il rejoint uniquement les salles lorsque votre backend le lui demande. Le modèle le plus simple consiste à inclure un RoomAgentDispatch dans le jeton d’accès LiveKit que le navigateur utilise pour se connecter.
Lorsqu’un navigateur utilise ce jeton pour créer ou rejoindre une salle, LiveKit envoie automatiquement le worker de pont dans cette même salle.
Se connecter depuis le navigateur
Le navigateur n’a besoin que du client LiveKit standard, il n’interagit pas directement avec Speech Engine.
Lorsque le bouton est sélectionné, le navigateur récupère un jeton LiveKit, rejoint la salle avec le microphone activé et commence à recevoir la piste audio de l’agent. Le worker est envoyé, ouvre sa session Speech Engine et transfère l’audio dans les deux sens.
Référence des formats audio
Speech Engine prend en charge les formats audio suivants. Configurez-les sur le moteur via asr.user_input_audio_format et tts.agent_output_audio_format.
AudioStream et AudioSource dans LiveKit gèrent le rééchantillonnage pour vous : vous pouvez demander n’importe quelle fréquence d’échantillonnage à AudioStream, et le SDK effectue la conversion à partir de la piste Opus sous-jacente de 48 kHz.
Points à considérer pour la production
- Envoi explicite : définissez toujours
agent_name/agentNamedansWorkerOptions. L’envoi automatique déclenche le worker pour chaque salle créée dans votre projet LiveKit, ce qui est rarement souhaitable. - Authentification du serveur brain : définissez un secret partagé sur Speech Engine et vérifiez-le dans votre serveur brain afin que seul Speech Engine puisse atteindre votre point de terminaison :
Le serveur brain vérifie ensuite
request.headers["x-api-key"]avant d’accepter la mise à niveau WebSocket. - Serveur de jetons : créez les jetons LiveKit et Speech Engine côté serveur. N’exposez jamais
LIVEKIT_API_SECRETouELEVENLABS_API_KEYau navigateur. - Hygiène de la boucle d’événements : évitez les tâches gourmandes en CPU dans la boucle d’événements du worker.
AudioSource.capture_frameet l’itération deAudioStreamsont sensibles au temps ; des appels synchrones longs retarderont ou ignoreront des événements d’interruption. Utilisezasyncio.to_thread()(Python) ouworker_threads(Node) pour les tâches bloquantes. - Arrêt : enregistrez
ctx.add_shutdown_callback/ctx.addShutdownCallbackpour fermer proprement le WebSocket ElevenLabs. Par défaut, la salle, et la tâche, sont terminées lorsque le dernier participant non agent quitte la salle.