Port missing in uri warning: Error opening http URL with Python cv2.VideoCapture() on Jetson

I’m trying to connect a Axis network camera with Jetson xavier using cv2.VideoCapture() , but I get the following error and cannot connect.

How can I get connected?
On my other Ubuntu PC, I was able to connect with the same program.

[tcp @ 0x28bb6cd0] Port missing in uri
[ WARN:0] global /home/nvidia/host/build_opencv/nv_opencv/modules/videoio/src/cap_gstreamer.cpp (1757) handleMessage OpenCV | GStreamer warning: Embedded video playback halted; module source reported: Could not resolve server name.
[ WARN:0] global /home/nvidia/host/build_opencv/nv_opencv/modules/videoio/src/cap_gstreamer.cpp (886) open OpenCV | GStreamer warning: unable to start pipeline
[ WARN:0] global /home/nvidia/host/build_opencv/nv_opencv/modules/videoio/src/cap_gstreamer.cpp (480) isPipelinePlaying OpenCV | GStreamer warning: GStreamer: pipeline have not been created

The program is as follows:


from threading import Thread
import cv2
import time

class VideoScreenshot(object):

def __init__(self, src=0):

    self.capture = cv2.VideoCapture(src)

    # Take screenshot every x seconds
    self.screenshot_interval = 1

    # Default resolutions of the frame are obtained (system dependent)
    self.frame_width = int(self.capture.get(3))
    self.frame_height = int(self.capture.get(4))

    # Start the thread to read frames from the video stream
    self.thread = Thread(target=self.update, args=())
    self.thread.daemon = True
    self.thread.start()

def update(self):
    # Read the next frame from the stream in a different thread
    while True:
        if self.capture.isOpened():
            (self.status, self.frame) = self.capture.read()

def show_frame(self):
    # Display frames in main program
    
    if self.status:
        cv2.imshow('frame', self.frame)
    
    # Press Q on keyboard to stop recording
    key = cv2.waitKey(1)
    if key == ord('q'):
        self.capture.release()
        cv2.destroyAllWindows()
        exit(1)

if name == ‘main’:

stream_link = 'http://root:password@192.xxx.x.xx/mjpg/1/video.mjpg?resolution=1920x1080'
video_stream_widget = VideoScreenshot(stream_link)

while True:
    try:
        video_stream_widget.show_frame()
    except AttributeError:
        pass

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

Also, when the stream link is rtsp, it connects to the camera, but there is a huge delay, so I would like to use htttp.

Hi,
Not sure if http link works in cv2.VideoCapture(). This would need other users to share experience.

We suggest try RTSP in gst-launch-1.0 command like:

$ gst-launch-1.0 uridecodebin uri=rtsp://_URI_OF_THE_SOURCE_ ! nvoverlaysink

If above command works, please apply the URI to this python sample and give it a try:
Doesn't work nvv4l2decoder for decoding RTSP in gstreamer + opencv - #3 by DaneLLL

Thanks for the reply.

I’ve tried rtsp before and confirmed that it connects, but I want to use http because of the high latency.

On my other PC, I was able to connect using http, so what is different about jetson?

In addition, is there any other way to connect to a network camera in python other than cv2.VideoCapture()?

Hi,
You may check if you can construct a gstreamer pipeline for http protocol. Not sure but may be able to utilize this plugin: souphttpsrc

We don’t have much experience in receiving http stream. You may go to gstreamer forum to get further assistance. Once you get a working pipeline with software decoder such as avdec_h264, you can replace it with nvv4l2decoder to enable hardware decoding.

You can use two ways from opencv. With ffmpeg or gstreamer. The latter is by far the easiest on jetson to get good performance. This works for me:

cap = cv2.VideoCapture("uridecodebin uri=http://192.168.0.40:8080/playlist.m3u8 ! nvvidconv ! video/x-raw,format=BGRx ! videoconvert ! video/x-raw,format=BGR ! appsink drop=1", cv::CAP_GSTREAMER);

With ffmpeg capture backend, in my case it works with C++

  setenv ("OPENCV_FFMPEG_CAPTURE_OPTIONS", "protocol_whitelist;tcp,http", 1);
  cap->open("http://192.168.0.40:8080/playlist.m3u8", cv::CAP_FFMPEG);

but python crashes with:

import os
os.environ["OPENCV_FFMPEG_CAPTURE_OPTIONS"] = "protocol_whitelist;tcp,http;1"
cap = cv2.VideoCapture("http://192.168.0.40:8080/playlist.m3u8", cv2.CAP_FFMPEG)

Anyway, you would need an opencv build configured for a FFMPEG version having HW acceleration and this is not trivial.

Try gstreamer pipeline with uridecodebin.