美文网首页
CMTime & CMTimeRange

CMTime & CMTimeRange

作者: 沉江小鱼 | 来源:发表于2020-03-19 16:32 被阅读0次

这篇文章主要是为了学习记录CMTime,为了之后用到时可以翻阅。

1.CMTime介绍

Core Media定义的一种时间数据类型,很精确。

CMTime实际上就是一个C结构体。它是这样的 :

typedef struct
{
   CMTimeValue    value;        /
   CMTimeScale    timescale;// 
   CMTimeFlags    flags;
   CMTimeEpoch    epoch;
} CMTime;
  • value
    64位有符号整型变量,作为分子
  • timescale
    32位有符号整型变量,作为分母
  • flags
    flas的各种值允许我们指出时间戳是正无穷还是负无穷,或者它是由于某种中间计算而四舍五入的

注意:value/timescale = 对应时间 - 秒

value的解释:将value存储为整数值是为了避免我们在浮点示例中看到的类型错误。同样,通过将整个64位分配给分子(value是分子,timescale是分母),我们可以表示90亿亿个不同的正数,最多可以是19个十进制数字,对于每个可能的时间刻度值,没有歧义。

timescale值是多少? 它表示每秒钟划分的“片”的数量。这很重要,因为CMTime对象作为一个整体的精度受到这个量的限制。例如,如果timescale是1,那么对象不能表示小于1秒的时间戳,并且时间戳以1秒为增量。类似地,如果timescale为1000,则每秒钟被细分为1000个片段,value表示我们希望表示的毫秒数。

苹果建议视频的timescale为600,并解释说600是普通视频帧率(24、25和30帧)的倍数。如果需要对音频文件进行精确的采样索引,您可能需要将此值调高到60,000或更高。这64位的好处在于你仍然可以以1/ 60000秒的增量来表示580万年。

2. CMTime方法介绍

2.1 创建CMTime
  • CMTime CMTimeMake( int64_t value,int32_t timescale)
CMTime time1 = CMTimeMake(3, 1);
CMTime time2 = CMTimeMake(300, 100);
CMTime time3 = CMTimeMake(1800, 600);
  • CMTimeMakeWithSeconds(Float64 seconds, int32_t preferredTimescale)
CMTime time1 = CMTimeMakeWithSeconds(5, 1);
  • CMTimeMakeFromDictionary()
NSDictionary *timeData = @{(id)kCMTimeValueKey : @2,
                           (id)kCMTimeScaleKey : @1,
                           (id)kCMTimeFlagsKey : @1,
                           (id)kCMTimeEpochKey : @0};
CMTime t = CMTimeMakeFromDictionary((__bridge CFDictionaryRef)timeData); 
2.2 CMTime运算
  • 加减
CMTime ts1 = CMTimeMake(3, 1);
CMTime ts2 = CMTimeMake(5, 2);

CMTime result;
result = CMTimeAdd(ts1, ts2);
//{11/2 = 5.500}

result = CMTimeSubtract(ts1, ts2);
//{1/2 = 0.500}
  • 比较
CMTime t1 = CMTimeMake(300, 100); // 3 seconds
CMTime t2 = CMTimeMakeWithSeconds(5, 1); // 5 seconds

int32_t r  = CMTimeCompare(t1, t2);
NSLog(@"compare: %d",r);
//t1 < t2   => -1
//t1 == t2  => 0
//t1 > ts   => 1

或者

NSLog(@"t1 > t2 => %@",CMTIME_COMPARE_INLINE(t1, >, t2) ? @"YES":@"NO");
  • 验证CMTIME_IS_VALID()
NSLog(@"ti is valid :%@",CMTIME_IS_VALID(t1) ? @"YES":@"NO");
// ti is valid :YES
2.3 CMTime转换为秒 CMTimeGetSeconds()
CMTime t1 = CMTimeMake(3001, 100);
NSLog(@"second : %f",CMTimeGetSeconds(t1));
//second : 30.010000
2.4 转换为对象NSValue
+ (NSValue *)valueWithCMTime:(CMTime)time;

CMTime structTime = CMTimeMake(1, 3);

NSValue *valueTime = [NSValue valueWithCMTime:structTime];
NSLog(@"%@", valueTime);
//CMTime: {1/3 = 0.333}

structTime = [valueTime CMTimeValue];
//{1/3 = 0.333}
2.5 转换字典NSDictionary
CMTime structTime = CMTimeMake(1, 3);
NSDictionary *timeDict = CFBridgingRelease(CMTimeCopyAsDictionary(structTime, NULL));
NSLog(@"%@", timeDict);

structTime = CMTimeMakeFromDictionary((__bridge CFDictionaryRef)(timeDict));

/*
 {
    epoch = 0;
    flags = 1;
    timescale = 3;
    value = 1;
}
{1/3 = 0.333}

*/

3. CMTimeRange介绍

时间范围的数据类型:CMTimeRange,由两个CMTime值组成,第一个定义时间范围的起点,第二个定义时间范围的持续时间。

typedef struct
{
    CMTime          start;
    CMTime          duration;
} CMTimeRange;

