音频持续时间NaN在某些页面请求动作

我一直在尝试使用HTML5和Jquery创建自定义媒体播放器。

我采用了不同的方法,并根据我刷新页面的方式遇到了一些麻烦。

第一种情况

$(document).ready(function(){
    duration = Math.ceil($('audio')[0].duration);
    $('#duration').html(duration);
});

在这种情况下,当我通过按地址栏中的ENTER键将页面重定向到相同的URL时,持续时间返回NaN。 但是,使用reload button或按F5按钮进行刷新时,它工作得很好。

第二种情况

我读了一些答案,加载loadedmetadata事件后的加载持续时间可能有所帮助。 所以我尝试了以下内容:

$(document).ready(function(){
    $('audio').on('loadedmetadata', function(){
        duration = Math.ceil($('audio')[0].duration);
        $('#duration').html(duration);
    });
});

令人惊讶的是,在这种情况下,发生了第一种情况的逆转。 在重定向的情况下,持续时间显示得很好,即在地址栏中按ENTER 。 但是,在使用F5按钮或reload button进行刷新的情况下,持续时间根本不会显示,甚至不会显示NaN,这导致我相信代码根本不会被执行。


进一步阅读表明,这可能是webkit浏览器中的一个错误,但我找不到任何结论性或有用的东西。

这种奇特行为背后的原因是什么? 如果你能解释这个问题并解决这个问题,那就太好了。

编辑:我主要是寻找这种行为差异背后的解释。 我想了解在重定向和刷新的情况下呈现页面背后的机制。


听起来问题在于事件处理程序设置得太晚,即音频文件在文档准备好之前已经加载了其元数据。

尝试通过删除$(document).ready调用尽快设置事件处理程序:

$('audio').on('loadedmetadata', function(){
    duration = Math.ceil($('audio')[0].duration);
    $('#duration').html(duration);
});

请注意,这要求<script> <audio>标签位于文档中的<audio>标签之后。

或者,您可以稍微调整逻辑,以便更新持续时间的代码始终运行(但如果获得NaN则优雅地失败):

function updateDuration() {
    var duration = Math.ceil($('audio')[0].duration);
    if (duration)
        $('#duration').html(duration);
}

$(document).ready(function(){
    $('audio').on('loadedmetadata', updateDuration);
    updateDuration();
});

可爱的代码示例和来自人的东西 - 但解释其实很简单。

如果文件已经存在于缓存中,那么loadedmetadata事件将不会触发(其他事件也不会发生 - 基本上是因为它们在您附加侦听器时已经触发了)并且duration将被设置。 如果它不在缓存中,那么duration将是NaN ,并且事件将会触发。

解决方案很简单。

function runWhenLoaded() { /* read duration etc, this = audio element */ }

if (!audio.readyState) { // or $audio[0].readyState
    audio.addEventListener("loadedmetadata", runWhenLoaded);
    // or $audio.on("loadedmetadata", runWhenLoaded);
} else {
    runWhenLoaded.call(audio);
    // or runWhenLoaded.call($audio[0]);
}

我在代码注释中包含了jQuery替代方法。


根据w3规范,当持续时间返回NaN时,这是标准行为。 所以我建议使用durationchange事件:

$('audio').on('durationchange', function(){
    var duration = $('audio')[0].duration;
    if(!isNaN(duration)) {
        $('#duration').html(Math.ceil(duration));
    }
});

注意:如果您在页面上有多个audio元素,则此代码(以及您的代码)将无法正确工作。 原因是你在页面上监听来自所有audio元素的事件,并且每个元素都会触发自己的事件:

$('audio').on('durationchange', function(){...});

要么

你可以试试:

    <script>
       function durationchange() {
          var duration = $('audio')[0].duration;
          if(!isNaN(duration)) {
              $('#duration').html(Math.ceil(duration));
          }
        }
    </script>

    <audio ondurationchange="durationchange()">
         <source src="test.mp3" type="audio/mpeg">
    </audio>
链接地址: http://www.djcxy.com/p/85681.html

上一篇: Audio duration NaN on certain page request action

下一篇: Amazon Kinesis + Integration Tests