¿Por qué no puedo establecer currentTime y la duración es igual a 0 en HTML AudioElement en Android WebView?

Por favor, perdóname, pero mientras escribía esta pregunta, surgieron algunas ideas, por lo que la pregunta puede parecer un registro de eventos, pero puedes saltar con seguridad a la parte TL; DR .

Tengo un módulo AAR en el que utilizo un WebView para mostrar una página y reproducir archivos de audio con diferentes horas de inicio, dependiendo del contexto. Tengo dos aplicaciones donde probar el módulo AAR : una aplicación de prueba, que es los huesos necesarios necesarios para ejecutar el módulo, y la aplicación real donde se necesita un tiempo para avanzar a través del flujo de la aplicación para llegar a la parte del módulo.

Se me informó de un error en varios de los dispositivos de prueba, donde la reproducción de audio siempre comienza desde 0, sin importar el elemento de audio currentTime utilizado.

Aquí está mi código, donde se maneja la reproducción:

 var instance = this; this.playbackCurrentAudioPath = newBufferPath; this.playbackCurrentAudio = document.createElement('audio'); this.playbackCurrentAudio.src = this.playbackCurrentAudioPath; this.playbackCurrentAudio.oncanplaythrough = function () { console.log("file loaded, try to play " + instance.playbackCurrentAudio); instance.loaded = true; // checked here, instance.playbackCurrentAudio.duration is equal 0 instance.playbackCurrentAudio.currentTime = audioTrackBeginTime; // instance.playbackCurrentAudio.currentTime is equal 0 instance.playbackCurrentAudio.play(); // playback starts from the beginning of the file }; this.playbackCurrentAudio.onerror = function () { instance.playbackLoadError() }; this.playbackCurrentAudio.onended = function () { instance.playbackAudioEnded(true) }; this.playbackCurrentAudio.load(); 

Como se indica en los comentarios, he añadido algunos puntos de interrupción para comprobar lo que está pasando, y he aquí algunas conclusiones:

  • Después de que se llama al evento oncanplaythrough , la duración se establece en 0 ,
  • Cuando se fija currentTime del elemento de audio a algún valor distinto de 0 , permanece en 0 ,
  • El archivo de audio se reproduce bien y el tiempo de reproducción se refleja en el valor currentTime .

De acuerdo con el sitio de W3Schools , canplaythrough es el último evento posible llamado al cargar el archivo de audio.

El escenario mencionado es posible recrear en el 10% de nuestros dispositivos de prueba. Estos dispositivos vienen de diferentes fabricantes (Lenovo, Samsung) y tienen diferentes versiones de Android (5.0.1, 6.0.1). También tengo diferentes dispositivos de estos fabricantes que funcionan bien.

He decidido probar con mi aplicación de huesos, porque es más rápido, y algo extraño sucedió – funciona bien en el mencionado 10% de los dispositivos de prueba:

  • Duración se informa correctamente después oncanplaythrough evento se dispara,
  • El ajuste de currentTime se refleja en el elemento de audio,
  • El audio comienza a reproducir desde el momento solicitado.

Me quedé bastante sorprendido, así que he comprobado todas las posibles diferencias entre las aplicaciones:

  • Se usaron las mismas configuraciones gradle de construcción
  • Se usaron las mismas versiones de bibliotecas
  • Los mismos métodos se llaman para iniciar la biblioteca
  • El mismo archivo AAR se utiliza en ambos proyectos

He encontrado una diferencia, las dos aplicaciones almacenar sus datos en diferentes lugares. La aplicación principal, almacena los datos en el directorio de documentos, mi aplicación desnuda almacena sus datos en el almacenamiento externo [por lo que es más fácil de depurar].

Después de haber cambiado la ruta de almacenamiento de la aplicación principal a externa, la aplicación comenzó a funcionar bien y reproducir el audio correctamente.

Sé que no puedo acceder fácilmente a los datos que se almacena dentro de la APK pero estos datos se descargan de la red y se almacena en el directorio de documentos, por lo que esperaría que no se aplican limitaciones.

TL, DR

Al cargar archivos de audio en el elemento de audio de HTML desde el directorio de documentos de la aplicación, en el evento canplaythrough , no puedo acceder a la duration del elemento de audio (es 0) ni a currentTime (permanece en 0 hasta que se reproduce). Cuando el mismo archivo se carga desde el almacenamiento externo (construido en la memoria) funciona bien y puedo obtener la duration archivo de audio y establecer la propiedad currentTime .

¿Qué puedo hacer para que funcione mientras el audio se encuentra en el directorio de documentos de la aplicación?

No estoy seguro de por qué afecta a algunos dispositivos, y no afecta a otros dispositivos, pero fui a través de las fuentes del proyecto Chromium y tropezó con esto:

https://chromium.googlesource.com/chromium/src/+/61c6121a6cb9dc16f9786830655049d68dcde67c/content/public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java

Y para ser más exactos:

 private List<String> getRawAcceptableDirectories() { List<String> result = new ArrayList<String>(); result.add("/mnt/sdcard/"); result.add("/sdcard/"); if (PACKAGE_NAME != null) result.add("/data/data/" + PACKAGE_NAME + "/cache/"); return result; } 

He cambiado el directorio de los documentos al directorio del escondrijo y todo trabaja como esperado.

  • Interceptar solicitudes POST en un WebView
  • No más Text Reflow después de ampliar KitKat WebView
  • Reproducir Youtube HTML5 incrustado de vídeo en Android WebView
  • Comportamiento extraño al usar WebView y RelativeLayout en pantalla completa
  • Android WebView impide la recarga de la página
  • Android Wikipedia La búsqueda de artículos no aparece correctamente en mi webview?
  • WebView con certificado de cliente SSL en Android 4 ICS
  • ¿Cómo desplazar la vista web horizontalmente dentro de ViewPager?
  • Mostrar mensaje para conocer la ubicación
  • WebView obtiene bajo ActionBar
  • Desarrollo de Android: Uso de la imagen de activos en un HTML de WebView
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.