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
相关产品推荐
相关产品推荐

