如何用Swift获取系统当前音频输出设备的名称或ID?
获取系统当前音频输出设备并适配AVAudioEngine
AVAudioEngine的主混音器确实没有直接提供获取系统当前音频输出设备的属性,系统的音频路由和设备信息是由AVAudioSession全局管理的,你需要通过会话层获取设备信息,再绑定到AVAudioEngine的输出节点上。
1. 获取系统当前音频输出设备
通过AVAudioSession的路由信息,提取当前输出端口对应的设备:
import AVFoundation func getCurrentSystemAudioOutputDevice() -> AVAudioDevice? { let audioSession = AVAudioSession.sharedInstance() // 获取当前路由的第一个输出端口 guard let outputPort = audioSession.currentRoute.outputs.first else { return nil } // 根据端口的deviceID匹配对应的AVAudioDevice let targetDeviceID = outputPort.deviceID for device in AVAudioDevice.devices() { if device.deviceID == targetDeviceID { return device } } return nil }
2. 将获取到的设备设置给AVAudioEngine
拿到设备后,需要先停止引擎,再为输出节点设置目标设备,最后重启引擎:
func configureAudioEngineOutput(with device: AVAudioDevice, engine: AVAudioEngine) throws { // 先停止引擎避免状态冲突 engine.stop() // 为输出节点设置指定设备 try engine.outputNode.setOutputDevice(device) // 重新启动引擎 try engine.start() }
3. 监听系统音频设备切换
当系统音频输出设备变更时(比如插入耳机、切换蓝牙音箱),需要及时更新AVAudioEngine的输出,可通过监听路由变化通知实现:
func setupAudioRouteObserver() { NotificationCenter.default.addObserver( forName: AVAudioSession.routeChangeNotification, object: AVAudioSession.sharedInstance(), queue: .main ) { notification in guard let reasonRawValue = notification.userInfo?[AVAudioSessionRouteChangeReasonKey] as? UInt, let reason = AVAudioSession.RouteChangeReason(rawValue: reasonRawValue) else { return } // 处理设备新增/移除的场景 if reason == .newDeviceAvailable || reason == .oldDeviceUnavailable { if let newDevice = getCurrentSystemAudioOutputDevice() { let yourAudioEngine = AVAudioEngine() // 替换为你实际的AVAudioEngine实例 try? configureAudioEngineOutput(with: newDevice, engine: yourAudioEngine) } } } }
注意事项
- 调用前确保已获取音频播放权限,可通过
AVAudioSession.sharedInstance().requestPlaybackPermission请求。 - 操作AVAudioEngine时要注意状态一致性,必须先停止引擎再修改输出设备。
内容的提问来源于stack exchange,提问作者33333
相关产品推荐
相关产品推荐

