音频持续时间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