用于连接的 FFmpeg 管道输入

blu*_*yke 5 c# ffmpeg unity-game-engine

我正在尝试使用 ffmpeg 制作实时录像机(不是屏幕录像机,特定尺寸的统一播放器录像机)

我能够获取 ARGB 数据,到目前为止,我一直将其写入一堆 bmp,然后运行 ​​ffmpegs concat 命令,例如

ffmpeg -i files.txt -i pictures/pic%06d.bmp output.mp4

使用不同的编解码器等,我的 files.txt 本质上是(伪)

ffconcat version 1.0 file pic000000.bmp duration 0.016 #etc, basically the durations were generated from time stamps

无论如何,不​​管你信不信,所有作品都将文件作为 bmp 写入磁盘(或者甚至将它们编码为压缩格式,然后将其写入磁盘)会占用大量额外时间,我更愿意将数据直接通过管道传输到 ffmpeg

我知道在某些情况下,您可以使用运算符输入文件-,然后在任何编程语言中,价格都是从通过标准输入传递字节数据开始的,我很确定,尽管问题是:

我只能找到如何使用设定的帧速率来做到这一点,但不能使用 concat,而且我(认为?)我需要在这里使用 concat,因为图像在主体上有准确的时间戳非常重要与音频对齐,因为捕获帧时会有轻微的延迟,到目前为止,我一直在根据时间戳计算每个帧的持续时间(最后一个没有持续时间),以便将它们与音频,但据我所知,连接功能似乎要求文件已写入磁盘,然后在文本文件中指定。

那么有没有什么方法可以为每个帧获取自定义帧速率,而无需先将帧写入磁盘,然后将它们通过管道传输呢?concat 以任何方式支持吗-?还有其他方法可以将帧与音频对齐吗?其他视频录制软件是否也遇到类似问题?

llo*_*gan 1

管道

我无权访问你的图像/视频/数据生成器,所以我不知道它在做什么,但你至少可以尝试一个管道:

your_data_process - | ffmpeg -f rawvideo -framerate 25 -pixel_format argb -video_size 640x480 -i - output.mp4
Run Code Online (Sandbox Code Playgroud)
  • your_data_process在这个例子中只是一个占位符示例,用于生成视频的任何内容。
  • -f应该是your_data_process输出的任何格式。请参阅ffmpeg -demuxers参考资料 以获得一长串列表。此示例假设原始视频。
  • 必须设置帧速率,但这并不一定意味着它会扰乱您的计时。
  • 如果您的玩家确实喜欢输出,请添加-vf format=yuv420p输出选项。

图像

另一种方法是输出到单个图像文件并为每次更改自动覆盖该文件。ffmpeg然后将使用该文件作为输入,并会注意到它何时更新。

ffmpeg -f image2 -loop 1 -framerate 25 -i input.bmp output.mp4
Run Code Online (Sandbox Code Playgroud)
  • 通常您不必-f image2为大多数图像输入手动设置。在这种情况下你必须这样做,否则它不会注意到图像更新。这是因为它会为某些图像格式选择更简单的解复用器。

  • 在此示例中ffmpeg,将复制帧以填充 25 fps,直到下一次图像更新,因此应保留计时。

  • 如果您的玩家确实喜欢输出,请添加-vf format=yuv420p输出选项。