Um app nativo controla sua própria mídia: tela cheia, reprodução automática e áudio em segundo plano funcionam. Dentro de um WebView esse controle some. A tela cheia precisa de uma view nativa feita à mão pelo host; a reprodução automática é bloqueada a menos que o host ative duas flags ocultas de configuração; e o áudio em segundo plano morre assim que o app vai para segundo plano. Um runtime próprio do host oferece uma ponte de mídia: uma superfície de reprodução previsível em todos os dispositivos.

O WebView não consegue ir para tela cheia sozinho

No Android, requestFullscreen() do HTML não faz nada para um <video> a menos que o WebChromeClient do app sobrescreva onShowCustomView() e onHideCustomView(). O WebView entrega a superfície do vídeo ao host e espera; se o host não implementa o callback, o botão de tela cheia simplesmente não funciona. O comportamento entre versões é pior: desde o Android 4.0 o callback recebe uma classe interna privada, então detectar o fim ou conectar controles próprios exige reflexão e ramificação por versão.

O iOS força tela cheia ou silêncio

No iOS, o WKWebView deixa allowsInlineMediaPlayback como false por padrão, então mesmo um vídeo playsinline é arrancado para o player do sistema no instante em que começa. A reprodução automática também é limitada: com o mediaTypesRequiringUserActionForPlayback padrão, um autoplay silenciado ainda precisa de um gesto, então o padrão "vídeo como banner" trava em silêncio. O Picture-in-Picture só funciona se o player inline já for um AVPlayerViewController — e não pode ser ativado automaticamente ao segundo plano, porque um visibilitychange não é interação do usuário.

O que quebra quando a mídia está pela metade

  • A tela cheia é um botão morto. Toque no Android e nada acontece a menos que o host tenha ligado onShowCustomView.
  • O vídeo inline pula para tela cheia. O iOS ignora playsinline a menos que o host tenha fixado a flag na configuração — mudar depois falha em silêncio.
  • A reprodução automática trava. Sem gesto, sem reprodução; a única saída são duas flags nativas ocultas.
  • O áudio em segundo plano morre. Ao segundo plano, a mídia do WebView pausa; PiP é o único caminho e não é automático.
  • Caos entre versões. A classe interna do Android e as flags do iOS mudam em cada build do SO.

A solução do runtime

Um runtime próprio do host controla a mídia. O host implementa a entrega de tela cheia nativamente, expõe uma API de reprodução uniforme à página, fixa as flags de inline e autoplay uma vez na configuração, e faz a ponte do áudio em segundo plano para a sessão de mídia do SO. Uma superfície de mídia, todos os dispositivos, todas as versões — em vez de uma página que funciona no telefone do engenheiro e quebra no do usuário.

DimensãoWebViewRuntime próprio do host
Tela cheiaMorta a menos que o host sobrescreva onShowCustomViewEntrega dirigida pelo host
Reprodução inline iOSIgnora playsinline por padrãoFlag fixada na configuração
AutoplayBloqueado sem gestoPolítica previsível
Áudio em segundo planoPausa ao segundo planoPonte para sessão de mídia do SO
Picture-in-PictureNão automáticoControlado pelo host
Entre versõesQuebra por buildEstável

Um app nativo nunca perde o controle de sua mídia. Um WebView comum frequentemente sim. Um runtime entrega à página um player previsível — e mantém o áudio vivo ao segundo plano.

Fontes