Search code examples
c#streamingrtspip-camera

Best practice how to display/receive IP network camera stream


I have a IP network camera that can stream MJPEG, H.264 and others using TCP, UDP, RTSP and so on. Within my client application I need to access this stream to get still images (capture) or the full video stream itself.

Because of network load and latency (to get the most current image), I would prefer RTSP. So I tried the MediaElement from WPF but even with the help of many posts here on Stackoverflow I did not manage to get it running.

Any help how to achieve that or which other protocol should be used?


Solution

  • I found the solution in another thread/post here. You will see that I'm only displaying every 10th frame. This is because the frame are received so fast, that imshow(...) will display destroyed/warped images. If you supply only every 10th frame to imshow(...), the result will be okay. In case the IP camera delivers 1080p on 30fps, I had to show only every 30th or 40th frame.

    #include "cv.h"
    #include "highgui.h"
    #include <iostream>
    
    int main(int, char**) {
        cv::VideoCapture vcap;
        cv::Mat image;
    
        const std::string videoStreamAddress = "rtsp://cam_address:554/live.sdp"; 
        /* it may be an address of an mjpeg stream, 
        e.g. "http://user:pass@cam_address:8081/cgi/mjpg/mjpg.cgi?.mjpg" */
    
        //open the video stream and make sure it's opened
        if(!vcap.open(videoStreamAddress)) {
            std::cout << "Error opening video stream or file" << std::endl;
            return -1;
        }
    
        int counter = 0;
        for(;;) {
            counter++;
    
            if(!vcap.read(image)) {
                std::cout << "No frame" << std::endl;
                cv::waitKey();
            }
    
            // if the picture is too large, imshow will display warped images, so show only every 10th frame
            if (counter % 10 != 0)
                continue;
    
            cv::imshow("Output Window", image);
            if(cv::waitKey(1) >= 0) break;
        }   
    }