使用 Pyaudio 在 Python 中录制音频,错误 ||PaMacCore (AUHAL)|| ... msg=音频单元:在当前上下文中无法执行

ste*_*tef 8 python core-audio portaudio pyaudio macos-big-sur

我正在使用 pyaudio 在 Mac BigSur 11.6 (20G165) 上录制声音。具体来说,我使用 BlackHole 将声音从应用程序重定向到输入,效果很好。

它通常工作正常,但有时,我在终端中收到此错误:

||PaMacCore (AUHAL)|| 第 2500 行错误:err='-10863',msg=音频单元:在当前上下文中无法执行

知道为什么或如何阻止它发生(例如,等到 PaMacCore 准备好再次录制或其他什么)?

我已经尝试过重新安装,但没有帮助

brew install portaudio
Run Code Online (Sandbox Code Playgroud)

或者

brew install portaudio --HEAD
Run Code Online (Sandbox Code Playgroud)

这是我的代码:

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
Run Code Online (Sandbox Code Playgroud)

使用示例:

recfile = Recorder(filename, 'wb', 2, 44100, 1024)
recfile.start_recording()
...
recfile.stop_recording()
Run Code Online (Sandbox Code Playgroud)

ste*_*tef 5

显然,问题是 BlackHole 聚合输出设备中的比特率不匹配。我正在聚合 Blackhole 的输出 (44,1kHz) 和 Mac 扬声器 (48kHz)。这不会导致任何一致的不良行为,但有时会导致这些错误。