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

iOS摄像头采集会话代码在iOS正常但Catalyst环境崩溃

iOS视频会话代码在Catalyst环境崩溃的解决方案

问题描述

以下用于配置AVCaptureSession视频输入输出的代码在iOS平台运行完全正常:

let videoOutput = AVCaptureVideoDataOutput()

guard let cameraDevice = device.device,
      let captureDeviceInput = try? AVCaptureDeviceInput(device: cameraDevice),
      self.canAddInput(captureDeviceInput),
      self.canAddOutput(videoOutput) else {
    log("FrameExtractor error: could not setup input or output.")
    return
}

self.addInput(captureDeviceInput)
videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: "sample buffer"))
self.addOutput(videoOutput)

guard let connection = videoOutput.connection(with: CAMERA_FEED_MEDIA_TYPE),
      connection.isVideoOrientationSupported,
      connection.isVideoMirroringSupported else {
    log("FrameExtractor: configureSession: Cannot establish connection")
    return
}

if let videoOrientation = getCameraOrientation(device: device) {
    connection.videoOrientation = videoOrientation
}

// Mirroring the front camera normalizes the display output for iPad's front camera
connection.isVideoMirrored = position == .front

但在Catalyst环境中运行时,执行self.addOutput(videoOutput)会持续崩溃,报错信息翻译如下:

应用因未捕获的异常NSInternalInconsistencyException终止,原因:无效参数,不满足条件:index>=0 && index<[_currentItems count]

问题原因与修复方案

  • 核心原因:Catalyst环境下AVCaptureSession的配置逻辑与纯iOS存在差异,默认配置兼容性不足,且会话状态管理、输入输出添加顺序的要求更严格。
  • 修复步骤:
    1. 提前设置视频输出格式:Catalyst对视频像素格式的兼容性要求更高,添加输出前显式指定兼容格式:
      let videoSettings: [String: Any] = [
          kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32BGRA
      ]
      videoOutput.videoSettings = videoSettings
      
    2. 开启丢弃迟滞帧:避免Catalyst环境下帧队列溢出引发异常:
      videoOutput.alwaysDiscardsLateVideoFrames = true
      
    3. 调整输入输出添加顺序:先添加输出,再添加输入(部分Catalyst版本存在顺序依赖问题):
      self.addOutput(videoOutput)
      self.addInput(captureDeviceInput)
      
    4. 确保会话处于停止状态:添加输入输出前先停止会话,避免状态冲突:
      self.stopRunning()
      

修复后完整代码示例

let videoOutput = AVCaptureVideoDataOutput()

// 配置视频输出参数
let videoSettings: [String: Any] = [
    kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32BGRA
]
videoOutput.videoSettings = videoSettings
videoOutput.alwaysDiscardsLateVideoFrames = true

guard let cameraDevice = device.device,
      let captureDeviceInput = try? AVCaptureDeviceInput(device: cameraDevice),
      self.canAddInput(captureDeviceInput),
      self.canAddOutput(videoOutput) else {
    log("FrameExtractor error: could not setup input or output.")
    return
}

// 确保会话处于停止状态
self.stopRunning()

// 先添加输出,再添加输入
self.addOutput(videoOutput)
self.addInput(captureDeviceInput)

videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: "sample buffer"))

guard let connection = videoOutput.connection(with: CAMERA_FEED_MEDIA_TYPE),
      connection.isVideoOrientationSupported,
      connection.isVideoMirroringSupported else {
    log("FrameExtractor: configureSession: Cannot establish connection")
    return
}

if let videoOrientation = getCameraOrientation(device: device) {
    connection.videoOrientation = videoOrientation
}

connection.isVideoMirrored = position == .front

// 按需重新启动会话
self.startRunning()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 07:45:37