From 3f70062c2b79f088d0a153d26c014c5c8aef9be2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E6=BD=AE?= Date: Sun, 21 Sep 2025 11:40:54 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9B=9E=E5=A3=B0=E5=BE=85=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- audio_processes.py | 43 +++++++++++++++++++++++++++++++++++++++++++ control_system.py | 5 +++++ 2 files changed, 48 insertions(+) diff --git a/audio_processes.py b/audio_processes.py index 0172f69..1838d96 100644 --- a/audio_processes.py +++ b/audio_processes.py @@ -171,6 +171,32 @@ class InputProcess: self.logger.error(f"音频设备初始化失败: {e}") raise + def _cleanup_audio_stream(self): + """清理音频流(但不关闭整个PyAudio实例)""" + try: + if self.input_stream: + print("🎙️ 输入进程:关闭音频输入流") + self.input_stream.stop_stream() + self.input_stream.close() + self.input_stream = None + except Exception as e: + self.logger.warning(f"关闭音频流时出错: {e}") + + def _cleanup(self): + """清理资源""" + print("🎙️ 输入进程:开始清理资源") + self._cleanup_audio_stream() + + if self.audio: + try: + print("🎙️ 输入进程:终止PyAudio实例") + self.audio.terminate() + except: + pass + self.audio = None + + print("🎙️ 输入进程:资源清理完成") + def _check_commands(self): """检查主进程控制命令""" try: @@ -178,6 +204,11 @@ class InputProcess: command = self.command_queue.get_nowait() if command.command == 'enable_recording': + if not self.recording_enabled: + # 从禁用到启用,需要重新初始化音频流 + print("🎙️ 输入进程:重新启用录音功能,重新初始化音频流") + self._cleanup_audio_stream() + self._setup_audio() self.recording_enabled = True self.logger.info("录音功能已启用") @@ -186,6 +217,8 @@ class InputProcess: # 如果正在录音,立即停止并发送数据 if self.is_recording: self._stop_recording() + # 禁用时关闭音频流,避免回声污染 + self._cleanup_audio_stream() self.logger.info("录音功能已禁用") elif command.command == 'shutdown': @@ -199,6 +232,10 @@ class InputProcess: def _process_audio(self): """处理音频数据""" try: + # 检查音频流是否存在 + if not self.input_stream: + return + data = self.input_stream.read(self.CHUNK_SIZE, exception_on_overflow=False) if len(data) == 0: return @@ -273,6 +310,12 @@ class InputProcess: except Exception as e: print(f"🎙️ 输入进程音频处理错误: {e}") + # 如果音频流出现问题,尝试重新初始化 + if "stream" in str(e).lower() or "audio" in str(e).lower(): + print(f"🎙️ 输入进程:音频流异常,尝试重新初始化") + self._cleanup_audio_stream() + if self.recording_enabled: + self._setup_audio() def _update_pre_record_buffer(self, audio_data: bytes): """更新预录音缓冲区""" diff --git a/control_system.py b/control_system.py index beaede1..e428c0b 100644 --- a/control_system.py +++ b/control_system.py @@ -361,6 +361,10 @@ class ControlSystem: self.stats['total_conversations'] += 1 print(f"📡 主控制:已更新统计,对话数 = {self.stats['total_conversations']}") + # 等待一段时间确保音频设备完全停止播放 + print(f"📡 主控制:等待音频设备完全停止...") + time.sleep(1.0) # 增加1秒等待时间 + # 切换到空闲状态 old_state = self.state.value self.state = RecordingState.IDLE @@ -370,6 +374,7 @@ class ControlSystem: try: self.input_command_queue.put(ControlCommand('enable_recording')) print(f"📡 主控制:已发送 enable_recording 命令到输入进程") + print(f"📡 主控制:输入进程已重新启用,可以开始新的录音") except Exception as e: print(f"❌ 主控制:发送 enable_recording 命令失败: {e}")