如何在macOS上捕获音频输出采样?已尝试AVAudioEngine未成功
在macOS上捕获指定输出设备的音频采样
你的代码问题在于使用了audioEngine.inputNode——这是捕获麦克风输入的节点,而非你需要的输出设备的音频流。要捕获输出设备的声音,需要针对目标输出设备的节点配置Tap,而非默认输入节点。
修正方案与完整代码
- 定位目标输出设备:先枚举系统可用的音频输出设备,筛选出你需要捕获的设备
- 绑定引擎到目标设备:将
AVAudioEngine关联到选定的输出设备 - 在输出节点安装Tap:针对输出节点设置数据回调,捕获输出的音频采样
- 处理权限:确保应用已获得macOS音频捕获权限(在系统隐私设置中开启)
完整实现代码:
import AVFoundation class AudioOutputCaptureManager { private let audioEngine = AVAudioEngine() private var captureCallback: (([Float]) -> Void)? private var targetDevice: AVAudioDevice? init(with device: AVAudioDevice?) { self.targetDevice = device setupEngine() } // 枚举所有可用的输出设备 static func getAvailableOutputDevices() -> [AVAudioDevice] { let session = AVAudioSession.sharedInstance() do { try session.setCategory(.playAndRecord, mode: .default) // 筛选支持输出的设备 return session.availableInputs?.filter { device in device.dataSources?.contains(where: { $0.dataSourceType == .lineOut || $0.dataSourceType == .speaker }) ?? false } ?? [] } catch { print("获取音频设备失败: \(error)") return [] } } private func setupEngine() { guard let device = targetDevice else { print("未指定目标输出设备") return } do { // 将引擎输出节点绑定到目标设备 try audioEngine.outputNode.setDevice(device) let outputFormat = audioEngine.outputNode.outputFormat(forBus: 0) // 在输出节点安装Tap,捕获音频数据 audioEngine.outputNode.installTap(onBus: 0, bufferSize: 1024, format: outputFormat) { buffer, _ in let frameCount = Int(buffer.frameLength) let channels = UnsafeBufferPointer(start: buffer.floatChannelData, count: Int(buffer.format.channelCount)) if let channelData = channels.first { let samples = Array(UnsafeBufferPointer(start: channelData, count: frameCount)) self.captureCallback?(samples) } } } catch { print("配置音频引擎失败: \(error)") } } func startCapture(callback: @escaping ([Float]) -> Void) { self.captureCallback = callback do { try AVAudioSession.sharedInstance().setActive(true) try audioEngine.start() } catch { print("启动捕获失败: \(error)") } } func stopCapture() { audioEngine.stop() audioEngine.reset() do { try AVAudioSession.sharedInstance().setActive(false) } catch { print("停用音频会话失败: \(error)") } } }
使用示例
// 获取可用输出设备并选择第一个 if let targetDevice = AudioOutputCaptureManager.getAvailableOutputDevices().first { let captureManager = AudioOutputCaptureManager(with: targetDevice) captureManager.startCapture { samples in // 处理捕获到的音频采样 print("捕获到\(samples.count)个采样点") } // 停止捕获时调用 // captureManager.stopCapture() }
关键注意事项
- 权限配置:必须在
Info.plist中添加NSMicrophoneUsageDescription字段(macOS音频捕获权限统一依赖此配置),否则应用会崩溃或无法访问设备 - 设备兼容性:部分输出设备不支持音频回环捕获,需确认目标设备具备此功能
- 格式自定义:如果需要特定采样率/位深的音频数据,可以在
installTap时传入自定义的AVAudioFormat参数
内容的提问来源于stack exchange,提问作者user1569766
相关产品推荐
相关产品推荐

