我正在尝试设置一个持久的音频监听器。我们的想法是记录一些音频,发送到谷歌的语音识别API,然后根据所说的内容运行命令。我知道这已经实施了好几次了;事实上,我从这里借用了大量的代码(略微适应):
https://github.com/jeysonmc/python-google-speech-scripts/blob/master/stt_google.py
我希望它能够在后台持续运行。现在,它在最初的几分钟内效果很好,但过了一段时间后录音机需要更长时间才能停止录音(即使完全静音),我也不确定正确的音频是否会被发送给Google,因为识别的质量陡然下降。请注意,我目前正在使用一个非常激进的尝试/除了绕过记录第一位音频后似乎出现的IOErrors。任何更优雅和/或更有效的解决方案当然是受欢迎的。我的代码如下:
#config
chunk = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 48000
THRESHOLD = 180 #The threshold intensity that defines silence signal (lower than).
SILENCE_LIMIT = 2 #Silence limit in seconds. The max ammount of seconds where only silence is recorded. When this time passes the recording finishes and the file is delivered.
p = pyaudio.PyAudio()
print "* listening. CTRL+C to finish."
all_m = []
data = ''
rel = RATE/chunk
slid_win = deque(maxlen=SILENCE_LIMIT*rel)
started = False
while (True):
try:
#listening loop, open new stream each time
stream = p.open(format = FORMAT,channels = CHANNELS, rate = RATE, input = True, frames_per_buffer = chunk)
data = stream.read(chunk)
slid_win.append (abs(audioop.avg(data, 2)))
#detect noise
if(True in [ x>THRESHOLD for x in slid_win]):
if(not started):
print "starting record"
started = True
all_m.append(data)
elif (started==True):
stream.close()
print "finished"
#the limit was reached, finish capture and deliver
filename = save_speech(all_m,p)
google(filename)
#reset all
started = False
slid_win = deque(maxlen=SILENCE_LIMIT*rel)
all_m= []
print "listening ..."
except IOError as e:
print "Caught IOError"
stream.close()
pass
其余代码只涉及转换为flac和向Google发送请求。
重申一点,我的代码在最初的几分钟内运行良好,前提是没有很多背景噪音,并且命令直接用于麦克风。我已经尝试在保存/发送任何文件之前关闭PyAudio流,除了在流打开的地方移动(它最初在主while()循环之外)。这两个变化似乎都有所帮助。然而,由于记录指示器随着时间的推移变得越来越不准确,我的预感是它与滑动窗口的“未对准”有关。肯定是错的。
提前感谢您的帮助。
答案 0 :(得分:0)
更有效的方法是在关键字定位模式中使用Pocketsphinx,专门用于连续收听。要尝试它,您需要从主干检出最新的开发版本并在文件上运行定位:
pocketsphinx_continuouos -kws "oh mighty computer" -infile file.wav
不需要互联网连接,去除噪音,您将能够调整检测阈值和关键字发音。
您可以通过Python API使用pocketspinx:
config = Decoder.default_config()
config.set_string('-kws', "oh mighty computer")
decoder = Decoder(config)
decoder.start_utt('')
stream = open(path.join('file.wav'), 'rb')
while True:
buf = stream.read(1024)
decoder.process_raw(buf, False, False)