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

macOS 15+下使用ScreenCaptureKit捕获麦克风输入失败求助

macOS 15.0+ 下 ScreenCaptureKit 无法捕获内置麦克风输入的解决方案

针对你遇到的屏幕视频捕获正常但内置麦克风无输入的问题,可从以下几个方向排查修复:

一、显式指定内置麦克风设备ID

尽管文档说明microphoneCaptureDeviceID = nil会使用默认设备,但 macOS 15+ 可能需要显式指定内置麦克风ID才能正常捕获。通过AVFoundation获取设备ID:

import AVFoundation

func getBuiltInMicrophoneID() -> String? {
    let session = AVAudioSession.sharedInstance()
    guard let inputs = session.availableInputs else { return nil }
    return inputs.first(where: { $0.portType == .builtInMic })?.deviceID
}

// 初始化streamConfiguration时替换原设置
streamConfiguration.microphoneCaptureDeviceID = getBuiltInMicrophoneID()

注:AVFoundation/AVFAudio完全支持macOS,你之前的误解导致错过了这个关键方案。

二、调整SCStreamOutput添加逻辑

文件录制输出与手动添加的麦克风流输出可能存在冲突,简化流输出添加逻辑:

do {
    try stream.addStreamOutput(streamOutput, type: .screen, sampleHandlerQueue: videoSamplesQueue)
    try stream.addStreamOutput(streamOutput, type: .audio, sampleHandlerQueue: audioSamplesQueue)
    // 注释掉单独的.microphone类型添加,依赖streamConfiguration.captureMicrophone = true让录制输出自动包含麦克风音频
    // try stream.addStreamOutput(streamOutput, type: .microphone, sampleHandlerQueue: microphoneSamplesQueue)
    
    stream.startCapture()
    logger.info("Started capturing...")
} catch {
    logger.error("Unable to start capturing: \(error.localizedDescription)")
}

三、主动验证并请求麦克风权限

即使Info.plist配置了权限,代码中仍需主动请求并确保用户授权:

import AVFoundation

func requestMicrophonePermission() async -> Bool {
    let session = AVAudioSession.sharedInstance()
    do {
        try session.setCategory(.playAndRecord, mode: .default)
        try session.setActive(true)
    } catch {
        print("Failed to set audio session: \(error)")
        return false
    }
    
    return await withCheckedContinuation { continuation in
        session.requestRecordPermission { granted in
            continuation.resume(returning: granted)
        }
    }
}

// 启动捕获前执行权限检查
let hasPermission = await requestMicrophonePermission()
guard hasPermission else {
    logger.error("Microphone permission not granted")
    return
}

四、完善recordingConfiguration配置

确保录制配置明确开启麦克风捕获,并设置音频编码参数:

let recordingConfiguration = SCStreamRecordingConfiguration(outputURL: URL(filePath: "some_file"))
recordingConfiguration.audioCodec = .aac
recordingConfiguration.videoCodec = .h264
recordingConfiguration.captureMicrophone = true // 与streamConfiguration保持一致,避免覆盖

五、检查CaptureEngineStreamOutput的样本处理逻辑

确保自定义输出类正确处理麦克风类型的样本,验证是否接收到数据:

class CaptureEngineStreamOutput: NSObject, SCStreamOutput {
    var capturedFrameHandler: ((CMSampleBuffer) -> Void)?
    var pcmBufferHandler: (AVAudioPCMBuffer) -> Void
    
    init(continuation: Any) {
        // 初始化逻辑
        self.pcmBufferHandler = { _ in }
        super.init()
    }
    
    func stream(_ stream: SCStream, didOutputSampleBuffer sampleBuffer: CMSampleBuffer, of type: SCStreamOutputType) {
        switch type {
        case .screen:
            capturedFrameHandler?(sampleBuffer)
        case .audio, .microphone:
            // 统一处理系统音频和麦克风音频,或区分处理
            print("Received audio sample of type: \(type.rawValue)")
            if let pcmBuffer = sampleBuffer.toAudioPCMBuffer() {
                pcmBufferHandler(pcmBuffer)
            }
        default:
            break
        }
    }
}

extension CMSampleBuffer {
    func toAudioPCMBuffer() -> AVAudioPCMBuffer? {
        guard let formatDesc = CMSampleBufferGetFormatDescription(self),
              let audioFormat = AVAudioFormat(cmAudioFormatDescription: formatDesc) else { return nil }
        let sampleCount = CMItemCount(CMSampleBufferGetNumSamples(self))
        guard let pcmBuffer = AVAudioPCMBuffer(pcmFormat: audioFormat, frameCapacity: sampleCount) else { return nil }
        
        pcmBuffer.frameLength = sampleCount
        CMSampleBufferCopyPCMDataIntoAudioBufferList(self, atOffset: 0, frameCount: Int(sampleCount), into: pcmBuffer.mutableAudioBufferList)
        return pcmBuffer
    }
}

如果控制台未打印麦克风类型的日志,说明流未输出麦克风数据,需回到配置层面重新检查;如果有日志但无有效数据,可能是设备硬件问题。

内容的提问来源于stack exchange,提问作者Vëx

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 17:39:59