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

iOS双AVCaptureSession录制音视频不同步问题求助

双AVCaptureSession音视频录制同步问题求助

背景说明

我采用两个独立的AVCaptureSession分别处理视频和音频录制,目标是实现动态启停音频会话而不中断视频会话——复刻Snapchat、Instagram的逻辑:打开相机时后台音乐可持续播放,仅在开始录制时因AVAudioSession.setCategory(..)调用出现轻微卡顿。但目前无法同步两个会话,将CMSampleBuffer写入AVAssetWriter时,音视频始终存在明显不同步问题。

问题表现

  • 音视频时序偏差:视频帧比第一个音频样本早近1秒开始播放,后期视频停止/冻结时音频仍在播放,延迟显著;
  • 视频包含无效帧:录制内容中混入了startRecording()调用前的视频帧。

核心代码示例

let videoCaptureSession = AVCaptureSession()
let audioCaptureSession = AVCaptureSession()

func setup() {
  // ...添加videoCaptureSession输出(AVCaptureVideoDataOutput)
  // ...添加audioCaptureSession输出(AVCaptureAudioDataOutput)
  videoCaptureSession.startRunning()
}

func startRecording() {
  self.assetWriter = AVAssetWriter(outputURL: tempURL, fileType: .mov)
  self.videoWriter = AVAssetWriterInput(...)
  assetWriter.add(videoWriter)
  self.audioWriter = AVAssetWriterInput(...)
  assetWriter.add(audioWriter)

  AVAudioSession.sharedInstance().setCategory(.playAndRecord, options: [.mixWithOthers, .defaultToSpeaker])
  audioCaptureSession.startRunning() // <-- 延迟启动
}

func captureOutput(_ captureOutput: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from _: AVCaptureConnection) {
  // 在自定义RecordingSession(AVAssetWriter)中录制视频帧/音频样本到文件
  if isRecording {
    switch captureOutput {
    case is AVCaptureVideoDataOutput:
      self.videoWriter.append(sampleBuffer)
    case is AVCaptureAudioDataOutput:
      // TODO: 是否需要更新PresentationTimestamp来同步另一个捕获会话?
      self.audioWriter.append(sampleBuffer)
    default:
      break
    }
  }
}

解决方案建议

1. 统一时间基准,修正帧时间戳

两个AVCaptureSession的时钟基准独立,需手动对齐时间戳:

  • 在startRecording()启动音频会话后,捕获第一个音频样本的presentationTimestamp作为同步基准audioStartTime;
  • 对后续视频帧,计算其原时间戳与startRecording()触发时刻的视频时间差,将该差值叠加到audioStartTime上,得到修正后的视频时间戳,再写入videoWriter。

2. 过滤录制前的无效视频帧

视频会话提前启动会缓存大量历史帧,需设置时间阈值过滤:

  • 在startRecording()中,记录当前最新视频帧的presentationTimestamp作为videoStartThreshold;
  • 在captureOutput的视频分支中,先判断当前帧的presentationTimestamp是否大于等于videoStartThreshold,仅符合条件的帧才执行append操作。

3. 优化音频会话启动逻辑

AVAudioSession配置和音频会话启动存在延迟,可调整时机减少偏差:

  • 提前在setup()阶段配置音频会话的category,但保持非激活状态;
  • 在startRecording()时仅激活音频会话,确保audioCaptureSession.startRunning()完成后再接收音频帧,避免丢失初始音频样本导致同步错位。

4. 用像素缓冲区适配器精准控制视频写入

直接写入CMSampleBuffer难以精准控制时间戳时,可改用AVAssetWriterInputPixelBufferAdaptor:

  • 将视频帧转换为CVPixelBuffer,手动设置修正后的时间戳;
  • 通过适配器将处理后的像素缓冲区写入AVAssetWriter,实现更精准的时序控制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 20:48:40