Ubuntu下Python能否用sounddevice替代pygame经虚拟音频线播放音频
该需求完全可以通过sounddevice实现,核心逻辑是提前加载虚拟音频输出设备,在调用sounddevice播放接口时指定该设备为输出目标即可,具体实现流程如下:
前置环境准备
- 配置Ubuntu虚拟音频线:直接用PulseAudio自带的null-sink模块实现,执行命令加载虚拟输出设备:
pactl load-module module-null-sink sink_name=VirtualCable sink_properties=device.description="Virtual_Audio_Cable"
如果需要图形化调整音频路由,可安装pavucontrol:sudo apt install pavucontrol - 安装系统依赖:
sudo apt install portaudio19-dev ffmpeg pulseaudio-utils - 安装Python依赖库:
pip install sounddevice soundfile numpy pydub
具体实现
1. 获取虚拟音频线的设备ID
sounddevice是通过设备索引指定输出目标的,先运行以下代码枚举所有音频设备,找到名称包含Virtual_Audio_Cable且支持输出的设备索引:
import sounddevice as sd print(sd.query_devices())
也可以写自动匹配逻辑,避免硬编码ID:
VIRTUAL_CABLE_NAME = "Virtual_Audio_Cable" virtual_cable_id = None for idx, dev in enumerate(sd.query_devices()): if VIRTUAL_CABLE_NAME in dev["name"] and dev["max_output_channels"] > 0: virtual_cable_id = idx break if virtual_cable_id is None: raise RuntimeError("未检测到虚拟音频线设备,请先加载null-sink模块")
2. 播放.wav格式文件
wav格式可以直接通过soundfile库解码为numpy数组,传入播放接口即可:
import soundfile as sf # 读取wav文件,自动适配采样率、声道数 audio_data, sample_rate = sf.read("your_audio.wav", dtype="float32") # 指定输出到虚拟音频线播放 sd.play(audio_data, samplerate=sample_rate, device=virtual_cable_id) sd.wait() # 阻塞当前线程直到播放完成
3. 播放.mp3格式文件
soundfile原生不支持mp3解码,通过pydub读取mp3文件后转成符合sounddevice要求的float32数组即可:
import numpy as np from pydub import AudioSegment # 读取mp3文件 mp3_obj = AudioSegment.from_mp3("your_audio.mp3") # 提取采样数据转numpy数组 audio_data = np.array(mp3_obj.get_array_of_samples(), dtype="float32") # 适配声道 if mp3_obj.channels == 2: audio_data = audio_data.reshape((-1, 2)) # 16位整型转[-1,1]区间的float32格式,避免爆音 audio_data = audio_data / (2 ** 15) sample_rate = mp3_obj.frame_rate # 输出到虚拟音频线播放 sd.play(audio_data, samplerate=sample_rate, device=virtual_cable_id) sd.wait()
常见问题排查
- 重启后虚拟音频线消失:把
load-module module-null-sink sink_name=VirtualCable sink_properties=device.description="Virtual_Audio_Cable"写入/etc/pulse/default.pa文件末尾,即可实现开机自动加载。 - 播放速度异常、有爆音:检查传入
sd.play()的采样率是否和音频文件实际采样率一致,音频数组数值范围是否在[-1,1]区间,dtype是否为float32,不要直接传入未归一化的整型音频数据。 - 其他程序无法捕获虚拟音频线的输出:将捕获程序的输入源设置为
Virtual_Audio_Cable Monitor,该源是null-sink自带的监听端口,会输出虚拟线中播放的全部音频流,可在pavucontrol的「输入设备」标签页下快速切换。
内容的提问来源于stack exchange,提问作者Musawar Baig
相关产品推荐
相关产品推荐

