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