Bem, já estou pesquisando há alguns dias como exibir vídeo HTML5 em modo de tela inteira no Android WebView.
Consegui reproduzir vídeos HTML5 no meu webview. Estão surgindo problemas ao exibir o vídeo no modo de tela inteira.
Como descobri, o Android tem duas maneiras de lidar com a tag <video>:
Nas versões do Android <= 2.3.3 , o método onShowCustomView é disparado e posso ter a instância VideoView e definir ouvintes quando o vídeo for concluído, definir controladores etc. Até agora, tudo bem.
No ICS (e provavelmente 3.0 e superior) , parece que o <vídeo> é tratado de maneira diferente. Quando o vídeo HTML5 é reproduzido, o onShowCustomView não está sendo chamado no modo normal - parece que há um negócio interno dentro do WebView que reproduz o vídeo, e todos os controles que são definidos na tag <video> são mostrados - I não pode acessá-lo de forma alguma. Na verdade, se o vídeo for reproduzido no modo normal, não há problema, porque os controles estão lá e funcionando.
Isso me levou ao grande problema: ao exibir o vídeo em modo de tela inteira, o onShowCustomView está sendo chamado - mas no ICS o parâmetro "view" não é uma instância de VideoView.
Consegui descobrir que a instância é de VideoSurfaceView, uma classe interna privada da classe HTML5VideoFullScreen. A única maneira de acessar essa classe interna é por meio de reflexão.
Depois de examinar GrepCode para essa classe, aprendi que, ao contrário de VideoView, o HTML5VideoFullScreen $ VideoSurfaceView não contém uma instância de MediaPlayer para que eu possa ouvir seus eventos ou acessar seus controles. A única coisa que posso fazer é pegar este VideoSurfaceView como está e colocá-lo em um layout de tela inteira sem controlá-lo.
Resumindo - Ao exibir o vídeo em tela cheia, não sei quando o vídeo termina, seus controles não são mostrados - isso é muito triste. Não consigo obter o gatilho para fechar a tela inteira.
Tentei algumas soluções alternativas sem sucesso:
Reflexão: tentei alcançar a instância HTML5VideoFullScreen, que contém um membro MediaPlayer, da classe interna VideoSurfaceView. Não consegui pegar, não tenho certeza se isso é possível (ViewSurfaceView não contém a instância de seu dono).
Registre-se para os eventos de vídeo via Javascript (onended, por exemplo) e cuide do que preciso em JAVA via JavascriptInterface: descobri que esta solução não é confiável porque, ao fazer isso, encontrei outro problema: a tag <video> pode ser aninhada em um. A fonte do iframe não é minha e não consigo obter seu conteúdo (getElementById ou getElementsByTagName [i] são nulos) - o que significa que não consigo alcançar o elemento <video> dentro do iframe.
Ainda estou procurando uma solução, muito pouco se escreveu sobre esse problema. Alguém conseguiu resolver? Ajuda seria muito apreciada!
Classe VideoView : Aqui (tem MediaPlayer)
Classe HTML5VideoFullScreen $ VideoSurfaceView : aqui (não tem MediaPlayer)
Respostas:
Editar 2014/10: por demanda popular, estou mantendo e movendo isso para o GitHub. Verifique cprcrack / VideoEnabledWebView para ver a última versão. Manterá esta resposta apenas para referência.
Editar 2014/01: exemplo de uso aprimorado para incluir as visualizações nonVideoLayout, videoLayout e videoLoading, para aqueles usuários que solicitam mais código de exemplo para melhor compreensão.
Editar 2013/12: algumas correções de bugs relacionados à compatibilidade de dispositivos Sony Xperia, mas que na verdade afetaram todos os dispositivos.
Editar 2013/11: após o lançamento do Android 4.4 KitKat (API de nível 19) com seu novo Chromium webview, eu tive que trabalhar duro novamente. Várias melhorias foram feitas. Você deve atualizar para esta nova versão. Eu libero esta fonte sob WTFPL .
Editar 2013/04: após 1 semana de muito trabalho, finalmente consegui tudo o que precisava. Acho que essas duas classes genéricas que criei podem resolver todos os seus problemas.
VideoEnabledWebChromeClient
pode ser usado sozinho se você não precisar da funcionalidade queVideoEnabledWebView
adiciona. MasVideoEnabledWebView
sempre deve contar com aVideoEnabledWebChromeClient
. Por favor, leia todos os comentários de ambas as classes com atenção.Classe VideoEnabledWebChromeClient
Classe VideoEnabledWebView
Exemplo de uso:
Layout principal activity_main.xml no qual colocamos um VideoEnabledWebView e outras visualizações usadas:
OnCreate () da atividade , em que a inicializamos:
E não se esqueça de chamar onBackPressed () :
fonte
Testado na versão Android 9.0
Nenhuma das respostas funcionou para mim. Esta é a última coisa que funcionou
Em AndroidManifest.xml
Source Monster Techno
fonte
Edit: por favor, veja minha outra resposta , já que você provavelmente não precisa disso agora.
Como você disse, nos níveis de API 11+, um HTML5VideoFullScreen $ VideoSurfaceView é passado. Mas não acho que você esteja certo quando diz que "não tem MediaPlayer".
Esta é a maneira de acessar a instância MediaPlayer a partir da instância HTML5VideoFullScreen $ VideoSurfaceView usando reflexão :
Portanto, agora você pode definir o ouvinte onCompletion da instância do MediaPlayer assim:
O código não falha, mas não tenho certeza se esse ouvinte onCompletion será realmente chamado ou se pode ser útil para a sua situação. Mas apenas no caso de alguém querer experimentar.
fonte
Muito obrigado por essa aula, Cristian.
Fiz um pequeno ajuste para que a visualização de carregamento personalizada seja opcional, assim:
Também adicionei um novo construtor que usa apenas dois parâmetros. De qualquer forma, apenas uma pequena simplificação se você não precisar da visualização de carregamento. Obrigado novamente por fornecer isso.
fonte
Basta definir
mWebView.setWebChromeClient(new WebChromeClient());
e o vídeo é reproduzido normalmente, não precisa de nenhuma visualização personalizada.
fonte
Isso é ótimo. Mas se você quiser que os links de seu site sejam abertos no próprio aplicativo, adicione este código em ExampleActivity.java:
fonte
A resposta de Cprcrack funciona muito bem para níveis de API 19 e inferiores. Apenas uma pequena adição ao cprcrack
onShowCustomView
fará com que funcione na API de nível 21+Você também precisará refletir as mudanças em
onHideCustomView
fonte
Parece que no lollipop e posteriores (ou talvez apenas em uma versão diferente do WebView) esse
cprcrack's
onHideCustomView()
método de chamada não funciona. Funciona se for chamado a partir do botão de saída da tela inteira, mas quando você chama especificamente o método, ele só sai da tela inteira, maswebView
permanece em branco. Uma maneira de contornar isso é simplesmente adicionar essas linhas de código aonHideCustomView()
:Isso notificará o webView de que a tela inteira foi encerrada.
fonte