MacOS终端选择音频设备:多进程分设备播放技术问询
问题描述
我正在开发一款Python程序,用于生成音频并播放现有音频文件。目前可以启动多个进程将音频统一播放到笔记本扬声器,但希望能将每个进程的音频信号发送至独立的音频设备,以便仅对部分进程的音频添加效果而非全部。
使用设备:MacBook
用到的工具/库:
- Python的
simpleaudio库(调用AudioToolbox连接输出设备) - 已安装
ffmpeg,可使用ffplay工具(pydub库会将波形导出至临时文件,再通过子进程调用ffplay播放)
已完成操作:
- 通过
ffplay -devices获取设备列表:
% ffplay -devices Devices: D. = Demuxing supported .E = Muxing supported -- E audiotoolbox AudioToolbox output device D avfoundation AVFoundation input device D lavfi Libavfilter virtual input device E sdl,sdl2 SDL2 output device D x11grab X11 screen capture, using XCB
- 通过
ffmpeg命令列出了可识别的CoreAudio设备:
% ffmpeg -f lavfi -i sine=r=44100 -f audiotoolbox -list_devices true - Input #0, lavfi, from 'sine=r=44100': Duration: N/A, start: 0.000000, bitrate: 705 kb/s Stream #0:0: Audio: pcm_s16le, 44100 Hz, mono, s16, 705 kb/s Stream mapping: Stream #0:0 -> #0:0 (pcm_s16le (native) -> pcm_s16le (native)) Press [q] to stop, [?] for help [AudioToolbox @ 0x135e3f230] CoreAudio devices: [AudioToolbox @ 0x135e3f230] [0] Background Music, (null) [AudioToolbox @ 0x135e3f230] [1] Background Music (UI Sounds), BGMDevice_UISounds [AudioToolbox @ 0x135e3f230] [2] MacBook Air Microphone, BuiltInMicrophoneDevice [AudioToolbox @ 0x135e3f230] [3] MacBook Air Speakers, BuiltInSpeakerDevice [AudioToolbox @ 0x135e3f230] [4] Aggregate Device, ~:AMS2_Aggregate:0 Output #0, audiotoolbox, to 'pipe:': Metadata: encoder : Lavf59.27.100 Stream #0:0: Audio: pcm_s16le, 44100 Hz, mono, s16, 705 kb/s Metadata: encoder : Lavc59.37.100 pcm_s16le size=N/A time=00:00:05.06 bitrate=N/A speed=0.984x video:0kB audio:436kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown Exiting normally, received signal 2.
疑问:
- 不清楚如何利用上述设备列表选择指定设备播放音频
- 添加更多Aggregate Device(聚合设备)后,能否将不同音频文件分别播放至各个设备?
解决方案
1. 使用ffplay/pydub指定输出设备
调用ffplay时,可通过-device参数指定设备的索引或名称,对应ffmpeg列出的CoreAudio设备列表中的序号或设备名。
示例命令
播放本地音频文件audio.wav到索引3的MacBook Air Speakers:
ffplay -f audiotoolbox -device 3 audio.wav
用设备名指定(名称含空格需加引号):
ffplay -f audiotoolbox -device "MacBook Air Speakers" audio.wav
Python中通过pydub调用的实现
手动修改ffplay的调用参数来指定设备,示例代码:
from pydub import AudioSegment import subprocess def play_to_device(audio_path, device_index): # 加载音频并导出为临时WAV文件 audio = AudioSegment.from_file(audio_path) temp_file = "/tmp/temp_audio.wav" audio.export(temp_file, format="wav") # 调用ffplay指定设备播放 subprocess.run([ "ffplay", "-f", "audiotoolbox", "-device", str(device_index), "-autoexit", # 播放完成后自动退出 temp_file ]) # 调用示例:播放到索引3的设备 play_to_device("your_audio_file.mp3", 3)
2. 使用simpleaudio指定输出设备
simpleaudio可通过获取设备列表后,指定设备ID实现定向播放:
import simpleaudio as sa # 获取并打印所有可用输出设备 devices = sa.query_devices() for idx, device in enumerate(devices): if device["output"]: print(f"ID: {idx}, 名称: {device['name']}") # 加载音频文件并指定设备播放 wave_obj = sa.WaveObject.from_wave_file("your_audio_file.wav") play_obj = wave_obj.play(device_id=3) # 选择ID3的设备 play_obj.wait_done() # 等待播放完成
关于聚合设备的疑问
添加更多聚合设备后,完全可以实现将不同音频文件分别播放至各个聚合设备。每个聚合设备在CoreAudio中会被识别为独立的输出设备,拥有唯一的索引和名称,可像普通设备一样通过ffplay或simpleaudio指定对应ID/名称播放。
需注意:聚合设备需在Mac的「音频 MIDI 设置」中创建,确保每个设备的输出通路配置正确,才能正常输出音频。
内容的提问来源于stack exchange,提问作者jon_two
相关产品推荐
相关产品推荐

