使用 Pyaudio 在 Python 中录音,错误 ||PaMacCore (AUHAL)|| ... msg=Audio Unit:在当前上下文中无法执行
Audio recording in Python with Pyaudio, error ||PaMacCore (AUHAL)|| ... msg=Audio Unit: cannot do in current context
我正在使用 pyaudio 在我的 Mac BigSur 11.6 (20G165) 上录制声音。具体来说,我使用 BlackHole 将声音从应用程序重定向到输入,效果很好。
它通常工作正常,但有时,我在终端中收到此错误:
||PaMacCore (AUHAL)|| Error on line 2500: err='-10863', msg=Audio Unit: cannot do in current context
知道为什么或如何防止它发生吗(比如,等到 PaMacCore 准备好再次录制或其他什么)?
我已经尝试重新安装,但没有帮助
brew install portaudio
或
brew install portaudio --HEAD
这是我的代码:
import pyaudio
import wave
class Recorder(object):
def __init__(self, fname, mode, channels,
rate, frames_per_buffer):
self.fname = fname
self.mode = mode
self.channels = channels
self.rate = rate
self.frames_per_buffer = frames_per_buffer
self._pa = pyaudio.PyAudio()
self.wavefile = self._prepare_file(self.fname, self.mode)
self._stream = None
def __enter__(self):
return self
def __exit__(self, exception, value, traceback):
self.close()
def record(self, duration):
# Use a stream with no callback function in blocking mode
self._stream = self._pa.open(format=pyaudio.paInt16,
channels=self.channels,
rate=self.rate,
input=True,
frames_per_buffer=self.frames_per_buffer)
for _ in range(int(self.rate / self.frames_per_buffer * duration)):
audio = self._stream.read(self.frames_per_buffer)
self.wavefile.writeframes(audio)
return None
def start_recording(self):
# Use a stream with a callback in non-blocking mode
self._stream = self._pa.open(format=pyaudio.paInt16,
channels=self.channels,
rate=self.rate,
input=True,
frames_per_buffer=self.frames_per_buffer,
stream_callback=self.get_callback())
self._stream.start_stream()
return self
def stop_recording(self):
self._stream.stop_stream()
return self
def get_callback(self):
def callback(in_data, frame_count, time_info, status):
self.wavefile.writeframes(in_data)
return in_data, pyaudio.paContinue
return callback
def close(self):
self._stream.close()
self._pa.terminate()
self.wavefile.close()
def _prepare_file(self, fname, mode='wb'):
wavefile = wave.open(fname, mode)
wavefile.setnchannels(self.channels)
wavefile.setsampwidth(self._pa.get_sample_size(pyaudio.paInt16))
wavefile.setframerate(self.rate)
return wavefile
用法示例:
recfile = Recorder(filename, 'wb', 2, 44100, 1024)
recfile.start_recording()
...
recfile.stop_recording()
显然,问题出在 BlackHole 的聚合输出设备中的比特率不匹配。我正在聚合 Blackhole 的输出 (44,1kHz) 和 Mac 扬声器 (48kHz)。这不会导致任何一致的不良行为,但有时会导致这些错误。
这是我的代码,对我有效。
def recording_by_pyaudio():
chunk = 1024 # Record in chunks of 1024 samples
sample_format = pyaudio.paInt32 # 16 bits per sample
channels = 2
fs = 44100 # Record at 44100 samples per second
seconds = 4
output = os.path.join(BASE_DIR, "recording.wav")
p = pyaudio.PyAudio() # Create an interface to PortAudio
print('Recording')
stream = p.open(format=sample_format,
channels=channels,
rate=fs,
frames_per_buffer=chunk,
input=True)
frames = [] # Initialize array to store frames
# Store data in chunks for 3 seconds
for i in range(0, int(fs / chunk * seconds)):
data = stream.read(chunk)
frames.append(data)
# Stop and close the stream
stream.stop_stream()
stream.close()
# Terminate the PortAudio interface
p.terminate()
print('Finished recording')
# Save the recorded data as a WAV file
wf = wave.open(output, 'wb')
wf.setnchannels(channels)
wf.setsampwidth(p.get_sample_size(sample_format))
wf.setframerate(fs)
wf.writeframes(b''.join(frames))
wf.close()
return output
我正在使用 pyaudio 在我的 Mac BigSur 11.6 (20G165) 上录制声音。具体来说,我使用 BlackHole 将声音从应用程序重定向到输入,效果很好。
它通常工作正常,但有时,我在终端中收到此错误:
||PaMacCore (AUHAL)|| Error on line 2500: err='-10863', msg=Audio Unit: cannot do in current context
知道为什么或如何防止它发生吗(比如,等到 PaMacCore 准备好再次录制或其他什么)?
我已经尝试重新安装,但没有帮助
brew install portaudio
或
brew install portaudio --HEAD
这是我的代码:
import pyaudio
import wave
class Recorder(object):
def __init__(self, fname, mode, channels,
rate, frames_per_buffer):
self.fname = fname
self.mode = mode
self.channels = channels
self.rate = rate
self.frames_per_buffer = frames_per_buffer
self._pa = pyaudio.PyAudio()
self.wavefile = self._prepare_file(self.fname, self.mode)
self._stream = None
def __enter__(self):
return self
def __exit__(self, exception, value, traceback):
self.close()
def record(self, duration):
# Use a stream with no callback function in blocking mode
self._stream = self._pa.open(format=pyaudio.paInt16,
channels=self.channels,
rate=self.rate,
input=True,
frames_per_buffer=self.frames_per_buffer)
for _ in range(int(self.rate / self.frames_per_buffer * duration)):
audio = self._stream.read(self.frames_per_buffer)
self.wavefile.writeframes(audio)
return None
def start_recording(self):
# Use a stream with a callback in non-blocking mode
self._stream = self._pa.open(format=pyaudio.paInt16,
channels=self.channels,
rate=self.rate,
input=True,
frames_per_buffer=self.frames_per_buffer,
stream_callback=self.get_callback())
self._stream.start_stream()
return self
def stop_recording(self):
self._stream.stop_stream()
return self
def get_callback(self):
def callback(in_data, frame_count, time_info, status):
self.wavefile.writeframes(in_data)
return in_data, pyaudio.paContinue
return callback
def close(self):
self._stream.close()
self._pa.terminate()
self.wavefile.close()
def _prepare_file(self, fname, mode='wb'):
wavefile = wave.open(fname, mode)
wavefile.setnchannels(self.channels)
wavefile.setsampwidth(self._pa.get_sample_size(pyaudio.paInt16))
wavefile.setframerate(self.rate)
return wavefile
用法示例:
recfile = Recorder(filename, 'wb', 2, 44100, 1024)
recfile.start_recording()
...
recfile.stop_recording()
显然,问题出在 BlackHole 的聚合输出设备中的比特率不匹配。我正在聚合 Blackhole 的输出 (44,1kHz) 和 Mac 扬声器 (48kHz)。这不会导致任何一致的不良行为,但有时会导致这些错误。
这是我的代码,对我有效。
def recording_by_pyaudio():
chunk = 1024 # Record in chunks of 1024 samples
sample_format = pyaudio.paInt32 # 16 bits per sample
channels = 2
fs = 44100 # Record at 44100 samples per second
seconds = 4
output = os.path.join(BASE_DIR, "recording.wav")
p = pyaudio.PyAudio() # Create an interface to PortAudio
print('Recording')
stream = p.open(format=sample_format,
channels=channels,
rate=fs,
frames_per_buffer=chunk,
input=True)
frames = [] # Initialize array to store frames
# Store data in chunks for 3 seconds
for i in range(0, int(fs / chunk * seconds)):
data = stream.read(chunk)
frames.append(data)
# Stop and close the stream
stream.stop_stream()
stream.close()
# Terminate the PortAudio interface
p.terminate()
print('Finished recording')
# Save the recorded data as a WAV file
wf = wave.open(output, 'wb')
wf.setnchannels(channels)
wf.setsampwidth(p.get_sample_size(sample_format))
wf.setframerate(fs)
wf.writeframes(b''.join(frames))
wf.close()
return output