refactor: vad独立时间戳,相关残余状态处理

This commit is contained in:
Sakura-RanChen
2026-04-09 17:15:35 +08:00
parent e08eb48d9a
commit a6904f6ebd
5 changed files with 16 additions and 8 deletions
+3 -4
View File
@@ -159,6 +159,7 @@ class ConnectionHandler:
self.client_voice_window = deque(maxlen=5)
self.first_activity_time = 0.0 # 记录首次活动的时间(毫秒)
self.last_activity_time = 0.0 # 统一的活动时间戳(毫秒)
self.vad_last_voice_time = 0.0 # 记录用户最后一次说话的时间(毫秒)
self.client_voice_stop = False
self.last_is_voice = False
@@ -1288,10 +1289,7 @@ class ConnectionHandler:
# 标记任务完成
self.report_queue.task_done()
def clearSpeakStatus(self, sentence_id=None):
# 如果sentence_id不匹配,说明是旧轮次的回调,不需要执行
if sentence_id is not None and sentence_id != self.sentence_id:
return
def clearSpeakStatus(self):
self.client_is_speaking = False
self.logger.bind(tag=TAG).debug(f"清除服务端讲话状态")
@@ -1433,6 +1431,7 @@ class ConnectionHandler:
self.client_voice_stop = False
self.client_voice_window.clear()
self.last_is_voice = False
self.vad_last_voice_time = 0.0
# Clear ASR buffers
self.asr_audio.clear()
@@ -77,6 +77,7 @@ async def startToChat(conn: "ConnectionHandler", text):
):
await max_out_size(conn)
return
# manual 模式下不打断正在播放的内容
if conn.client_is_speaking and conn.client_listen_mode != "manual":
await handleAbortMessage(conn)
@@ -284,8 +284,10 @@ async def send_tts_message(conn: "ConnectionHandler", state, text=None):
# 停止音频发送循环(仅在流控器已初始化时调用)
if hasattr(conn, "audio_rate_controller") and conn.audio_rate_controller:
conn.audio_rate_controller.stop_sending()
# 清除服务端讲话状态,传入 sentence_id 用于判断是否是当前轮次
conn.clearSpeakStatus(current_sentence_id)
# 检查是否是当前轮次
if current_sentence_id != conn.sentence_id:
return
conn.clearSpeakStatus()
# 发送消息到客户端
await conn.websocket.send(json.dumps(message))
@@ -84,6 +84,12 @@ class ASRProviderBase(ABC):
async def handle_voice_stop(self, conn: "ConnectionHandler", asr_audio_task: List[bytes]):
"""并行处理ASR和声纹识别"""
try:
# 如果处于退出流程中,直接关闭连接,不处理新消息
if conn.close_after_chat or conn.is_exiting:
logger.bind(tag=TAG).info("退出流程中收到新消息,直接关闭连接")
await conn.close()
return
total_start_time = time.monotonic()
# 准备音频数据
@@ -107,12 +107,12 @@ class VADProvider(VADProviderBase):
# 如果之前有声音,但本次没有声音,且与上次有声音的时间差已经超过了静默阈值,则认为已经说完一句话
if conn.client_have_voice and not client_have_voice:
stop_duration = time.time() * 1000 - conn.last_activity_time
stop_duration = time.time() * 1000 - conn.vad_last_voice_time
if stop_duration >= self.silence_threshold_ms:
conn.client_voice_stop = True
if client_have_voice:
conn.client_have_voice = True
conn.last_activity_time = time.time() * 1000
conn.vad_last_voice_time = time.time() * 1000
return client_have_voice
except opuslib_next.OpusError as e: