python - pyaudio stream.close() führt zum Absturz des Programms und die Ausnahme kann nicht abgefangen werden
我想大声告诉你
我想大声告诉你 2017-06-12 09:25:06
0
1
1210

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()
...
我想大声告诉你
我想大声告诉你

Antworte allen(1)
阿神

這裡給了一個可能解決方法(workaround),ghost commented on 30 Jul 2016

Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage