引入新的rtsp获取流代码
This commit is contained in:
@@ -450,29 +450,90 @@ class RTSPCaptureWorker(threading.Thread):
|
|||||||
self.camera_cfg = camera_cfg
|
self.camera_cfg = camera_cfg
|
||||||
self.raw_queue = raw_queue
|
self.raw_queue = raw_queue
|
||||||
self.stop_event = stop_event
|
self.stop_event = stop_event
|
||||||
|
# 添加重连计数器
|
||||||
|
self.reconnect_count = 0
|
||||||
|
self.max_reconnects = 10
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
cap = cv2.VideoCapture(self.camera_cfg.rtsp_url, cv2.CAP_FFMPEG)
|
while not self.stop_event.is_set() and self.reconnect_count < self.max_reconnects:
|
||||||
if not cap.isOpened():
|
|
||||||
print(f"[ERROR] Cannot open RTSP: {self.camera_cfg.rtsp_url}")
|
|
||||||
return
|
|
||||||
print(f"[INFO] Capturing {self.camera_cfg.name} (ID:{self.camera_cfg.id})")
|
|
||||||
while not self.stop_event.is_set():
|
|
||||||
ret, frame = cap.read()
|
|
||||||
if not ret:
|
|
||||||
time.sleep(0.2)
|
|
||||||
continue
|
|
||||||
item = {
|
|
||||||
"camera_id": self.camera_cfg.id,
|
|
||||||
"camera_name": self.camera_cfg.name,
|
|
||||||
"timestamp": time.time(),
|
|
||||||
"frame": frame,
|
|
||||||
}
|
|
||||||
try:
|
try:
|
||||||
self.raw_queue.put(item, timeout=1.0)
|
# 方法1:使用TCP传输(更稳定)
|
||||||
except queue.Full:
|
rtsp_url = self.camera_cfg.rtsp_url
|
||||||
pass
|
if "?" not in rtsp_url:
|
||||||
cap.release()
|
rtsp_url += "?transport=tcp" # 强制TCP传输
|
||||||
|
else:
|
||||||
|
rtsp_url += "&transport=tcp"
|
||||||
|
|
||||||
|
# 方法2:添加更多FFmpeg参数
|
||||||
|
cap = cv2.VideoCapture(rtsp_url, cv2.CAP_FFMPEG)
|
||||||
|
|
||||||
|
# 方法3:设置缓冲区大小
|
||||||
|
cap.set(cv2.CAP_PROP_BUFFERSIZE, 10) # 增加缓冲区
|
||||||
|
|
||||||
|
# 方法4:设置超时和重连参数
|
||||||
|
os.environ["OPENCV_FFMPEG_CAPTURE_OPTIONS"] = \
|
||||||
|
"rtsp_transport;tcp|buffer_size;1024000|max_delay;500000|stimeout;2000000"
|
||||||
|
|
||||||
|
# 方法5:设置解码器flags,忽略解码错误
|
||||||
|
# cap.set(cv2.CAP_PROP_HW_ACCELERATION, cv2.VIDEO_ACCELERATION_ANY)
|
||||||
|
|
||||||
|
if not cap.isOpened():
|
||||||
|
print(f"[ERROR] Cannot open RTSP: {self.camera_cfg.rtsp_url}")
|
||||||
|
time.sleep(2)
|
||||||
|
self.reconnect_count += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
print(f"[INFO] Successfully opened RTSP: {self.camera_cfg.name}")
|
||||||
|
self.reconnect_count = 0 # 重置重连计数
|
||||||
|
|
||||||
|
# # 设置帧率(可选)
|
||||||
|
# cap.set(cv2.CAP_PROP_FPS, 25)
|
||||||
|
|
||||||
|
while not self.stop_event.is_set():
|
||||||
|
ret, frame = cap.read()
|
||||||
|
if not ret:
|
||||||
|
# 检查流是否结束
|
||||||
|
print(f"[WARN] Failed to read frame from {self.camera_cfg.name}")
|
||||||
|
|
||||||
|
# 检查是否还有数据
|
||||||
|
time.sleep(0.1)
|
||||||
|
# 尝试几次后重连
|
||||||
|
break
|
||||||
|
|
||||||
|
item = {
|
||||||
|
"camera_id": self.camera_cfg.id,
|
||||||
|
"camera_name": self.camera_cfg.name,
|
||||||
|
"timestamp": time.time(),
|
||||||
|
"frame": frame,
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
# 添加队列满时的处理
|
||||||
|
if self.raw_queue.full():
|
||||||
|
# 丢弃最旧的一帧
|
||||||
|
try:
|
||||||
|
self.raw_queue.get_nowait()
|
||||||
|
self.raw_queue.task_done()
|
||||||
|
except queue.Empty:
|
||||||
|
pass
|
||||||
|
|
||||||
|
self.raw_queue.put(item, timeout=0.5)
|
||||||
|
except queue.Full:
|
||||||
|
print(f"[WARN] Queue full, dropping frame from {self.camera_cfg.name}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 控制读取速度,避免过快
|
||||||
|
time.sleep(0.02) # 约50ms间隔
|
||||||
|
|
||||||
|
cap.release()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[ERROR] Error in RTSP capture for {self.camera_cfg.name}: {e}")
|
||||||
|
time.sleep(2)
|
||||||
|
self.reconnect_count += 1
|
||||||
|
|
||||||
|
if self.reconnect_count >= self.max_reconnects:
|
||||||
|
print(f"[ERROR] Max reconnects reached for {self.camera_cfg.name}, stopping.")
|
||||||
|
|
||||||
|
|
||||||
# ========================= 帧处理线程 =========================
|
# ========================= 帧处理线程 =========================
|
||||||
|
|||||||
Reference in New Issue
Block a user