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

macOS:如何通过命令行或Objective-C/Swift API修改音频MIDI设置?

在macOS程序化调整Audio Midi Setup配置的方案

当然可以!在macOS上完全可以通过命令行或原生Objective-C/Swift API来修改Audio Midi Setup里的设置,包括调整多输出设备的成员组成。下面给你分两种方式详细说明:

一、原生CoreAudio API(Objective-C/Swift)

这是最直接、可控的方式,通过macOS的CoreAudio框架直接操作音频设备配置,完全覆盖Audio Midi Setup能做的所有设置。

核心思路

多输出设备属于**聚合设备(Aggregate Device)**的一种类型(子类型为kAudioSubType_MultiOutput),我们可以通过CoreAudio的属性读写接口来修改它的成员列表:

  1. 枚举系统中的所有音频设备,定位到目标多输出设备
  2. 获取该设备的kAudioDevicePropertyAggregateDeviceList属性(当前成员设备ID列表)
  3. 修改成员列表后,将新列表写回该属性
  4. 保存系统音频配置,让修改生效

Swift 代码示例

import CoreAudio

// 辅助函数:枚举所有音频设备,找到指定名称的多输出设备
func findMultiOutputDevice(named deviceName: String) -> AudioDeviceID? {
    var address = AudioObjectPropertyAddress(
        mSelector: kAudioHardwarePropertyDevices,
        mScope: kAudioObjectPropertyScopeGlobal,
        mElement: kAudioObjectPropertyElementMain
    )
    
    var deviceCount: UInt32 = 0
    var status = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &address, 0, nil, &deviceCount)
    guard status == noErr else { return nil }
    
    let deviceCountInt = Int(deviceCount)
    var devices = Array(repeating: AudioDeviceID(), count: deviceCountInt)
    status = AudioObjectGetPropertyData(kAudioObjectSystemObject, &address, 0, nil, &deviceCount, &devices)
    guard status == noErr else { return nil }
    
    for deviceID in devices {
        var nameSize: UInt32 = 0
        var nameAddress = AudioObjectPropertyAddress(
            mSelector: kAudioDevicePropertyDeviceNameCFString,
            mScope: kAudioObjectPropertyScopeGlobal,
            mElement: kAudioObjectPropertyElementMain
        )
        status = AudioObjectGetPropertyDataSize(deviceID, &nameAddress, 0, nil, &nameSize)
        guard status == noErr else { continue }
        
        var deviceNameCF: CFString?
        status = AudioObjectGetPropertyData(deviceID, &nameAddress, 0, nil, &nameSize, &deviceNameCF)
        guard let name = deviceNameCF as String?, name == deviceName else { continue }
        
        // 验证是否为多输出设备
        var subTypeSize: UInt32 = UInt32(MemoryLayout<AudioDeviceID>.stride)
        var subTypeAddress = AudioObjectPropertyAddress(
            mSelector: kAudioDevicePropertyDeviceSubType,
            mScope: kAudioObjectPropertyScopeGlobal,
            mElement: kAudioObjectPropertyElementMain
        )
        var subType = AudioDeviceID()
        status = AudioObjectGetPropertyData(deviceID, &subTypeAddress, 0, nil, &subTypeSize, &subType)
        if subType == kAudioSubType_MultiOutput {
            return deviceID
        }
    }
    return nil
}

// 修改多输出设备的成员列表
func updateMultiOutputMembers(multiOutputName: String, newMemberDeviceIDs: [AudioDeviceID]) -> OSStatus {
    guard let multiOutputID = findMultiOutputDevice(named: multiOutputName) else {
        return kAudioHardwareBadDeviceError
    }
    
    var propertySize = UInt32(MemoryLayout<AudioDeviceID>.stride * newMemberDeviceIDs.count)
    let address = AudioObjectPropertyAddress(
        mSelector: kAudioDevicePropertyAggregateDeviceList,
        mScope: kAudioObjectPropertyScopeGlobal,
        mElement: kAudioObjectPropertyElementMain
    )
    
    // 写入新的成员列表
    var status = AudioObjectSetPropertyData(multiOutputID, &address, 0, nil, propertySize, newMemberDeviceIDs)
    guard status == noErr else { return status }
    
    // 保存系统音频配置,确保修改持久化
    let configAddress = AudioObjectPropertyAddress(
        mSelector: kAudioSystemPropertyConfiguration,
        mScope: kAudioObjectPropertyScopeGlobal,
        mElement: kAudioObjectPropertyElementMain
    )
    status = AudioObjectSetPropertyData(kAudioObjectSystemObject, &configAddress, 0, nil, 0, nil)
    return status
}

// 使用示例:假设你已经知道要添加的成员设备ID
// let memberIDs: [AudioDeviceID] = [0x123, 0x456]
// let status = updateMultiOutputMembers(multiOutputName: "我的多输出设备", newMemberDeviceIDs: memberIDs)
// print(status == noErr ? "修改成功" : "失败,错误码:\(status)")

注意事项

  • 运行这类代码需要辅助功能权限(在「系统设置-隐私与安全性-辅助功能」中给你的应用授权)
  • 如果是沙盒应用,还需要开启「音频输入/输出」权限,并且可能无法修改系统级配置,建议在沙盒外运行工具
  • 修改配置后,部分应用可能需要重启才能识别到新的多输出设备

二、命令行方式

macOS没有原生的命令行工具直接修改多输出设备成员,但你可以基于上面的CoreAudio API自己编译一个命令行工具,或者使用第三方开源工具。

自制命令行工具

  1. 用Swift写一个简单的命令行程序,整合上面的代码逻辑
  2. 通过swift build -c release编译成可执行文件
  3. 在终端直接调用该工具,传入多输出设备名称和成员设备ID参数

比如编译后的工具可以这样使用:

./MultiOutputUpdater --name "我的多输出设备" --members 0x123 0x456

第三方工具(可选)

部分开源项目如switchaudio-osx主要用于切换默认音频设备,但如果需要修改多输出设备,还是建议基于CoreAudio自己实现,这样更可控。

额外提示

如果你不确定设备的AudioDeviceID,可以在代码中添加枚举设备并打印ID的逻辑,来获取目标设备的ID。

内容的提问来源于stack exchange,提问作者Bri Bri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:40:38