簡體   English   中英

使用 Pyaudio 在 Python 中錄音,錯誤 ||PaMacCore (AUHAL)||... msg=Audio Unit: cannot do in current context

[英]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(奧哈爾)|| 第 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)。 這不會導致任何一致的不良行為,但有時會導致這些錯誤。

我也嘗試過,然后我發現問題顯然是比特率不匹配,這導致了 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM