import threading import queue import datetime import cv2 from core.DBManager import DBManager from myutils.ConfigManager import myCongif class WarnData: def __init__(self): self.width = None #视频画面的width self.height = None #视频画面的height self.channel_id = None self.model_name = None #模型名称,如人员入侵 self.img_buffer = None #视频缓冲区 赋值时要拷贝一个备份 self.warn_text = None self.channel_name = None class WarnManager: def __init__(self): self.warn_q = queue.Queue() #线程安全 self.brun = True # 保存视频相关内容 self.FPS = myCongif.get_data("verify_rate") # 视频帧率--是否能实现动态帧率 self.fourcc = cv2.VideoWriter_fourcc(*'mp4v') # 使用 mp4 编码 def __del__(self): pass def add_warn_data(self,warn_data): self.warn_q.put(warn_data) def th_warnmanager(self): myDBM = DBManager() myDBM.connect() while self.brun: warn_data = self.warn_q.get() self.save_warn(warn_data.model_name,warn_data.img_buffer,warn_data.width,warn_data.height, warn_data.channel_id,self.FPS,self.fourcc,myDBM) self.send_warn() del warn_data.img_buffer del warn_data def start_warnmanager_th(self): th_warn = threading.Thread(target=self.th_warnmanager) # 一个视频通道一个线程,线程句柄暂时部保留 th_warn.start() def stop_warnmanager_th(self): self.brun = False del self.warn_q def send_warn(self): '''发送报警信息''' pass def save_warn(self,model_name,buffer,width,height,channnel_id,FPS,fourcc,myDBM): ''' 保存报警信息 --- 涉及到I/O操作可以通过线程取执行 -- 避免主线程阻塞 --还未验证-2024-7-6 :param model_name: 模型名称,如人员入侵 :param w_s_count: 报警已存储的最新帧序列 :param buffer_count: 当前视频缓冲区的最新帧序列 :param buffer: 视频缓存区 :param width: 视频画面的width :param height: 视频画面的height :param channnel_id: 视频通道ID :return: ret 数据库操作记录 ''' now = datetime.datetime.now() # 获取当前日期和时间 current_time_str = now.strftime("%Y-%m-%d_%H-%M-%S") filename = f"{channnel_id}_{current_time_str}" save_path = myCongif.get_data("warn_video_path") # 保存视频 video_writer = cv2.VideoWriter(f"{save_path}{filename}.mp4", fourcc, FPS, (width, height)) if not video_writer.isOpened(): print(f"Failed to open video writer for model/warn/{filename}.mp4") return False ilen = len(buffer) istart = 0; iend = ilen for i in range(len(buffer)): video_writer.write(buffer[i]) video_writer.release() # 保存图片 ret = cv2.imwrite(f"model/warn/{filename}.png", buffer[-1]) # buffer使用完后删除 del buffer if not ret: print("保存图片失败") return False # 保存数据库 strsql = (f"INSERT INTO warn (model_name ,video_path ,img_path ,creat_time,channel_id ) " f"Values ('{model_name}','model/warn/{filename}.mp4','model/warn/{filename}.png'," f"'{current_time_str}','{channnel_id}');") ret = myDBM.do_sql(strsql) del myDBM # 释放数据库连接资源 return ret