Swift中如何检查AVCaptureSession预设分辨率是否支持并降级?
在Swift中检查AVCaptureSession预设分辨率是否被设备支持
要实现「优先使用hd1280x720,不支持则选更低分辨率」的需求,核心是利用AVCaptureDevice的supportedPresets属性动态判断设备能力,下面是具体的实现步骤和代码示例:
首先要明确:不同摄像头(前后置)支持的预设可能不同,所以一定要针对你实际要使用的捕获设备做检查,比如常用的后置广角摄像头。
完整实现代码(iOS 13+)
import AVFoundation func selectAppropriateVideoPreset() -> AVCaptureSession.Preset { // 1. 获取目标捕获设备(这里以后置广角摄像头为例) guard let videoDevice = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back) else { // 设备不支持后置摄像头时, fallback 到最低预设 return .vga640x480 } // 2. 定义目标预设,同时获取设备支持的所有预设列表 let targetPreset = AVCaptureSession.Preset.hd1280x720 let supportedPresets = videoDevice.supportedPresets // 3. 先检查目标预设是否直接可用 if supportedPresets.contains(targetPreset) { return targetPreset } // 4. 若目标预设不可用,筛选出比它分辨率更低的最高可用预设 // 先把支持的预设按分辨率从高到低排序 let sortedPresets = supportedPresets.sorted { preset1, preset2 in guard let res1 = preset1.resolution, let res2 = preset2.resolution else { return false } // 通过总像素数判断分辨率高低 return (res1.width * res1.height) > (res2.width * res2.height) } // 获取目标预设的分辨率信息 guard let targetResolution = targetPreset.resolution else { // 无法获取目标分辨率时,直接选最高可用预设 return sortedPresets.first ?? .vga640x480 } let targetTotalPixels = targetResolution.width * targetResolution.height // 找到第一个比目标分辨率低的预设 if let fallbackPreset = sortedPresets.first { preset in guard let res = preset.resolution else { return false } return (res.width * res.height) < targetTotalPixels } { return fallbackPreset } // 极端情况:所有预设都比目标高(几乎不会出现),选最低预设兜底 return .vga640x480 } // 使用示例 let captureSession = AVCaptureSession() captureSession.beginConfiguration() captureSession.sessionPreset = selectAppropriateVideoPreset() // 这里添加你的输入、输出配置(比如添加摄像头输入、视频输出等) captureSession.commitConfiguration() // 按需启动会话 // captureSession.startRunning()
兼容iOS 13以下的处理
如果你的App需要支持iOS 13之前的版本,由于AVCaptureSession.Preset.resolution是iOS 13才引入的API,需要手动建立预设与分辨率的映射:
extension AVCaptureSession.Preset { var resolution: CGSize? { switch self { case .hd4K3840x2160: return CGSize(width: 3840, height: 2160) case .hd1920x1080: return CGSize(width: 1920, height: 1080) case .hd1280x720: return CGSize(width: 1280, height: 720) case .vga640x480: return CGSize(width: 640, height: 480) case .medium: return CGSize(width: 480, height: 360) case .low: return CGSize(width: 320, height: 240) // 可根据需求添加其他预设的映射 default: return nil } } }
关键注意点
- 设备差异:不同型号的iPhone/iPad支持的预设差异很大(比如旧款SE可能不支持1080P),绝对不能硬编码预设,必须动态检查。
- 摄像头区分:前置摄像头支持的预设通常比后置少,若要使用前置摄像头,记得修改
position: .front获取对应设备。 - 会话配置规则:设置
sessionPreset必须在beginConfiguration()和commitConfiguration()之间进行,否则会触发报错。 - 系统限制:少数场景下,即使硬件支持某个预设,系统可能因权限或场景限制(如后台录制)禁止使用,
supportedPresets会自动过滤这些不可用选项,直接检查该数组即可。
内容的提问来源于stack exchange,提问作者Chewie The Chorkie
相关产品推荐
相关产品推荐

