You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MacOS终端选择音频设备:多进程分设备播放技术问询

问题描述

我正在开发一款Python程序,用于生成音频并播放现有音频文件。目前可以启动多个进程将音频统一播放到笔记本扬声器,但希望能将每个进程的音频信号发送至独立的音频设备,以便仅对部分进程的音频添加效果而非全部。

使用设备:MacBook
用到的工具/库:

  • Python的simpleaudio库(调用AudioToolbox连接输出设备)
  • 已安装ffmpeg,可使用ffplay工具(pydub库会将波形导出至临时文件,再通过子进程调用ffplay播放)

已完成操作:

  1. 通过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
  1. 通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 17:10:16