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

Mac OS开发:ScreenCaptureKit框架无法同步录制音频求助

ScreenCaptureKit同步录制音频解决方案
  • 确认权限配置
    必须在Info.plist中添加NSMicrophoneUsageDescription键,填写麦克风使用的说明文本,否则系统会直接拒绝麦克风访问请求。同时要确保应用已获得系统级的屏幕录制和麦克风权限(可通过系统偏好设置>安全性与隐私>隐私面板检查并授权)。

  • 开启SCStream的音频捕获
    创建SCStreamConfiguration实例时,显式开启音频捕获并配置相关参数:

    let streamConfig = SCStreamConfiguration()
    streamConfig.capturesAudio = true
    streamConfig.audioSampleRate = 44100.0
    streamConfig.audioChannelCount = 2
    
  • 同时处理视频与音频样本
    在SCStreamOutput的回调方法中,需要区分视频和音频样本,分别写入到AVAssetWriter对应的输入中:

    func stream(_ stream: SCStream, didOutputSampleBuffer sampleBuffer: CMSampleBuffer, of type: SCStreamOutputType) {
        guard let assetWriter = self.assetWriter else { return }
        
        assetWriterQueue.async {
            if assetWriter.status == .unknown {
                assetWriter.startWriting()
                assetWriter.startSession(atSourceTime: sampleBuffer.presentationTimeStamp)
            }
            
            switch type {
            case .video:
                if self.assetWriterVideoInput.isReadyForMoreMediaData {
                    self.assetWriterVideoInput.append(sampleBuffer)
                }
            case .audio:
                // 首次收到音频样本时初始化音频输入
                if self.assetWriterAudioInput == nil {
                    guard let formatDesc = CMSampleBufferGetFormatDescription(sampleBuffer) else { return }
                    let audioInput = AVAssetWriterInput(mediaType: .audio, outputSettings: nil, sourceFormatHint: formatDesc)
                    audioInput.expectsMediaDataInRealTime = true
                    if assetWriter.canAdd(audioInput) {
                        assetWriter.add(audioInput)
                        self.assetWriterAudioInput = audioInput
                    }
                }
                if let audioInput = self.assetWriterAudioInput, audioInput.isReadyForMoreMediaData {
                    audioInput.append(sampleBuffer)
                }
            default:
                break
            }
        }
    }
    
  • 使用专用串行队列处理写入操作
    创建一个串行队列来处理AVAssetWriter的所有操作,避免多线程冲突:

    private let assetWriterQueue = DispatchQueue(label: "com.your.app.asset.writer.queue")
    
  • 检查录制结束时的状态
    停止录制时,需确保音频和视频输入都完成写入,再结束AVAssetWriter会话:

    assetWriterQueue.async {
        self.assetWriterVideoInput.markAsFinished()
        self.assetWriterAudioInput?.markAsFinished()
        self.assetWriter.finishWriting {
            // 处理录制完成后的逻辑
        }
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 10:55:16