4. CMTimeRange方法

4.1 创建
  • CMTimeRangeMake()
CMTimeRange CMTimeRangeMake( CMTime start, CMTime duration) 

//创建一个时间范围,从时间轴的5秒位置开始,持续时长5秒
CMTime duration = CMTimeMake(5, 1);
CMTimeRange range = CMTimeRangeMake(duration, duration);
CMTimeRangeShow(range);

//{{5/1 = 5.000}, {5/1 = 5.000}}
  • CMTimeRangeFromTimeToTime()
CMTimeRange CMTimeRangeFromTimeToTime( CMTime start, CMTime end ) 

CMTime beginTime = CMTimeMake(5, 1);
CMTime endTime = CMTimeMake(12, 1);
CMTimeRange rangeTime = CMTimeRangeFromTimeToTime(beginTime, endTime);
CMTimeRangeShow(rangeTime);
//{{5/1 = 5.000}, {7/1 = 7.000}}
4.2 运算
  • 定义变量:
CMTime duration = CMTimeMake(5, 1);
CMTimeRange range = CMTimeRangeMake(duration, duration);
CMTimeRangeShow(range);
//{{5/1 = 5.000}, {5/1 = 5.000}}

CMTime beginTime = CMTimeMake(7, 1);
CMTime endTime = CMTimeMake(12, 1);
CMTimeRange rangeTime = CMTimeRangeFromTimeToTime(beginTime, endTime);
//{{7/1 = 7.000}, {5/1 = 5.000}}
  • 取交叉时间范围
CMTimeRange intersetionRange = CMTimeRangeGetIntersection(range, rangeTime);
//{{7/1 = 7.000}, {3/1 = 3.000}}
  • 取时间范围总和
CMTimeRange unionRange = CMTimeRangeGetUnion(range, rangeTime);
    CMTimeRangeShow(unionRange);
//{{5/1 = 5.000}, {7/1 = 7.000}}
4.3 转换为对象NSValue
+ (NSValue *)valueWithCMTimeRange:(CMTimeRange)timeRange

CMTimeRange structTimeRange = CMTimeRangeMake(kCMTimeZero, kCMTimePositiveInfinity);

NSValue *valueTimeRange = [NSValue valueWithCMTimeRange:structTimeRange];
NSLog(@"%@", valueTimeRange);
//CMTimeRange: {{0/1 = 0.000}, {+INFINITY}}

structTimeRange = [valueTimeRange CMTimeRangeValue];
CMTimeRangeShow(structTimeRange);
//{{0/1 = 0.000}, {+INFINITY}}
4.4 转换成字典NSDictionary
NSDictionary *timeRangeDict = CFBridgingRelease(CMTimeRangeCopyAsDictionary(structTimeRange, NULL));
NSLog(@"%@", timeRangeDict);

structTimeRange = CMTimeRangeMakeFromDictionary((__bridge CFDictionaryRef)(timeRangeDict));
CMTimeRangeShow(structTimeRange);

/*
 {
    duration =     {
        epoch = 0;
        flags = 5;
        timescale = 0;
        value = 0;
    };
    start =     {
        epoch = 0;
        flags = 1;
        timescale = 1;
        value = 0;
    };
}
{{0/1 = 0.000}, {+INFINITY}}
*/

参考文章:
https://blog.csdn.net/fengzhixinfei/article/details/80729346
https://warrenmoore.net/understanding-cmtime

相关文章

  • CMTime & CMTimeRange

    这篇文章主要是为了学习记录CMTime,为了之后用到时可以翻阅。 1.CMTime介绍 Core Media定义的...

  • AVPlayer seek 位置不精确问题

    func seek(to time: CMTime, toleranceBefore: CMTime, toler...

  • CMTime

    CMTime 一个用来描述视频时间的结构体。他有两个构造函数:\ * CMTimeMake\* CMTimeMak...

  • CMTime

    要求时间高精度时一般使用CMTime,比如音频视频。其他一般情况下一般使用NSTimeInterval,NSTim...

  • CMTime

    最近看到一篇关于CMTime的文章,感觉讲得通俗易懂,正好最近也在看相关的资料就顺便记录下来,以便自己今后回忆复习...

  • CMTime

    CMTime 其实是帧时间,取值为(0,1),单位是秒是用当前帧数除以帧率算出来的,表示当前帧在视频时长的哪个点 ...

  • CMTime

    参考:https://www.jianshu.com/p/d6f9d7e493b6 一、CMTimeMakeWit...

  • AVFoundation视频处理的时间CMTime

    一、CMTime Core Media定义的一种时间数据类型 1、创建CMTime 1、CMTimeMake()C...

  • iOS CMTimeMake 和 CMTimeMakeWithS

    CMTime是专门用于标识电影时间的结构体,通常用如下两个函数来创建CMTime1、CMTimeMake valu...

  • iOS 了解CMTime

    认识cmtime cmtime有两个重要的值,一个是value,一个是timescale这里的timescale并...

网友评论

      本文标题:CMTime & CMTimeRange

      本文链接:https://www.haomeiwen.com/subject/cidlyhtx.html