引入新的rtsp获取流代码
This commit is contained in:
@@ -450,30 +450,91 @@ class RTSPCaptureWorker(threading.Thread):
|
||||
self.camera_cfg = camera_cfg
|
||||
self.raw_queue = raw_queue
|
||||
self.stop_event = stop_event
|
||||
# 添加重连计数器
|
||||
self.reconnect_count = 0
|
||||
self.max_reconnects = 10
|
||||
|
||||
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:
|
||||
try:
|
||||
# 方法1:使用TCP传输(更稳定)
|
||||
rtsp_url = self.camera_cfg.rtsp_url
|
||||
if "?" not in rtsp_url:
|
||||
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}")
|
||||
return
|
||||
print(f"[INFO] Capturing {self.camera_cfg.name} (ID:{self.camera_cfg.id})")
|
||||
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:
|
||||
time.sleep(0.2)
|
||||
continue
|
||||
# 检查流是否结束
|
||||
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:
|
||||
self.raw_queue.put(item, timeout=1.0)
|
||||
except queue.Full:
|
||||
# 添加队列满时的处理
|
||||
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.")
|
||||
|
||||
|
||||
# ========================= 帧处理线程 =========================
|
||||
class FrameProcessorWorker(threading.Thread):
|
||||
|
||||
Reference in New Issue
Block a user