mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-27 09:33:55 +08:00
refactor: vad独立时间戳,相关残余状态处理
This commit is contained in:
@@ -159,6 +159,7 @@ class ConnectionHandler:
|
|||||||
self.client_voice_window = deque(maxlen=5)
|
self.client_voice_window = deque(maxlen=5)
|
||||||
self.first_activity_time = 0.0 # 记录首次活动的时间(毫秒)
|
self.first_activity_time = 0.0 # 记录首次活动的时间(毫秒)
|
||||||
self.last_activity_time = 0.0 # 统一的活动时间戳(毫秒)
|
self.last_activity_time = 0.0 # 统一的活动时间戳(毫秒)
|
||||||
|
self.vad_last_voice_time = 0.0 # 记录用户最后一次说话的时间(毫秒)
|
||||||
self.client_voice_stop = False
|
self.client_voice_stop = False
|
||||||
self.last_is_voice = False
|
self.last_is_voice = False
|
||||||
|
|
||||||
@@ -1288,10 +1289,7 @@ class ConnectionHandler:
|
|||||||
# 标记任务完成
|
# 标记任务完成
|
||||||
self.report_queue.task_done()
|
self.report_queue.task_done()
|
||||||
|
|
||||||
def clearSpeakStatus(self, sentence_id=None):
|
def clearSpeakStatus(self):
|
||||||
# 如果sentence_id不匹配,说明是旧轮次的回调,不需要执行
|
|
||||||
if sentence_id is not None and sentence_id != self.sentence_id:
|
|
||||||
return
|
|
||||||
self.client_is_speaking = False
|
self.client_is_speaking = False
|
||||||
self.logger.bind(tag=TAG).debug(f"清除服务端讲话状态")
|
self.logger.bind(tag=TAG).debug(f"清除服务端讲话状态")
|
||||||
|
|
||||||
@@ -1433,6 +1431,7 @@ class ConnectionHandler:
|
|||||||
self.client_voice_stop = False
|
self.client_voice_stop = False
|
||||||
self.client_voice_window.clear()
|
self.client_voice_window.clear()
|
||||||
self.last_is_voice = False
|
self.last_is_voice = False
|
||||||
|
self.vad_last_voice_time = 0.0
|
||||||
|
|
||||||
# Clear ASR buffers
|
# Clear ASR buffers
|
||||||
self.asr_audio.clear()
|
self.asr_audio.clear()
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ async def startToChat(conn: "ConnectionHandler", text):
|
|||||||
):
|
):
|
||||||
await max_out_size(conn)
|
await max_out_size(conn)
|
||||||
return
|
return
|
||||||
|
|
||||||
# manual 模式下不打断正在播放的内容
|
# manual 模式下不打断正在播放的内容
|
||||||
if conn.client_is_speaking and conn.client_listen_mode != "manual":
|
if conn.client_is_speaking and conn.client_listen_mode != "manual":
|
||||||
await handleAbortMessage(conn)
|
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:
|
if hasattr(conn, "audio_rate_controller") and conn.audio_rate_controller:
|
||||||
conn.audio_rate_controller.stop_sending()
|
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))
|
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]):
|
async def handle_voice_stop(self, conn: "ConnectionHandler", asr_audio_task: List[bytes]):
|
||||||
"""并行处理ASR和声纹识别"""
|
"""并行处理ASR和声纹识别"""
|
||||||
try:
|
try:
|
||||||
|
# 如果处于退出流程中,直接关闭连接,不处理新消息
|
||||||
|
if conn.close_after_chat or conn.is_exiting:
|
||||||
|
logger.bind(tag=TAG).info("退出流程中收到新消息,直接关闭连接")
|
||||||
|
await conn.close()
|
||||||
|
return
|
||||||
|
|
||||||
total_start_time = time.monotonic()
|
total_start_time = time.monotonic()
|
||||||
|
|
||||||
# 准备音频数据
|
# 准备音频数据
|
||||||
|
|||||||
@@ -107,12 +107,12 @@ class VADProvider(VADProviderBase):
|
|||||||
|
|
||||||
# 如果之前有声音,但本次没有声音,且与上次有声音的时间差已经超过了静默阈值,则认为已经说完一句话
|
# 如果之前有声音,但本次没有声音,且与上次有声音的时间差已经超过了静默阈值,则认为已经说完一句话
|
||||||
if conn.client_have_voice and not client_have_voice:
|
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:
|
if stop_duration >= self.silence_threshold_ms:
|
||||||
conn.client_voice_stop = True
|
conn.client_voice_stop = True
|
||||||
if client_have_voice:
|
if client_have_voice:
|
||||||
conn.client_have_voice = True
|
conn.client_have_voice = True
|
||||||
conn.last_activity_time = time.time() * 1000
|
conn.vad_last_voice_time = time.time() * 1000
|
||||||
|
|
||||||
return client_have_voice
|
return client_have_voice
|
||||||
except opuslib_next.OpusError as e:
|
except opuslib_next.OpusError as e:
|
||||||
|
|||||||
Reference in New Issue
Block a user