如何让VideoJS精准停在指定帧且无帧偏差?
解决VideoJS精准停帧的问题
原方法依赖timeupdate事件,该事件触发间隔约250ms,精度不足,仅通过currentTime() >= stopAt判断后暂停,会因视频帧间隔和事件延迟导致停帧偏差。以下是精准停帧的实现方案:
核心优化点
- 用
requestAnimationFrame替代timeupdate,以屏幕刷新率同步的高频率检查播放进度,提升检测精度 - 暂停后主动校正视频时间到目标值,消除停帧偏差
- 播放前清理旧的监听任务,避免多次绑定引发逻辑冲突
实现代码
var player = videojs('my-video'); let stopAt = 1.549464; // 目标停止时间 let checkProgressId = null; // 实时进度检查函数 function checkProgress() { const currentTime = player.currentTime(); // 设置微小误差范围,提前触发暂停逻辑 if (currentTime >= stopAt - 0.01) { player.pause(); // 强制将视频时间校正到目标值 player.currentTime(stopAt); // 停止进度检查 cancelAnimationFrame(checkProgressId); checkProgressId = null; } else { checkProgressId = requestAnimationFrame(checkProgress); } } document.getElementById('playbtn').addEventListener('click', () => { // 清理之前的检查任务,避免重复执行 if (checkProgressId) { cancelAnimationFrame(checkProgressId); } player.play(); // 启动实时进度检查 checkProgressId = requestAnimationFrame(checkProgress); }); document.getElementById('reset').addEventListener('click', () => { // 重置时同步清理检查任务 if (checkProgressId) { cancelAnimationFrame(checkProgressId); checkProgressId = null; } player.currentTime(0); });
补充说明
若仍存在偏差,需考虑视频关键帧限制:视频编码时仅关键帧可独立显示,浏览器只能停在最近的关键帧上。这种情况下:
- 确认目标时间对应视频的关键帧位置
- 或先调用
player.currentTime(stopAt)预定位到目标帧,再启动播放并触发暂停逻辑
完整HTML结构:
<link href="https://vjs.zencdn.net/7.20.3/video-js.css" rel="stylesheet"/> <script src="https://vjs.zencdn.net/7.20.3/video.min.js"></script> <button id="playbtn">Play and stop at 00:00:01.13</button> <button id="reset">Reset(start from 0)</button> <video id="my-video" class="video-js" controls preload="auto" width="640" height="264" poster="MY_VIDEO_POSTER.jpg" data-setup="{}" > <source src="https://cheetahresume.com/static/millsecond_counter.webm" type="video/webm" /> <p class="vjs-no-js"> To view this video please enable JavaScript, and consider upgrading to a web browser that supports HTML5 video </p> </video>
内容的提问来源于stack exchange,提问作者EaBengaluru
相关产品推荐
相关产品推荐

