首页 > 解决方案 > 手动运行时系统运行的语音识别代码不起作用(引发错误 -9997,无效的采样率)

问题描述

我有一个 systemd 服务可以在启动时运行一些语音识别代码。我已将麦克风的采样率从 44,100 Hz 更改为 16,000 Hz,以便运行它的 Raspberry Pi Zero W 可以处理它。当我通过从 SSH 运行代码来测试代码时,它运行良好。但是,当我通过我的 systemd 服务运行它时,它会抛出一个错误 -9997,这是无效的采样率错误。这是我的系统服务:

After=sound.target

[Service]
Type=simple
ExecStart=/usr/bin/python3 /home/pi/speech.py
Restart=on-abort

[Install]
WantedBy=sysinit.target

这是我的 Python 3 代码:

print("INFO: Importing libraries...")
import speech_recognition as sr
import i2c
from gpiozero import LED
from math import ceil
from time import sleep
import sys
import os
import atexit
import traceback
print("INFO: Done.")
r = sr.Recognizer()
m = sr.Microphone(sample_rate=16000)
print(m)
#device_index=1
#GPIO.setmode(GPIO.BCM)
#GPIO.setwarnings(False)
#GPIO.setup(11,GPIO.OUT)
#GPIO.output(11,GPIO.HIGH)
#sleep(2)
#GPIO.output(11,GPIO.LOW)

class ExitHooks(object):
    def __init__(self):
        self.exit_code = None
        self.exception = None

    def hook(self):
        self._orig_exit = sys.exit
        sys.exit = self.exit
        sys.excepthook = self.exc_handler

    def exit(self, code=0):
        self.exit_code = code
        self._orig_exit(code)

    def exc_handler(self, exc_type, exc, *args):
        self.exception = exc
        traceback.print_exception(exc_type, exc, args[0], file=open("debug.txt", "w"))
        print('ended')
        print(traceback.format_exception(exc_type, exc, args[0]))
        led.off()
        lcd.lcd_clear()
        #lcd.lcd_display_string("Program ended", 1)
        #lcd.lcd_display_string("Check debug.txt", 2)

hooks = ExitHooks()
hooks.hook()


led = LED(17)
lcd = i2c.lcd()
#def foo():
    #print(traceback.format_exc())
#atexit.register(foo)

"""
def exit_handler():
    print('ended')
    led.off()
    lcd.lcd_clear()
    lcd.lcd_display_string("Program ended", 1)
    lcd.lcd_display_string("Check debug.txt", 2)
    errorr = "unexpected program exit\n"
    if hooks.exception is not None:
        errorr += "exception: "
        print(hooks.exception)
        errorr += str(hooks.exception)
        print(str(hooks.exception) + " string test wowowow")
    f = open("debug.txt", "w")
    f.write(errorr)
    f.close()
atexit.register(exit_handler)"""
lcd.lcd_display_string("DEBUG: ver " + str(sys.version_info.major))
"""Sets parameters to stop recognizer.listening faster.

Parameters:
"r.pause_threshold":      an integer in seconds for how long the recognizer needs of silence to stop recording
"r.non_speaking_duration: seconds of non-speaking audio to keep on both sides of the recording, changed because it cannot be higher than `r.pause_threshold`
"""
r.pause_threshold = 0.3
r.non_speaking_duration = 0.3
done = False
def speech(recognizer, microphone):

    """Transcribe speech from recorded from `microphone`.

    Returns a dictionary with three keys:
    "success": a boolean indicating whether or not the API request was
               successful
    "error":   `None` if no error occured, otherwise a string containing
               an error message if the API could not be reached or
               speech was unrecognizable
    "transcription": `None` if speech could not be transcribed,
               otherwise a string containing the transcribed text
    """
    # check that recognizer and microphone arguments are appropriate type
    if not isinstance(recognizer, sr.Recognizer):
        raise TypeError("`recognizer` must be `Recognizer` instance")

    if not isinstance(microphone, sr.Microphone):
        raise TypeError("`microphone` must be `Microphone` instance")

    # adjust the recognizer sensitivity to ambient noise and record audio
    # from the microphone
    audio = None
    with microphone as source:
        global done
        if done is not True:
            recognizer.adjust_for_ambient_noise(source)
            done = True
        print("INFO: Recording...")
        led.on()
        audio = recognizer.listen(source)
        led.off()
        rawwavdata = audio.get_wav_data()
        f = open("debug.wav", "w")
        f.write(str(rawwavdata))
        f.close()
    print(audio)
    print("INFO: Recognizing...")
    
    try:
        return recognizer.recognize_google(audio)
    except sr.RequestError:
        print("uh-ojh")
    except sr.UnknownValueError:
        print("uh-ojh")
while True:
     print("INFO: Ready for speech.")
     
     trans = speech(r, m)
     if trans == "exit":
         exit()
     if trans == None:
         continue
     print(trans);
     lcd.lcd_clear()
     if len(trans) > 32:
         print("INFO: Larger than 32")
         lcd.lcd_display_string(trans[:17], 1)
         lcd.lcd_display_string(trans[16:33], 2)
         sleep(2)
         if int(ceil(float(len(trans)))) - 32 > 32:
              for i in range(int(ceil(float(len(trans) - 32) / 32)) + 1):
                   lcd.lcd_clear()
                   lcd.lcd_display_string(trans[i*32:i*32+17], 1)
                   lcd.lcd_display_string(trans[i*32+16:i*32+33], 2)
                   
                   print("INFO: Sleeping")
                   sleep(2)
                   print("INFO: Done sleeping")
         else:
              lcd.lcd_clear()
              lcd.lcd_display_string(trans[1*32:1*32+17], 1)
              print("INFO: First line:", trans[1*32:1*32+17])
              lcd.lcd_display_string(trans[1*32+16:1*32+33], 2)
              print("INFO: Second line:", trans[1*32+16:1*32+33])
              print("INFO: Sleeping")
              sleep(2)
              print("INFO: Done sleeping")
     elif len(trans) > 16:
         print("INFO: Larger than 16")
         lcd.lcd_display_string(trans[:17], 1)
         lcd.lcd_display_string(trans[16:len(trans)], 2)

     else:
         print("INFO: Short")
         lcd.lcd_display_string(trans)

我也尝试过使用这样的 bash 文件:

系统文件:

[Unit]
Description=Create test directory
After=pulseaudio.service

[Service]
Type=simple
ExecStart=/usr/bin/sh /home/pi/run.sh
Restart=on-abort

[Install]
WantedBy=sysinit.target

bash 文件:

/usr/bin/python3 /home/pi/speech.py 2>&1 | tee log.txt

请注意,我是 python 新手,尤其是使用 python 的 IO。另请注意,这只是一个有趣的项目。

标签: python-3.xspeech-recognitionsystemdpyaudio

解决方案


推荐阅读