HTML5 Audio提前终止:Chrome不触发onended事件问题求助
解决HTML5 Audio在Chrome/Firefox中无法准确检测播放结束的问题
看起来你碰到了一个挺棘手的浏览器兼容性问题——Chrome下MP3不仅触发不了onended事件,甚至没法播放到文件结尾;Firefox虽然能触发事件,但时长计算总是出错。既然已经排除了代码问题,还提交了Chromium的bug,那我们可以用一些替代方案来检测音频何时停止播放。
可行的替代检测方案
方案1:轮询播放状态与进度
利用定时器定期检查音频的paused状态和播放进度,当音频处于暂停状态且进度接近文件时长时,判定为播放结束。这种方式不受onended事件失效的影响。
方案2:监听timeupdate事件
timeupdate会在播放进度变化时触发,我们可以在这个事件回调里判断当前播放进度是否接近结尾,同时结合paused状态来确认播放结束,相比定时器更贴合播放的实际节奏。
修改后的代码示例
var audio = document.getElementById('audio'); var endThreshold = 0.5; // 结束检测阈值,可根据实际音频调整 var hasTriggeredEnd = false; // 避免重复触发结束逻辑 $('#clickButton').click(function(){ hasTriggeredEnd = false; audio.src = 'Blem.mp3'; }); $('#nearEndButton').click(function(){ if (!isNaN(audio.duration)) { audio.currentTime = audio.duration - 20; } }); audio.oncanplay = function () { audio.play(); } // 保留原onended事件作为浏览器bug修复后的备用 audio.onended = function(){ handleAudioEnd(); } // 方案1:定时器轮询检测 setInterval(function(){ var div = $('#textarea'); div.val('CurrentTime: ' + audio.currentTime + '\nFulltime: ' + audio.duration + '\nEnded: ' + audio.ended); if (!hasTriggeredEnd && !isNaN(audio.duration) && audio.paused) { var remainingTime = audio.duration - audio.currentTime; // 两种判定条件:剩余时长小于阈值,或播放进度达到99%以上 if (remainingTime < endThreshold || audio.currentTime >= audio.duration * 0.99) { handleAudioEnd(); } } }, 100); // 方案2:监听timeupdate事件(可选择其中一种方案使用) audio.addEventListener('timeupdate', function() { if (!hasTriggeredEnd && !isNaN(audio.duration) && audio.paused) { var remainingTime = audio.duration - audio.currentTime; if (remainingTime < endThreshold || audio.currentTime >= audio.duration * 0.99) { handleAudioEnd(); } } }); // 统一处理播放结束的逻辑 function handleAudioEnd() { hasTriggeredEnd = true; alert('音频已停止播放!'); // 这里可以添加你需要执行的后续操作 }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <audio id='audio'></audio> <button id='clickButton'>Load and Play Song</button> <button id='nearEndButton'>Move to end</button> <a href='Blem.mp3'>Open Blem.mp3</a><br> <textarea id='textarea' style='width: 200px; height: 200px;'></textarea>
注意事项
endThreshold的数值可以根据音频的实际情况调整,如果音频结尾有静音片段,可以适当调大阈值;- 必须先判断
audio.duration是否为有效数值(非NaN),否则会出现计算错误; - 加入
hasTriggeredEnd标记是为了避免结束逻辑被重复触发; - 保留原
onended事件,当浏览器的bug修复后,依然能正常兼容。
内容的提问来源于stack exchange,提问作者Fr34k
相关产品推荐
相关产品推荐

