<audio> .addEventListener进度无法在内容加载过快时触发</audio>

时间:2012-03-17 11:44:21

标签: javascript html5 audio html5-audio

我从来没有想过快速加载内容会成为一个问题,但我遇到了一个特殊的问题。

我已经制作了一个HTML5音乐播放器,如果内容以正常速度加载,“缓冲”栏可以正常工作,但如果内容加载速度非常快,即通过局域网加载,那么听众就不会快速响应做任何事情。 addEventListener位于jQuery文档就绪函数中。我正在使用的代码如下:

audio.addEventListener('progress', function() {
    if(audio.duration && audio.buffered.end(0)) {
        if(resuming == 1) {
            resuming = 0;
            resumeplaypos = ReadCookie('resumeplaypos');
            audio.currentTime = resumeplaypos;
        }
        loaded = (audio.buffered.end(0) / audio.duration) * 100;
        $('.player-loaded').width(loaded + '%');
        console.log('Loaded: ' + loaded);
    }
}, false);

现在通常发生的事情是(使用console.log来检查),这只会触发一次,通常在10到20%之间。因此,尽管整个轨道已经加载,但我的缓冲条仍然卡在该值。在极少数情况下,它可以设法发射两次,输出:

[11:37:42.323] Loaded: 7.525227180155711 @ http://topaz:88/music.js:316
[11:37:42.605] Loaded: 59.57557430800252 @ http://topaz:88/music.js:316

但通常情况就是这样:

[11:39:52.773] Loaded: 13.313090306445885 @ http://topaz:88/music.js:316

有没有办法让进度监听器更可靠,还是我必须以其他方式解决这个问题? (或者我正在做些傻事)。

你可以忽略恢复代码,这是我正在处理的其他东西,当有人回到页面时恢复跟踪,在这种情况下不会使用它。

通过以下行加载JS文件时立即创建audio元素:

var audio = document.createElement("audio");

我已将代码移到文档就绪函数之外,并在if检查之外的进程中添加了一个控制台日志,但该行为仍像以前一样模仿内部记录:

[10:49:24.698] 31.702494 / 276.8 @ http://topaz:88/music.js:302
[10:49:24.728] 31.702494 / 276.8 @ http://topaz:88/music.js:302

使用时:

console.log(audio.buffered.end(0) + " / " + audio.duration);

虽然奇怪的是,当第二个值明显应该是“完成”值时,它会报告相同的值两次。浏览器是Firefox 11,Apache服务器(2.2.22)。请注意,我现在获得了50/50的成功失败率(成功时实际报告最终加载了100%)。

我在这里提供了示例代码 - https://xnode.org/paste/12(我无法弄清楚如何让jsfiddle正确运行它,加上它无论如何都会丢失音频文件) - 这表明了相同的行为极简主义的方式。

5次中只有2次(通过Ctrl + F5刷新)触发100%完成结果。其他3次在10%到40%之间(随机)发射一次。测试音频文件是一个6.9MB质量的6 OGG Vorbis编码轨道,位于LAN上的另一台机器上,由Apache 2.2.22盒子提供。

值得注意的是,如果您尝试将音频文件托管在与网页相同的计算机上,它将无法正常工作,因为它加载速度太快(它会立即触发100%完成)。所以看起来这只会发生在A)文件没有加载 - 并且B)它没有足够慢地加载以使处理程序一遍又一遍地开火。

1 个答案:

答案 0 :(得分:0)

据我所知,你要做的事情应该有效。每the specification

  

一旦获取了整个媒体资源(但可能在解码任何媒体资源之前)      在媒体元素处触发名为progress的简单事件。

我在Firefox中看到相关代码:

   // Ensure a progress event is dispatched at the end of download.

尝试在duration之外的任何audio.buffered之外的监听器中单独记录ifduration - 我的测试NaN可以是Infinity或{{1最终进展事件发生的那一刻。

如果这没有帮助,我建议您提及浏览器,HTTP服务器,您使用的音频格式,以及提供简化的测试用例。

以下是我每天在Firefox上测试的代码python -m SimpleHTTPServer 8000作为HTTP服务器(bunny.ogg取自here):

<audio src="bunny.ogg" controls>

</audio>

<script>
  var audio = document.getElementsByTagName("audio")[0];
  audio.addEventListener("progress", onProgress, false);

  function onProgress() {
    var loaded = (audio.buffered.end(0) / audio.duration) * 100;
    console.log(audio.buffered.end(0) + " / " + audio.duration + " * 100 = " + loaded);
  }
</script>