我有一个 Electron JS 应用程序,我在其中绘制到 Canvas ,然后将每一帧发送到 ffmpeg 以创建视频。它运行良好,但性能不是很好。这就是我目前的做法:
- 我有一个图像流(新的 PassThrough)通过管道传输到我的 ffmpeg 进程
- 框架准备就绪后,我使用 canvas.toBlob() 将其转换为 blob
- 我将 blob 转换为 arrayBuffer
- 并使用 Buffer.from() 获取缓冲区
- 我使用 .write() 将缓冲区写入图像流
我已经测量了每一步花费的时间,到目前为止,瓶颈是 canvas.toBlob
有没有办法更快地完成整个过程或 toBlob 步骤?我查看了 HTMLCanvasElement.captureStream() 但我认为我无法将其通过管道传输到 ffmpeg。
我正在使用 P5js 进行绘图。似乎没有办法直接绘制(更多)到 blob 或缓冲区。甚至 p5.Graphics 似乎也绘制到隐藏的 Canvas 上 https://p5js.org/reference/#/p5.Graphics
谢谢
最佳答案
您应该能够完全跳过 blob 转换。来自 HTML5 Canvas 的原始图像数据已作为 RGBA 格式的 Uint8ClampedArray 提供。 canvas.toBlob
进行图像编码(默认为 PNG)需要大量时间,然后将其转换回数组缓冲区会浪费额外的时间。但是,FFmpeg 可以配置为以未压缩的形式获取原始视频,因此完全不需要通过 blob 进行编码和往返并返回到 arraybuffer 格式(您需要在命令行选项中使用类似 -vcodec rawvideo -pix_fmt rgba -s <width>x<height>
的内容)。
为 FFmpeg 获取正确的命令行选项,您应该能够使用 CanvasRenderingContext2D.getImageData().data
并每帧一次将其直接流式传输到 FFmpeg。
关于javascript - 最快的 Canvas 到 ffmpeg 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64900133/