簡體   English   中英

在 Raspberry Pi 上使用 Python,我無法通過 Thonny/終端使用 PyAudio 錄制音頻

[英]Using Python on Raspberry Pi, I'm unable to record audio with PyAudio via Thonny/terminal

使用來自: https://realpython.com/playing-and-recording-sound-python/#python-sounddevice_1的示例,使用 Thonny 時出現以下錯誤:“后端終止或斷開連接。使用“停止/重新啟動” ' 重新啟動。”。 當我在終端中運行程序時,我得到這個錯誤:“OSError:[Errno -9981] Input overflowed”。 如果我將示例代碼(未線程化)修改為不在溢出時拋出異常“data = stream.read(chunk, exception_on_overflow = False)”,則示例代碼(未線程化)可以在終端和 Thonny 中工作,但在新的情況下不起作用線。 我還嘗試將塊大小更改為更大或更小無濟於事。 當我有線程版本的溢出異常時,我在終端中得到一個不同的錯誤:“分段錯誤”。 我正在運行 Raspbian 10 Buster 和 Python 3.7.3,如果有人可以測試/看看它是否有效,謝謝。

import time
import board
import busio
import digitalio
from adafruit_mcp230xx.mcp23017 import MCP23017
from adafruit_debouncer import Debouncer
i2c = busio.I2C(board.SCL, board.SDA)
mcp = MCP23017(i2c)

import threading
import pyaudio
import wave
import sys
import subprocess

record = False

def background_audio_recording():
    
    #chunk = 1024  # Record in chunks of 1024 samples
    chunk = 1024
    sample_format = pyaudio.paInt16  # 16 bits per sample
    channels = 2
    fs = 44100  # Record at 44100 samples per second
    #seconds = 3
    filename = "output.wav"
    
    p = pyaudio.PyAudio()  # Create an interface to PortAudio
    
    stream = p.open(format=sample_format,
        channels=channels,
        rate=fs,
        frames_per_buffer=chunk,
        #input_device_index = 2,
        input=True)
    
    frames = []  # Initialize array to store frames
    
    while record:
        #data = stream.read(chunk, exception_on_overflow = False)
        data = stream.read(chunk)
        frames.append(data)
    '''
    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(filename, 'wb')
    wf.setnchannels(channels)
    wf.setsampwidth(p.get_sample_size(sample_format))
    wf.setframerate(fs)
    wf.writeframes(b''.join(frames))
    wf.close()

    print("File Saved")

    return

button1PinSetup = mcp.get_pin(0) # GPA0
button1PinSetup.direction = digitalio.Direction.INPUT
button1PinSetup.pull = digitalio.Pull.UP
button1Pin = Debouncer(button1PinSetup)

button2PinSetup = mcp.get_pin(1) # GPA1
button2PinSetup.direction = digitalio.Direction.INPUT
button2PinSetup.pull = digitalio.Pull.UP
button2Pin = Debouncer(button2PinSetup)

while True:
    button1Pin.update()
    button2Pin.update()
    if button1Pin.fell:
        print("Record")
        if record == True:
            print("Already Recording")
        else:
            record = True
            threading.Thread(target=background_audio_recording).start()
    if button2Pin.fell:
        print("Recording Stopped")
        record = False

似乎,我需要將 PyAudio object 創建為全局以及在線程內(對於每次額外的錄制嘗試)。 我讓它使用以下代碼

import pyaudio
import wave
import time
import threading

import board
import busio
import digitalio
from adafruit_mcp230xx.mcp23017 import MCP23017
from adafruit_debouncer import Debouncer
i2c = busio.I2C(board.SCL, board.SDA)
mcp = MCP23017(i2c)

form_1 = pyaudio.paInt16 # 16-bit resolution
chans = 2 # 1 channel
samp_rate = 44100 # 44.1kHz sampling rate
chunk = 4096 # 2^12 samples for buffer
#record_secs = 3 # seconds to record
dev_index = 2 # device index found by p.get_device_info_by_index(ii)
wav_output_filename = 'test1.wav' # name of .wav file

audio = pyaudio.PyAudio() # create pyaudio instantiation

record = False

def background_audio_recording():
    audio = pyaudio.PyAudio() # create pyaudio instantiation
    # create pyaudio stream
    stream = audio.open(format = form_1,rate = samp_rate,channels = chans, \
                    input_device_index = dev_index,input = True, \
                    frames_per_buffer=chunk)
    print("recording")
    frames = []

    # loop through stream and append audio chunks to frame array
    #for ii in range(0,int((samp_rate/chunk)*record_secs)):
    while record == True:
        data = stream.read(chunk)
        frames.append(data)

    print("finished recording")

    # stop the stream, close it, and terminate the pyaudio instantiation
    stream.stop_stream()
    stream.close()
    audio.terminate()
    
    # save the audio frames as .wav file
    wavefile = wave.open(wav_output_filename,'wb')
    wavefile.setnchannels(chans)
    wavefile.setsampwidth(audio.get_sample_size(form_1))
    wavefile.setframerate(samp_rate)
    wavefile.writeframes(b''.join(frames))
    wavefile.close()
    return


button1PinSetup = mcp.get_pin(0) # GPA0
button1PinSetup.direction = digitalio.Direction.INPUT
button1PinSetup.pull = digitalio.Pull.UP
button1Pin = Debouncer(button1PinSetup)

button2PinSetup = mcp.get_pin(1) # GPA1
button2PinSetup.direction = digitalio.Direction.INPUT
button2PinSetup.pull = digitalio.Pull.UP
button2Pin = Debouncer(button2PinSetup)

while True:
    button1Pin.update()
    button2Pin.update()
    if button1Pin.fell:
        print("Record")
        if record == True:
            print("Already Recording")
        else:
            record = True
            threading.Thread(target=background_audio_recording).start()
    if button2Pin.fell:
        print("Recording Stopped")
        record = False

暫無
暫無

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

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