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

如何修复语音助手项目中函数自动重复执行的问题?

问题:语音助手函数重复执行的修复方案

我开发了一个使用speech recognition和pyttsx3的语音助手项目,目前遇到函数重复执行的问题。例如执行Wikipedia指令时,对应代码会重复运行5次。以下是我的代码:

main.py

import possibilities as ps

clear = lambda: os.system('cls')
engine = pyttsx3.init('sapi5')
voices = engine.getProperty('voices')
engine.setProperty('voice', voices[3].id)
engine.setProperty("rate", 160)
def speak(audio):
    engine.say(audio)
    engine.runAndWait()
while True:
    
    rec = sr.Recognizer()
    with sr.Microphone() as mic:
        print("Manini listen...")
        audio = rec.listen(mic)
        try:
            text = rec.recognize_google(audio, language='en')
            query = text.lower()
        except Exception as e:
            print("Manini Listen...")   

    
    if 'wikipedia' in query:
        ps.wikipediaSer(query)

    elif "say" in query:
        ps.sayrep(query)
        
    elif 'open youtube' in query:
        ps.openyoutube()

possibilities.py

def wikipediaSer(query):
    speak('Searching Wikipedia...')
    query = query.replace("wikipedia", "")
    results = wikipedia.summary(query, sentences = 2)
    speak("According to Wikipedia")
    print(results)
    speak(results)

def sayrep(query):
        say_text = query.replace("say", "")
        speak(say_text)
        
def openyoutube():
    speak("Here you go to Youtube\n")
    webbrowser.open("youtube.com")

请问该如何修复这种重复执行的问题?


修复方案

问题根源

  1. 重复创建识别资源:每次循环都重新初始化sr.Recognizer()和sr.Microphone(),导致音频识别不稳定,可能多次捕获同一段语音指令。
  2. 无监听边界限制:rec.listen(mic)未设置超时或短语时长限制,会持续监听音频,甚至把语音助手自身的发音误识别为新指令。
  3. 异常时未重置指令:识别失败时query保留上次的有效值,导致循环重复执行旧指令。

具体修改步骤

  1. 将识别器初始化移到循环外:避免重复创建资源,提升识别稳定性。
  2. 添加监听限制参数:给listen方法设置timeout(超时未检测到语音则停止)和phrase_time_limit(限制单次语音短语的最长时长)。
  3. 每次循环重置query:确保识别失败或无有效指令时,不会触发旧逻辑。
  4. 执行指令后添加延迟:避免语音助手自身的发音被再次识别。

修改后的main.py代码

import possibilities as ps
import speech_recognition as sr
import os
import time

clear = lambda: os.system('cls')
engine = pyttsx3.init('sapi5')
voices = engine.getProperty('voices')
engine.setProperty('voice', voices[3].id)
engine.setProperty("rate", 160)

def speak(audio):
    engine.say(audio)
    engine.runAndWait()

# 初始化识别器和麦克风,移到循环外部
rec = sr.Recognizer()
mic = sr.Microphone()

while True:
    query = ""  # 每次循环重置指令变量
    with mic:
        print("Manini listen...")
        # 调整识别器适应环境噪音,提升识别准确率
        rec.adjust_for_ambient_noise(mic, duration=0.5)
        try:
            # 设置监听超时10秒,单次语音最长3秒
            audio = rec.listen(mic, timeout=10, phrase_time_limit=3)
            text = rec.recognize_google(audio, language='en')
            query = text.lower()
            print(f"识别到指令: {query}")
        except sr.WaitTimeoutError:
            print("未检测到语音,重新监听...")
        except sr.UnknownValueError:
            print("无法识别语音,请再说一遍...")
        except Exception as e:
            print(f"识别出错: {str(e)}")   

    if 'wikipedia' in query:
        ps.wikipediaSer(query)
        time.sleep(1)  # 执行后延迟,避免误识别自身发音
    
    elif "say" in query:
        ps.sayrep(query)
        time.sleep(1)
        
    elif 'open youtube' in query:
        ps.openyoutube()
        time.sleep(1)
    elif 'exit' in query:  # 新增退出指令,方便终止程序
        speak("再见")
        break

额外优化建议

  • 确保possibilities.py中导入必要模块(如import wikipedia、import webbrowser),避免运行报错。
  • 可以添加指令去重逻辑,比如记录最近执行的指令,短时间内重复触发则跳过。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 21:40:25