JavaScript视频分段循环播放问题:第二段无法重复3次
问题排查与修复:视频分段重复播放异常
问题背景
计划开发基于JavaScript的视频应用,需求如下:
- 每个视频分段重复播放3次后切换至下一分段
- 多视频多分段结构,视频链接与分段信息存储在嵌套数组中
- 点击一次Play按钮后按顺序完成所有播放流程:如先重复播放
journey27.mp4的1-2秒分段3次,再切换至该视频5-7秒分段重复3次,以此类推
现有代码中首个分段可正常重复3次,但第二个分段无法实现重复播放。
核心问题分析
- 重复绑定事件监听器:每次调用
playVideo时都会给video添加新的timeupdate匿名监听器,导致同一事件被多个监听器触发,逻辑混乱,分段切换后旧监听器仍在执行,干扰新分段的播放控制。 - video的loop属性干扰:video标签设置了
loop属性,会自动循环整个视频,与自定义的分段重复逻辑冲突。 - 播放状态未正确重置:切换分段或视频时,没有暂停视频并清理旧的播放状态,导致播放流程错乱。
修复方案
- 移除video标签的
loop属性,避免自动循环干扰自定义逻辑 - 将
timeupdate的匿名监听函数改为命名函数,每次添加前先移除旧监听器,确保同一时间只有一个监听器生效 - 切换分段时暂停视频,重置播放状态,确保新分段从正确位置开始播放
- 增加播放完成判断,当所有视频分段都播放完毕后停止流程
修复后完整代码
<html> <head> <script> var sentences= [ ['journey27.mp4', [ [1, 2], [5, 7] ] ], ['journey28.mp4', [ [10, 12], [13, 17], [25, 36] ] ], ['journey29.mp4', [ [13, 15], [15, 19], [21, 30] ] ] ]; let video_index = 0; let time_index = 0; let repeat = 0; const video = document.getElementById("myVideo"); // 命名监听函数,方便移除 function onTimeUpdate() { const maxTime = this.dataset.endTime; if (this.currentTime >= maxTime) { this.pause(); myLoop(); } } function playVideo(myUrl, startTime, endTime) { document.getElementById("demo").innerHTML += myUrl + " start:"+startTime+" end: "+endTime+"<br>"; // 先移除旧的监听器 video.removeEventListener("timeupdate", onTimeUpdate); video.src = 'video/'+myUrl; // 存储结束时间到元素dataset,避免闭包问题 video.dataset.endTime = endTime; video.currentTime = startTime; // 添加新的监听器 video.addEventListener("timeupdate", onTimeUpdate); video.play(); } function myLoop(){ // 检查是否所有视频都播放完毕 if (video_index >= sentences.length) { document.getElementById("demo").innerHTML += "所有视频播放完成<br>"; return; } playVideo(sentences[video_index][0], sentences[video_index][1][time_index][0], sentences[video_index][1][time_index][1]); repeat++; if (repeat >= 3) { repeat = 0; time_index++; if (time_index >= sentences[video_index][1].length) { time_index = 0; video_index++; } } } </script> </head> <body> <video id="myVideo" width="500" height="400" controls autoplay> Your browser does not support the video tag. </video> <br> <a href="#" onclick="myLoop()"> Play </a> <br> <p id="demo"></p> </body> </html>
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

