diff --git a/core/connection.py b/core/connection.py index 3f59762f..cb2d06d0 100644 --- a/core/connection.py +++ b/core/connection.py @@ -153,17 +153,12 @@ class ConnectionHandler: text = None try: future = self.tts_queue.get() - if future is None: - continue text = None try: - self.logger.debug("正在处理TTS任务...") tts_file, text = future.result(timeout=10) - self.logger.debug(f"TTS文件生成完毕,文件路径: {tts_file}") if os.path.exists(tts_file): opus_datas, duration = self.tts.wav_to_opus_data(tts_file) else: - self.logger.error(f"TTS文件不存在: {tts_file}") opus_datas = [] duration = 0 except TimeoutError: @@ -180,7 +175,6 @@ class ConnectionHandler: if self.tts.delete_audio_file and os.path.exists(tts_file): os.remove(tts_file) except Exception as e: - self.logger.error(f"TTS任务处理错误: {e}") self.clearSpeakStatus() asyncio.run_coroutine_threadsafe( self.websocket.send(json.dumps({"type": "tts", "state": "stop", "session_id": self.session_id})), @@ -196,7 +190,7 @@ class ConnectionHandler: if tts_file is None: self.logger.error(f"tts转换失败,{text}") return None - self.logger.debug(f"TTS 文件生成完毕: {tts_file}") + self.logger.debug(f"TTS 文件生成完毕") return tts_file, text def clearSpeakStatus(self): diff --git a/core/handle/audioHandle.py b/core/handle/audioHandle.py index 4e55d115..d15d1ff5 100644 --- a/core/handle/audioHandle.py +++ b/core/handle/audioHandle.py @@ -55,51 +55,60 @@ async def startToChat(conn, text): async def sendAudioMessage(conn, audios, duration, text): base_delay = conn.tts_duration - # 发送 tts.start if text == conn.tts_first_text: logger.info(f"发送第一段语音: {text}") conn.tts_start_speak_time = time.time() - await send_tts_message(conn, "start", text) + await conn.websocket.send(json.dumps({ + "type": "tts", + "state": "start", + "session_id": conn.session_id + })) - # 先等待0.5秒,确保客户端处于 speaking 状态 - await asyncio.sleep(0.5) + # 调度文字显示任务 + text_task = asyncio.create_task( + schedule_with_interrupt( + base_delay - 0.5, + send_sentence_start(conn, text) + ) + ) + conn.scheduled_tasks.append(text_task) - # 发送 sentence_start(每个音频文件之前发送一次) - await send_tts_message(conn, "sentence_start", text) - - conn.tts_duration += duration + conn.tts_duration = conn.tts_duration + duration # 发送音频数据 - for idx, opus_packet in enumerate(audios): + for opus_packet in audios: await conn.websocket.send(opus_packet) - # 每个音频文件发送结束时,发送 sentence_end - if idx == len(audios) - 1: - await send_tts_message(conn, "sentence_end", text) - if conn.llm_finish_task and text == conn.tts_last_text: - stop_duration = conn.tts_duration - \ - (time.time() - conn.tts_start_speak_time) + stop_duration = conn.tts_duration - (time.time() - conn.tts_start_speak_time) stop_task = asyncio.create_task( - schedule_with_interrupt( - stop_duration, send_tts_message(conn, 'stop')) + schedule_with_interrupt(stop_duration, send_tts_stop(conn, text)) ) conn.scheduled_tasks.append(stop_task) -async def send_tts_message(conn, state, text=None): - """发送 TTS 状态消息""" - message = { +async def send_sentence_start(conn, text): + await conn.websocket.send(json.dumps({ "type": "tts", - "state": state, + "state": "sentence_start", + "text": text, "session_id": conn.session_id - } - if text is not None: - message["text"] = text + })) - await conn.websocket.send(json.dumps(message)) - if state == "stop": - conn.clearSpeakStatus() + +async def send_tts_stop(conn, text): + await conn.websocket.send(json.dumps({ + "type": "tts", + "state": "sentence_end", + "text": text, + "session_id": conn.session_id + })) + await conn.websocket.send(json.dumps({ + "type": "tts", + "state": "stop", + "session_id": conn.session_id + })) + conn.clearSpeakStatus() async def schedule_with_interrupt(delay, coro):