从 ffmpeg 流式传输视频并使用 OpenCV 捕获
我有一个视频流通过 rtp 传入 ffmpeg,我想将其传输到我的 OpenCV 工具以进行实时流处理。 rtp 链接正在工作,因为我能够将传入数据发送到文件并播放它(或者如果通过 ffplay 则播放)。我的 OpenCV 实现也很实用,因为我能够从文件和网络摄像头捕获视频。
问题是流式传输到 OpenCV。我听说这可以使用命名管道来完成。首先,我可以将 ffmpeg 输出流式传输到管道,然后让 OpenCV 打开该管道并开始处理。
我尝试过的:
我在 cygwin bash 中通过以下方式创建了一个命名管道:
$ mkfifo stream_pipe
接下来我使用 ffmpeg 命令从 rtp 中提取流并将其发送到管道:
$ ffmpeg -f avi -i rtp://xxx.xxx.xxx.xxx:1234 -f avi -y out.avi > stream_pipe
我不确定这是否是正确的方法将流发送到命名管道,但它似乎正在接受命令并工作,因为 ffmpeg 的输出为我提供了比特率、fps 等。
接下来,我在 OpenCV 捕获函数中使用命名管道:
$ ./cvcap.exe stream_pipe
其中 cvcap.cpp 的代码归结为:
cv::VideoCapture *pIns = new cv::VideoCapture(argv[1]);
程序在到达这一行时似乎挂起,所以,我想知道这是否是解决此问题的正确方法。我以前从未使用过命名管道,我不确定这是否是正确的用法。另外,我不知道是否需要在 OpenCV 中以不同的方式处理命名管道——更改代码以接受此类输入。就像我说的,我的代码已经接受文件和摄像头输入,我只是挂在传入的流上。我只听说命名管道可以用于 OpenCV——我还没有看到任何实际的代码或命令!
任何帮助或见解表示赞赏!
更新:
我相信命名管道可能无法按我预期的方式工作。如 此 cygwin 论坛帖子所示:
问题是 Cygwin 的 fifos 实现有很多错误。除了最简单的应用程序之外,我不建议使用 fifo。
我可能需要找到另一种方法来做到这一点。我尝试将 ffmpeg 输出通过管道传输到普通文件中,然后让 OpenCV 同时读取它。这在某种程度上有效,但我想同时从文件中读取和写入可能会很危险——谁知道会发生什么!
I have a video stream coming in on rtp to ffmpeg and I want to pipe this to my OpenCV tools for live streaming processing. The rtp linkage is working because I am able to send the incoming data to a file and play it (or play if via ffplay). My OpenCV implementation is functional as well because I am able to capture video from a file and also a webcam.
The problem is the streaming to OpenCV. I have heard that this may be done using a named pipe. First I could stream the ffmpeg output to the pipe and then have OpenCV open this pipe and begin processing.
What I've tried:
I make a named-pipe in my cygwin bash by:
$ mkfifo stream_pipe
Next I use my ffmpeg command to pull the stream from rtp and send it to the pipe:
$ ffmpeg -f avi -i rtp://xxx.xxx.xxx.xxx:1234 -f avi -y out.avi > stream_pipe
I am not sure if this is the right way to go about sending the stream to the named pipe but it seems to be accepting the command and work because of the output from ffmpeg gives me bitrates, fps, and such.
Next I use the named pipe in my OpenCV capture function:
$ ./cvcap.exe stream_pipe
where the code for cvcap.cpp boils down to this:
cv::VideoCapture *pIns = new cv::VideoCapture(argv[1]);
The program seems to hang when reaching this one line, so, I am wondering if this is the right way of going about this. I have never used named pipes before and I am not sure if this is the correct usage. In addition, I don't know if I need to handle the named pipe differently in OpenCV--change code around to accept this kind of input. Like I said, my code already accepts files and camera inputs, I am just hung up on a stream coming in. I have only heard that named pipes can be used for OpenCV--I haven't seen any actual code or commands!
Any help or insights are appreciated!
UPDATE :
I believe named pipes may not be working in the way I intended. As seen on this cygwin forum post:
The problem is that Cygwin's implementation of fifos is very buggy. I wouldn't recommend using fifos for anything but the simplest of applications.
I may need to find another way to do this. I have tried to pipe the ffmpeg output into a normal file and then have OpenCV read it at the same time. This works to some extent, but I imagine in can be dangerous to read and write from a file concurrently--who knows what would happen!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
希望现在回答还不算太晚,但我前段时间也尝试过同样的事情,这就是我的做法。
OpenCV 的视频解码后端实际上是 ffmpeg,因此它的所有功能在 OpenCV 中也可用。并非所有接口都公开,这增加了一些困难,但您可以将 rtp 流地址发送到 OpenCV。
重要:OpenCV 无法访问受密码保护的 rtp 流。为此,您需要提供用户名和密码,没有为此公开的 API。
hope it's not too late to answer, but I have tried the same thing some time ago, and here is how I did it.
The video-decoding backend for OpenCV is actually ffmpeg, so all its facitilites are available in OpenCV as well. Not all the interface is exposed, and that adds some difficulties, but you can send the rtp stream address to OpenCV.
Important: OpenCV is not able to access password-protected rtp streams. To do that, you would need to provide the username and the password, there is no API exposed for it.