【干货】CoreTime框架中的时间类型
CMTime CMTimeRange CMTimeMapping
在使用 AVFoundation 框架处理多媒体资源时,通常会用到一些在 CoreMedia 框架中定义的结构体, 这里对其中描述时间的类型 CMTime 、CMTimeRange 、CMTimeMapping 进行简单的小结。
CMTime
(资料图)
概述
CMTime 是一个结构体,其用来表示一个有理数,描述一个时刻或时段。在结构体中有4个成员,如下:
typedef struct{ CMTimeValue value; CMTimeScale timescale; CMTimeFlags flags; CMTimeEpoch epoch;} CMTime;
该结构体类型的变量表示的时刻或时段的值为 value/timescale ,单位是秒。
timescale 这个分母值的含义是将 1 秒钟分成了多少个单元value 这个分子值的含义是所表示的时刻或时段共计占用了多少个单元
那么 1/timescale 表示一个单元占用了多长时间,这个时间小于 1 秒,而 value * (1/timescale) 即表示整个结构体变量所表示的时间长度。
flags 该标识可以表示当前变量表示的时刻或时段是否有效、是否是准确值等,可取的值如下:
kCMTimeFlags_Valid = 1UL<<0该值必需设置,否则当前变量会被认为是无效的kCMTimeFlags_HasBeenRounded = 1UL<<1表示当前变量是约数并不是原始的精确值,或者是由其他非精确的值生成的kCMTimeFlags_PositiveInfinity = 1UL<<2表示当前变量为正无穷kCMTimeFlags_NegativeInfinity = 1UL<<3表示当前变量为负无穷kCMTimeFlags_Indefinite = 1UL<<4表示当前变量未定义kCMTimeFlags_ImpliedValueFlagsMask = kCMTimeFlags_PositiveInfinity | kCMTimeFlags_NegativeInfinity | kCMTimeFlags_Indefinite表示正负无穷或未定义
epoch 可以用来区分两个表示相同时间的变量,如循环递增的时间,这个值可以区分不同循环内的相同的时间的变量。
常量
在 CoreMedia 框架中,提供了一些常量,用来表示特殊的 CMTime 值。
kCMTimeInvalid 用来初始化无效的 CMTime 值,该变量的每个成员的值都是 0kCMTimeZero 用来表示时间为 0 ,该变量的成员值为 value=0,timescale=1,flags=kCMTimeFlags_Valid,epoch=0kCMTimePositiveInfinity 表示时间为正无穷,flags=5(即 kCMTimeFlags_Valid|kCMTimeFlags_PositiveInfinity),其他成员的值都是 0kCMTimeNegativeInfinity 表示时间为负无穷,flags=9(即 kCMTimeFlags_Valid|kCMTimeFlags_NegativeInfinity),其他成员的值都是 0kCMTimeIndefinite 表示时间未定义,flags=17(即 kCMTimeFlags_Valid|kCMTimeFlags_Indefinite),其他成员的值都是 0
要判断已知的变量是否等于上述的变量时,不可以使用 “==” 进行判断,而是要使用框架中提供的宏,在这些宏定义中,都是对变量的成员 flags 值进行了判断。
CMTIME_IS_VALID(time)判断已知的 CMTime 变量是否是有效的CMTIME_IS_INVALID(time)判断已知的 CMTime 变量是否是无效的CMTIME_IS_POSITIVE_INFINITY(time)判断已知的 CMTime 变量是否表示时间正无穷CMTIME_IS_NEGATIVE_INFINITY(time)判断已知的 CMTime 变量是否表示时间负无穷CMTIME_IS_INDEFINITE(time)判断已知的 CMTime 变量是否是未定义的CMTIME_IS_NUMERIC(time)判断已知的 CMTime 变量是否是明确的时间,而不是正负无穷或未定义CMTIME_HAS_BEEN_ROUNDED(time)判断已知的 CMTime 变量是否是约数
函数
CMTime CMTimeMake(int64_t value,int32_t timescale);
CMTime CMTimeMakeWithEpoch(int64_t value,int32_t timescale,int64_t epoch);
上面两个是生成 CMTime 变量的常见函数,通过指定相应的成员变量的值来生成相应的变量。
CMTime CMTimeMakeWithSeconds(Float64 seconds,int32_t preferredTimescale)
除了指定相应的成员变量来生成 CMTime 变量外,还可以通过指定时间和时间粒度来生成变量。返回的变量,其成员 epoch 被设置为 0 ,而 value 的值则是 seconds 与 preferredTimescale 的乘积,所以 value 的值可能会溢出。
当发生溢出时,会将 preferredTimescale 的值自动减半,直到 value 的值不再溢出,或者 preferredTimescale 减到 1 ,如果减到 1 后,value 仍然溢出,则这个变量表示无穷大。
由于提供的时间是浮点型,而计算得到的成员变量 value 是整型值,所以计算时,value 的值可能含有小数,如果有小数部分,便需要舍入。如此,使用成员变量再次计算得到的时间值与原来提供的时间值不相等,所以对于这种情况,返回值的成员变量 flags 中,kCMTimeFlags_HasBeenRounded 标识会被设置。
Float64 CMTimeGetSeconds(CMTime time);使用该方法将 CMTime 类型的变量转化为时间值,如果变量本身表示的值无效或是正负无穷值,则返回 NaN 或 +Inf 、-Inf 。
CMTime CMTimeConvertScale(CMTime time,int32_t newTimescale,CMTimeRoundingMethod method);
该方法可以修改已知的 CMTime 类型变量的 timescale 成员变量的值,计算 value 的值时可能需要舍入小数部分,所以调用函数时要指定舍入方法。
CMTimeRoundingMethod 有以下可取值:
kCMTimeRoundingMethod_RoundHalfAwayFromZero = 1, 表示四舍五入kCMTimeRoundingMethod_RoundTowardZero = 2, 始终舍弃小数部分kCMTimeRoundingMethod_RoundAwayFromZero = 3, 始终进1kCMTimeRoundingMethod_QuickTime = 4, 当时间粒度值变大,则应进1,反之,时间粒度值变小,舍弃小数部分,而当表示的时间是负的时,舍弃小数后,value 若为 0 ,应将其置为 -1kCMTimeRoundingMethod_Default = kCMTimeRoundingMethod_RoundHalfAwayFromZero
//转换后 time2 的 value 为 1CMTime time1 = CMTimeMake(1, 4);CMTime tiem2 = CMTimeConvertScale(time, 2, kCMTimeRoundingMethod_RoundHalfAwayFromZero);//转换后 time2 的 value 为 0 CMTime time1 = CMTimeMake(1, 5); CMTime tiem2 = CMTimeConvertScale(time, 2, kCMTimeRoundingMethod_RoundHalfAwayFromZero); //转换后 time2 的 value 为 0 CMTime time1 = CMTimeMake(1, 5); CMTime tiem2 = CMTimeConvertScale(time, 2, kCMTimeRoundingMethod_QuickTime); //转换后 time2 的 value 为 -1 CMTime time1 = CMTimeMake(-1, 5); CMTime tiem2 = CMTimeConvertScale(time, 2, kCMTimeRoundingMethod_QuickTime);
CMTime CMTimeAdd( CMTime addend1,CMTime addend2);
CMTime CMTimeSubtract(CMTime minuend,CMTime subtrahend);
两个 CMTime 类型的变量之和或之差,得到的结果的 timescale 的值是两个变量的 timescale 的最小公倍数。如果这个公倍数大于 kCMTimeMaxTimescale 这个值,那么 timescale 就使用 kCMTimeMaxTimescale 这个值。在转换这个 timescale 的过程中,计算 value 的值时采用默认的舍入方法,如果 value 的值溢出,便减半 timescale 再进行计算,判断其是否溢出,若溢出,再次减半,直到其值为 1 ,如果仍然溢出,则返回的结果为无穷大。
CMTime CMTimeMultiply(CMTime time,int32_t multiplier);
CMTime CMTimeMultiplyByFloat64(CMTime time,Float64 multiplier);
扩大已知的 time 的倍数,value 的值扩大 multiplier 倍,如果溢出,持续减半 timescale 的值,直到不再溢出或为 1 ,如果为 1 时仍然溢出,返回的值表示无穷大。
CMTime CMTimeMultiplyByRatio(CMTime time,int32_t multiplier,int32_t divisor)
用已知的 time 的 value 值乘以 multiplier 再除以 divisor 得到新的 value 值,如果 value 的值发生溢出,那么 timescale 便会发生转变。
int32_t CMTimeCompare(CMTime time1,CMTime time2)
两个时间比较,遵循的规则:负无穷 < 具体时间 < 未定义 < 正无穷 < 无效时间
具体的两个时间比较大小时,其成员 epoch 也参与比较,epoch 较大的时间较大。
time1 > time2 ,返回值为 1time1 < time2 ,返回值为 -1time1 = time2 ,返回值为 0
框架中提供了一个宏 CMTIME_COMPARE_INLINE(time1, comparator, time2) ,通过提供比较运算符(>、>=、=、<、=<)comparator 来获取 time1 与 time2 的大小关系。
CMTime CMTimeMinimum(CMTime time1,CMTime time2)返回 time1 与 time2 中较小的值
CMTime CMTimeMaximum(CMTime time1,CMTime time2)返回 time1 与 time2 中较大的值
CMTime CMTimeAbsoluteValue(CMTime time)
返回 time 的绝对值
CFDictionaryRef CM_NULLABLE CMTimeCopyAsDictionary(CMTime time,CFAllocatorRef CM_NULLABLE allocator)
CMTime CMTimeMakeFromDictionary(CFDictionaryRef CM_NULLABLE dict)
上面两个方法,可以将 CMTime 类型的变量转化为 CFDictionaryRef 类型的变量,或者从已经转化的变量中生成一个 CMTime 类型的变量。在 CFDictionary 中,它应包含键值:kCMTimeValueKey 、kCMTimeScaleKey 、kCMTimeEpochKey 、kCMTimeFlagsKey 分别对应 CMTime 的各个成员变量。
CFStringRef CM_NULLABLE CMTimeCopyDescription(CFAllocatorRef CM_NULLABLE allocator,CMTime time)
void CMTimeShow(CMTime time)
上面的两个方法,可以获取 CMTime 类型变量的字符串描述,或者直接将字符串描述打印出来。
CMTimeRange
概述
CMTimeRange 是用来表示一个时间范围的结构体变量,它的两个成员变量都是 CMTime 类型的变量,分别表示时间范围的开始时刻和时间范围的持续时长,所以开始时刻与持续时长的和得到的时刻并不属于该类型表示的时间范围。
typedef struct{ CMTime start; CMTime duration;} CMTimeRange;
可以使用 kCMTimeRangeZero 、kCMTimeRangeInvalid 分别表示时间范围为 0 和无效的的 CMTimeRange 类型变量。
对于有效的 CMTimeRange 类型变量,它的两个 CMTime 成员变量都必须是有效的,并且 duration.epoch 必须是 0 ,duration.value 的值必须是非负的。可以直接使用框架中提供的宏定义,进行判断。
CMTIMERANGE_IS_VALID(range) 当 start 、duration 是有效的,且 duration.epoch == 0 且 duration.value >= 0 时,返回 trueCMTIMERANGE_IS_INVALID(range) 返回的真假值与上面的宏返回的值相反CMTIMERANGE_IS_INDEFINITE(range) 当 range 为有效值,且 range.start 和 range.duration 中至少有一个为未定义时,这个宏返回 trueCMTIMERANGE_IS_EMPTY(range) 当 range 为有效值,且 range.duration 为 kCMTimeZero 时,这个宏返回 true
函数
CMTimeRange CMTimeRangeMake(CMTime start,CMTime duration)创建一个表示时间范围的变量
CMTimeRange CMTimeRangeGetUnion(CMTimeRange range1,CMTimeRange range2)
返回两个时间范围的最小并集
CMTimeRange CMTimeRangeGetIntersection(CMTimeRange range1,CMTimeRange range2)
返回两个时间范围的最大交集
Boolean CMTimeRangeEqual(CMTimeRange range1,CMTimeRange range2)
返回两个时间范围是否相等
Boolean CMTimeRangeContainsTime(CMTimeRange range,CMTime time)
返回指定的时间范围内是否包含指定的时间
Boolean CMTimeRangeContainsTimeRange(CMTimeRange range1,CMTimeRange range2)
返回指定的时间范围 range1 是否包含 指定的时间范围 range2
CMTime CMTimeRangeGetEnd(CMTimeRange range)
返回指定时间范围的结束时间,这个时间是不包含在时间范围内的,即
CMTimeRangeContainsTime(range, CMTimeRangeGetEnd(range))的返回值总是 false 。
CMTime CMTimeMapTimeFromRangeToRange(CMTime t,CMTimeRange fromRange,CMTimeRange toRange )
将指定的时间 t 根据时间范围 fromRange 和 toRange 进行转换,如果 t 是 fromRange 的开始或者结束时间,那么转换后,其就是 toRange 的开始或结束时间。如果 t 是其他时间,那么按照公式 result = (t-fromRange.start)*(toRange.duration/fromRange.duration)+toRange.start进行计算。
CMTime CMTimeClampToRange(CMTime time,CMTimeRange range)
返回的是指定的时间范围内 range 中距离指定时间 time 最近的时间。如果 time 的时间小于 range 的开始时间,那么返回的就是 range 的开始时间,如果 time 在 range 范围内,那么返回其本身,如果 time 是 range 的结束时间或结束时间之后,那么返回的都是 range 的结束时间(即使该结束时间不属于 range 表示的时间范围之内)。
CMTime CMTimeMapDurationFromRangeToRange(CMTime dur,CMTimeRange fromRange,CMTimeRange toRange )
将指定的时间范围的持续时长根据时间范围 fromRange 和 toRange 进行转换,实际是对持续时长进行了缩小或放大,其计算公式为 result = dur*(toRange.duration/fromRange.duration)
CMTimeRange CMTimeRangeFromTimeToTime(CMTime start,CMTime end)根据指定的开始时间和结束时间构建一个表示时间范围的变量。
CFDictionaryRef CM_NULLABLE CMTimeRangeCopyAsDictionary(CMTimeRange range,CFAllocatorRef CM_NULLABLE allocator)
CMTimeRange CMTimeRangeMakeFromDictionary(CFDictionaryRef CM_NONNULL dict)
上面的方法实现了 CMTimeRange 类型变量与 CFDictionaryRef 变量的相互转换,CFDictionary 中的键 kCMTimeRangeStartKey 、kCMTimeRangeDurationKey 分别对应着 CMTimeRange 中的成员。
CFStringRef CM_NULLABLE CMTimeRangeCopyDescription(CFAllocatorRef CM_NULLABLE allocator,CMTimeRange range)
void CMTimeRangeShow(CMTimeRange range)
上面的两个方法,可以获取 CMTimeRange 类型变量的字符串描述,或者直接将字符串描述打印出来。
CMTimeMapping
概述
CMTimeMapping 是一个描述媒体资源时间线映射关系的结构体变量,其包含两个 CMTimeRange 类型的成员变量。
typedef struct { CMTimeRange source; CMTimeRange target;} CMTimeMapping;
source 表示的是源资源的时间线范围,包括开始的时刻和持续的时长,如果开始时间为 kCMTimeInvalid ,表示没有资源的编辑信息,即该变量为空。target 表示的是资源目标的时间线,包含开始时间和持续时长,如果 source 和 target 的 duration 不同,那么资源在播放时,速度为 source.duration/target.duration 以保证资源播放完整。
在框架中,使用 kCMTimeMappingInvalid 来表示无效的 CMTimeMapping 类型变量,可以使用 CMTIMEMAPPING_IS_VALID(mapping)、CMTIMEMAPPING_IS_INVALID(mapping)来判断变量 mapping 是否有效(mapping.target 有效即可),或者使用 CMTIMEMAPPING_IS_EMPTY(mapping)来判断 mapping 是否为空(mapping 有效且 mapping.source.start 为 kCMTimeInvalid)
函数
CMTimeMapping CMTimeMappingMake(CMTimeRange source,CMTimeRange target)
创建一个映射关系变量,提供的 source 和 target 的 epoch 的值必需为 0 ,否则将返回一个无效值。
CMTimeMapping CMTimeMappingMakeEmpty(CMTimeRange target)
创建一个空的变量,提供的 target 的 epoch 必需时 0 ,否则将返回一个无效值。
CFDictionaryRef CM_NULLABLE CMTimeMappingCopyAsDictionary(CMTimeMapping mapping,CFAllocatorRef CM_NULLABLE allocator)
CMTimeMapping CMTimeMappingMakeFromDictionary(CFDictionaryRef CM_NONNULL dict)
上面的方法实现了 CMTimeMapping 类型变量与 CFDictionaryRef 变量的相互转换,CFDictionary 中的键 kCMTimeMappingSourceKey 、kCMTimeMappingTargetKey 分别对应着 CMTimeMapping 中的成员。
CFStringRef CM_NULLABLE CMTimeMappingCopyDescription(CFAllocatorRef CM_NULLABLE allocator,CMTimeMapping mapping)
void CMTimeMappingShow(CMTimeMapping mapping)
上面的两个方法,可以获取 CMTimeMapping 类型变量的字符串描述,或者直接将字符串描述打印出来。
标签:
相关推荐:
最新新闻:
- 毕业生想做猎头前景如何?猎头前景分析_全球快讯
- 数藏行业首现“傍名牌” 百度搜“十八数藏”首页第一条是ibox广告
- Linux下chmod 777 修改权限怎么设置?设置方法
- oki打印机设置参数 OKI帮你找到最适合办公打印机
- 做火车随机一坐是自己位置的概率为多少?必须掌握的疯子找座问题
- 电脑ip地址怎么查看?查看ip地址最简单方法
- 手机投屏到电视上怎么操作?手机投屏到电视的方法
- 怎样清除手机病毒的教程?手机中病毒的解决办法
- 剪贴板在哪里找?Windows 10系统剪切板位置
- 在哪看电脑配置是什么?查看电脑配置的实用方法
- 微软msvcrtd.dll文件修复教程(附下载)_焦点要闻
- u盘文件夹exe病毒解决方法有哪些?清除exe病毒文件的技巧
- 两台电脑如何共享文件?文件共享的方法步骤图解
- 【全球快播报】谁说上网本已经死了?华硕正式推出基于MeeGo的超薄本
- “3.6亿”事件引发国人持续热议 事情的背后究竟有何隐情?_每日视点
- 【干货】CoreTime框架中的时间类型
- 关于QQ的相关代码收集整理 WEB版在线聊天技巧-天天热点
- tf卡写保护无法格式化怎么办?u盘被写保护最简单解除方法
- 版主联盟是什么?版主联盟推广法 天天热消息
- 全球今头条!2019年笔记本电脑性价比排行榜 前10名都有哪些?
- 安卓手机如何刷机?安卓手机刷机教程
- 世界看热讯:yy电影频道是多少?如何使用yy看在线电影?
- 网页自动刷新怎么设置?网页实现自动刷新步骤
- 车载导航品牌哪个好?汽车导航品牌推荐
- 索泰显卡怎么样?索泰RTX 4090 AMP EXTREME AIRO显卡评测
- 华为MateBook14怎么样?华为MateBook14值不值得买?|每日速递
- 无法连接到iTunes Store怎么办?无法连接到iTunes Store的解决方法
- 如何快速输入特殊符号?特殊符号怎么打出来?
- 热消息:客户呼叫中心系统结构及应用服务器
- 电脑温度多少度正常?看看你的电脑温度多少?
- 计算机指纹识别的原理是什么?指纹识别原理和过程_天天快播
- 显卡检测工具有哪些?显卡用什么软件去检测?
- 不干胶打印机哪种好?不干胶打印机推荐
- 当前快报:如何使用手机可视电话?可视电话使用方法
- win7网络连接不可用是怎么回事?电脑连接不可用解决方法
- 手机地图哪个好?老虎地图详情介绍
- visio序列号有哪些?visio序列号大全
- 内存条价格上涨的原因是什么?内存条价格上涨的原因介绍
- 为什么百度云网盘登录不了?网页版、pc版 都登陆不进去的解决方法
- 手机电子签名怎么弄?电子签名制作步骤
- 网页制作入门级软件推荐——FrontPage-焦点快看
- epson630k打印机怎么换色带?针式打印机色带安装方法
- 非负数正则怎么表示?非负数正则表达式
- 今日看点:MIUI是什么?MIUI的主要特色
- 天天短讯!RFC4144中的Abstract 你了解多少?
- 天天新动态:html代码怎么在空间应用?HTML制帖空间的代码
- 环球新消息丨热管换热器工作原理是什么?热管换热器工作原理及特点介绍
- 擦掉照片上的衣服app 去掉照片上衣服操作步骤
- 花样直播是什么?花样直播的详细介绍|今日看点
- Word如何绘制斜线表头?方法步骤如下
- 视讯!单变量积分的知识可参考 二重积分的意义
- 计算机指纹识别的原理是什么?指纹识别原理和过程_天天快播
- 环球讯息:扇形计算公式是怎么得来的?扇形计算公式介绍
- 宝塔面板教程 基于云服务器搭建学生机最全详解
- 全球观焦点:CSDN社区简介: 全球最大的IT技术社区 日访问用户数达100万
- 网络小黑揭秘系列之黑产江湖黑吃黑—厨房切菜之利器
- 金山打字通五笔怎么使用?金山打字通五笔介绍及讲解
- 安卓手机如何刷机?安卓手机刷机教程
- 网页自动刷新怎么设置?网页实现自动刷新步骤
- 索泰显卡怎么样?索泰RTX 4090 AMP EXTREME AIRO显卡评测
- 如何快速输入特殊符号?特殊符号怎么打出来?
- 电脑温度多少度正常?看看你的电脑温度多少?
- 显卡检测工具有哪些?显卡用什么软件去检测?
- win7网络连接不可用是怎么回事?电脑连接不可用解决方法
- 内存条价格上涨的原因是什么?内存条价格上涨的原因介绍
- 手机电子签名怎么弄?电子签名制作步骤
- 专家狠批算法推荐 看短视频频率影响未成年人价值取向
- Steam年度游戏数据回顾 今年玩了多少款游戏?
- epson630k打印机怎么换色带?针式打印机色带安装方法
- 擦掉照片上的衣服app 去掉照片上衣服操作步骤
- 讯息:《巫师:血源》翻车 成烂番茄观众评分最差网飞剧集
- 《蜡笔小新 我与博士的暑假》Steam国区售价永降 全区最低
- MAGES.发表2022财年财报 共损失6.13亿日元
- Falcom公开《伊苏10》新概念图 游戏将于2023年发售
- 《星战绝地:幸存者》新加坡分级完成 适合16岁观众游玩