3
votes

I'm on windows 10 using python 3.6.4, installed opencv (3.4) through pip. Here's the code I'm using:

import numpy as np
import cv2
cap = cv2.VideoCapture("rtsp://192.168.0.100:554/onvif1")
while(True):
    ret, frame = cap.read()
    print(frame)
    cv2.imshow('frame',frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()

[rtsp @ 0000016f6d5995a0] Nonmatching transport in server reply warning: Error opening file (/build/opencv/modules/videoio/src/cap_ffmpeg_impl.hpp:834) warning: rtsp://192.168.0.100:554/onvif1 (/build/opencv/modules/videoio/src/cap_ffmpeg_impl.hpp:835)

But when I'm using ffmpeg code:

ffplay rtsp://192.168.0.100:554/onvif1 --> Capture oke
ffplay -rtsp_transport udp rtsp://192.168.0.100:554/onvif1 --> Capture oke
ffplay -rtsp_transport tcp rtsp://192.168.0.100:554/onvif1 --> Nonmatching transport in server reply

Can you help me, please?

4

4 Answers

10
votes

As mentionned, I tried to put in the python code the following:

import os
  os.environ["OPENCV_FFMPEG_CAPTURE_OPTIONS"] = "rtsp_transport;0"

or

import os
  os.environ["OPENCV_FFMPEG_CAPTURE_OPTIONS"] = "rtsp_transport;udp"

or

import os
  os.environ["OPENCV_FFMPEG_CAPTURE_OPTIONS"] = "dummy"

unfortunately none was working as I was still running my program in the same cmd window.

I simply opened a new cmd window and gave a try for a new run... and it works (with "rtsp_transport;0" :)

4
votes

To force the RTSP to use UDP insted TCP, you can change the enviroment variable OPENCV_FFMPEG_CAPTURE_OPTIONS.

In C/C++ it can be done like that:

#if WIN32
    _putenv_s("OPENCV_FFMPEG_CAPTURE_OPTIONS", "rtsp_transport;udp");
#else
    setenv("OPENCV_FFMPEG_CAPTURE_OPTIONS", "rtsp_transport;udp", 1);
#endif

cap = VideoCapture("rtsp://192.168.0.100:554/onvif1", cv::CAP_FFMPEG);

On Python, I think you can change the environment variable doing that:

import os
os.environ["OPENCV_FFMPEG_CAPTURE_OPTIONS"] = "rtsp_transport;udp"

cap = cv2.VideoCapture("rtsp://192.168.0.100:554/onvif1", cv2.CAP_FFMPEG)

I tested only the C++ solution, the Python one I'm not sure. Please test.

0
votes

OpenCV defaults to using TCP for RTP transport, and it seems that your device does not support that (as can be seen with FFmpeg). OpenCV stie actually has a question on the same topic. Here is the github issue that mentions switching to TCP. There does not seem to be a way to force UDP in OpenCV. So you have two options:

  1. Recompile OpenCV and enable UDP in the sources by default (the question above mentions how to do that)
  2. Use an older version of OpenCV before this change was introduced
  3. Try to enable TCP on the device
0
votes
  1. Set env variable OPENCV_FFMPEG_CAPTURE_OPTIONS
  2. Create and start a process with video capture code
  3. Join the process
# file package/__main__.py

import os
from multiprocessing import Process
from package.main import run

if __name__ == '__main__':
    os.environ["OPENCV_FFMPEG_CAPTURE_OPTIONS"] = "rtsp_transport;udp"
    p = Process(target=run)
    p.start()
    p.join()

# file package/main.py

import numpy as np
import cv2


def run():
    capture = cv2.VideoCapture("rtsp://192.168.1.150/onvif1", cv2.CAP_FFMPEG)
    while True:
        result, frame = capture.read()
        cv2.imshow('video', frame)

        if cv2.waitKey(16) == ord("q"):
            break