wangzhibo
2026-09-11 659c470eba542383987aad227b7f918100f131fa
xiaozhi-esp32-server/main/xiaozhi-server/core/providers/asr/base.py
@@ -66,7 +66,16 @@
            # 自动/实时模式:使用VAD检测
            conn.asr_audio.append(pcm_frame)
            # 如果没有语音,且之前也没有声音,缓存部分音频
            shadowing_listen = (
                getattr(conn, "interaction_mode", "") == "SHADOWING"
                and getattr(conn, "shadowing_awaiting_user", False)
            )
            if shadowing_listen:
                from core.app_runtime.runtime import append_shadowing_listen_pcm
                append_shadowing_listen_pcm(conn, pcm_frame)
            # 跟读整句录音走 shadowing_listen_pcm。asr_audio 仍按 VAD 裁剪,避免跨句粘连。
            if not audio_have_voice and not conn.client_have_voice:
                conn.asr_audio = conn.asr_audio[-10:]
                return
@@ -77,7 +86,11 @@
                pcm_bytes = b"".join(conn.asr_audio)
                # 检查是否有足够的音频数据(每帧1920字节,15帧约28800字节)
                if len(pcm_bytes) > 1920 * 15:
                    await self.handle_voice_stop(conn, [pcm_bytes])
                    mode = getattr(conn, "interaction_mode", "CHAT")
                    if mode == "SHADOWING":
                        asyncio.create_task(self.handle_voice_stop(conn, [pcm_bytes]))
                    else:
                        await self.handle_voice_stop(conn, [pcm_bytes])
                conn.reset_audio_states()
    # 处理语音停止
@@ -163,10 +176,26 @@
            text_len, _ = remove_punctuation_and_length(content_for_length_check)
            self.stop_ws_connection()
            audio_snapshot = asr_audio_task.copy() if asr_audio_task else []
            mode = getattr(conn, "interaction_mode", "")
            if mode == "SHADOWING":
                from core.app_runtime.session import stash_asr_audio
                stash_asr_audio(conn, audio_snapshot)
            if text_len > 0:
                audio_snapshot = asr_audio_task.copy()
                enqueue_asr_report(conn, enhanced_text, audio_snapshot)
                # 使用自定义模块进行上报
                from core.app_runtime.session import should_report_asr_now, stash_asr_audio
                if mode != "SHADOWING":
                    stash_asr_audio(conn, audio_snapshot)
                if should_report_asr_now(conn):
                    try:
                        from core.audio_archive import archive_pcm_snapshot
                        archive_pcm_snapshot(conn, audio_snapshot)
                    except Exception:
                        pass
                    enqueue_asr_report(conn, enhanced_text, audio_snapshot)
                await startToChat(conn, enhanced_text)
        except Exception as e:
            logger.bind(tag=TAG).error(f"处理语音停止失败: {e}")