@zapo-js/voip é o plugin oficial de chamadas de voz para zapo-js. Ele se apoia no sistema de plugins, expõe um WaVoipCoordinator em client.voip e emite eventos voip_* no host client.
Instalação
@roamhq/wrtc(>= 0.10.0) — fornece SCTP para o transporte de relay.libmlow-wasm(^0.1.1) — perfil Opus do WhatsApp, compilado para WebAssembly. Sem etapa de build nativo.zapo-js(^1.0.0) — o host client.
ffmpeg no PATH:
loadAudiodecodifica o arquivo de áudio viaffmpeg.- Streamar áudio com
feedLiveAudioa partir de um arquivo igualmente precisa deffmpegpara produzir chunksFloat32Array16 kHz mono.
Conecte o plugin
AdicionevoipPlugin() em WaClientOptions.plugins. O coordinator aparece em client.voip e os eventos voip_* ficam disponíveis em client.on.
Opções do plugin
Máximo de chamadas simultâneas não-ended (ringing, connecting ou active). Aumente para habilitar multi-call em paralelo.
startCall de saída rejeita, e chamadas de entrada chegam com acceptBlocked: true, quando o limite é atingido.Log level mínimo para o (verboso) plugin de VoIP. Por padrão usa o nível do host client; defina-o para limitar diagnósticos de forma independente — por exemplo
'warn' para manter o ruído do VoIP fora de um host logger em trace.A superfície do coordinator
Iniciando uma chamada
JID bare ou de dispositivo a chamar.
Marca a chamada como vídeo nas stanzas de signaling. O encode/transport de mídia de vídeo não está implementado; apenas mídia de áudio trafega.
Arquivo de áudio a pré-carregar e tocar assim que a chamada conectar (precisa de
ffmpeg). Equivalente a chamar loadAudio depois que a chamada ficar ativa.JIDs explícitos de dispositivo do peer para tocar; omita para resolvê-los automaticamente.
startCall resolve com o id da nova chamada uma vez que a oferta é enviada. O progresso então chega via voip_call_state. Rejeita quando você está no limite de maxConcurrentCalls ou se a oferta falha em enviar.
Atendendo e encerrando
acceptCall(callId)— aceita uma chamada de entrada tocando. Lança secallIdfor desconhecido ou não estiver em um estado aceitável.rejectCall(callId, reason?)— rejeita uma chamada de entrada tocando (reason padrãoDeclined). Envia a stanza de reject e em seguida desmonta a chamada.endCall(callId, reason?)— encerra uma chamada ativa ou conectando (reason padrãoUserEnded). No-op se a chamada for desconhecida ou já estiver encerrada.
Áudio de saída pré-carregado
audioPath via ffmpeg e o enfileira como o áudio de saída, tocado assim que a chamada ficar ativa. Lança se o arquivo estiver ausente ou se ffmpeg não estiver disponível.
Para uma fonte ilimitada ou ao vivo (stream de TTS, captura contínua) use modo de áudio externo — veja abaixo.
Mute
Áudio ao vivo de saída (modo externo)
Para fontes que você não consegue pré-carregar — TTS streaming, captura em tempo real — coloque a chamada em modo de áudio externo e bombeie samples conforme chegam. O plugin os bufferiza por meio de um jitter buffer limitado e cria watermarks no buffer de modo que um produtor respeitoso nunca perde áudio.Snapshots
CallInfo captura tudo que você precisa para renderizar UI: callId, peerJid, direction, mediaType, createdAt, callerPn, mais um objeto stateData (state, audioMuted, videoOff, connectedAt, endReason, durationSecs, acceptBlocked, …) e getters derivados isInitiator, isActive, isRinging, isEnded, canAccept, canReject, isAcceptBlocked.
Eventos
AdicionevoipPlugin() a plugins e estes eventos ficam disponíveis em client.on. Sem o plugin eles não existem no tipo — veja Plugins.
Enums
Todos os valores doenum são strings minúsculas — use as constantes do enum para evitar erros de digitação.
CallState
CallDirection
CallMediaType
EndCallReason
Formato do áudio
- Sample rate: 16 kHz.
- Canais: mono.
- Formato de sample:
Float32Arrayem[-1.0, 1.0]. - Codec no fio: perfil Opus do WhatsApp, codificado via
libmlow-wasm. O payload type RTP é120(PayloadType.WhatsAppOpus).
voip_call_inbound_audio) quanto a saída (feedLiveAudio) usam o mesmo formato Float32Array — mantenha seus buffers neste formato e você consegue roteá-los direto.
Exemplo prático
Um auto-accept mínimo de entrada que grava o PCM de entrada em um buffer em memória:examples/voip-example.ts na árvore de source do zapo.
Veja também
Sistema de plugins
Como
voipPlugin() se encaixa no WaClient e como autorar o seu próprio.Eventos
A superfície de eventos do host client; eventos
voip_* ficam ao lado dos built-ins.Créditos
O plugin de VoIP foi construído por:- @vinikjkkj
- @edgardmessias — Edgard Lorraine Messias
- @w3nder — Wender Teixeira
