Why can't I set currentTime and the duration is 0 in HTML AudioElement in Android WebView?

Please forgive me, but when I wrote this question, some ideas came up, so the question may look like an event log, but you can safely go to the TL part ; DR .

I have an AAR module in which I use WebView to display a page and play audio files with different start times - depending on the context. I have two applications where I am testing the AAR module: a test application, which is the bare bones needed to run the module, and a real application, where it takes some time to move through the application flow to get to the module part.

I was informed about an error on several test devices where audio playback always starts at 0, not to mention the currentTime audio currentTime setting used.

Here is my code where the playback is performed:

 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(); 

As stated in the comments, I added a few breakpoints to check what was going on, and here are some conclusions:

  • after oncanplaythrough event is raised, the duration is set to 0 ,
  • when the currentTime audio currentTime to a value other than 0 , it remains at 0 ,
  • the sound file plays perfectly, and the playing time is reflected in the currentTime value.

According to W3Schools , canplaythrough is the last possible event triggered when an audio file is uploaded.

The described scenario can be recreated on 10% of our test devices. These devices come from different manufacturers (Lenovo, Samsung) and have different versions of Android (5.0.1, 6.0.1). I also have different devices from these manufacturers that work fine.

I decided to test using my bare-bones application because it is faster and something strange happened - it works fine on the above 10% of the test devices:

  • the duration is displayed correctly after the oncanplaythrough event oncanplaythrough fired,
  • the currentTime setting is reflected in the audio element,
  • sound starts from the moment of request.

I was very shocked, so I checked all the possible differences between the applications:

  • the same gradle layout settings were used
  • used the same library versions
  • The same methods are called to start the library.
  • the same AAR file is used in both projects

I found one difference: two applications will store their data in different places. The main application that stores data in the document directory, my My Bones application stores its data in external storage [so it’s easier to debug].

After I changed the storage path of the main application to an external one, the application began to work normally and play sound correctly.

I know that I can’t easily get the data stored inside the APK , but this data is downloaded from the network and stored inside the document directory, so I expect that there will be no restrictions.

TL; DR

When loading audio files in the HTML audio element from the application’s document catalog in the canplaythrough event canplaythrough I cannot access the duration audio duration (its 0) and not set the currentTime (it remains until 0 until playback). When the same file is downloaded from external storage (internal memory), it works fine, and I can get the duration audio file and set the currentTime property.

What can I do to make it work when the audio is in the application’s document directory?

+8
android html5-audio webview
source share
1 answer

I'm not sure why this affects some devices, and it does not affect other devices, but I looked at the sources of the Chromium project and came across this:

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

more precisely:

 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; } 

I changed the document directory to the cache directory, and everything works as expected.

+2
source share

All Articles