From 659c470eba542383987aad227b7f918100f131fa Mon Sep 17 00:00:00 2001
From: wangzhibo <wangzhibo@shsening.com>
Date: 星期五, 11 九月 2026 15:09:05 +0800
Subject: [PATCH] 小智终端 5种 场景模式 OK

---
 xiaozhi-esp32-server/main/xiaozhi-server/core/handle/sendAudioHandle.py |   37 ++++++++++++++++++++++++-------------
 1 files changed, 24 insertions(+), 13 deletions(-)

diff --git a/xiaozhi-esp32-server/main/xiaozhi-server/core/handle/sendAudioHandle.py b/xiaozhi-esp32-server/main/xiaozhi-server/core/handle/sendAudioHandle.py
index 421554d..c2ecdb9 100644
--- a/xiaozhi-esp32-server/main/xiaozhi-server/core/handle/sendAudioHandle.py
+++ b/xiaozhi-esp32-server/main/xiaozhi-server/core/handle/sendAudioHandle.py
@@ -9,7 +9,7 @@
 from core.utils import textUtils
 from core.utils.util import audio_to_data
 from core.providers.tts.dto.dto import SentenceType
-from core.utils.audioRateController import AudioRateController
+from core.utils.audioRateController import AudioRateController, audio_completion_timeout_sec
 
 TAG = __name__
 # 闊抽甯ф椂闀匡紙姣锛�
@@ -21,11 +21,16 @@
 async def sendAudioMessage(conn: "ConnectionHandler", sentenceType, audios, text, sentence_id=None):
     # 璺宠繃鏃у彞瀛愭畫鐣欓煶棰�
     if sentence_id is not None and sentence_id != conn.sentence_id:
+        conn.logger.bind(tag=TAG).warning(
+            f"涓㈠純杩囨湡TTS闊抽 sentence={sentence_id} current={conn.sentence_id} type={sentenceType}"
+        )
         return
 
     if conn.tts.tts_audio_first_sentence:
         conn.logger.bind(tag=TAG).info(f"鍙戦�佺涓�娈佃闊�: {text}")
         conn.tts.tts_audio_first_sentence = False
+        # speak_txt 涓嶈蛋 STT锛岃ˉ涓�鏉� tts start锛岃璁惧鍏堣繘鍏� speaking 鍐嶆敹 opus銆�
+        await send_tts_message(conn, "start")
 
     if sentenceType == SentenceType.FIRST:
         # 鍚屼竴鍙ュ瓙鐨勫悗缁秷鎭姞鍏ユ祦鎺ч槦鍒楋紝鍏朵粬鎯呭喌绔嬪嵆鍙戦��
@@ -45,7 +50,10 @@
     await sendAudio(conn, audios)
     # 鍙戦�佸彞瀛愬紑濮嬫秷鎭�
     if sentenceType is not SentenceType.MIDDLE:
-        conn.logger.bind(tag=TAG).info(f"鍙戦�侀煶棰戞秷鎭�: {sentenceType}, {text}")
+        sent = (getattr(conn, "audio_flow_control", None) or {}).get("packet_count", 0)
+        conn.logger.bind(tag=TAG).info(
+            f"鍙戦�侀煶棰戞秷鎭�: {sentenceType}, {text}, opus鍖�={sent}"
+        )
 
     # 鍙戦�佺粨鏉熸秷鎭紙濡傛灉鏄渶鍚庝竴涓枃鏈級
     # 閫氳瘽闇�瑕佺淮鎸乻peaking鐘舵��
@@ -58,19 +66,22 @@
 async def _wait_for_audio_completion(conn: "ConnectionHandler"):
     """
     绛夊緟闊抽闃熷垪娓呯┖骞剁瓑寰呴缂撳啿鍖呮挱鏀惧畬鎴�
-
-    Args:
-        conn: 杩炴帴瀵硅薄
     """
     if hasattr(conn, "audio_rate_controller") and conn.audio_rate_controller:
         rate_controller = conn.audio_rate_controller
-        conn.logger.bind(tag=TAG).debug(
-            f"绛夊緟闊抽鍙戦�佸畬鎴愶紝闃熷垪涓繕鏈� {len(rate_controller.queue)} 涓寘"
-        )
-        await rate_controller.queue_empty_event.wait()
+        try:
+            queued = len(rate_controller.queue)
+            timeout = audio_completion_timeout_sec(queued, rate_controller.frame_duration)
+            conn.logger.bind(tag=TAG).debug(
+                f"绛夊緟闊抽鍙戦�佸畬鎴愶紝闃熷垪涓繕鏈� {queued} 涓寘锛宼imeout={timeout:.1f}s"
+            )
+            await asyncio.wait_for(rate_controller.queue_empty_event.wait(), timeout=timeout)
+        except asyncio.TimeoutError:
+            leftover = len(rate_controller.queue) if rate_controller else -1
+            conn.logger.bind(tag=TAG).warning(
+                f"绛夊緟闊抽鍙戦�佸畬鎴愯秴鏃� leftover={leftover}锛岀户缁笅鍙� tts stop"
+            )
 
-        # 绛夊緟棰勭紦鍐插寘鎾斁瀹屾垚
-        # 鍓峃涓寘鐩存帴鍙戦�侊紝澧炲姞2涓綉缁滄姈鍔ㄥ寘锛岄渶瑕侀澶栫瓑寰呭畠浠湪瀹㈡埛绔挱鏀惧畬鎴�
         frame_duration_ms = rate_controller.frame_duration
         pre_buffer_playback_time = (PRE_BUFFER_COUNT + 2) * frame_duration_ms / 1000.0
         await asyncio.sleep(pre_buffer_playback_time)
@@ -263,12 +274,12 @@
     sequence = flow_control.get("sequence", 0)
 
     if conn.conn_from_mqtt_gateway:
-        # 璁$畻鏃堕棿鎴筹紙鍩轰簬鎾斁浣嶇疆锛�
         start_time = time.time()
         timestamp = int(start_time * 1000) % (2**32)
         await _send_to_mqtt_gateway(conn, opus_packet, timestamp, sequence)
     else:
-        # 鐩存帴鍙戦�乷pus鏁版嵁鍖�
+        if packet_index == 0:
+            conn.logger.bind(tag=TAG).info(f"寮�濮嬩笅鍙慣TS opus锛岄鍖卋ytes={len(opus_packet)}")
         await conn.websocket.send(opus_packet)
 
     # 鏇存柊娴佹帶鐘舵��

--
Gitblit v1.9.1