我想要頻繁地使用pyaudio來播放音頻,雖然他不是多線程模組,但是只使用一個子線程播放,主線程控製播放的開關應該是沒有問題的。但是當我使用它播放時遇到了不能解決的麻煩。
import threading
import wave
import pyaudio
import time
pa=pyaudio.PyAudio()
f=wave.open('/home/dyan/catkin_ws/src/hlf_robot/scripts/hlf_voice/my.wav','rb')
raw_data=f.readframes(f.getnframes())
f.close()
samplewidth,channels,framerate,raw_data=2,1,16000,raw_data
i=0
stream1=''
def test():
while True:
global i,pa,stream1
try:
print i
stream1=pa.open(format=pa.get_format_from_width(samplewidth),
channels=channels,
rate=framerate,
output=True)
stream1.write(raw_data)
i+=1
print i
except IOError,e:
print e
except Exception,e:
print e
break
t0=threading.Thread(target=test)
t0.start()
time.sleep(3)
while True:
if stream1.is_active():
print "is_active"
else:
print "not active"
if stream1.is_stopped():
print "is_stopped"
else:
print "not stopped"
print stream1._is_running
print stream1._stream
print '123'
try:
stream1.stop_stream()
print '456'
stream1.close()
except Exception,e:
print e
break
print '789'
time.sleep(3)
輸出是這樣的,然後崩了
0 #子线程循环第一次
is_active #
not stopped #
True #stream1._is_running
<_portaudio.Stream object at 0x7efd71e00cb0> #stream1._stream
123 #调用stop_stream()之前
456 #调用stop_stream()之后,close()之前
[Errno Unanticipated host error] -9999 #子线程捕获到主线程调用stream1.stop_stream()时由stream1.write()抛出的异常IOError,忽略这个异常继续执行
0 #子线程stream1.write()抛出异常i+=1未执行继续循环在pa.open()之前的print
1、也就是說在呼叫stream1.stop_stream()後呼叫stream1.close()導致程式崩潰了,而且子執行緒和主執行緒都沒有捕獲到異常! ! ! !
2、如果將stop_stream()後的close()註解掉短時間內沒有任何問題,但是持續運行大約10分鐘左右雖然不會崩潰但是再也不能繼續播放。 pa.open()一直拋出異常[Errno Illegal combination of I/O devices] -9993,當我關閉程式重啟時pa.open()會拋出異常('Invalid sample rate', -9997),播放用不了了! ! !
這個問題該如何解決?
暫時使用每次播放均重開一個pyaudio.Pyaudio()物件的方式解決,這大概額外使用了cpu時間10ms。持續跑了將近20個小時沒出問題。
...
try:
self.pa=pyaudio.PyAudio()
self.stream=self.pa.open(format=self.pa.get_format_from_width(samplewidth),
channels=channels,
rate=framerate,
output=True)
self.stream.write(raw_data)
except IOError,e:
pass
finally:
self.stream.close()
self.pa.terminate()
...
這裡給了一個可能解決方法(workaround),ghost commented on 30 Jul 2016