【问题标题】:OpenCV won't capture frames from a RTMP source, while FFmpeg doesOpenCV 不会从 RTMP 源捕获帧,而 FFmpeg 会
【发布时间】:2015-07-17 17:54:36
【问题描述】:

我的目标是每秒从 rtmp 流中捕获一帧,并使用 OpenCV 对其进行处理。我正在使用带有 Java 接口的 FFmpeg 版本 N-71899-g6ef3426 和 OpenCV 2.4.9(但我首先尝试使用 Python)。 目前,我只能采取简单而肮脏的解决方案,即使用 FFmpeg 捕获图像,将它们存储在磁盘中,然后从我的 OpenCV 程序中读取这些图像。这是我正在使用的 FFmpeg 命令:

ffmpeg -i "rtmp://antena3fms35livefs.fplive.net:1935/antena3fms35live-live/stream-lasexta_1 live=1" -r 1 capImage%03d.jpg

这目前对我有用,至少对于这个具体的 rtmp 源。然后我需要以适当的方式从我的 OpenCV 程序中读取这些图像。我还没有真正实现这部分,因为我正在尝试找到更好的解决方案。

我认为理想的方法是直接从 OpenCV 捕获 rtmp 帧,但我找不到这样做的方法。这是我正在使用的 Python 代码:

cv2.namedWindow("camCapture", cv2.CV_WINDOW_AUTOSIZE)
cap = cv2.VideoCapture()
cap.open('"rtmp://antena3fms35livefs.fplive.net:1935/antena3fms35live-live/stream-lasexta_1 live=1"')
if not cap.open:
    print "Not open"
while (True):
    err,img = cap.read()
    if img and img.shape != (0,0):
        cv2.imwrite("img1", img)
        cv2.imshow("camCapture", img)
    if err:
        print err
        break
    cv2.waitKey(30)

我也在尝试使用grab() 和retrieve() 函数而不是read() 函数,但没有任何好的结果。每次都在执行 read() 函数,但没有收到“img”或“err”。 还有其他方法吗?或者也许没有办法从这样的流中直接从 OpenCV 2.4.9 获取帧?

我已经阅读过 OpenCV 使用 FFmpeg 来执行此类任务,但正如您所见,在我的情况下,FFmpeg 能够从流中获取帧,而 OpenCV 则不能。

如果我找不到直接从 OpenCV 获取帧的方法,我的下一个想法是以某种方式将 FFmpeg 输出到 OpenCV,这似乎更难实现。

任何想法, 谢谢!

更新 1: 我在 Windows 8.1 中。由于我是从 Eclipse PyDev 运行 python 脚本,所以这次我从 cmd 运行它,我收到以下警告:

warning: Error opening file (../../modules/highgui/src/cap_ffmpeg_impl.hpp:545)

据我所知,此警告意味着文件路径错误或不支持编解码器。现在,问题是一样的。 OpenCV 是否无法从该来源获取帧?

【问题讨论】:

  • 我得到同样的错误,任何更新
  • 我不能那样解决它。我认为至少 2.4.9 版本的 OpenCV 不支持那些类型的编解码器(参考我的 UPDATE 1)。最后,我通过用 FFmpeg 输出提供 OpenCV 的输入,将 FFmpeg 集成到我的程序中。如果您找到更清洁的解决方案,请告诉我。
  • 你能解决这个错误吗?
  • 我在重新启动 mac 后遇到了同样的问题。 !_img.empty() 来自本地 rmpt 的函数“imwrite”

标签: opencv video ffmpeg rtmp


【解决方案1】:
python -c "import cv2; print(cv2.getBuildInformation())"   

检查build opencv with ffmpeg。如果正确,你的代码应该没问题。

如果没有,用ffmpeg重建opencv。 osx下

brew install opencv --with-ffmpeg

【讨论】:

    【解决方案2】:

    实际上我花了更多的时间来弄清楚如何解决这个问题。最后我在this link 的帮助下解决了这个问题。 这是客户端代码。

        #include <opencv2/core/core.hpp>
        #include <opencv2/imgproc/imgproc.hpp>
        #include <opencv2/highgui/highgui.hpp>
        #include <opencv2/opencv.hpp>
    
        using namespace cv;
    
        int main(int, char**) {
            cv::VideoCapture vcap;
            cv::Mat image;
            const std::string videoStreamAddress = "rtmp://192.168.173.1:1935/live/test.flv";
            if(!vcap.open(videoStreamAddress)) {
                std::cout << "Error opening video stream or file" << std::endl;
                return -1;
            }
    
            cv::namedWindow("Output Window");
            cv::Mat edges;
            for(;;) {
                if(!vcap.read(image)) {
                    std::cout << "No frame" << std::endl;
                    cv::waitKey();
                }
                cv::imshow("Output Window", image);
                if(cv::waitKey(1) >= 0) break;
            }
        }
    

    注意:在这种情况下,我创建了一个 android 应用程序来获取实时视频并将其发送到部署在 PC 中的 rtmp 服务器wowza。这就是我为实时视频处理创建这个 c++ 实现的地方。

    【讨论】:

    • 您的代码适用于我尝试过的一些 rtmp 源。恭喜!
    猜你喜欢
    • 2020-10-27
    • 2013-10-04
    • 2012-05-21
    • 2021-11-26
    • 1970-01-01
    • 2020-12-19
    • 2014-06-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多