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

从CMFormatDescription计算视频帧率得到异常值的解决方法

核心问题说明

你直接读取CMFormatDescription.frameDuration得到的异常值是无效脏数据,不是真实的单帧时长。
你观察到的「timescale取值始终等于视频高度」的现象已经能直接佐证这一点:你读到的根本不是被正确赋值的CMTime结构,只是该内存偏移位置上存储的其他格式描述字段(比如视频维度的高度参数),和帧时长没有任何关系。
关键规则提醒:CMTime的value/timescale = seconds计算规则仅对标记为有效的CMTime实例生效,如果对应CMTime的flags字段为kCMTimeFlags_Invalid,说明这个时间值本身没有被初始化赋值,强行计算出来的结果没有任何参考意义。
CMFormatDescription的frameDuration字段只会在解析本地固定帧率封装媒体(比如本地存储的MP4、MOV视频文件的轨道格式描述)时被填充有效值,对于实时摄像头采集流的格式描述,苹果没有对这个字段做赋值,直接读取必然拿到无意义的内存垃圾值。

正确获取摄像头格式帧率的方案

不要从formatDescription读取帧时长,AVCaptureDevice.Format专门提供了官方的帧率查询属性videoSupportedFrameRateRanges,这是获取设备格式支持帧率的唯一可靠入口:

let currentActiveFormat = device.activeFormat
// 遍历当前格式支持的所有帧率区间
for frameRateRange in currentActiveFormat.videoSupportedFrameRateRanges {
    print("支持的最小帧率: \(frameRateRange.minFrameRate)")
    print("支持的最大帧率: \(frameRateRange.maxFrameRate)")
    // 如需对应单帧时长,可通过帧率反向计算,例如30fps对应单帧时长为1/30秒
    let minSingleFrameDuration = CMTime(
        value: 1,
        timescale: CMTimeScale(frameRateRange.maxFrameRate)
    )
}

如果你需要获取采集过程中的实时实际帧率,不要依赖静态格式描述计算,直接在AVCaptureVideoDataOutput的采集回调中,通过相邻CMSampleBuffer的输出展示时间戳差值做统计,结果是最准确的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 07:39:21