diff --git a/main/xiaozhi-server/core/connection.py b/main/xiaozhi-server/core/connection.py index ac83a656..98bc87ed 100644 --- a/main/xiaozhi-server/core/connection.py +++ b/main/xiaozhi-server/core/connection.py @@ -24,7 +24,6 @@ from core.utils.modules_initialize import ( initialize_asr, ) from core.handle.reportHandle import report -from core.utils.modules_initialize import initialize_voiceprint from core.providers.tts.default import DefaultTTS from concurrent.futures import ThreadPoolExecutor from core.utils.dialogue import Message, Dialogue @@ -39,6 +38,7 @@ from core.providers.tts.dto.dto import ContentType, TTSMessageDTO, SentenceType from config.logger import setup_logging, build_module_string, create_connection_logger from config.manage_api_client import DeviceNotFoundException, DeviceBindException from core.utils.prompt_manager import PromptManager +from core.utils.voiceprint_provider import VoiceprintProvider TAG = __name__ @@ -109,6 +109,9 @@ class ConnectionHandler: self.memory = _memory self.intent = _intent + # 为每个连接单独管理声纹识别 + self.voiceprint_provider = None + # vad相关变量 self.client_audio_buffer = bytearray() self.client_have_voice = False @@ -348,14 +351,10 @@ class ConnectionHandler: self.vad = self._vad if self.asr is None: self.asr = self._initialize_asr() - try: - success = initialize_voiceprint(self.asr, self.config) - if success: - self.logger.bind(tag=TAG).info("声纹识别功能已在连接时动态启用") - else: - self.logger.bind(tag=TAG).info("声纹识别功能未启用或配置不完整") - except Exception as e: - self.logger.bind(tag=TAG).warning(f"声纹识别初始化失败: {str(e)}") + + # 初始化声纹识别 + self._initialize_voiceprint() + # 打开语音识别通道 asyncio.run_coroutine_threadsafe( self.asr.open_audio_channels(self), self.loop @@ -426,6 +425,18 @@ class ConnectionHandler: return asr + def _initialize_voiceprint(self): + """为当前连接初始化声纹识别""" + try: + voiceprint_config = self.config.get("voiceprint", {}) + if voiceprint_config: + self.voiceprint_provider = VoiceprintProvider(voiceprint_config) + self.logger.bind(tag=TAG).info("声纹识别功能已在连接时动态启用") + else: + self.logger.bind(tag=TAG).info("声纹识别功能未启用或配置不完整") + except Exception as e: + self.logger.bind(tag=TAG).warning(f"声纹识别初始化失败: {str(e)}") + def _initialize_private_config(self): """如果是从配置文件获取,则进行二次实例化""" if not self.read_config_from_api: diff --git a/main/xiaozhi-server/core/providers/asr/base.py b/main/xiaozhi-server/core/providers/asr/base.py index ef9fa01e..e34d5c2f 100644 --- a/main/xiaozhi-server/core/providers/asr/base.py +++ b/main/xiaozhi-server/core/providers/asr/base.py @@ -17,7 +17,6 @@ from core.handle.receiveAudioHandle import startToChat from core.handle.reportHandle import enqueue_asr_report from core.utils.util import remove_punctuation_and_length from core.handle.receiveAudioHandle import handleAudioMessage -from core.utils.voiceprint_provider import VoiceprintProvider TAG = __name__ logger = setup_logging() @@ -25,13 +24,7 @@ logger = setup_logging() class ASRProviderBase(ABC): def __init__(self): - self.voiceprint_provider = None - - def init_voiceprint(self, voiceprint_config: dict): - """初始化声纹识别""" - if voiceprint_config: - self.voiceprint_provider = VoiceprintProvider(voiceprint_config) - logger.bind(tag=TAG).info("声纹识别模块已初始化") + pass # 将声纹识别从ASR实例分离,移到连接级别管理 # 打开音频通道 async def open_audio_channels(self, conn): @@ -94,7 +87,8 @@ class ASRProviderBase(ABC): # 预先准备WAV数据 wav_data = None - if self.voiceprint_provider and combined_pcm_data: + # 使用连接的声纹识别提供者 + if conn.voiceprint_provider and combined_pcm_data: wav_data = self._pcm_to_wav(combined_pcm_data) @@ -129,8 +123,9 @@ class ASRProviderBase(ABC): loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) try: + # 使用连接的声纹识别提供者 result = loop.run_until_complete( - self.voiceprint_provider.identify_speaker(wav_data, conn.session_id) + conn.voiceprint_provider.identify_speaker(wav_data, conn.session_id) ) return result finally: @@ -145,7 +140,7 @@ class ASRProviderBase(ABC): with concurrent.futures.ThreadPoolExecutor(max_workers=2) as thread_executor: asr_future = thread_executor.submit(run_asr) - if self.voiceprint_provider and wav_data: + if conn.voiceprint_provider and wav_data: voiceprint_future = thread_executor.submit(run_voiceprint) # 等待两个线程都完成