diff --git a/main/xiaozhi-server/core/connection.py b/main/xiaozhi-server/core/connection.py index 8f406ed1..fbd3569e 100644 --- a/main/xiaozhi-server/core/connection.py +++ b/main/xiaozhi-server/core/connection.py @@ -203,12 +203,16 @@ class ConnectionHandler: finally: await self.close(ws) + async def reset_timeout(self): + """重置超时计时器""" + if self.timeout_task: + self.timeout_task.cancel() + self.timeout_task = asyncio.create_task(self._check_timeout()) + async def _route_message(self, message): """消息路由""" # 重置超时计时器 - if self.timeout_task: - self.timeout_task.cancel() - self.timeout_task = asyncio.create_task(self._check_timeout()) + await self.reset_timeout() if isinstance(message, str): await handleTextMessage(self, message) diff --git a/main/xiaozhi-server/core/handle/sendAudioHandle.py b/main/xiaozhi-server/core/handle/sendAudioHandle.py index 3387a133..b9148238 100644 --- a/main/xiaozhi-server/core/handle/sendAudioHandle.py +++ b/main/xiaozhi-server/core/handle/sendAudioHandle.py @@ -52,8 +52,8 @@ async def sendAudioMessage(conn, audios, text, text_index=0): logger.bind(tag=TAG).info(f"发送第一段语音: {text}") await send_tts_message(conn, "sentence_start", text) - # 播放音频 - await sendAudio(conn, audios) + is_first_audio = (text_index == conn.tts_first_text_index) + await sendAudio(conn, audios, pre_buffer=is_first_audio) await send_tts_message(conn, "sentence_end", text) @@ -65,22 +65,32 @@ async def sendAudioMessage(conn, audios, text, text_index=0): # 播放音频 -async def sendAudio(conn, audios): +async def sendAudio(conn, audios, pre_buffer=True): # 流控参数优化 frame_duration = 60 # 帧时长(毫秒),匹配 Opus 编码 start_time = time.perf_counter() play_position = 0 + last_reset_time = time.perf_counter() # 记录最后的重置时间 - # 预缓冲:发送前 3 帧 - pre_buffer = min(3, len(audios)) - for i in range(pre_buffer): - await conn.websocket.send(audios[i]) + # 仅当第一句话时执行预缓冲 + if pre_buffer: + pre_buffer_frames = min(3, len(audios)) + for i in range(pre_buffer_frames): + await conn.websocket.send(audios[i]) + remaining_audios = audios[pre_buffer_frames:] + else: + remaining_audios = audios - # 正常播放剩余帧 - for opus_packet in audios[pre_buffer:]: + # 播放剩余音频帧 + for opus_packet in remaining_audios: if conn.client_abort: return + # 每分钟重置一次计时器 + if time.perf_counter() - last_reset_time > 60: + await conn.reset_timeout() + last_reset_time = time.perf_counter() + # 计算预期发送时间 expected_time = start_time + (play_position / 1000) current_time = time.perf_counter()