不能。requestvideoframecallback仅提供帧时间戳和元信息,不返回像素数据;需配合offscreencanvas+capturestream()实现滤镜,因setinterval不可控且drawimage会阻塞主线程,而该api与合成器同步、真正每帧一次。

requestVideoFrameCallback 能不能直接拿帧数据?
不能。它只提供 video 元素当前渲染帧的元信息(时间戳、metadata),不返回像素数据。想做滤镜,必须配合 OffscreenCanvas + captureStream() + requestVideoFrameCallback 三者协同——前者负责读像素,后者驱动时机,中间层负责流转。
为什么不用 drawImage + setInterval?
-
setInterval时间不可控,容易跳帧或重复采样,尤其在页面失焦或低性能设备上 -
drawImage同步调用会阻塞主线程,高分辨率视频下明显卡顿 -
requestVideoFrameCallback是浏览器原生帧同步机制,与 compositor 步调一致,真正“每帧一次” - 必须搭配
OffscreenCanvas在 worker 中解码+处理,否则仍会阻塞 UI
最小可行滤镜链怎么搭?
核心流程:媒体流 → video 元素 → OffscreenCanvas 拷贝 → Web Worker 中 getImageData → 处理像素 → putImageData → 回传到主屏显示。关键点:
-
video必须设playsinline muted autoplay,且已触发play()(用户手势后) - 调用
requestVideoFrameCallback前,确保video.videoWidth > 0,否则回调不触发 -
OffscreenCanvas尺寸需与video当前尺寸严格一致,否则拉伸失真;建议监听resize事件动态重设 - Web Worker 中不能访问
document或canvas.getContext('2d'),所有绘图操作必须在主线程完成,worker 只做纯计算
示例片段(主线程):
PigX UI Pro 前端开发指南 - Vue 3 + TypeScript + Element Plus。当用户提到 PigX UI、PigX 前端、lgb-mgui 项目、Vue 3 企业级后台开发、Element Plus 后台开发时使用此技能。
const canvas = document.getElementById('filterCanvas').transferControlToOffscreen();
const ctx = canvas.getContext('2d');
<p>video.requestVideoFrameCallback(() => {
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
// 此时可调用 postMessage 把 canvas.getImageData(0,0,w,h) 发给 worker
});</p>
Chrome 114+ 的 performance.now() 时间戳不准怎么办?
requestVideoFrameCallback 回调参数里的 now 是 wall-clock 时间,在某些 Chrome 版本中与 video.currentTime 存在毫秒级漂移,导致帧率误判或时间敏感滤镜(如闪烁、频闪)错位。稳妥做法是:
- 完全忽略回调的
now,改用video.getVideoPlaybackQuality().totalVideoFrames判断是否新帧 - 或用
performance.timeOrigin + video.currentTime * 1000计算逻辑时间戳(需校准初始偏移) - 对实时性要求极高的场景(如 AR 锚点),必须加一层帧序号比对:每次回调递增计数器,丢弃重复序号帧
这个时间差在低端 Android 设备上可能达 20–50ms,不处理就会让滤镜“拖影”或“抽搐”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










