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

KMM集成MLKit扫码时iOS相机周期性卡顿问题

解决KMM iOS端MLKit条码扫描周期性卡顿问题

问题分析

在KMM的iOS模块中集成MLKit条码扫描时,创建VisionImage后出现周期性卡顿(15帧流畅→卡顿10秒→循环),核心原因是MLKit对CMSampleBuffer的处理逻辑与AVCaptureSession的内存/线程调度冲突,手动释放SampleBuffer会引发过度释放崩溃,复制SampleBuffer无法解决本质问题。

有效解决方案

1. 确保处理队列是独立串行队列

AVCaptureVideoDataOutput的处理队列必须是独立的串行队列,避免和主线程或其他队列竞争资源。如果你的processingQueue未正确初始化,直接创建串行队列:

@OptIn(ExperimentalForeignApi::class)
private val processingQueue = dispatch_queue_create("com.your.app.camera.processing", DISPATCH_QUEUE_SERIAL)

在setupCaptureSession中使用这个队列:

videoOutput = AVCaptureVideoDataOutput().apply {
    setSampleBufferDelegate(this@CameraViewController, processingQueue)
    // 其他配置...
}

2. 改用CVPixelBuffer创建VisionImage

直接传递CMSampleBuffer给MLKit可能导致内存持有延迟,改为提取CVPixelBuffer来创建VisionImage,减少不必要的资源绑定:

override fun captureOutput(
    output: AVCaptureOutput,
    didOutputSampleBuffer: CMSampleBufferRef?,
    fromConnection: AVCaptureConnection
) {
    didOutputSampleBuffer ?: return
    
    frameCounter += 1
    logging("CViewC").i { "FRAME #$frameCounter" }

    // 提取CVPixelBuffer
    val pixelBuffer = CMSampleBufferGetImageBuffer(didOutputSampleBuffer) ?: return
    
    // 用CVPixelBuffer创建VisionImage
    val visionImage = MLKVisionImage(pixelBuffer)
    // 设置相机方向(根据你的设备方向调整)
    visionImage.imageOrientation = UIImageOrientationUp.toMLKImageOrientation()
    
    // 执行条码扫描
    val scanner = MLKBarcodeScanner.barcodeScanner()
    scanner.processImage(visionImage) { barcodes, error ->
        error ?: barcodes?.firstOrNull()?.rawValue?.let {
            // 回到主线程回调结果
            dispatch_async(dispatch_get_main_queue()) {
                onQRCodeDetected(it)
            }
        }
    }
}

添加UIImageOrientation到MLKImageOrientation的扩展:

fun UIImageOrientation.toMLKImageOrientation(): MLKImageOrientation {
    return when (this) {
        UIImageOrientationUp -> MLKImageOrientationUp
        UIImageOrientationDown -> MLKImageOrientationDown
        UIImageOrientationLeft -> MLKImageOrientationLeft
        UIImageOrientationRight -> MLKImageOrientationRight
        UIImageOrientationUpMirrored -> MLKImageOrientationUpMirrored
        UIImageOrientationDownMirrored -> MLKImageOrientationDownMirrored
        UIImageOrientationLeftMirrored -> MLKImageOrientationLeftMirrored
        UIImageOrientationRightMirrored -> MLKImageOrientationRightMirrored
    }
}

3. 禁止手动释放原CMSampleBuffer

AVCaptureSession会自动管理didOutputSampleBuffer的生命周期,绝对不要调用CFRelease(didOutputSampleBuffer),否则会引发CFTypeRef过度释放崩溃。

4. 优化AVCaptureSession配置

  • 确认alwaysDiscardsLateVideoFrames = true,避免积压未处理的帧导致内存暴涨
  • 可尝试降低分辨率(比如AVCaptureSessionPreset640x480),减少MLKit的处理压力
  • 确保视频格式kCVPixelFormatType_32BGRA是MLKit优化支持的格式

验证步骤

  1. 运行应用后观察帧计数日志,确认是否持续流畅输出
  2. 检查Xcode的Memory Graph Debugger,查看内存是否稳定无暴涨
  3. 测试扫码功能是否正常,无卡顿或崩溃

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 05:34:55