diff --git a/main/xiaozhi-server/core/providers/tts/alibl_stream.py b/main/xiaozhi-server/core/providers/tts/alibl_stream.py index 8eb0f708..1a639651 100644 --- a/main/xiaozhi-server/core/providers/tts/alibl_stream.py +++ b/main/xiaozhi-server/core/providers/tts/alibl_stream.py @@ -33,6 +33,7 @@ class TTSProvider(TTSProviderBase): self.api_key = config.get("api_key") if not self.api_key: raise ValueError("api_key is required for CosyVoice TTS") + self.report_on_last = True # WebSocket配置 self.ws_url = "wss://dashscope.aliyuncs.com/api-ws/v1/inference/" diff --git a/main/xiaozhi-server/core/providers/tts/aliyun_stream.py b/main/xiaozhi-server/core/providers/tts/aliyun_stream.py index cf06e7ff..9548595e 100644 --- a/main/xiaozhi-server/core/providers/tts/aliyun_stream.py +++ b/main/xiaozhi-server/core/providers/tts/aliyun_stream.py @@ -104,6 +104,7 @@ class TTSProvider(TTSProviderBase): self.access_key_secret = config.get("access_key_secret") self.appkey = config.get("appkey") self.format = config.get("format", "pcm") + self.report_on_last = True # 音色配置 - CosyVoice大模型音色 if config.get("private_voice"): diff --git a/main/xiaozhi-server/core/providers/tts/base.py b/main/xiaozhi-server/core/providers/tts/base.py index 4fef87dd..be42b14d 100644 --- a/main/xiaozhi-server/core/providers/tts/base.py +++ b/main/xiaozhi-server/core/providers/tts/base.py @@ -40,6 +40,7 @@ class TTSProviderBase(ABC): self.tts_audio_queue = queue.Queue() self.tts_audio_first_sentence = True self.before_stop_play_files = [] + self.report_on_last = False self.tts_text_buff = [] self.punctuations = ( @@ -322,7 +323,7 @@ class TTSProviderBase(ABC): def _audio_play_priority_thread(self): # 需要上报的文本和音频列表 enqueue_text = None - enqueue_audio = None + enqueue_audio = [] while not self.conn.stop_event.is_set(): text = None try: @@ -342,14 +343,24 @@ class TTSProviderBase(ABC): # 收到下一个文本开始或会话结束时进行上报 if sentence_type is not SentenceType.MIDDLE: - # 上报TTS数据 - if enqueue_text is not None and enqueue_audio is not None: - enqueue_tts_report(self.conn, enqueue_text, enqueue_audio) - enqueue_audio = [] - enqueue_text = text + if self.report_on_last: + # 累积模式:适用于全程只有一个语音流的TTS(如seed-tts-2.0) + # FIRST时只记录文本,音频持续累积,仅在LAST时统一上报 + if text: + enqueue_text = text + if sentence_type == SentenceType.LAST: + enqueue_tts_report(self.conn, enqueue_text, enqueue_audio) + enqueue_audio = [] + enqueue_text = None + else: + # 非累积模式:每个句子分别上报 + if enqueue_text is not None: + enqueue_tts_report(self.conn, enqueue_text, enqueue_audio) + enqueue_audio = [] + enqueue_text = text # 收集上报音频数据 - if isinstance(audio_datas, bytes) and enqueue_audio is not None: + if isinstance(audio_datas, bytes): enqueue_audio.append(audio_datas) # 发送音频 diff --git a/main/xiaozhi-server/core/providers/tts/huoshan_double_stream.py b/main/xiaozhi-server/core/providers/tts/huoshan_double_stream.py index a2680063..a237eedc 100644 --- a/main/xiaozhi-server/core/providers/tts/huoshan_double_stream.py +++ b/main/xiaozhi-server/core/providers/tts/huoshan_double_stream.py @@ -149,6 +149,7 @@ class TTSProvider(TTSProviderBase): self.cluster = config.get("cluster") self.resource_id = config.get("resource_id") self.resource_type = True if self.resource_id == "seed-tts-2.0" else False + self.report_on_last = self.resource_type self.activate_session = False if config.get("private_voice"): self.voice = config.get("private_voice") diff --git a/main/xiaozhi-server/core/providers/tts/xunfei_stream.py b/main/xiaozhi-server/core/providers/tts/xunfei_stream.py index be53284e..ed0a58d6 100644 --- a/main/xiaozhi-server/core/providers/tts/xunfei_stream.py +++ b/main/xiaozhi-server/core/providers/tts/xunfei_stream.py @@ -76,6 +76,7 @@ class TTSProvider(TTSProviderBase): self.app_id = config.get("app_id") self.api_key = config.get("api_key") self.api_secret = config.get("api_secret") + self.report_on_last = True # 接口地址 self.api_url = config.get("api_url", "wss://cbm01.cn-huabei-1.xf-yun.com/v1/private/mcd9m97e6")