|
1 | | -import socket |
2 | | - |
| 1 | +import os |
3 | 2 | import cv2 |
4 | | -import numpy |
5 | | -import socks |
6 | 3 |
|
7 | 4 |
|
8 | 5 | class RtspClient: |
9 | 6 |
|
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): |
11 | 8 | """ |
12 | 9 |
|
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 |
17 | 14 | :param profile: "main" or "sub" |
| 15 | + :param use_upd: True to use UDP, False to use TCP |
18 | 16 | :param proxies: {"host": "localhost", "port": 8000} |
19 | 17 | """ |
| 18 | + capture_options = 'rtsp_transport;' |
20 | 19 | self.ip = ip |
21 | 20 | self.username = username |
22 | 21 | self.password = password |
23 | 22 | self.port = port |
24 | | - self.sockt = None |
25 | | - self.url = "rtsp://" + self.username + ":" + self.password + "@" + self.ip + ":" + str( |
26 | | - self.port) + "//h264Preview_01_" + profile |
27 | 23 | 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' |
28 | 30 |
|
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 |
69 | 32 |
|
70 | 33 | def preview(self): |
71 | 34 | """ 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) |
76 | 41 |
|
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')): |
82 | 44 | break |
83 | | - cv2.waitKey() |
| 45 | + |
| 46 | + cap.release() |
84 | 47 | cv2.destroyAllWindows() |
85 | | - cv2.waitKey() |
0 commit comments