使用命名管道向 ffmpeg 提供输入

Posted

技术标签:

【中文标题】使用命名管道向 ffmpeg 提供输入【英文标题】:Give input to ffmpeg using named pipes 【发布时间】:2011-04-06 19:01:27 【问题描述】:

我有一个生成一系列图像的 C 程序,我想将它们制作成一个视频,该视频应该实时流式传输或存储在文件中。在阅读 ffmpeg 文档时,我反复发现 ffmpeg 可以从命名管道获取输入。

我的问题是输入到管道中的文件应该是什么格式以及如何将文件输入到管道中。

【问题讨论】:

【参考方案1】:

据我所知,对于将放入命名管道的视频格式没有任何要求。你可以放任何 ffmpeg 可以打开的东西。例如,我使用 ffmpeg 库开发了一个程序,该程序正在从命名管道读取 h264 视频并从中检索统计信息 - 命名管道是通过另一个程序填充的。对于连续视频来说,这确实是一个非常好的和干净的解决方案。

现在,关于你的情况,我相信你有一个小问题,因为命名管道只是一个文件,而 ffmpeg 将无法知道同一个文件中有多个图像!因此,如果您将命名管道声明为输入,ffmpeg 将认为您只有一个图像 - 不够好......

我能想到的一个解决方案是声明您的命名管道包含视频 - 因此 ffmpeg 将不断地从中读取并存储或流式传输它。当然,您的 C 程序需要生成该视频并将其写入命名管道……这并不像看起来那么难!您可以将图像(您没有告诉我们它们的格式是什么)转换为 YUV,然后在命名管道中一个接一个地写入(YUV 视频是一系列无标题的 YUV 图像 - 您也可以轻松地从 BPM 转换为YUV,只需检查wikipedia entry on YUV)。然后 ffmpeg 会认为命名管道包含一个简单的 YUV 文件,因此您最终可以从中读取并做任何您想做的事情。

【讨论】:

好吧,我以类似于上面的方式解决了这个问题。我使用 openCV 将 MJPEG 流输出到命名管道,然后使用 ffmpeg 对其进行编码。我认为由 openCV 在内部完成的 MJPEG 编码不应该占用太多 CPU,因为它只是连续的 jpeg 图像流。 :-) 顺便说一句,我的图像是 RGB 位图。【参考方案2】:

您可以使用 *-loop_input* 命令行选项:

ffmpeg -loop_input -re -timestamp now -f image2 -r 25 -sameq -i input.jpg -an -vcodec mpeg2video out.mp4

在您的情况下,将 input.jpg 替换为管道。然后,FFmpeg 将每 1/25 秒从输入文件(或管道)创建一个新帧。

【讨论】:

【参考方案3】:

使用带有通配符文件名的 image2,假设这些图像作为文件存在,来自 ffmpeg 文档:

for creating a video from the images in the file sequence ‘img-001.jpeg’, ‘img-002.jpeg’, ..., assuming an input frame rate of 10 frames per second:

ffmpeg -i 'img-%03d.jpeg' -r 10 out.mkv

AVFormatContext *pFormatCtx = avformat_alloc_context();
avformat_open_input(&pFormatCtx,"img-%03d.jpeg",NULL,NULL);

【讨论】:

以上是关于使用命名管道向 ffmpeg 提供输入的主要内容,如果未能解决你的问题,请参考以下文章

使用命名管道使用 FFMPEG 记录 RTP VP8 数据包

ffmpeg中的多个命名管道

使用命名管道向子进程发送参数

命名管道(C#)

将 Windows 命名管道用于 IPC 的一种有效方法

如何在 perl 中读/写命名管道?