Bueno, ya he estado buscando unos días cómo mostrar video HTML5 en modo de pantalla completa en Android WebView.
Logré reproducir videos HTML5 en mi vista web. Surgen problemas al mostrar video en modo de pantalla completa.
Como descubrí, Android tiene dos formas de manejar la etiqueta <video>:
En las versiones de Android <= 2.3.3 , se activa el método onShowCustomView, y puedo tener la instancia de VideoView y establecer oyentes cuando se completa el video, configurar controladores, etc. Hasta ahora todo bien.
En ICS (y probablemente 3.0 y superior) , parece que el <video> se maneja de manera diferente. Cuando se reproduce el video HTML5, no se llama a onShowCustomView en modo normal; parece que hay un negocio interno dentro de WebView que reproduce el video, y se muestran todos los controles que están definidos en la etiqueta <video> - I no puede acceder a él de ninguna manera. En realidad, si el video se reproduce en modo normal, está bien porque los controles están ahí y funcionan.
Eso me llevó al gran problema: cuando se muestra el video en modo de pantalla completa, se llama a onShowCustomView, pero en ICS el parámetro "view" no es una instancia de VideoView.
Me las arreglé para descubrir que la instancia es de VideoSurfaceView, una clase interna privada de la clase HTML5VideoFullScreen. La única forma en que podemos acceder a esta clase interna es a través de la reflexión.
Después de mirar GrepCode para esta clase, aprendí que, a diferencia de VideoView, HTML5VideoFullScreen $ VideoSurfaceView no contiene una instancia de MediaPlayer que pueda escuchar sus eventos o acceder a sus controles. Lo único que puedo hacer es tomar este VideoSurfaceView como está y colocarlo dentro de un diseño de pantalla completa sin controlarlo.
En pocas palabras: cuando se muestra un video en pantalla completa, no sé cuándo termina el video, sus controles no se muestran; esto es bastante triste. No consigo el disparador para cerrar la pantalla completa.
Probé algunas soluciones alternativas fallidas:
Reflexión: Traté de llegar a la instancia de HTML5VideoFullScreen, que contiene un miembro MediaPlayer, desde la clase interna VideoSurfaceView. No logré obtenerlo, no estoy seguro de que esto sea posible (ViewSurfaceView no tiene la instancia de su propietario).
Regístrese para los eventos de video a través de Javascript (al final, por ejemplo) y maneje lo que necesito en JAVA a través de JavascriptInterface: encontré que esta solución no es confiable porque mientras hacía esto encontré otro problema: la etiqueta <video> se puede anidar en un. La fuente del iframe no es mía y no puedo obtener su contenido (getElementById o getElementsByTagName [i] son nulos), lo que significa que no puedo alcanzar el elemento <video> dentro del iframe.
Todavía estoy buscando una solución, se ha escrito muy poco sobre este problema. ¿Alguien logró resolverlo? ¡La ayuda será muy apreciada!
Clase VideoView : Aquí (tiene MediaPlayer)
HTML5VideoFullScreen $ VideoSurfaceView clase: Aquí (no tiene MediaPlayer)
Respuestas:
Editar 2014/10: por demanda popular estoy manteniendo y moviendo esto a GitHub. Consulte cprcrack / VideoEnabledWebView para ver la última versión. Mantendré esta respuesta solo como referencia.
Editar 2014/01: uso de ejemplo mejorado para incluir las vistas nonVideoLayout, videoLayout y videoLoading, para aquellos usuarios que soliciten más código de ejemplo para una mejor comprensión.
Edición 2013/12: algunas correcciones de errores relacionados con la compatibilidad de los dispositivos Sony Xperia, pero que de hecho afectaron a todos los dispositivos.
Edición 2013/11: después del lanzamiento de Android 4.4 KitKat (API nivel 19) con su nueva vista web Chromium, tuve que trabajar duro nuevamente. Se realizaron varias mejoras. Debería actualizar a esta nueva versión. Libero esta fuente bajo WTFPL .
Edición 2013/04: después de 1 semana de arduo trabajo, finalmente he logrado todo lo que necesitaba. Creo que estas dos clases genéricas que he creado pueden resolver todos tus problemas.
VideoEnabledWebChromeClient
se puede usar solo si no requiere la funcionalidad queVideoEnabledWebView
agrega. PeroVideoEnabledWebView
siempre debe confiar en unVideoEnabledWebChromeClient
. Por favor lea atentamente todos los comentarios de ambas clases.Clase VideoEnabledWebChromeClient
Clase VideoEnabledWebView
Uso de ejemplo:
Diseño principal activity_main.xml en el que colocamos un VideoEnabledWebView y otras vistas utilizadas:
Activity's onCreate () , en el que lo inicializamos:
Y no olvide llamar a onBackPressed () :
fuente
Probado en la versión de Android 9.0
Ninguna de las respuestas me funcionó. Esta es la última cosa que funcionó
En AndroidManifest.xml
Fuente Monster Techno
fuente
Editar: vea mi otra respuesta , ya que probablemente no necesite esto ahora.
Como dijiste, en los niveles de API 11+ se pasa un HTML5VideoFullScreen $ VideoSurfaceView. Pero no creo que tengas razón cuando dices que "no tiene MediaPlayer".
Esta es la forma de llegar a la instancia de MediaPlayer desde la instancia HTML5VideoFullScreen $ VideoSurfaceView usando la reflexión :
Entonces, ahora puede configurar el oyente onCompletion de la instancia de MediaPlayer de esta manera:
El código no falla, pero no estoy completamente seguro de si realmente se llamará a ese oyente de onCompletion o si podría ser útil para su situación. Pero por si acaso alguien quisiera probarlo.
fuente
Muchas gracias por esa clase, Cristian.
Le hice un pequeño ajuste para que la vista de carga personalizada sea opcional, así:
También agregué un nuevo constructor que solo toma dos parámetros. De todos modos, solo una pequeña simplificación si no necesita la vista de carga. Gracias de nuevo por proporcionar esto.
fuente
Solo configurar
mWebView.setWebChromeClient(new WebChromeClient());
y el video se reproduce como normalmente no necesita ninguna vista personalizada.
fuente
Esto es genial. Pero si desea que los enlaces de su sitio web se abran en la propia aplicación, agregue este código en su ExampleActivity.java:
fuente
La respuesta de Cprcrack funciona muy bien para los niveles de API 19 y menores. Solo una pequeña adición a cprcrack
onShowCustomView
hará que funcione en el nivel de API 21+También deberá reflejar los cambios en
onHideCustomView
fuente
Parece que en lollipop y versiones posteriores (o tal vez solo en una versión de WebView diferente) ese
cprcrack's
onHideCustomView()
método de llamada no funciona. Funciona si se llama desde el botón de salida de pantalla completa, pero cuando llama específicamente al método, solo saldrá de pantalla completa, perowebView
permanece en blanco. Una forma de evitarlo es simplemente agregar estas líneas de código aonHideCustomView()
:Esto notificará a webView que la pantalla completa ha salido.
fuente