修复音频缓冲进度条回退时不重置的异常问题
问题分析
你遇到的问题根源在于:原代码仅用单个元素展示缓冲进度,且只取buffered对象的最后一个区间结束位置,无法正确处理媒体跳转后出现的多个不连续缓冲区间。当你跳转到音频末尾再回退到开头时,浏览器已经缓存了开头和末尾两段缓冲数据,但原代码会错误地将灰色缓冲条宽度设置为最后一个区间的结束位置(即音频全长),导致视觉上出现大片灰色痕迹,无法体现中间未缓冲的部分。
解决方案
我们需要动态生成多个元素来分别展示每个缓冲区间,同时在用户完成跳转后强制更新缓冲显示。以下是修改后的完整代码:
HTML 代码
<audio id="my-audio" preload controls> <source src="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" type="audio/mp4"> </audio> <div class="buffered" id="buffered-container"> <!-- 缓冲区间元素将通过JS动态生成 --> </div> <div class="progress"> <span id="progress-amount"></span> </div>
CSS 代码
.buffered { height: 20px; position: relative; background: #555; width: 300px; } .buffered-segment { position: absolute; height: 100%; background-color: #777; } .progress { margin-top: -20px; height: 20px; position: relative; width: 300px; } #progress-amount { display: block; height: 100%; background-color: #595; width: 0; }
JavaScript 代码
window.onload = function(){ var myAudio = document.getElementById('my-audio'); var bufferedContainer = document.getElementById('buffered-container'); // 统一更新缓冲显示的函数 function updateBuffered() { var duration = myAudio.duration; if (duration <= 0) return; // 清除旧的缓冲元素,避免重复渲染 bufferedContainer.innerHTML = ''; // 遍历所有缓冲区间,生成对应展示元素 for (var i = 0; i < myAudio.buffered.length; i++) { var start = myAudio.buffered.start(i); var end = myAudio.buffered.end(i); var segment = document.createElement('div'); segment.className = 'buffered-segment'; // 设置区间的起始位置(百分比) segment.style.left = ((start / duration) * 100) + '%'; // 设置区间的宽度(百分比) segment.style.width = (((end - start) / duration) * 100) + '%'; bufferedContainer.appendChild(segment); } } // 监听缓冲加载进度 myAudio.addEventListener('progress', updateBuffered); // 监听跳转完成事件,确保跳转后立即更新缓冲显示 myAudio.addEventListener('seeked', updateBuffered); // 播放进度更新逻辑保持不变 myAudio.addEventListener('timeupdate', function() { var duration = myAudio.duration; if (duration > 0) { document.getElementById('progress-amount').style.width = ((myAudio.currentTime / duration)*100) + "%"; } }); }
修改说明
- 缓冲区间动态渲染:通过遍历
buffered对象的所有区间,为每个区间生成独立的buffered-segment元素,用left和width属性精准定位每个缓冲段的位置和长度,解决了单一元素无法展示不连续缓冲的问题。 - 新增跳转监听:添加
seeked事件监听,确保用户完成跳转操作后立即更新缓冲显示,避免跳转后缓冲状态不刷新的问题。 - 清理旧元素:每次更新缓冲前先清空容器内的旧元素,防止重复渲染导致的视觉混乱。
内容的提问来源于stack exchange,提问作者Davelon Sahz
相关产品推荐
相关产品推荐

