Integrazione LiveKit
Questa guida spiega come usare ElevenLabs Speech Engine come livello vocale per una stanza LiveKit. Un worker LiveKit Agents entra nella stanza come partecipante, si iscrive alla traccia audio dell’utente, apre un WebSocket verso Speech Engine e pubblica l’audio sintetizzato da Speech Engine nella stanza come propria traccia.
Architettura
Speech Engine accetta due tipi di connessioni WebSocket:
- Il WebSocket brain a cui si connette l’API ElevenLabs. Il tuo server lo esegue con l’SDK Speech Engine (
engine.serve()/engine.attach()) e riceve trascrizioni a cui rispondere. - Il WebSocket di conversazione a cui si connettono i client. I browser si connettono tramite un token WebRTC; i client non browser (come un worker LiveKit Agents) si connettono tramite un URL firmato e trasmettono audio PCM raw in entrambe le direzioni.
Il worker LiveKit usa la seconda connessione. Agisce come “client” di Speech Engine per conto dei partecipanti nella stanza LiveKit.
Il server brain rimane invariato rispetto alla guida rapida di Speech Engine: il worker LiveKit sostituisce il browser come sorgente audio, ma la logica LLM resta la stessa.
Quando usare questo schema
Usa il bridge LiveKit quando la stanza stessa fa parte dell’esperienza:
- Sessioni con più partecipanti in cui gli utenti parlano con l’agente insieme
- Implementazioni LiveKit esistenti in cui cambiare trasporto interromperebbe i client
- Agenti vocali che condividono una stanza con condivisione schermo, video o chat testuale
- Chiamate inviate da SIP a LiveKit che richiedono un agente IA in linea
Se ti serve solo un loop vocale dal browser a Speech Engine senza altri partecipanti, il client WebRTC nella guida rapida di Speech Engine è più semplice: Speech Engine comunica direttamente via WebRTC con il browser, senza bisogno di una stanza LiveKit.
Prerequisiti
- Un progetto LiveKit (LiveKit Cloud o un server ospitato autonomamente). Il worker richiede
LIVEKIT_URL,LIVEKIT_API_KEYeLIVEKIT_API_SECRET. - Un ElevenLabs Speech Engine. Segui la guida rapida di Speech Engine per crearne uno ed eseguire il server brain.
- Python 3.9+ o Node.js 18+.
Il worker bridge Node usa
@livekit/rtc-node, attualmente in
Developer Preview. Per le implementazioni in produzione, preferisci il worker Python.
Configura i formati audio di Speech Engine
AudioStream di LiveKit ricampiona le tracce Opus in entrata a qualsiasi frequenza di campionamento PCM richiesta, quindi puoi adattarla direttamente all’input di Speech Engine. Aggiorna Speech Engine affinché accetti PCM a 16 kHz per l’input ASR ed emetta PCM a 24 kHz per l’output TTS.
Il PCM di Speech Engine è sempre little-endian con segno a 16 bit. Consulta il riferimento dei formati audio per le altre frequenze supportate.
Crea il worker bridge
Il worker è un processo a lunga esecuzione che si connette al tuo server LiveKit, attende i job, entra nelle stanze assegnate e fa da ponte per l’audio tra la stanza e Speech Engine.
Genera un URL firmato Speech Engine
Il worker richiede un URL firmato a breve durata per il WebSocket di conversazione Speech Engine. L’URL firmato incorpora l’ID del motore e una firma monouso, così il worker può aprire il WebSocket senza esporre la tua chiave API.
Definisci l'entrypoint del worker
Ogni volta che il worker viene inviato a una stanza, viene eseguito il suo entrypoint. L’entrypoint si connette alla stanza, apre un WebSocket di conversazione Speech Engine e avvia due bridge audio: uno per l’audio del chiamante diretto a Speech Engine e uno per l’audio sintetizzato di ritorno.
Il worker esclude il proprio audio pubblicato nell’handler track_subscribed confrontandolo con l’identità del partecipante locale. Senza questo controllo, il worker tenterebbe di inviare il proprio audio sintetizzato di nuovo a Speech Engine.
Due dettagli sull’ordinamento sono importanti per la correttezza:
- Tempistica del listener:
TrackSubscribedviene registrato prima dictx.connect(). LiveKit si iscrive automaticamente alle tracce esistenti durante l’handshake della connessione e un listener registrato successivamente potrebbe non ricevere l’evento. La pompa audio attende unFuture/Promiseper il WebSocket Speech Engine, così può iscriversi immediatamente e inoltrare l’audio non appena la connessione viene aperta. - Solo TypeScript — serializzazione dell’acquisizione:
AudioSource.captureFramedi@livekit/rtc-nodegeneraInvalidStatese viene chiamato contemporaneamente. L’handler TypeScript serializza le acquisizioni con una catena di promise. Il singolo loopasync for el_to_roomdi Python è naturalmente sequenziale e non ne ha bisogno.
Invia il worker a una stanza
Poiché il worker ha un agent_name, usa l’invio esplicito: entra nelle stanze solo quando il tuo backend glielo indica. Lo schema più semplice consiste nell’includere un RoomAgentDispatch nel token di accesso LiveKit che il browser usa per connettersi.
Quando un browser usa questo token per creare o entrare in una stanza, LiveKit invia automaticamente il worker bridge nella stessa stanza.
Connettiti dal browser
Il browser necessita solo del client LiveKit standard: non interagisce direttamente con Speech Engine.
Quando si fa clic sul pulsante, il browser recupera un token LiveKit, entra nella stanza con il microfono abilitato e inizia a ricevere la traccia audio dell’agente. Il worker viene inviato, apre la sua sessione Speech Engine e fa da ponte per l’audio in entrambe le direzioni.
Riferimento dei formati audio
Speech Engine supporta i seguenti formati audio. Configurali sul motore tramite asr.user_input_audio_format e tts.agent_output_audio_format.
AudioStream e AudioSource in LiveKit gestiscono il ricampionamento per te: puoi richiedere qualsiasi frequenza di campionamento a AudioStream e l’SDK converte dalla traccia Opus sottostante a 48 kHz.
Considerazioni per la produzione
- Invio esplicito: imposta sempre
agent_name/agentNamesuWorkerOptions. L’invio automatico attiva il worker per ogni stanza creata nel tuo progetto LiveKit, cosa che raramente desideri. - Autenticazione del server brain: imposta un segreto condiviso su Speech Engine e verificalo nel tuo server brain, così solo Speech Engine può raggiungere il tuo endpoint:
Il server brain verifica quindi
request.headers["x-api-key"]prima di accettare l’upgrade WebSocket. - Server dei token: genera i token LiveKit e Speech Engine lato server. Non esporre mai
LIVEKIT_API_SECREToELEVENLABS_API_KEYal browser. - Igiene dell’event loop: non eseguire operazioni vincolate alla CPU nell’event loop del worker.
AudioSource.capture_framee l’iterazione diAudioStreamsono sensibili ai tempi; lunghe chiamate sincrone ritarderanno o scarteranno gli eventi di interruzione. Usaasyncio.to_thread()(Python) oworker_threads(Node) per le operazioni bloccanti. - Arresto: registra
ctx.add_shutdown_callback/ctx.addShutdownCallbackper chiudere correttamente il WebSocket ElevenLabs. Per impostazione predefinita, la stanza (e il job) viene terminata quando l’ultimo partecipante non agente esce.