为什么我无法在Android WebView的HTML AudioElement中设置currentTime和持续时间等于0?

问题描述:

请原谅我,但是当我写这个问题时,有些想法出现了,所以这个问题可能看起来像事件的日志,但您可以放心地跳到TL; DR部分。为什么我无法在Android WebView的HTML AudioElement中设置currentTime和持续时间等于0?

我有一个AAR模块,其中我使用WebView来显示一个页面并播放具有不同开始时间的音频文件 - 具体取决于上下文。 我有两个应用程序,我测试AAR模块:一个测试应用程序,它是运行模块所需的基本骨骼,以及真正的应用程序,需要一段时间才能完成应用程序的流程以访问模块部分。

我被告知有几个测试设备上的错误,其中音频播放始终从0开始,而不介意使用的音频元素currentTime设置。

这里是我的代码,其中播放的处理:

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

正如评论所说,我已经添加了几个断点检查发生了什么事情,这里有一些结论:

  • oncanplaythrough事件被调用时,持续时间设置为0,
  • 当将音频元素的currentTime设置为除0以外的某个值时,它保持在0,
  • 音频文件播放良好,播放时间反映在currentTime值中。

根据W3Schools网站,canplaythrough是加载音频文件时调用的最后一个可能事件。

提到的情况可以在我们的测试设备的10%上重新创建。这些设备来自不同的制造商(联想,三星),并有不同的Android版本(5.0.1,6.0.1)。我也有这些制造商的不同设备工作正常。

我决定用我的裸露的骨头应用程序来测试,因为它的速度更快,而且奇怪的事情发生 - 它工作正常,在上述测试设备的10%:

  • 持续时间oncanplaythrough后正确地报告事件被触发,
  • currentTime的设置反映在音频元素中,
  • 音频从请求开始播放。

我很震惊,所以我检查了所有的应用程序之间可能存在差异:库的同一版本中使用

    • 相同的构建gradle这个设置使用
    • 调用相同的方法启动库
    • 相同AAR文件在两个项目中都使用

    我已经找到一个差异,这两个应用程序将存储在不同的地方他们的数据。主应用程序将数据存储在文档目录中,我的裸骨应用程序将其数据存储在外部存储器中[因此更易于调试]。

    后,我已经改变了存储路径为主要应用外,该应用程序开始正常工作,正确地播放音频。

    我知道我无法轻松访问存储在APK中的数据,但是这些数据是从网络下载并存储在文档目录中的,因此我预计不会有任何限制。

    TL; DR

    当从应用程序的文件目录HTML的音频元素加载音频文件,在canplaythrough事件,我无法访问音频元素的duration(这是0),也不设置为0 currentTime(之前的住宿发挥)。当同一个文件从外部存储器(内置存储器)中能正常工作,我可以得到的音频文件duration并设置currentTime属性。

    我能做些什么,使工作在音频位于应用程序的文件目录?

  • +0

    HTML5音频似乎在内部使用的MediaPlayer的大部分时间。这意味着音频文件需要世界可读的权限才能正确运行播放器。这就是为什么它不能在本地存储上正常工作,而是在外部存储上运行。 –

    +0

    ,但如果文件没有读取权限,则根本无法使用,在我的情况下,只有WebAudio的某些功能不起作用:设置currentTime和读取持续时间。音频播放良好。 – Krystian

    +0

    否的情况下的一些元素可以有权限阅读,有些人可能不。你不能跳到这个结论。这显然是一种权限问题,因为文件的位置是唯一的区别。如果没有,那么时间(比赛条件)是我能想到的唯一的事情。 –

    我不知道为什么它会影响一些设备,而不会影响其他设备,但我通过Chromium项目的来源去了,偶然发现了这一点:

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

    和更准确:

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

    我已经改变了文件目录到缓存目录,一切都按预期工作。