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

Swift/SwiftUI中如何录制设备播放声音并排除麦克风输入?

实现iOS设备内录(仅捕获播放音频,排除麦克风)的可行方案

方案1:使用AVCaptureSession(iOS 11+)

这是官方推荐的简洁方案,适配多数现代iOS设备:

  • 配置AVCaptureSession时,指定音频输入设备为AVCaptureDevice.default(.audioDataRecorder, for: .audio, position: .unspecified),该设备专门用于捕获设备内部播放的音频
  • 添加AVCaptureAudioDataOutput到会话,通过代理方法获取实时音频数据
  • 启动会话后,在代理回调中处理捕获到的音频样本(写入文件或直接处理)

示例代码片段:

import AVFoundation

class InternalAudioRecorder: NSObject, AVCaptureAudioDataOutputSampleBufferDelegate {
    private let captureSession = AVCaptureSession()
    private let audioOutput = AVCaptureAudioDataOutput()
    
    func startInternalRecording() {
        guard let audioCaptureDevice = AVCaptureDevice.default(.audioDataRecorder, for: .audio, position: .unspecified) else {
            print("当前设备不支持音频内录")
            return
        }
        
        do {
            let audioInput = try AVCaptureDeviceInput(device: audioCaptureDevice)
            if captureSession.canAddInput(audioInput) {
                captureSession.addInput(audioInput)
            }
            
            if captureSession.canAddOutput(audioOutput) {
                captureSession.addOutput(audioOutput)
                let captureQueue = DispatchQueue(label: "com.audio.capture.queue")
                audioOutput.setSampleBufferDelegate(self, queue: captureQueue)
            }
            
            captureSession.startRunning()
        } catch {
            print("配置捕获会话失败:\(error.localizedDescription)")
        }
    }
    
    func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
        // 处理捕获到的音频数据,示例:提取原始数据
        guard let dataBuffer = CMSampleBufferGetDataBuffer(sampleBuffer) else { return }
        var totalLength = 0
        var rawData: UnsafeMutablePointer<Int8>?
        CMBlockBufferGetDataPointer(dataBuffer, atOffset: 0, lengthAtOffsetOut: nil, totalLengthOut: &totalLength, dataPointerOut: &rawData)
        
        // 在此处将rawData写入文件或进行后续处理
    }
}

方案2:使用AudioToolbox(底层控制,兼容更早iOS版本)

若需支持iOS 11以下版本,或需要更精细的音频参数控制,可使用AudioToolbox框架:

  • 通过AudioObjectPropertyAddress查询系统内支持内录的音频设备ID
  • 配置AudioQueue,指定输入设备为查询到的内录设备,设置回调接收音频数据
  • 启动AudioQueue开始捕获音频

关键设备查询代码:

import AudioToolbox

func getInternalCaptureDeviceID() -> AudioDeviceID? {
    var deviceID: AudioDeviceID = 0
    var propertyAddr = AudioObjectPropertyAddress(
        mSelector: kAudioHardwarePropertyDefaultInputDevice,
        mScope: kAudioObjectPropertyScopeGlobal,
        mElement: kAudioObjectPropertyElementMaster
    )
    
    var propertySize = UInt32(MemoryLayout<AudioDeviceID>.size)
    let status = AudioObjectGetPropertyData(AudioObjectID(kAudioObjectSystemObject), &propertyAddr, 0, nil, &propertySize, &deviceID)
    
    return status == noErr ? deviceID : nil
}

核心注意点

  • AVAudioRecord仅支持麦克风输入,无法实现内录,必须切换上述方案
  • 内录功能无需麦克风权限,若APP之前请求过麦克风权限,需确保内录流程不激活麦克风输入
  • 部分旧款iOS设备可能不支持内录,需提前做兼容性判断

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 08:50:21