[英]Pyaudio: How to Playback wav file in separate process(multiprocessing)?
我正在编写一个程序,只要麦克风检测到的幅度超过一定水平,它就应该播放 wav 文件。 我想使用(并且过去在某种程度上成功)pyaudio,因为我需要同时处理 2 个流。 现在问题出现了
我想在与主线程分开的进程中播放 wav 文件。 以下代码只是概念证明:
import pyaudio,wave
import multiprocessing,time
filename='/home/larfan/Documents/PythonProgramming/overtone_horn/soundsamples/ZOOM0065.WAV'
#open soundfile
wf = wave.open(filename, 'rb')
chunk = 1024*4
p = pyaudio.PyAudio()
class output:
def __init__(self):
self.stream = p.open(format = p.get_format_from_width(wf.getsampwidth()),
channels = wf.getnchannels(),
rate = wf.getframerate(),
output = True)
# Read data in chunks
self.origdata = wf.readframes(chunk)
def actualoutput(self):
data=self.origdata
# Play the sound by writing the audio data to the stream
while data:
self.stream.write(data)
data = wf.readframes(chunk)
def testfuntion(self):
print('hi')
out=output()
t1=multiprocessing.Process(target=out.actualoutput)
t1.start()
time.sleep(2)
out.stream.close()
t1.terminate()
p.terminate()
如果我运行此代码,我会得到:
Traceback (most recent call last):
File "/usr/lib/python3.7/multiprocessing/process.py", line 297, in _bootstrap
self.run()
File "/usr/lib/python3.7/multiprocessing/process.py", line 99, in run
self._target(*self._args, **self._kwargs)
File "/home/larfan/Documents/PythonProgramming/overtone_horn/ultimatetest.py", line 23, in actualoutput
self.stream.write(data)
File "/usr/lib/python3/dist-packages/pyaudio.py", line 586, in write
exception_on_underflow)
OSError: [Errno -9999] Unanticipated host error
当我单独调用 out.actualoutput() 时,如果完全正常,并且如果我使用多处理与 run() 而不是 start() 它也可以工作。 但是我不能使用 run() 因为我希望主线程继续并且我想使用上面代码中举例说明的 terminate() 选项。 在实际程序中,我显然想在振幅低于阈值时立即调用 terminate() ,而不是在固定的秒数之后。
有没有人知道如何进行这项工作。 即使只是对解决方案的提示也会非常感激。 你好
如果您只想与主程序分开播放文件,asyncio 的run_in_executor()
可能是最好的方法。 当有多个线程并且您需要同时启动它们并收集结果时,多处理是首选。
例如:
import pyaudio
import wave
import sys
import asyncio
from datetime import datetime
def background(f):
def wrapped(*args, **kwargs):
return asyncio.get_event_loop().run_in_executor(None, f, *args, **kwargs)
return wrapped
@background
def play_audio(audio_file = 'sample.wav', CHUNK = 1024): #define play function however you like!
print(f'Audio Play starts at {datetime.now()}')
wf = wave.open(audio_file, 'rb')
p = pyaudio.PyAudio()
stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
channels=wf.getnchannels(),
rate=wf.getframerate(),
output=True)
data = wf.readframes(CHUNK)
while len(data)!=0:
stream.write(data)
data = wf.readframes(CHUNK)
stream.stop_stream()
stream.close()
p.terminate()
print(f'Audio play finishes {datetime.now()}')
现在,您可以根据需要运行调用此函数,它将始终与主程序分开运行,而不会将其置于等待状态:
print(f'Main Program Starts at {datetime.now()}')
play_audio('sample.wav', 1024)
print(f'Main program finishes at {datetime.now()}')
产生以下输出:
Main Program Starts at 2020-10-24 16:57:30.819964
Audio Play starts at 2020-10-24 16:57:30.819964
Main program finishes at 2020-10-24 16:57:30.820960
Audio play finishes 2020-10-24 16:58:04.684334
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.