在后台运行requestAnimationFrame

3

我正在使用requestAnimationFrame来动画视频流,但是我知道request animation无法在后台运行。那么有没有办法让它在后台运行呢?

我知道我们也可以使用setInterval或者setTimeout来实现动画,但是当我尝试这些方法时,动画效果不正常,视频流中的图片会闪烁。

以下是我的代码:

const drawFrame = function drawFrame() {
            if (!ctx) {
                ctx = canvas.getContext('2d');
            }
            if (!tmpCanvas) {
              tmpCanvas = document.createElement('canvas');
              tmpCtx = tmpCanvas.getContext('2d');
              tmpCanvas.width = canvas.width;
              tmpCanvas.height = canvas.height;
            }
            tmpCtx.drawImage(videoElement, 0, 0, tmpCanvas.width, tmpCanvas.height);
            const imgData = tmpCtx.getImageData(0, 0, tmpCanvas.width, tmpCanvas.height);
            const data = selectedFilter(imgData);
            ctx.putImageData(data, 0, 0);
            if (!stopped) {
              requestAnimationFrame(drawFrame);
            } else {
              tmpCanvas = null;
              tmpCtx = null;
              ctx = null;
            }
        };
        requestAnimationFrame(drawFrame);

我有完全相同的问题。我们正在使用的库使用requestAnimationFrame(),现在改变已经太晚了。 - Mrinal Saurabh
1个回答

4

我猜你运气不好。requestAnimationFrame故意在后台暂停,因为动画没有理由在后台运行,正如你提到的setInterval和setTimeout不适用于动画,并且不应该被用于此目的。

你提到你需要对视频流进行动画处理。你是指在video标签上应用动画,还是通过canvas元素更改视频元素的外观?无论哪种情况,你都不应该在后台继续这样做,但你可以尝试使用computeFrame(仅适用于Firefox),它将在每一帧视频中触发一次。或者你是通过连续动画一组静态图像来模拟视频流吗?在那种情况下,为什么不使用video元素呢?


实际上,我正在使用Tokbox js API,它不支持在运行时更改流,并且我们需要在视频上添加效果(静态图像),为此我们正在使用camera-filter API,它使用requestAnimationFrame,但正如我所提到的,它不会在后台运行,那么有没有办法克服这个问题? - Anuj Negi
1
requestAnimationFrame是专门为前台标签页设计的,每次动画只运行一次,并具有实时优先级,但不适用于后台标签页。在后台运行会导致性能问题。并非浏览器中的所有内容都可以优先处理。我不知道还有其他跨浏览器的方法可以模拟requestAnimationFrame。 - Xyz
1
而setTimeout/setInterval并不适用于此情况。如果你设置了一个30ms的延迟,你得到的唯一保证是它不会在至少30ms内触发。当30ms过去后,它将开始等待当前正在运行的上下文完成运行(因为Javascript是[大多数情况下]单线程语言)。除此之外,浏览器很可能会尝试进一步减少这种操作以节省系统资源。或者,如果多个标签页中运行了大量的javascript,则操作系统可以限制浏览器自身的访问核心数量。 - Xyz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接