修改rtsp获取帧相关代码,使得减少数据丢失,测试有效
This commit is contained in:
@@ -42,7 +42,7 @@ police_prisoner_input_size = 1280
|
||||
|
||||
# RTSP 服务配置
|
||||
RTSP_TARGET_FPS = 30.0
|
||||
FRAMES_PER_SEGMENT = 1800
|
||||
FRAMES_PER_SEGMENT = 300
|
||||
VIDEO_OUTPUT_DIR = "./videos"
|
||||
WS_HOST = "0.0.0.0"
|
||||
WS_PORT = 8765
|
||||
@@ -412,30 +412,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):
|
||||
@@ -495,6 +556,7 @@ class FrameProcessorWorker(threading.Thread):
|
||||
|
||||
def run(self):
|
||||
target_interval = 1.0 / RTSP_TARGET_FPS
|
||||
# last_processed_time = {} # 记录每个摄像头上次处理时间
|
||||
while not self.stop_event.is_set():
|
||||
try:
|
||||
item = self.raw_queue.get(timeout=0.5)
|
||||
@@ -516,6 +578,16 @@ class FrameProcessorWorker(threading.Thread):
|
||||
self.kadian_detectors[cam_id] = KadianDetector()
|
||||
detector = self.kadian_detectors[cam_id]
|
||||
|
||||
# # 计算距离上次处理的时间间隔
|
||||
# current_time = time.time()
|
||||
# time_since_last = 0
|
||||
# if cam_id in last_processed_time:
|
||||
# time_since_last = (current_time - last_processed_time[cam_id]) * 1000 # 转换为毫秒
|
||||
# last_processed_time[cam_id] = current_time
|
||||
#
|
||||
# if time_since_last > 0:
|
||||
# print(f"[DEBUG] 摄像头{cam_id} - 距离上次处理间隔: {time_since_last:.1f}ms")
|
||||
|
||||
# 2) 进行人脸识别(如果启用)
|
||||
current_face_alert = None
|
||||
face_results = []
|
||||
|
||||
Reference in New Issue
Block a user