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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:56:20