根据视频帧率,使用requestAnimationFrame播放动画
当时使用webRTC进行视频通话时,通常会设置视频流的帧率,行业内一般默认帧数为15或者30,一般每秒只需要渲染15或30次
当要需要对本地视频或者远端视频流进行特殊处理时,通常会使用requestAnimationFrame方法进行再次渲染
requestAnimationFrame,这个方法是用来在页面重绘之前,通知浏览器调用一个指定的函数,以满足开发者操作动画的需求。
这个函数类似setTimeout,只调用一次。
function draw() { requestAnimationFrame(draw); // ... Code for Drawing the FrameRate ... }
递归调用,就可以实现定时器。回调函数执行次数通常是每秒 60 次。
但是,这样完全跟浏览器帧频同步了,无法根据视频帧率渲染,会造成一定程度的CPU和GPU资源的浪费
自行控制时间跨度:
var fps = 30; var now; var then = Date.now(); var interval = 1000/fps; var delta;
var reqId = null; function tick() { regId = requestAnimationFrame(tick); now = Date.now(); delta = now - then; if (delta > interval) { // 这里不能简单then=now,否则会出现细微时间差问题。例如fps=10,每帧100ms,而现在每16ms(60fps)执行一次draw。16*7=112>100,需要7次才实际绘制一次。这个情况下,实际10帧需要112*10=1120ms>1000ms才绘制完成。 then = now - (delta % interval); draw(); // ... Code for Drawing the Frame ... } } tick();
针对低版本浏览器再优化:
var fps = 30; var now; var then = Date.now(); var interval = 1000/fps; var delta;
var reqId = null;
var timeId = null; window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame; function tick() { if(window.requestAnimationFrame) { reqId = requestAnimationFrame(tick); now = Date.now(); delta = now - then; if (delta > interval) { // 这里不能简单then=now,否则还会出现细微时间差问题。例如fps=10,每帧100ms,而现在每16ms(60fps)执行一次draw。16*7=112>100,需要7次才实际绘制一次。这个情况下,实际10帧需要112*10=1120ms>1000ms才绘制完成。 then = now - (delta % interval); draw(); // ... Code for Drawing the Frame ... } } else { timeId = setTimeout(tick, interval);
draw(); } } tick();
停止动画
if(window.requestAnimationFrame){ cancelAnimationFrame(regId) }else{ clearTimeout(timeId) }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义