iOS 音视频中的 CMTime
status
category
date
summary
slug
icon
tags
password
最近需要用到 AVFoundation,将照片合成为视频。实际上视频也可以看做多张照片合集在时间维度上的扩展,只要播放照片的速度(帧率)足够快,就可以欺骗人眼达到连续的效果。衡量这个效果的指标是帧率和刷新率。
帧率 FPS(Frames Per Second)表示每秒传输的帧数,可以理解为每秒播放了多少张照片。一般电影达到 24、25 帧就可以实现流畅播放,而各类游戏始终将 60 FPS 视为流畅的标准。刷新率表示显示设备输出画面的帧率上限,例如 60 Hz 的屏幕表示即使显卡一秒内传输的帧数超过 60,显示器每秒最多也只能输出 60 帧图像。iPhone 的 60 FPS 曾经是流畅的象征,不过现在高刷新率 Android 手机的使用体验可以明显区别于 iPhone(传言今年的 iPhone 12 会提供高刷新率的版本),许多电竞屏幕的刷新率也达到了 144 Hz。
顺便记录一件趣事:我在某手机品牌线下店体验 144 Hz 手机时,听到店员说:“怎么微信现在也有视频号这种乱七八糟的东西了?”
在具体实现中,通过 AVFoundation 中的 AVAssetWriter 将图片“逐帧”写入视频。为了输出视频,我们的输入除了每帧的图片信息,还要指定每帧图片所占的时间,这样既控制了帧率,也控制了视频的长度。主要使用的方法是:
CVPixelBufferRef
其中 CVPixelBufferRef 对象用于储存图片的缓冲信息:
CMTime
CMTime 用于指定图片所占的时间:
CMTime 通过 value(int64_t)和 timescale(int32_t)来描述时间,其中 timescale 表示把一秒平均分为多少份,value 表示占用的份数,有点类似于时间片的概念,具体时间长度为 value / timescale(秒)。例如,当我们需要描述 1.5 秒的时间长度,可以将 timescale 设置为 2,value 设置为 3。同理可得,将 timescale 设置为 4,value 设置为 6,得到的 CMTime 值和前面的是相等的。
个人猜测 CMTime 出现的原因,主要是为了精确化音视频中的时间计算,如果直接通过浮点数进行计算,随着视频时长增长,重复加法乘法操作引起的误差就会被放大。而 CMTime 的比较运算、加法运算相当于通过 timescale 进行了通分,然后进行分数运算,因此提高了精确度。
flags 用于标记特殊值,例如正无穷、负无穷等。epoch 直接翻译为“纪元”或者“世”,在一些深度学习领域中,表示遍历一次训练集中的所有样本。在这里表示同一个 CMTime 值重复循环的次数或序号,例如,在某个 timeline 中需要同一个 CMTime 重复 n 次,为了区分这些以 CMTime 为最小粒度的“时间片”,可以使用 epoch 从 0 到 n 序号进行标记。
CMTime 与帧率
这里将 value 设置为 6000,timescale 设置为 600,表示了 10 秒这个时间,但实际帧率与 CMTime 是无关的。苹果官方文档曾经推荐将 timescale 设置为 600,因为 600 是当时所有主流帧率(24、25、30、60)的最小公倍数。但后来文档中删去了这句话,个人猜测可能是其他帧率或者更高帧率(240)的视频出现导致的。
Loading...