HTML5 video不支持负playbackRate,倒放需手动控制currentTime:暂停视频后用requestAnimationFrame逐帧递减并限幅至0,注意缓冲、I帧依赖及性能限制。

HTML5原生不支持playbackRate设为负数
直接给video.playbackRate = -1在所有主流浏览器都会被忽略,playbackRate只接受 ≥ 0 的值。这不是bug,是规范限制——W3C明确要求负值必须被clamp到0。所以“倒放”必须靠其他手段模拟。
用requestAnimationFrame手动控制currentTime
核心思路:禁用默认播放,用定时循环不断减小video.currentTime,并确保帧率稳定。关键点不是“快慢”,而是“逐帧逆向跳转”的精度和同步性。
- 先调用
video.pause(),避免原生播放逻辑干扰 - 用
requestAnimationFrame而非setInterval,更贴合渲染节奏,减少丢帧 - 每次减去的毫秒数要对应目标帧率(如60fps → 每次减
1000/60 ≈ 16.67ms) - 必须监听
timeupdate或检查currentTime ≤ 0来终止,否则会卡在负值或触发异常
let isReversing = false; let reverseInterval;function startReverse(video) { if (isReversing) return; isReversing = true; video.pause();
function reverseStep() { if (!isReversing || video.currentTime <= 0) { video.currentTime = 0; isReversing = false; return; } video.currentTime = Math.max(0, video.currentTime - 16.67); requestAnimationFrame(reverseStep); } requestAnimationFrame(reverseStep); }
注意video.buffered和解码限制
浏览器不会预加载“反向所需”的帧。当currentTime跳到未缓冲的位置,会出现卡顿、黑屏或seeking事件反复触发。尤其H.264视频依赖I帧,倒放时若跳到P/B帧位置,可能无法渲染。
- 倒放前尽量确保整段视频已
buffered(可监听canplaythrough后再操作) - 对长视频,倒放体验差是常态,不要强求全时段流畅
- MP4封装+H.264编码下,倒放实际是“向前解码+向后丢弃”,性能开销比正向高
WebGL/Canvas方案适合高精度但复杂度陡增
如果需要逐帧像素级控制(比如加滤镜、变速倒放),就得把视频帧抽成ImageBitmap或texture,用Canvas重绘。这时video仅作数据源,播放逻辑完全自控。
立即学习“前端免费学习笔记(深入)”;
- 需开启
video.crossOrigin = "anonymous"才能读取像素(否则canvas.getContext('2d').getImageData()报错) - 用
video.requestVideoFrameCallback()(Chrome 94+)比requestAnimationFrame更准,能对齐视频帧节奏 - 移动端性能敏感,Canvas倒放易掉帧,务必做
cancelVideoFrameCallback清理
真要倒放,优先接受“近似可用”;追求精确,就得放弃标签直连,转向底层帧处理。这点容易被低估。











