尝试修复画面延迟问题
This commit is contained in:
@@ -331,7 +331,7 @@ class HLSKadianService:
|
|||||||
|
|
||||||
self.stop_event = threading.Event()
|
self.stop_event = threading.Event()
|
||||||
self.raw_queue = queue.Queue(maxsize=3) # 原始队列,容量较小
|
self.raw_queue = queue.Queue(maxsize=3) # 原始队列,容量较小
|
||||||
self.ws_queue = queue.Queue(maxsize=1000) # WebSocket队列
|
self.ws_queue = queue.Queue(maxsize=10) # WebSocket队列,减小容量防止延迟累积
|
||||||
|
|
||||||
self.frame_processor_workers = []
|
self.frame_processor_workers = []
|
||||||
self.biz_processor = get_processor(self.algorithm)(self.raw_queue, self.ws_queue, self.stop_event, self.cameras)
|
self.biz_processor = get_processor(self.algorithm)(self.raw_queue, self.ws_queue, self.stop_event, self.cameras)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
|
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import asyncio
|
import asyncio
|
||||||
import websockets
|
import websockets
|
||||||
@@ -26,18 +27,71 @@ class WebSocketSender(threading.Thread):
|
|||||||
finally:
|
finally:
|
||||||
self.ws_clients.discard(websocket)
|
self.ws_clients.discard(websocket)
|
||||||
|
|
||||||
|
def _get_latest_msg(self):
|
||||||
|
"""
|
||||||
|
从队列获取最新消息,丢弃旧消息
|
||||||
|
返回: (最新消息, 丢弃数量)
|
||||||
|
"""
|
||||||
|
msg = None
|
||||||
|
dropped = 0
|
||||||
|
try:
|
||||||
|
# 获取第一条消息
|
||||||
|
msg = self.send_queue.get_nowait()
|
||||||
|
dropped = 0
|
||||||
|
|
||||||
|
# 尝试获取更新的消息,丢弃旧的
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
msg = self.send_queue.get_nowait()
|
||||||
|
dropped += 1
|
||||||
|
except queue.Empty:
|
||||||
|
break
|
||||||
|
|
||||||
|
if dropped > 0:
|
||||||
|
self.send_queue.task_done() # 为第一条标记完成
|
||||||
|
except queue.Empty:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return msg, dropped
|
||||||
|
|
||||||
async def _broadcaster(self):
|
async def _broadcaster(self):
|
||||||
while not self.stop_event.is_set():
|
while not self.stop_event.is_set():
|
||||||
try:
|
try:
|
||||||
msg = await asyncio.to_thread(self.send_queue.get, timeout=0.5)
|
# 使用短超时获取消息
|
||||||
|
msg = await asyncio.to_thread(self.send_queue.get, timeout=0.1)
|
||||||
except queue.Empty:
|
except queue.Empty:
|
||||||
|
# 尝试获取最新消息(丢弃队列中的旧消息)
|
||||||
|
msg, dropped = await asyncio.to_thread(self._get_latest_msg)
|
||||||
|
if msg is None:
|
||||||
|
continue
|
||||||
|
if dropped > 0:
|
||||||
|
logger.debug(f"[DEBUG] Dropped {dropped} old frames to catch up")
|
||||||
|
|
||||||
|
# 尝试丢弃更多旧消息,只保留最新
|
||||||
|
dropped = 0
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
msg = self.send_queue.get_nowait()
|
||||||
|
dropped += 1
|
||||||
|
except queue.Empty:
|
||||||
|
break
|
||||||
|
if dropped > 0:
|
||||||
|
logger.debug(f"[DEBUG] Dropped {dropped} queued frames, sending latest")
|
||||||
|
|
||||||
|
# 在线程池中执行JSON序列化,避免阻塞事件循环
|
||||||
|
try:
|
||||||
|
data = await asyncio.to_thread(json.dumps, msg)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"[ERROR] JSON serialization failed: {e}")
|
||||||
|
self.send_queue.task_done()
|
||||||
continue
|
continue
|
||||||
data = json.dumps(msg)
|
|
||||||
dead = []
|
dead = []
|
||||||
for ws in list(self.ws_clients):
|
for ws in list(self.ws_clients):
|
||||||
try:
|
try:
|
||||||
await ws.send(data)
|
await ws.send(data)
|
||||||
except:
|
except Exception as e:
|
||||||
|
logger.debug(f"[DEBUG] WebSocket send error: {e}")
|
||||||
dead.append(ws)
|
dead.append(ws)
|
||||||
for ws in dead:
|
for ws in dead:
|
||||||
self.ws_clients.discard(ws)
|
self.ws_clients.discard(ws)
|
||||||
|
|||||||
Reference in New Issue
Block a user