You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于SpeechRecognition的语音助手:区分用户指令与主动静默需求

区分语音助手的用户静默与识别失败场景解决方案

一、基于音频分贝阈值的并行实现方案

核心思路

通过多线程并行执行两个任务:

  • 线程1:实时采集音频并计算音量(RMS均方根值),判断是否处于持续静默状态
  • 线程2:执行原有takeCommand函数进行语音识别
    共享一个状态标记,当线程1检测到用户主动静默时,触发标记,线程2识别失败后优先判断该标记,决定返回main函数还是提示重说。

代码实现

  1. 安装依赖:
pip install SpeechRecognition sounddevice numpy
  1. 完整代码示例:
import speech_recognition as sr
import sounddevice as sd
import numpy as np
import threading
import time

# 全局标记:是否检测到静默
silence_detected = False
# 静默阈值(可根据环境调整,RMS值越小越安静)
SILENCE_THRESHOLD = 0.001
# 持续静默判定时长(秒)
SILENCE_DURATION = 3

def detect_silence():
    global silence_detected
    silence_start = None

    def audio_callback(indata, frames, time, status):
        nonlocal silence_start
        # 计算当前音频帧的RMS值
        rms = np.sqrt(np.mean(indata**2))
        if rms < SILENCE_THRESHOLD:
            if silence_start is None:
                silence_start = time.time()
            elif time.time() - silence_start >= SILENCE_DURATION:
                silence_detected = True
        else:
            silence_start = None
            silence_detected = False

    # 启动音频监听流
    with sd.InputStream(callback=audio_callback):
        while True:
            if silence_detected:
                break
            time.sleep(0.1)

def takeCommand():
    r = sr.Recognizer()
    with sr.Microphone() as source:
        print("请说话...")
        r.adjust_for_ambient_noise(source, duration=0.5)
        audio = r.listen(source)
    
    try:
        print("识别中...")
        query = r.recognize_google(audio, language='zh-CN')
        print(f"你说的是: {query}")
        return query
    except sr.UnknownValueError:
        return None
    except sr.RequestError:
        print("语音识别服务不可用")
        return None

def conversation():
    global silence_detected
    while True:
        # 重置静默标记
        silence_detected = False
        # 启动静默检测线程
        silence_thread = threading.Thread(target=detect_silence)
        silence_thread.daemon = True
        silence_thread.start()
        
        # 执行语音识别
        command = takeCommand()
        
        if command:
            # 处理有效指令逻辑
            print(f"处理指令: {command}")
            if command == "退出":
                break
        else:
            if silence_detected:
                print("检测到主动静默,返回主函数")
                return  # 返回main函数
            else:
                print("未识别到有效指令,请重说")

def main():
    print("主函数启动,进入对话模式...")
    conversation()
    print("回到主函数,结束对话")

if __name__ == "__main__":
    main()

注意事项

  • SILENCE_THRESHOLD和SILENCE_DURATION需要根据实际环境调整,避免误判
  • 线程设置为守护线程,防止程序退出时残留线程

二、AI/ML进阶方案(语音活动检测VAD)

单纯分贝阈值容易被背景噪音干扰,使用专业的**语音活动检测(VAD)**模型可以更准确区分用户主动静默和背景噪音,推荐使用webrtcvad(谷歌开源的轻量级VAD模型),无需训练即可直接使用。

核心思路

在采集音频前,先通过VAD模型判断是否存在有效语音:

  • 如果VAD检测到无语音活动,直接判定为用户主动静默,返回main函数
  • 如果检测到语音活动,再执行语音识别,识别失败则提示重说

代码实现

  1. 安装依赖:
pip install SpeechRecognition webrtcvad pyaudio
  1. 关键代码片段:
import webrtcvad
import speech_recognition as sr
from collections import deque

def has_voice_activity(audio_data, sample_rate=16000):
    vad = webrtcvad.Vad(3)  # 模式3,最严格的检测
    # 将音频转换为16kHz单声道PCM格式
    pcm_data = audio_data.get_raw_data(convert_rate=sample_rate, convert_width=2)
    frame_duration = 30  # 每帧30毫秒
    frame_size = int(sample_rate * frame_duration / 1000)
    
    # 滑动窗口检测语音活动
    voice_frames = deque(maxlen=10)
    for i in range(0, len(pcm_data), frame_size*2):
        frame = pcm_data[i:i+frame_size*2]
        if len(frame) < frame_size*2:
            break
        is_speech = vad.is_speech(frame, sample_rate)
        voice_frames.append(is_speech)
    
    # 判断是否存在连续语音帧
    return any(voice_frames)

def takeCommandWithVAD():
    r = sr.Recognizer()
    with sr.Microphone() as source:
        print("请说话...")
        r.adjust_for_ambient_noise(source, duration=0.5)
        audio = r.listen(source)
    
    # 先检测是否有语音活动
    if not has_voice_activity(audio):
        return "silence"
    
    try:
        print("识别中...")
        query = r.recognize_google(audio, language='zh-CN')
        print(f"你说的是: {query}")
        return query
    except sr.UnknownValueError:
        return None
    except sr.RequestError:
        print("语音识别服务不可用")
        return None

def conversation():
    while True:
        command = takeCommandWithVAD()
        
        if command == "silence":
            print("检测到主动静默,返回主函数")
            return
        elif command:
            print(f"处理指令: {command}")
            if command == "退出":
                break
        else:
            print("未识别到有效指令,请重说")

方案优势

  • 基于语音特征检测,比单纯分贝阈值准确率高
  • 轻量级模型,无需额外训练,运行效率高

内容的提问来源于stack exchange,提问作者styles

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 09:35:31