当时使用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) }
参考文档:js:指定FPS帧频,requestAnimationFrame播放动画
标签:动画,tick,播放,requestAnimationFrame,window,delta,var,now From: https://www.cnblogs.com/hyt09/p/17446017.html