macOS 13 Ventura下CoreAudio切换音频输出设备方案求助
macOS 13 Ventura 下音频输出设备切换方案
问题背景
此前基于CoreAudio底层API(AudioUnitSetProperty搭配kAudioOutputUnitProperty_CurrentDevice)的音频设备切换逻辑,在macOS 13 Ventura系统中已无法正常工作,需适配苹果推荐的新API实现。
适配后的实现方案
在Ventura及后续系统中,建议使用AVFoundation框架提供的AVAudioDevice与AVAudioEngine结合的方式,替代原CoreAudio底层调用,具体实现如下:
1. 获取可用音频输出设备
替代原availableDevices()方法,直接通过AVAudioSession枚举输出设备:
import AVFoundation func getAvailableOutputDevices() -> [AVAudioDevice] { let session = AVAudioSession.sharedInstance() do { try session.setCategory(.playback) // 过滤仅保留具备输出能力的设备 return session.availableOutputDevices.filter { $0.hasOutput } } catch { print("获取输出设备失败: \(error.localizedDescription)") return [] } }
2. 切换音频引擎输出设备
替代原assignAudioDeviceTo方法,通过AVAudioNode的设备属性完成切换:
func switchAudioEngineOutput(to targetDevice: AVAudioDevice, engine: AVAudioEngine) { let outputNode = engine.outputNode // 切换设备前必须先停止引擎并断开连接 engine.stop() engine.disconnectNodeOutput(engine.mainMixerNode) do { // 设置目标输出设备 try outputNode.setDevice(targetDevice) // 重新连接混音节点与输出节点 engine.connect(engine.mainMixerNode, to: outputNode, format: nil) // 重启音频引擎 engine.prepare() try engine.start() } catch { print("切换输出设备失败: \(error.localizedDescription)") } }
3. 根据设备名称匹配目标设备
如果需要通过设备名称定位目标设备,可扩展如下方法:
func findOutputDevice(named deviceName: String) -> AVAudioDevice? { return getAvailableOutputDevices().first { $0.name == deviceName } }
关键适配说明
- 放弃直接操作
AudioUnit与AudioDeviceID的底层逻辑,改用AVFoundation封装的AVAudioDevice,这是苹果在Ventura系统中推荐的兼容方案。 - 切换设备必须在音频引擎停止、节点断开连接的状态下进行,修改设备后需重新连接并启动引擎。
AVAudioSession.availableOutputDevices已自动过滤系统内可用的输出设备,无需手动通过CoreAudio枚举解析设备ID。
内容的提问来源于stack exchange,提问作者Чайка
相关产品推荐
相关产品推荐

