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

AVCaptureMultiCamSession无法添加多个摄像头输入问题求助

解决AVFoundation同时捕获前后置摄像头失败的问题

问题根源

AVCaptureMultiCamSession要求添加的多个摄像头输入必须使用兼容的媒体格式(包括分辨率、帧率、颜色空间等参数)。默认情况下,系统为前后置摄像头分配的默认格式往往不匹配,导致canAddInput:返回NO,无法添加第二个摄像头输入。此外,未明确设置支持多摄像头的会话预设也会引发该问题。

解决步骤

1. 设置支持多摄像头的会话预设

在创建AVCaptureMultiCamSession后,优先设置兼容的会话预设,且必须在添加输入前完成设置:

AVCaptureSession *startSession()
{
    AVCaptureMultiCamSession *session = [AVCaptureMultiCamSession new];
    
    // 检查设备是否支持多摄像头捕获
    if (![AVCaptureMultiCamSession isMultiCamSupported]) {
        NSLog(@"Multi-camera capture is not supported on this device");
        return nil;
    }
    
    // 设置支持多摄像头的会话预设(以720p为例)
    if ([session canSetSessionPreset:AVCaptureSessionPreset1280x720]) {
        session.sessionPreset = AVCaptureSessionPreset1280x720;
    } else {
        NSLog(@"1280x720 preset not supported");
        return nil;
    }
    
    if (!addDevice(session, true) || !addDevice(session, false)) {
        return nil;
    }

    // 添加输出逻辑
    
    [session startRunning];
    return session;
}

2. 为前后置摄像头选择兼容格式

添加辅助方法筛选出前后置摄像头都支持的格式,强制设备使用该格式:

// 获取设备支持的指定分辨率格式(帧率≥30fps)
AVCaptureDeviceFormat *getCompatibleFormatForDevice(AVCaptureDevice *device, CGSize targetResolution) {
    for (AVCaptureDeviceFormat *format in device.formats) {
        CMVideoDimensions dimensions = CMVideoFormatDescriptionGetDimensions(format.formatDescription);
        CGSize size = CGSizeMake(dimensions.width, dimensions.height);
        
        if (CGSizeEqualToSize(size, targetResolution)) {
            for (AVFrameRateRange *range in format.videoSupportedFrameRateRanges) {
                if (range.maxFrameRate >= 30.0) {
                    return format;
                }
            }
        }
    }
    return nil;
}

修改addDevice方法,在创建输入前设置设备的兼容格式:

bool addDevice(AVCaptureSession *session, bool front)
{
    AVCaptureDevicePosition position = front ? AVCaptureDevicePositionFront : AVCaptureDevicePositionBack;
    AVCaptureDevice *device;
    AVCaptureDeviceInput *input;
    NSError *error;

    device = [AVCaptureDevice defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltinWideAngleCamera mediaType:AVMediaTypeVideo position:position];
    if (!device) {
        NSLog(@"Cannot create %s device", front ? "front" : "back");
        return false;
    }

    // 获取兼容格式(与会话预设匹配的1280x720)
    AVCaptureDeviceFormat *targetFormat = getCompatibleFormatForDevice(device, CGSizeMake(1280, 720));
    if (!targetFormat) {
        NSLog(@"No compatible format for %s device", front ? "front" : "back");
        return false;
    }

    // 锁定设备并设置格式
    if ([device lockForConfiguration:&error]) {
        device.activeFormat = targetFormat;
        // 固定帧率为30fps
        device.activeVideoMinFrameDuration = CMTimeMake(1, 30);
        device.activeVideoMaxFrameDuration = CMTimeMake(1, 30);
        [device unlockForConfiguration];
    } else {
        NSLog(@"Failed to configure %s device: %@", front ? "front" : "back", error.localizedDescription);
        return false;
    }

    input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
    if (!input) {
        NSLog(@"Cannot create input for %s device: %@", front ? "front" : "back", error.localizedDescription);
        return false;
    }

    if (![session canAddInput:input]) {
        NSLog(@"Cannot add input for %s device", front ? "front" : "back");
        return false;
    }
    [session addInput:input];
    
    return true;
}

注意事项

  • 先通过[AVCaptureMultiCamSession isMultiCamSupported]确认当前设备支持多摄像头捕获;
  • 高分辨率预设(如4K)可能无法支持前后置摄像头同时工作,建议从720p/1080p开始测试;
  • 确保已获取摄像头访问权限(AVAuthorizationStatusAuthorized),权限不足会导致添加输入失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 03:23:13