iOS - AudioKit:输入与输出使用不同设备的实现问题
实现AudioKit音频输入输出设备分离(麦克风录制+远程扬声器播放)
我来帮你搞定这个输入输出设备分离的需求!核心是要给AVAudioSession分别指定**输入(内置麦克风)和输出(远程扬声器)**端口,再配合AudioKit的节点连接和启动逻辑来实现。下面是具体的实现步骤和完整代码:
1. 先枚举所有可用音频设备(方便确认目标设备)
先完善你代码里的printDevices()函数,用来列出当前所有的输入/输出设备,这样你能准确找到要使用的内置麦克风和远程扬声器:
func printDevices() { let inputs = session.availableInputs ?? [] let outputs = session.currentRoute.outputs print("======= 可用输入设备 =======") for input in inputs { print("设备名: \(input.portName), 类型: \(input.portType.rawValue)") } print("\n======= 当前输出设备 =======") for output in outputs { print("设备名: \(output.portName), 类型: \(output.portType.rawValue)") } }
运行后你会看到类似这样的输出,其中内置麦克风的portType是.builtInMic,远程扬声器(比如AirPlay/蓝牙)的portType可能是.airPlay或.bluetoothA2DP。
2. 配置AVAudioSession实现设备分离
在按钮点击事件里,我们需要先配置会话的类别、激活会话,然后指定输入和输出端口:
@IBAction func buttonWasPressed() { printDevices() do { // 1. 设置会话类别为播放+录制,允许蓝牙/AirPlay输出 try session.setCategory(.playAndRecord, mode: .default, options: [.allowBluetoothA2DP, .allowAirPlay]) // 2. 指定输入设备为内置麦克风 if let builtInMic = session.availableInputs?.first(where: { $0.portType == .builtInMic }) { try session.setPreferredInput(builtInMic) print("已选择内置麦克风作为输入") } // 3. 指定输出设备为远程扬声器(这里以AirPlay为例,可根据实际设备修改) let outputRoutes = session.availableOutputs ?? [] if let remoteSpeaker = outputRoutes.first(where: { $0.portType == .airPlay }) { try session.setPreferredOutput(remoteSpeaker) print("已选择AirPlay扬声器作为输出") } // 4. 激活音频会话 try session.setActive(true) // 5. 启动AudioKit try AudioKit.start() print("AudioKit已启动,开始麦克风录制+远程播放") } catch { print("配置音频会话失败: \(error.localizedDescription)") } }
3. 完善AudioKit节点连接和清理逻辑
还要在viewDidLoad里调整节点连接的时机,并在控制器销毁时停止AudioKit:
override func viewDidLoad() { super.viewDidLoad() // 先连接音频节点,启动AudioKit时才会生效 mic >>> reverb AudioKit.output = reverb // 设置低延迟缓冲(0.002可能过于激进,建议从0.01开始测试) AKSettings.ioBufferDuration = 0.01 } deinit { // 控制器销毁时停止AudioKit并停用会话 Task { do { try await AudioKit.stop() try session.setActive(false) } catch { print("停止AudioKit失败: \(error.localizedDescription)") } } }
注意事项
- 记得在
Info.plist中添加麦克风权限描述(NSMicrophoneUsageDescription),否则App会崩溃 - 如果远程扬声器是蓝牙设备,可能需要额外处理连接状态监听
AKSettings.ioBufferDuration不要设置得过小,否则可能导致音频卡顿或设备不支持,建议根据实际设备调整
内容的提问来源于stack exchange,提问作者goldwalk
相关产品推荐
相关产品推荐

