Ich möchte Pyaudio häufig zum Abspielen von Audio verwenden. Obwohl es sich nicht um ein Multithread-Modul handelt, sollte es kein Problem mit der Steuerung des Wiedergabeschalters geben. Aber als ich damit spielte, geriet ich in Schwierigkeiten, die ich nicht lösen konnte.
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)
Die Ausgabe sieht so aus und dann stürzt es ab
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. Mit anderen Worten: Der Aufruf von stream1.close() nach dem Aufruf von stream1.stop_stream() führte zum Absturz des Programms und weder der untergeordnete Thread noch der Hauptthread haben die Ausnahme abgefangen! ! ! !
2. Wenn Sie close() nach stop_stream() auskommentieren, gibt es für kurze Zeit kein Problem. Wenn es jedoch etwa 10 Minuten lang weiterläuft, stürzt es nicht mehr ab weiterspielen. pa.open() löst weiterhin eine Ausnahme aus [Fehler: Ungültige Kombination von E/A-Geräten] -9993 Wenn ich das Programm schließe und neu starte, löst pa.open() eine Ausnahme aus („Ungültige Abtastrate“, -9997). . Zur Wiedergabe Nicht mehr! ! !
Wie kann dieses Problem gelöst werden?
Derzeit besteht die Lösung darin, ein pyaudio.Pyaudio()-Objekt bei jeder Wiedergabe erneut zu öffnen, was etwa 10 ms zusätzliche CPU-Zeit verbraucht. Ich habe es fast 20 Stunden lang ohne Probleme laufen lassen.
...
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