PyAudio录音教程(电脑编程如何录音)

Pyaudio 简介

Pyaudio 简介

PyAudio是Python的一个音频处理模块,它可以让我们在Python中使用音频设备,比如录音、播放音频等。PyAudio是基于PortAudio的,所以它可以在多种平台上使用,比如Windows、Linux、Mac等。

安装

pip install pyaudio

接下来通过两段代码来演示PyAudio的使用。通过 record.py 可以录音 录制一段 10 秒的音频,然后通过 play.py 可以播放刚刚录制的音频。

录音 recorder.py

import pyaudio import wave CHUNK = 1024 FORMAT = pyaudio.paInt16 CHANNELS = 2 RATE = 44100 RECORD_SECONDS = 10 WAVE_OUTPUT_FILENAME = "output.wav" audio = pyaudio.PyAudio() # start Recording stream = 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 Recording stream.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

import pyaudio import wave CHUNK = 1024 wf = wave.open('output.wav', 'rb') p = pyaudio.PyAudio() # open stream stream = p.open(format=p.get_format_from_width(wf.getsampwidth()), channels=wf.getnchannels(), rate=wf.getframerate(), output=True) # read data data = wf.readframes(CHUNK) # play stream while data != '': stream.write(data) data = wf.readframes(CHUNK) # stop stream stream.stop_stream() stream.close() # close PyAudio p.terminate() wf.close()

录音详解

录音参数

CHUNK = 1024 FORMAT = pyaudio.paInt16 CHANNELS = 2 RATE = 44100 RECORD_SECONDS = 10 WAVE_OUTPUT_FILENAME = "output.wav"

  • • CHUNK:每次读取的音频块大小,单位是字节,一般取1024的倍数,比如1024、2048、4096等。
  • • FORMAT:音频的格式,这里使用的是16位整数,即paInt16。
  • • CHANNELS:声道数,这里使用的是双声道,即2。
  • • RATE:采样率,这里使用的是44100,即44.1kHz。
  • • RECORD_SECONDS:录音的时长,这里是10秒。
  • • WAVE_OUTPUT_FILENAME:输出的音频文件名。

录音设备

PC录音一般有以下几种声音来源:

录制声音的几种来源

  • • 外录:麦克风
  • • 内录:录制电脑上正在播放的声音,即从声卡录制,而不是从麦克风录制

上面的 record.py 虽然实现了录音的功能,但是我们不知道声音的输入是什么?是内录还是外录?

以下是 Windows 系统下录音的几种方式:

Windows 系统下录音的几种方式

在 PyAudio 不指定录音设备的情况下,它会自动选择系统默认的录音设备,比如上面的 麦克风陈列,也就是我们常说的外录。而立体声混音即是内录,内录须在声音面板启用立体声混音。

那么如何指定录音设备呢?我们可以通过 PyAudio 的 get_device_info_by_index 方法来获取设备信息,然后通过 get_default_input_device_info 方法来获取系统默认的录音设备。

指定录音设备

PyAudio提供了一个 get_device_count() 方法,可以获取当前系统的录音设备数量,然后通过 get_device_info_by_index() 方法可以获取指定设备的信息。

import pyaudio audio = pyaudio.PyAudio() # get device count device_count = audio.get_device_count() print(f"device count: {device_count}") # get device info for i in range(device_count): device_info = audio.get_device_info_by_index(i) print(f"device {i}: {device_info}")

以下是我电脑运行结果:

C:\projects\python\pyaudio> python .\devs.py device count: 24 device 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 进行内录。

# start Recording stream = audio.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, input_device_index = 2, frames_per_buffer=CHUNK)

如何同时内录和外录

我们可以使用 2 个单独的线程将 2 个不同的录音设备(声音输入源)记录到单独的 Wav 文件中。然后使用 pydub[1] 库混合这两个文件。

import pyaudio import wave from tqdm import tqdm from pydub import AudioSegment CHUNK = 1024 FORMAT = pyaudio.paInt16 CHANNELS = 2 RATE = 44100 RECORD_SECONDS = 10 audio = 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 Recording system_sound.stop_stream() system_sound.close() speaker_sound.stop_stream() speaker_sound.close() audio.terminate() # save the audio frames as .wav file wf1 = 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 files speakersound = 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 文档[2]
  • • PyAudio: Cross-platform audio I/O for Python, with PortAudio[3]
  • • python – PyAudio — How to capture microphone and system sounds in a single stream? – Stack Overflow[4]

欢迎关注我的公众号“码中人”,原创技术文章第一时间推送。

引用链接

[1] pydub: http://pydub.com/
[2] wave — 读写WAV格式文件 — Python 3.10.8 文档: https://docs.python.org/zh-cn/3/library/wave.html
[3] PyAudio: Cross-platform audio I/O for Python, with PortAudio: http://people.csail.mit.edu/hubert/pyaudio/
[4] python – PyAudio — How to capture microphone and system sounds in a single stream? – Stack Overflow: https://stackoverflow.com/questions/59665469/pyaudio-how-to-capture-microphone-and-system-sounds-in-a-single-stream

PyAudio录音教程(电脑编程如何录音)

相关文章:

你感兴趣的文章:

标签云: