TypeScript实现指定帧范围播放时视频无法自动暂停问题求助
你遇到的问题本质是两个原因导致的:
- 视频的
timeupdate事件触发频率不稳定,间隔在16ms到250ms不等,不会逐帧触发,很容易跳过你设定的精确时间点 - 浮点数做等值对比本身就存在精度误差,用
toFixed转字符串再对比的方式容错性极低
方案1:最低成本修复现有逻辑
- 把等值判断改为「大于等于结束时间」,同时添加执行锁避免重复触发暂停动作:
// 提前把endDuration存为数值类型,不要存toFixed后的字符串 this.endDuration = ((1000 / this.fpsCount) * this.rangeFrame.frameInputEnd / 1000; // 加标记位,防止重复触发暂停 let hasPaused = false; this.videoPlayer.nativeElement.ontimeupdate = (e: any) => { this.whatFps = `${Math.ceil(e.target.currentTime * this.fpsCount)} / ${this.totalFrame}`; // 不需要做toFixed转换,直接数值比较 if(!hasPaused && e.target.currentTime >= this.endDuration) { // 可选:手动把currentTime强制设为结束时间,让画面停在准确的结束帧 e.target.currentTime = this.endDuration; this.pause(); hasPaused = true; } } // 每次用户手动调整播放进度/重新播放的时候重置标记 this.videoPlayer.nativeElement.onplay = () => { hasPaused = false; }
方案2:更高精度实现(适合对帧精度要求高的场景)
如果需要严格卡在结束帧暂停,改用requestAnimationFrame轮询时间,触发频率远高于timeupdate,精度更高:
let pauseChecker = null; this.endDuration = ((1000 / this.fpsCount) * this.rangeFrame.frameInputEnd) / 1000; this.videoPlayer.nativeElement.onplay = () => { // 播放时启动轮询 pauseChecker = requestAnimationFrame(function checkTime() { const current = this.videoPlayer.nativeElement.currentTime; this.whatFps = `${Math.ceil(current * this.fpsCount)} / ${this.totalFrame}`; if(current >= this.endDuration) { this.videoPlayer.nativeElement.currentTime = this.endDuration; this.pause(); cancelAnimationFrame(pauseChecker); return; } pauseChecker = requestAnimationFrame(checkTime.bind(this)); }.bind(this)) } this.videoPlayer.nativeElement.onpause = () => { // 暂停时销毁轮询 if(pauseChecker) cancelAnimationFrame(pauseChecker); }
额外优化提示:
计算startDuration的时候也不要用toFixed转字符串,直接存原始数值,设置currentTime的时候直接用数值,精度更高。
内容的提问来源于stack exchange,提问作者naoval luthfi
相关产品推荐
相关产品推荐

