PyAudio
是一个功能强大的 Python 库,用于在 Python 中进行音频输入和输出操作
1. 安装
在使用 PyAudio
之前,需要先安装它。可以使用 pip
进行安装:
pip install pyaudio
在某些系统(如 Ubuntu)上,可能还需要安装一些系统级别的依赖:
sudo apt-get install portaudio19-dev python3-pyaudio
2. 基本概念
- 声道(Channels):音频信号的独立路径,常见的有单声道(1 个声道)和立体声(2 个声道)。
- 采样率(Sample Rate):每秒采集音频样本的数量,常见的采样率有 44100 Hz、48000 Hz 等。
- 采样宽度(Sample Width):每个音频样本的位数,常见的有 8 位、16 位、32 位等。
- 音频格式(Format):
PyAudio
支持多种音频格式,如paInt8
、paInt16
、paFloat32
等。
3. 基本操作
3.1 列举音频设备
import pyaudio
p = pyaudio.PyAudio()
# 获取主机API信息
info = p.get_host_api_info_by_index(0)
numdevices = info.get('deviceCount')
# 遍历所有设备
for i in range(0, numdevices):
device_info = p.get_device_info_by_host_api_device_index(0, i)
device_name = device_info.get('name')
max_input_channels = device_info.get('maxInputChannels')
max_output_channels = device_info.get('maxOutputChannels')
if max_input_channels > 0:
print(f"输入设备ID: {i}, 名称: {device_name}")
if max_output_channels > 0:
print(f"输出设备ID: {i}, 名称: {device_name}")
p.terminate()
3.2 录制音频
import pyaudio
import wave
# 配置参数
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
CHUNK = 1024
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "output.wav"
p = pyaudio.PyAudio()
# 打开音频流
stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK)
print("* 开始录制")
frames = []
# 读取音频数据
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
data = stream.read(CHUNK)
frames.append(data)
print("* 录制结束")
# 停止并关闭音频流
stream.stop_stream()
stream.close()
p.terminate()
# 保存音频为WAV文件
wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()
3.3 播放音频
import pyaudio
import wave
# 配置参数
CHUNK = 1024
WAVE_FILE = "output.wav"
wf = wave.open(WAVE_FILE, 'rb')
p = pyaudio.PyAudio()
# 打开音频流
stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
channels=wf.getnchannels(),
rate=wf.getframerate(),
output=True)
data = wf.readframes(CHUNK)
# 播放音频
while data:
stream.write(data)
data = wf.readframes(CHUNK)
# 停止并关闭音频流
stream.stop_stream()
stream.close()
p.terminate()
4. 回调模式
PyAudio
还支持回调模式,这种模式在处理实时音频时非常有用。
4.1 录制音频(回调模式)
import pyaudio
import wave
# 配置参数
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
CHUNK = 1024
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "output_callback.wav"
frames = []
def callback(in_data, frame_count, time_info, status):
frames.append(in_data)
return (in_data, pyaudio.paContinue)
p = pyaudio.PyAudio()
# 以回调模式打开音频流
stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK,
stream_callback=callback)
print("* 开始录制(回调模式)")
# 启动音频流
stream.start_stream()
while stream.is_active():
pass
print("* 录制结束(回调模式)")
# 停止并关闭音频流
stream.stop_stream()
stream.close()
p.terminate()
# 保存音频为WAV文件
wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()
4.2 播放音频(回调模式)
import pyaudio
import wave
# 配置参数
CHUNK = 1024
WAVE_FILE = "output.wav"
wf = wave.open(WAVE_FILE, 'rb')
def callback(in_data, frame_count, time_info, status):
data = wf.readframes(frame_count)
return (data, pyaudio.paContinue if data else pyaudio.paComplete)
p = pyaudio.PyAudio()
# 以回调模式打开音频流
stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
channels=wf.getnchannels(),
rate=wf.getframerate(),
output=True,
frames_per_buffer=CHUNK,
stream_callback=callback)
print("* 开始播放(回调模式)")
# 启动音频流
stream.start_stream()
while stream.is_active():
pass
print("* 播放结束(回调模式)")
# 停止并关闭音频流
stream.stop_stream()
stream.close()
p.terminate()
wf.close()
5. 音频处理
除了基本的录制和播放,PyAudio
还可以与其他音频处理库(如 numpy
和 scipy
)结合使用,进行更复杂的音频处理。
5.1 音频数据的简单处理(使用 numpy
)
import pyaudio
import wave
import numpy as np
# 配置参数
CHUNK = 1024
WAVE_FILE = "output.wav"
wf = wave.open(WAVE_FILE, 'rb')
p = pyaudio.PyAudio()
# 打开音频流
stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
channels=wf.getnchannels(),
rate=wf.getframerate(),
output=True)
data = wf.readframes(CHUNK)
while data:
# 将音频数据转换为numpy数组
audio_array = np.frombuffer(data, dtype=np.int16)
# 简单的音频处理,例如音量放大两倍
audio_array = audio_array * 2
# 将处理后的数组转换回字节数据
new_data = audio_array.tobytes()
stream.write(new_data)
data = wf.readframes(CHUNK)
# 停止并关闭音频流
stream.stop_stream()
stream.close()
p.terminate()
wf.close()
6. 错误处理
在使用 PyAudio
时,可能会遇到各种错误,如设备未找到、格式不支持等。可以使用 try - except
块来捕获和处理这些错误。
import pyaudio
try:
p = pyaudio.PyAudio()
# 尝试打开音频流
stream = p.open(format=pyaudio.paInt16,
channels=1,
rate=44100,
input=True)
# 处理音频流
stream.stop_stream()
stream.close()
p.terminate()
except pyaudio.PyAudioError as e:
print(f"PyAudio错误: {e}")
7. 跨平台注意事项
- Windows:在 Windows 系统上,确保音频设备驱动程序是最新的。某些旧版本的驱动程序可能会导致音频输入输出问题。
- Linux:需要安装
portaudio
库及其开发文件。在某些发行版中,可能需要手动配置音频设备的权限。 - macOS:通常情况下,
PyAudio
可以直接在 macOS 上运行,但如果遇到问题,可能需要检查系统的音频设置和权限。