最快的canvas转ffmpeg方法

Kaj*_*una 4 html javascript ffmpeg html5-canvas p5.js

我有一个 Electron JS 应用程序,我可以在画布上绘制内容,然后将每个帧发送到 ffmpeg 以创建视频。它运作良好,但性能不是很好。这就是我目前的做法:

  • 我有一个图像流(新的 PassThrough)通过管道传输到我的 ffmpeg 进程
  • 当框架准备就绪时,我使用 canvas.toBlob() 将其转换为 blob
  • 我将 blob 转换为 arrayBuffer
  • 并使用 Buffer.from() 获取缓冲区
  • 我使用 .write() 将缓冲区写入图像流

我测量了每个步骤所需的时间,到目前为止,瓶颈是 canvas.toBlob

有没有办法更快地完成整个过程或 toBlob 步骤?我已经研究过 HTMLCanvasElement.captureStream() 但我不认为我可以将其通过管道传递给 ffmpeg。

我正在使用 P5js 进行绘图。似乎没有办法直接(更多地)绘制到 blob 或缓冲区。甚至 p5.Graphics 似乎也绘制到隐藏的画布https://p5js.org/reference/#/p5.Graphics

谢谢

Log*_*ley 6

您应该能够完全跳过 blob 转换。HTML5 画布中的原始图像数据已作为 RGBA 格式的 Uint8ClampedArray 提供。canvas.toBlob进行图像编码(默认为 PNG)需要花费大量时间,然后您通过将其转换回数组缓冲区来浪费额外的时间。但是,FFmpeg 可以配置为以未压缩的形式获取原始视频,因此完全不需要通过 blob 进行编码和往返并返回到 arraybuffer 格式(您需要类似于-vcodec rawvideo -pix_fmt rgba -s <width>x<height>命令行选项中的内容)。

为 FFmpeg 获取正确的命令行选项,您应该能够CanvasRenderingContext2D.getImageData().data每帧使用一次并将其直接流式传输到 FFmpeg。

  • 我终于找到时间再次从事这方面的工作。我接受了这个答案,因为这种方法在小型测试项目中速度更快,就像我创建的比较:https://github.com/JuanIrache/canvas-stream-test 迄今为止最快的选择是在网络工作者中运行 ffmpeg。然而,在我的实际项目中,原始方法仍然更快。不知道为什么。会继续努力 (2认同)