Integração com LiveKit
Integração com LiveKit
Este guia mostra como usar o Speech Engine da ElevenLabs como a camada de voz de uma sala do LiveKit. Um worker do LiveKit Agents entra na sala como participante, assina a faixa de áudio do usuário, abre um WebSocket para o Speech Engine e publica o áudio sintetizado pelo Speech Engine de volta na sala como sua própria faixa.
Arquitetura
O Speech Engine aceita dois tipos de conexões WebSocket:
- O WebSocket do cérebro, ao qual a API da ElevenLabs se conecta. Seu servidor o executa com o SDK do Speech Engine (
engine.serve()/engine.attach()) e recebe transcrições para responder. - O WebSocket da conversa, ao qual os clientes se conectam. Os navegadores se conectam por um token WebRTC; clientes que não são navegadores (como um worker do LiveKit Agents) se conectam por uma URL assinada e transmitem áudio PCM bruto em ambas as direções.
O worker do LiveKit usa a segunda conexão. Ele atua como um “cliente” do Speech Engine em nome dos participantes da sala do LiveKit.
O servidor do cérebro não muda em relação ao guia rápido do Speech Engine — o worker do LiveKit substitui o navegador como fonte de áudio, mas a lógica do LLM continua a mesma.
Quando usar este padrão
Use a ponte com o LiveKit quando a própria sala fizer parte da experiência:
- Sessões com vários participantes, em que os usuários conversam com o agente ao mesmo tempo
- Implantações existentes do LiveKit, nas quais trocar o transporte interromperia os clientes
- Agentes de voz que compartilham uma sala com compartilhamento de tela, vídeo ou chat de texto
- Chamadas SIP para LiveKit distribuídas que precisam de um agente de IA na chamada
Se você só precisa de um loop de voz do navegador para o Speech Engine, sem outros participantes, o cliente WebRTC no guia rápido do Speech Engine é mais simples — o Speech Engine se comunica diretamente com o navegador via WebRTC, sem precisar de uma sala do LiveKit.
Pré-requisitos
- Um projeto do LiveKit (LiveKit Cloud ou um servidor auto-hospedado). O worker precisa de
LIVEKIT_URL,LIVEKIT_API_KEYeLIVEKIT_API_SECRET. - Um Speech Engine da ElevenLabs. Siga o guia rápido do Speech Engine para criar um e executar o servidor do cérebro.
- Python 3.9+ ou Node.js 18+.
O worker de ponte em Node usa
@livekit/rtc-node, que está atualmente em
Developer Preview. Para implantações em produção, prefira o worker em Python.
Configure os formatos de áudio do Speech Engine
O AudioStream do LiveKit reamostra faixas Opus recebidas para qualquer taxa de amostragem PCM que você solicitar, então é possível corresponder diretamente à entrada do Speech Engine. Atualize o Speech Engine para aceitar PCM de 16 kHz como entrada de ASR e gerar PCM de 24 kHz como saída de TTS.
O PCM do Speech Engine é sempre assinado, de 16 bits e little-endian. Consulte a referência de formatos de áudio para ver outras taxas compatíveis.
Crie o worker de ponte
O worker é um processo de longa execução que se conecta ao seu servidor LiveKit, aguarda tarefas, entra nas salas atribuídas e faz a ponte de áudio entre a sala e o Speech Engine.
Gere uma URL assinada do Speech Engine
O worker solicita uma URL assinada de curta duração para o WebSocket de conversa do Speech Engine. A URL assinada inclui o ID do mecanismo e uma assinatura de uso único, para que o worker possa abrir o WebSocket sem expor sua chave de API.
Defina o ponto de entrada do worker
Sempre que o worker é enviado a uma sala, seu ponto de entrada é executado. O ponto de entrada se conecta à sala, abre um WebSocket de conversa do Speech Engine e inicia duas pontes de áudio: uma para o áudio do interlocutor que vai para o Speech Engine e outra para o áudio sintetizado que retorna.
O worker filtra o próprio áudio publicado no manipulador track_subscribed, comparando-o à identidade do participante local. Sem essa verificação, o worker tentaria enviar seu próprio áudio sintetizado de volta ao Speech Engine.
Dois detalhes de ordem são importantes para o funcionamento correto:
- Momento do listener:
TrackSubscribedé registrado antes dectx.connect(). O LiveKit assina automaticamente as faixas existentes durante o handshake de conexão, e um listener registrado depois pode não receber o evento. A bomba de áudio aguarda umFuture/Promisepelo WebSocket do Speech Engine para poder assinar imediatamente e encaminhar o áudio assim que a conexão é aberta. - Somente TypeScript — serialização de captura: o
AudioSource.captureFramede@livekit/rtc-nodelançaInvalidStatese for chamado simultaneamente. O manipulador TypeScript serializa as capturas com uma cadeia de promises. O loop únicoasync for el_to_roomdo Python é naturalmente sequencial e não precisa disso.
Envie o worker para uma sala
Como o worker tem um agent_name, ele usa envio explícito — só entra em salas quando seu backend solicita. O padrão mais simples é incluir um RoomAgentDispatch no token de acesso do LiveKit usado pelo navegador para se conectar.
Quando um navegador usa esse token para criar ou entrar em uma sala, o LiveKit envia automaticamente o worker de ponte para a mesma sala.
Conecte-se pelo navegador
O navegador só precisa do cliente padrão do LiveKit — ele não interage diretamente com o Speech Engine.
Quando o botão é clicado, o navegador busca um token do LiveKit, entra na sala com o microfone ativado e começa a receber a faixa de áudio do agente. O worker é enviado, abre sua sessão do Speech Engine e faz a ponte de áudio nas duas direções.
Referência de formatos de áudio
O Speech Engine é compatível com os seguintes formatos de áudio. Configure-os no mecanismo usando asr.user_input_audio_format e tts.agent_output_audio_format.
AudioStream e AudioSource no LiveKit fazem a reamostragem para você — é possível solicitar qualquer taxa de amostragem ao AudioStream, e o SDK converte a partir da faixa Opus subjacente de 48 kHz.
Considerações para produção
- Despacho explícito: Sempre defina
agent_name/agentNameemWorkerOptions. O despacho automático aciona o worker para cada sala criada no seu projeto LiveKit, o que raramente é o desejado. - Autenticação do servidor de raciocínio: Defina um segredo compartilhado no Speech Engine e verifique-o no seu servidor de raciocínio para que apenas o Speech Engine possa acessar seu endpoint:
Em seguida, o servidor de raciocínio verifica
request.headers["x-api-key"]antes de aceitar a atualização do WebSocket. - Servidor de tokens: Gere tokens do LiveKit e do Speech Engine no servidor. Nunca exponha
LIVEKIT_API_SECRETnemELEVENLABS_API_KEYno navegador. - Higiene do loop de eventos: Mantenha tarefas que exigem CPU fora do loop de eventos do worker. A iteração de
AudioSource.capture_frameeAudioStreamé sensível ao tempo; chamadas síncronas longas atrasarão ou descartarão eventos de interrupção. Useasyncio.to_thread()(Python) ouworker_threads(Node) para tarefas bloqueantes. - Encerramento: Registre
ctx.add_shutdown_callback/ctx.addShutdownCallbackpara fechar corretamente o WebSocket da ElevenLabs. Por padrão, a sala (e o trabalho) é encerrada quando o último participante que não é agente sai.