diff --git a/reproject/alert.py b/reproject/alert.py index ccc54ee..4df414e 100644 --- a/reproject/alert.py +++ b/reproject/alert.py @@ -1,5 +1,3 @@ - - import os import queue import threading @@ -18,11 +16,15 @@ class Alert: self.encode_thread = None self.upload_thread = None self.stop_event = threading.Event() - self.abort_event = threading.Event() # 新增:用于超时强制中断 self.dropped_frames = 0 + self.accepting_frames = False + self.ended = False def start(self, width=1920, height=1080, fps=30): print(f"Starting alert with {width}x{height}") + self.accepting_frames = True + self.ended = False + self.stop_event.clear() read_fd, write_fd = os.pipe() self.read_pipe = os.fdopen(read_fd, "rb", buffering=0) self.write_pipe = os.fdopen(write_fd, "wb", buffering=0) @@ -55,23 +57,17 @@ class Alert: self.stream.width = width self.stream.height = height self.stream.pix_fmt = "yuv420p" - self.stream.options = {"preset": "ultrafast", "tune": "zerolatency", "crf": "23"} + # 使用更快的编码预设 + # self.stream.options = {"preset": "ultrafast", "crf": "23"} print("AV container and stream initialized") # 启动编码线程 def _encode() -> None: try: print("Encode thread starting") - # 修改循环条件:增加 abort_event 检查 while not self.stop_event.is_set() or not self.frame_queue.empty(): - if self.abort_event.is_set(): - print("Encode thread aborted by timeout (dropping remaining frames)") - break - try: frame = self.frame_queue.get(timeout=0.1) - if frame is None: - break av_frame = av.VideoFrame.from_ndarray(frame, format="bgr24") for packet in self.stream.encode(av_frame): self.container.mux(packet) @@ -88,6 +84,8 @@ class Alert: self.encode_thread.start() def provide_frame(self, frame): + if not self.accepting_frames or self.ended: + return try: self.frame_queue.put(frame, block=True, timeout=0.05) except queue.Full: @@ -99,16 +97,22 @@ class Alert: ) def end(self): + if self.ended: + return + self.ended = True + self.accepting_frames = False print( f"Stopping alert, queued frames: {self.frame_queue.qsize()}, dropped frames: {self.dropped_frames}" ) - self.frame_queue.put(None) self.stop_event.set() - # 等待编码线程完成(不设超时,确保所有帧都编码完成) + # 等待编码线程完成 if self.encode_thread: self.encode_thread.join() - print(f"Encode thread completed with {self.frame_count} frames") + if self.encode_thread.is_alive(): + print("Warning: Encode thread still running") + else: + print(f"Encode thread completed with {self.frame_count} frames") # 完成编码,flush所有待处理的数据 try: