Skip to content

Commit 6bb9900

Browse files
committed
Refactor Rtsp client
1 parent f26045a commit 6bb9900

File tree

2 files changed

+32
-71
lines changed

2 files changed

+32
-71
lines changed

RtspClient.py

Lines changed: 25 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,47 @@
1-
import socket
2-
1+
import os
32
import cv2
4-
import numpy
5-
import socks
63

74

85
class RtspClient:
96

10-
def __init__(self, ip, username, password, port=554, profile="main", **kwargs):
7+
def __init__(self, ip, username, password, port=554, profile="main", use_udp=True, **kwargs):
118
"""
129
13-
:param ip:
14-
:param username:
15-
:param password:
16-
:param port: rtsp port
10+
:param ip: Camera IP
11+
:param username: Camera Username
12+
:param password: Camera User Password
13+
:param port: RTSP port
1714
:param profile: "main" or "sub"
15+
:param use_upd: True to use UDP, False to use TCP
1816
:param proxies: {"host": "localhost", "port": 8000}
1917
"""
18+
capture_options = 'rtsp_transport;'
2019
self.ip = ip
2120
self.username = username
2221
self.password = password
2322
self.port = port
24-
self.sockt = None
25-
self.url = "rtsp://" + self.username + ":" + self.password + "@" + self.ip + ":" + str(
26-
self.port) + "//h264Preview_01_" + profile
2723
self.proxy = kwargs.get("proxies")
24+
self.url = "rtsp://" + self.username + ":" + self.password + "@" + \
25+
self.ip + ":" + str(self.port) + "//h264Preview_01_" + profile
26+
if use_udp:
27+
capture_options = capture_options + 'udp'
28+
else:
29+
capture_options = capture_options + 'tcp'
2830

29-
def __enter__(self):
30-
self.sockt = self.connect()
31-
return self
32-
33-
def __exit__(self, exc_type, exc_val, exc_tb):
34-
self.sockt.close()
35-
36-
def connect(self) -> socket:
37-
try:
38-
sockt = socks.socksocket(socket.AF_INET, socket.SOCK_STREAM)
39-
sockt.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
40-
if self.proxy is not None:
41-
sockt.set_proxy(socks.SOCKS5, self.proxy["host"], self.proxy["port"])
42-
sockt.connect((self.ip, self.port))
43-
return sockt
44-
except Exception as e:
45-
print(e)
46-
47-
def get_frame(self) -> bytearray:
48-
try:
49-
self.sockt.send(str.encode(self.url))
50-
data = b''
51-
while True:
52-
try:
53-
r = self.sockt.recv(90456)
54-
if len(r) == 0:
55-
break
56-
a = r.find(b'END!')
57-
if a != -1:
58-
data += r[:a]
59-
break
60-
data += r
61-
except Exception as e:
62-
print(e)
63-
continue
64-
nparr = numpy.fromstring(data, numpy.uint8)
65-
frame = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
66-
return frame
67-
except Exception as e:
68-
print(e)
31+
os.environ["OPENCV_FFMPEG_CAPTURE_OPTIONS"] = capture_options
6932

7033
def preview(self):
7134
""" Blocking function. Opens OpenCV window to display stream. """
72-
self.connect()
73-
win_name = 'RTSP'
74-
cv2.namedWindow(win_name, cv2.WINDOW_AUTOSIZE)
75-
cv2.moveWindow(win_name, 20, 20)
35+
win_name = self.ip
36+
cap = cv2.VideoCapture(self.url, cv2.CAP_FFMPEG)
37+
ret, frame = cap.read()
38+
39+
while ret:
40+
cv2.imshow(win_name, frame)
7641

77-
while True:
78-
cv2.imshow(win_name, self.get_frame())
79-
# if self._latest is not None:
80-
# cv2.imshow(win_name,self._latest)
81-
if cv2.waitKey(25) & 0xFF == ord('q'):
42+
ret, frame = cap.read()
43+
if (cv2.waitKey(1) & 0xFF == ord('q')):
8244
break
83-
cv2.waitKey()
45+
46+
cap.release()
8447
cv2.destroyAllWindows()
85-
cv2.waitKey()

api/recording.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,15 @@ def get_recording_advanced(self) -> object:
3030
###########
3131
# RTSP Stream
3232
###########
33-
def open_video_stream(self, profile: str = "main") -> Image:
33+
def open_video_stream(self, profile: str = "main", proxies=None) -> None:
3434
"""
35-
profile is "main" or "sub"
36-
https://support.reolink.com/hc/en-us/articles/360007010473-How-to-Live-View-Reolink-Cameras-via-VLC-Media-Player
37-
:param profile:
38-
:return:
35+
'https://support.reolink.com/hc/en-us/articles/360007010473-How-to-Live-View-Reolink-Cameras-via-VLC-Media-Player'
36+
:param profile: profile is "main" or "sub"
37+
:param proxies: Default is none, example: {"host": "localhost", "port": 8000}
3938
"""
40-
with RtspClient(ip=self.ip, username=self.username, password=self.password,
41-
proxies={"host": "127.0.0.1", "port": 8000}) as rtsp_client:
42-
rtsp_client.preview()
39+
rtsp_client = RtspClient(
40+
ip=self.ip, username=self.username, password=self.password, proxies=proxies)
41+
rtsp_client.preview()
4342

4443
def get_snap(self, timeout: int = 3, proxies=None) -> Image or None:
4544
"""

0 commit comments

Comments
 (0)