Áudio e vídeo ao vivo sobre WebRTC é de primeira classe na web móvel, até rodar dentro de um WebView. No Android, a decisão de permissão do getUserMedia é delegada ao host via onPermissionRequest, e no iOS WKWebView traz a captura de mídia desativada por padrão. A maioria dos navegadores integrados nunca conecta uma chamada. Um runtime próprio do host faz a ponte da mídia em tempo real: uma API para câmera, microfone e conexão peer em cada motor.

Android: a decisão de permissão está no host

Quando a página chama navigator.mediaDevices.getUserMedia, o WebView não pergunta ao usuário; ele chama WebChromeClient.onPermissionRequest e o host concede ou nega. Antes de conceder, o host precisa solicitar as permissões de runtime CAMERA e RECORD_AUDIO e, idealmente, verificar a origem. Se essa cadeia não estiver ligada, o log mostra CheckMediaAccessPermission: Not supported e o getUserMedia rejeita em silêncio com NotAllowedError. A documentação do Android é clara: solicite a permissão de runtime antes de grant(). Assim, se a chamada ao vivo conecta depende inteiramente de o contêiner implementar a ponte.

iOS: a captura de mídia vem desativada por padrão

O iOS 11 trouxe WebRTC ao Safari, mas o WKWebView não habilita a captura por padrão. Um app de terceiros precisa configurá-la: adicionar NSCameraUsageDescription e NSMicrophoneUsageDescription ao Info.plist, ajustar allowsInlineMediaPlayback = true e mediaTypesRequiringUserActionForPlayback = [], e no iOS 14+ permitir a captura via WKMediaCapturePermissionsPolicy. Mesmo assim, navegadores integrados como WeChat, Douyin e Facebook costumam não habilitá-la, então getUserMedia reporta not found. Além da captura, o SDK web da Agora observa que iOS Safari e WKWebView não suportam getDisplayMedia (compartilhar tela), e ao ir para segundo plano o AVCaptureSession não pode usar a câmera, então o remoto vê um quadro preto; o controle de fps via RTCRTPSender.setParameters também não está disponível.

O que quebra quando a chamada se cala

  • Suporte por vídeo e telemedicina travam. A chamada nunca obtém a câmera.
  • Salas de voz e live co-streaming em silêncio. Nenhum fluxo de microfone chega ao par.
  • Compartilhar tela indisponível. getDisplayMedia não é suportado no iOS WebView.
  • Segundo plano corta a chamada. A câmera fica preta.
  • Safari funciona, WebView não. Uma página que conecta no Safari falha no navegador integrado do mesmo dispositivo.

A solução do runtime

Um runtime próprio do host faz a ponte da camada de mídia em tempo real. Ele envolve getUserMedia com permissões nativas de câmera e microfone e expõe uma API uniforme para câmera, micro e conexão peer. O host gerencia um RTCPeerConnection estável —STUN/TURN compartilhados, tratamento ICE e negociação de codec de hardware (H.264/VP8)— para que a chamada ao vivo conecte em cada motor. A permissão é pedida uma vez, de forma nativa; o fluxo e a conexão são consistentes.

DimensãoWebViewRuntime próprio do host
Permissão AndroidonPermissionRequest do hostConcessão nativa
Captura iOSDesativada por padrãoHabilitação nativa
Compartilhar telagetDisplayMedia não suportadoPonte nativa
Câmera em segundo planoQuadro pretoSessão gerenciada
Conexão peerPor motorUniforme
ConsistênciaPor motorUniforme

Um app nativo roda uma videoligação em cada telefone. Um WebView padrão quase em nenhum. Um runtime dá à página uma superfície de mídia — e um par ao vivo do outro lado.

Fontes