import threading from collections import deque import numpy as np import time import copy import queue class ChannelData: def __init__(self, str_url, int_type, bool_run, deque_length,icount_max): self.str_url = str_url #视频源地址 self.int_type = int_type #视频源类型,0-usb,1-rtsp,2-hksdk self.bool_run = bool_run #线程运行标识 self.deque_frame = deque(maxlen=deque_length) self.last_frame = None # 保存图片数据 self.frame_queue = queue.Queue(maxsize=1) self.counter = 0 #帧序列号--保存报警录像使用 self.icount_max = icount_max #帧序列号上限 self.lock = threading.RLock() # 用于保证线程安全 #添加一帧图片 def add_deque(self, value): self.deque_frame.append(value) #deque 满了以后会把前面的数据移除 #拷贝一份数据 def copy_deque(self): return copy.deepcopy(self.deque_frame) #获取最后一帧图片 def get_last_frame(self): with self.lock: frame = self.last_frame return frame # if not self.frame_queue.empty(): # return self.frame_queue.get() # else: # return None def update_last_frame(self,buffer): if buffer: with self.lock: self.last_frame = None self.last_frame = buffer # if not self.frame_queue.full(): # self.frame_queue.put(buffer) # else: # self.frame_queue.get() # 丢弃最旧的帧 # self.frame_queue.put(buffer) #帧序列号自增 一个线程中处理,不用加锁 def increment_counter(self): self.counter += 1 if self.counter > self.icount_max: self.counter = 0 def get_counter(self): return self.counter #清空数据,主要是删除deque 和 last_frame def clear(self): with self.lock: self.bool_run = False time.sleep(1) #休眠一秒,等待通道对应的子线程,停止工作。 self.deque_frame.clear() self.last_frame = None def stop_run(self): self.bool_run = False class ChannelManager: def __init__(self): self.channels = {} self.lock = threading.RLock() # 用于保证字典操作的线程安全 #增加节点 def add_channel(self, channel_id, str_url, int_type, bool_run, deque_length=10,icount_max=100000): with self.lock: if channel_id in self.channels: #若已经有数据,先删除后再增加 self.channels[channel_id].clear() # 手动清理资源 del self.channels[channel_id] self.channels[channel_id] = ChannelData(str_url, int_type, bool_run, deque_length,icount_max) #删除节点 def delete_channel(self, channel_id): with self.lock: if channel_id in self.channels: self.channels[channel_id].clear() # 手动清理资源 del self.channels[channel_id] #获取节点 def get_channel(self, channel_id): with self.lock: return self.channels.get(channel_id) #停止工作线程 def stop_channel(self,channel_id): with self.lock: if channel_id == 0: for clannel_id,clannel_data in self.channels.items(): clannel_data.clear() del self.channels else: if channel_id in self.channels: self.channels[channel_id].clear() # 手动清理资源 del self.channels[channel_id] if __name__ == "__main__": # 示例使用 manager = ChannelManager() manager.add_channel('channel_1', 'test', 123, True, deque_length=5) # 更新和读取操作 manager.update_channel_deque('channel_1', 'data1') manager.update_channel_buffer('channel_1', np.array([[1, 2], [3, 4]])) manager.increment_channel_counter('channel_1') channel_data = manager.get_channel_data('channel_1') print(channel_data)