mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-22 07:03:53 +08:00
refactor: vad独立时间戳,相关残余状态处理
This commit is contained in:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user