gpt4 book ai didi

node.js - 仅在 Linux 上将原始图像字节馈送到 ffmpeg rawvideo 失败,缓冲区大小无效

转载 作者:行者123 更新时间:2023-12-04 22:50:06 27 4
gpt4 key购买 nike

我有一个 nodejs 程序,它生成原始(rgb24)图像,然后我将其通过管道传输到 ffmpeg 中,以便将其保存为 png 或 mp4。我的代码如下所示:

const fs = require("fs");
// ...
const outputBuffer = Buffer.alloc(outputPngWidth * 3 * outputPngHeight);
// ... write data into outputBuffer
fs.writeSync(process.stdout.fd, outputBuffer);
然后我在 CLI 中执行以下操作:
node generate | ffmpeg -f rawvideo -pixel_format rgb24 -video_size 1000x1000 -i - test.png
或者,如果我从我的程序中生成大量图像,我会这样做来生成视频文件:
node generate | ffmpeg -f rawvideo -pixel_format rgb24 -video_size 1000x1000 -r 60 -i - -codec:v libx265 test.mp4
在 Windows 上,这可以完美运行。在 linux 上(在 Ubuntu 20 VM 上,或直接安装在物理机上的 Ubuntu 20 上),它始终失败并显示:
pipe:: corrupt input packet in stream 0
[rawvideo @ 0x55f5256c8040] Invalid buffer size, packet size 65536 < expected frame_size 3000000
Error while decoding stream #0:0: Invalid argument
如果我像这样将它分成两个阶段,那么它也可以在 linux 上完美运行:
node generate > test.raw
cat test.raw | ffmpeg -f rawvideo -pixel_format rgb24 -video_size 1000x1000 -i - test.png
通过查看错误“数据包大小 65536 < 预期 frame_size 3000000”,似乎 Node 的 fs.writeSync 一次只发送 65536 个字节,但 ffmpeg 预计 3000000 个字节(即 1000 宽度 * 1000 高度 * 3 个 channel )。
如果我将图像尺寸缩小到较小的尺寸,例如 50x50 或 100x100,那么它可以工作。一旦 x * y * 3 超过 65536,它就会失败(例如,160x160 失败,“数据包大小 65536 < 预期 frame_size 76800”,因为 160 * 160 * 3 = 76800)。
到目前为止,我尝试解决的问题没有运气:
  • 强制 Node 一次吐出整个缓冲区:
  • fs.writeSync(process.stdout.fd, outputBuffer, 0, outputBuffer.length);
  • Add a big buffer to a pipe between two commands 的所有建议,带有各种 linux 命令在 nodeffmpeg 之间缓冲。
  • 使用 Ubuntu 18 而不是 20。
  • 使用 Node 12 而不是 15。
  • 想办法改变https://nodejs.org/api/fs.html中的 block 大小

  • 有没有办法克服这个问题?

    最佳答案

    这是在黑暗中刺伤,我知道以下内容可能听起来很奇怪。
    从测试中看到错误消息,似乎 ffmpeg 在等待足够的数据时超时,并且生成器同时没有足够快地填充管道。
    我问自己,尽管 ffmpeg - 希望 - 会使用阻塞读取调用,但如何显然会超时收听 STDIN?好吧,也许它不会对 read 进行阻塞调用,而是在文件描述符上调用 select 并使用短暂的超时,然后在等待足够的数据时遇到该超时。
    一个简洁的解释是,如果系统一直忙于生成数据或使用数据,即对方总是空闲的。
    既然你说它是一个运行所有这些的虚拟机,我可以想象虚拟机被配置为只有一个可用的 CPU。然后它可以在任何给定时间只执行两个进程中的一个,这些进程竞争 CPU。
    我可以看到您运行的其他测试支持这一点:您首先创建了测试数据并将其存储在一个文件中。然后你让 ffmpeg 消费它。每个进程都可以全时使用可用的 CPU。没有竞争。
    此外,如果多 CPU 或多超线程系统足够忙于其他具有更高优先级的进程,它也可能会暴露此行为。
    底线:我会确保我的虚拟机对这两个进程都有足够的处理能力。

    关于node.js - 仅在 Linux 上将原始图像字节馈送到 ffmpeg rawvideo 失败,缓冲区大小无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66060074/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com