我正在测试 HTML5 的视频 API。计划是播放带有效果的视频,例如将其设置为黑白。我有并且使用缓冲区一起工作。我获取当前视频帧并复制到暂存缓冲区,我可以在其中处理它。问题在于它的运行速度。
HTML5 的视频 API 有 'timeupdate' 事件。我尝试使用它来让处理程序处理帧,每帧一次,但它的运行速度比视频慢。
有什么想法可以加快处理帧的速度吗?
我正在测试 HTML5 的视频 API。计划是播放带有效果的视频,例如将其设置为黑白。我有并且使用缓冲区一起工作。我获取当前视频帧并复制到暂存缓冲区,我可以在其中处理它。问题在于它的运行速度。
HTML5 的视频 API 有 'timeupdate' 事件。我尝试使用它来让处理程序处理帧,每帧一次,但它的运行速度比视频慢。
有什么想法可以加快处理帧的速度吗?
您可以通过使用requestAnimationFrame来确定何时更新您的画布,而不是依赖每 200-250 毫秒更新一次的 ,您可以获得更频繁的重绘timeupdate
。对于精确到帧的动画来说,这绝对是不够的。requestAnimationFrame
最多每 16 毫秒更新一次(大约 60 fps),但浏览器会根据需要对其进行节流并与视频缓冲区绘制调用同步。这几乎正是你想要的这种东西。
即使帧速率更高,使用 2D 画布处理视频帧也会非常缓慢。一方面,您在 CPU 中按顺序处理每个像素,运行 Javascript。另一个问题是您正在复制大量内存。无法直接访问视频元素中的像素。相反,您必须先将整个框架复制到画布中。然后,您必须调用getImageData
,这不仅会再次复制整个帧,而且还必须再次分配整个内存块,因为它ImageData
每次都会创建一个新的。如果您可以复制到现有缓冲区中会很好,但您不能。
事实证明,您可以使用 WebGL 进行极快的图像处理。为此,我编写了一个名为Seriously.js的库。查看wiki以获取常见问题解答和教程。您可以使用一个色相/饱和度插件 - 只需将饱和度降至 -1 即可让您的视频变为灰度。
代码将如下所示:
var composition = new Seriously();
var effect = composition.effect('hue-saturation');
var target = composition.target('#mycanvas');
effect.source = '#myvideo';
effect.saturation = -1;
target.source = effect;
composition.go();
使用 WebGL 的最大缺点是并非所有浏览器或计算机都支持它 - Internet Explorer 已经过时,任何带有旧的或奇怪的视频驱动程序的机器也是如此。大多数移动浏览器不支持它。你可以在这里和这里得到很好的统计数据。但是你可以在相当大的视频上获得非常高的帧速率,即使是更复杂的效果。
(还有一个浏览器错误的小问题,奇怪的是,它同时出现在Chrome和Firefox中。您的画布通常会在视频后面一帧,这只有在视频暂停时才会出现问题,并且是最令人震惊的如果您跳过。唯一的解决方法似乎是继续强制更新,即使您的视频被暂停,这样效率较低。请随时投票给这些票,以便他们得到一些关注。)