PyAudio是Python的一个音频处理模块,它可以让我们在Python中使用音频设备,比如录音、播放音频等。PyAudio是基于PortAudio的,所以它可以在多种平台上使用,比如Windows、Linux、Mac等。
安装1pip install pyaudio示例接下来通过两段代码来演示PyAudio的使用。通过 record.py 可以录音 录制一段 10 秒的音频,然后通过 play.py 可以播放刚刚录制的音频。
录音 recorder.py
1 2 3 4 5 6 7 8 91011121314151617181920212223242526272829303132333435import pyaudioimport waveCHUNK = 1024FORMAT = pyaudio.paInt16CHANNELS = 2RATE = 44100RECORD_SECONDS = 10WAVE_OUTPUT_FILENAME = "output.wav"audio = pyaudio.PyAudio()# start Recordingstream = audio.open(format=FORMAT, channels=CHANNELS,rate=RATE, input=True,frames_per_buffer=CHUNK)print("recording...")frames = []for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):data = stream.read(CHUNK)frames.append(data)print("finished recording")# stop Recordingstream.stop_stream()stream.close()audio.terminate()waveFile = wave.open(WAVE_OUTPUT_FILENAME, 'wb')waveFile.setnchannels(CHANNELS)waveFile.setsampwidth(audio.get_sample_size(FORMAT))waveFile.setframerate(RATE)waveFile.writeframes(b''.join(frames))waveFile.close()播放 play.py
1 2 3 4 5 6 7 8 9101112131415161718192021222324252627282930import pyaudioimport waveCHUNK = 1024wf = wave.open('output.wav', 'rb')p = pyaudio.PyAudio()# open streamstream = p.open(format=p.get_format_from_width(wf.getsampwidth()),channels=wf.getnchannels(),rate=wf.getframerate(),output=True)# read datadata = wf.readframes(CHUNK)# play streamwhile data != '':stream.write(data)data = wf.readframes(CHUNK)# stop streamstream.stop_stream()stream.close()# close PyAudiop.terminate()wf.close()录音详解录音参数123456CHUNK = 1024FORMAT = pyaudio.paInt16CHANNELS = 2RATE = 44100RECORD_SECONDS = 10WAVE_OUTPUT_FILENAME = "output.wav"CHUNK:每次读取的音频块大小,单位是字节,一般取1024的倍数,比如1024、2048、4096等。FORMAT:音频的格式,这里使用的是16位整数,即paInt16。CHANNELS:声道数,这里使用的是双声道,即2。RATE:采样率,这里使用的是44100,即44.1kHz。RECORD_SECONDS:录音的时长,这里是10秒。WAVE_OUTPUT_FILENAME:输出的音频文件名。录音设备上面的 record.py 虽然实现了录音的功能,但是我们不知道声音的输入是什么?是内录还是外录?
PC录音一般有以下几种声音
外录:麦克风内录:录制电脑上正在播放的声音,即从声卡录制,而不是从麦克风录制以下是 Windows 系统下录音的几种方式:
录音设备列表在 PyAudio 不指定录音设备的情况下,它会自动选择系统默认的录音设备,比如上面的 麦克风陈列,也就是我们常说的外录。而立体声混音即是内录,内录须在声音面板启用立体声混音。
那么如何指定录音设备呢?我们可以通过 PyAudio 的 get_device_info_by_index 方法来获取设备信息,然后通过 get_default_input_device_info 方法来获取系统默认的录音设备。
指定录音设备PyAudio提供了一个 get_device_count() 方法,可以获取当前系统的录音设备数量,然后通过 get_device_info_by_index() 方法可以获取指定设备的信息。
1 2 3 4 5 6 7 8 9101112import pyaudioaudio = pyaudio.PyAudio()# get device countdevice_count = audio.get_device_count()print(f"device count: {device_count}")# get device infofor i in range(device_count):device_info = audio.get_device_info_by_index(i)print(f"device {i}: {device_info}")以下是我电脑运行结果:
12345678C:\projects\python\pyaudio> python .\devs.pydevice count: 24device 0: {'index': 0, 'structVersion': 2, 'name': 'Microsoft 声音映射器 - Input', 'hostApi': 0, 'maxInputChannels': 2, 'maxOutputChannels': 0, 'defaultLowInputLatency': 0.09, 'defaultLowOutputLatency': 0.09, 'defaultHighInputLatency': 0.18, 'defaultHighOutputLatency': 0.18, 'defaultSampleRate': 44100.0}device 1: {'index': 1, 'structVersion': 2, 'name': '麦克风阵列 (适用于数字麦克风的英特尔® 智音技 术)', 'hostApi': 0, 'maxInputChannels': 4, 'maxOutputChannels': 0, 'defaultLowInputLatency': 0.09, 'defaultLowOutputLatency': 0.09, 'defaultHighInputLatency': 0.18, 'defaultHighOutputLatency': 0.18, 'defaultSampleRate': 44100.0}device 2: {'index': 2, 'structVersion': 2, 'name': '立体声混音 (Realtek(R) Audio)', 'hostApi': 0, 'maxInputChannels': 2, 'maxOutputChannels': 0, 'defaultLowInputLatency': 0.09, 'defaultLowOutputLatency': 0.09, 'defaultHighInputLatency': 0.18, 'defaultHighOutputLatency': 0.18, 'defaultSampleRate': 44100.0}device 3: {'index': 3, 'structVersion': 2, 'name': 'Microsoft 声音映射器 - Output', 'hostApi': 0, 'maxInputChannels': 0, 'maxOutputChannels': 2, 'defaultLowInputLatency': 0.09, 'defaultLowOutputLatency': 0.09, 'defaultHighInputLatency': 0.18, 'defaultHighOutputLatency': 0.18, 'defaultSampleRate': 44100.0}device 4: {'index': 4, 'structVersion': 2, 'name': 'Realtek HD Audio 2nd output (Re', 'hostApi': 0, 'maxInputChannels': 0, 'maxOutputChannels': 2, 'defaultLowInputLatency': 0.09, 'defaultLowOutputLatency': 0.09, 'defaultHighInputLatency': 0.18, 'defaultHighOutputLatency': 0.18, 'defaultSampleRate': 44100.0}... ...其中 立体声混音 (Realtek(R) Audio) 是 device 2。即使此时系统默认的录音设备是外录,我们也可以通过指定 `input_device_index = 2 进行内录。
12345# start Recordingstream = audio.open(format=FORMAT, channels=CHANNELS,rate=RATE, input=True,input_device_index = 2,frames_per_buffer=CHUNK)如何同时内录和外录我们可以使用 2 个单独的线程将 2 个不同的录音设备(声音输入源)记录到单独的 Wav 文件中。然后使用 pydub 库混合这两个文件。
1 2 3 4 5 6 7 8 91011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768import pyaudioimport wavefrom tqdm import tqdmfrom pydub import AudioSegmentCHUNK = 1024FORMAT = pyaudio.paInt16CHANNELS = 2RATE = 44100RECORD_SECONDS = 10audio = pyaudio.PyAudio()system_sound = audio.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, input_device_index=2, frames_per_buffer=CHUNK)speaker_sound = audio.open(format=FORMAT, channels=CHANNELS,rate=RATE, input=True,input_device_index=1,frames_per_buffer=CHUNK)print("recording...")system_sound.start_stream()speaker_sound.start_stream()frames1 = []frames2 = []for i in tqdm(range(0, int(RATE / CHUNK * RECORD_SECONDS))):data1 = system_sound.read(CHUNK)frames1.append(data1)data2 = speaker_sound.read(CHUNK)frames2.append(data2)print("finished recording")# stop Recordingsystem_sound.stop_stream()system_sound.close()speaker_sound.stop_stream()speaker_sound.close()audio.terminate()# save the audio frames as .wav filewf1 = wave.open("system.wav", 'wb')wf1.setnchannels(CHANNELS)wf1.setsampwidth(audio.get_sample_size(FORMAT))wf1.setframerate(RATE)wf1.writeframes(b''.join(frames1))wf1.close()wf2 = wave.open("speaker.wav", 'wb')wf2.setnchannels(CHANNELS)wf2.setsampwidth(audio.get_sample_size(FORMAT))wf2.setframerate(RATE)wf2.writeframes(b''.join(frames2))wf2.close()# merge two wav filesspeakersound = AudioSegment.from_file("speaker.wav")micsound = AudioSegment.from_file("system.wav")mixsound = speakersound.overlay(micsound)mixsound.export("mixsound.wav", format='wav')参考资料wave — 读写WAV格式文件 — Python 3.10.8 文档
PyAudio: Cross-platform audio I/O for Python, with PortAudio
python - PyAudio – How to capture microphone and system sounds in a single stream? - Stack Overflow