AVFoundation視頻處理的時(shí)間CMTime

一、CMTime

Core Media定義的一種時(shí)間數(shù)據(jù)類型

typedef struct
{
    CMTimeValue value;  //64位有符號整型變量,作為分子
    CMTimeScale timescale;   //32位有符號整型變量,作為分母
    // value/timescale = 對應(yīng)時(shí)間-秒
    CMTimeFlags flags; //位掩碼,表示時(shí)間的指定狀態(tài),比如判定詩句是否有效、不確定或是是否出現(xiàn)舍入等
    CMTimeEpoch epoch;      
} CMTime;

1、創(chuàng)建CMTime

  • 1、CMTimeMake()
    CMTime CMTimeMake( int64_t value,int32_t timescale)

創(chuàng)建一個(gè)代表3秒的CMTime表達(dá)式(value/timescale):

CMTime ts1 = CMTimeMake(3, 1);
CMTime ts2 = CMTimeMake(1800, 600);
CMTime ts3 = CMTimeMake(132300, 44100);

//打印時(shí)間結(jié)果
CMTimeShow(ts1);
CMTimeShow(ts2);
CMTimeShow(ts3);

//打印結(jié)果
{3/1 = 3.000}
{1800/600 = 3.000}
{132300/44100 = 3.000}

在處理視頻內(nèi)容時(shí)常見的時(shí)間刻度為600,這是大部分常用視頻幀率24FPS、25FPS、30FPS的公倍數(shù)。音頻常見的時(shí)間刻度就是采樣率,如44.1kHz(44100)、48kHz(48000)。

  • 2、CMTimeMakeWithSeconds()

CMTime CMTimeMakeWithSeconds( Float64 seconds, int32_t preferredTimescale)

CMTime t = CMTimeMakeWithSeconds(5, 1); // 5 seconds

CMTimeShow(t);
//{5/1 = 5.000}
  • 3、CMTimeMakeFromDictionary
NSDictionary *timeData = @{(id)kCMTimeValueKey : @2,
                           (id)kCMTimeScaleKey : @1,
                           (id)kCMTimeFlagsKey : @1,
                           (id)kCMTimeEpochKey : @0};
CMTime t = CMTimeMakeFromDictionary((__bridge CFDictionaryRef)timeData); 

CMTimeShow(t);
//{2/1 = 2.000}
   

2、CMTime運(yùn)算

  • 1、加減
CMTime ts1 = CMTimeMake(3, 1);
CMTime ts2 = CMTimeMake(5, 2);
    
CMTime result;
result = CMTimeAdd(ts1, ts2);
CMTimeShow(result);
//{11/2 = 5.500}
    
result = CMTimeSubtract(ts1, ts2);
CMTimeShow(result);
//{1/2 = 0.500}
  • 2、比較
CMTime t1 = CMTimeMake(300, 100); // 3 seconds
CMTime t2 = CMTimeMakeWithSeconds(5, 1); // 5 seconds

CMTimeCompare()

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

CMTIME_COMPARE_INLINE()

NSLog(@"t1 > t2 => %@",CMTIME_COMPARE_INLINE(t1, >, t2) ? @"YES":@"NO");
// t1 > t2 => NO
  • 3、驗(yàn)證CMTIME_IS_VALID()
NSLog(@"ti is valid :%@",CMTIME_IS_VALID(t1) ? @"YES":@"NO");
// ti is valid :YES

3、CMTime轉(zhuǎn)換為秒

Float64 CMTimeGetSeconds( CMTime time)

CMTime t1 = CMTimeMake(3001, 100);
NSLog(@"second : %f",CMTimeGetSeconds(t1));
//second : 30.010000

4、轉(zhuǎn)換為對象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];
CMTimeShow(structTime);
//{1/3 = 0.333}

5、轉(zhuǎn)換字典NSDictionary

 CMTime structTime = CMTimeMake(1, 3);
NSDictionary *timeDict = CFBridgingRelease(CMTimeCopyAsDictionary(structTime, NULL));
NSLog(@"%@", timeDict);

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

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

*/

二、CMTimeRange

時(shí)間范圍的數(shù)據(jù)類型:CMTimeRange,由兩個(gè)CMTime值組成,第一個(gè)定義時(shí)間范圍的起點(diǎn),第二個(gè)定義時(shí)間范圍的持續(xù)時(shí)間。

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

1、創(chuàng)建

  • 1、CMTimeRangeMake()

CMTimeRange CMTimeRangeMake( CMTime start, CMTime duration)
根據(jù)開始時(shí)間點(diǎn)與持續(xù)時(shí)間確定時(shí)間范圍。

//創(chuàng)建一個(gè)時(shí)間范圍,從時(shí)間軸的5秒位置開始,持續(xù)時(shí)長5秒
CMTime duration = CMTimeMake(5, 1);
CMTimeRange range = CMTimeRangeMake(duration, duration);
CMTimeRangeShow(range);

//{{5/1 = 5.000}, {5/1 = 5.000}}
  • 2、CMTimeRangeFromTimeToTime()

CMTimeRange CMTimeRangeFromTimeToTime( CMTime start, CMTime end )
根據(jù)起始時(shí)間點(diǎn)和終止時(shí)間點(diǎn),確定時(shí)間范圍。

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}}

2、運(yùn)算

定義變量:

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);
CMTimeRangeShow(rangeTime);
//{{7/1 = 7.000}, {5/1 = 5.000}}

取交叉時(shí)間范圍

CMTimeRange intersetionRange = CMTimeRangeGetIntersection(range, rangeTime);
CMTimeRangeShow(intersetionRange);
//{{7/1 = 7.000}, {3/1 = 3.000}}

取時(shí)間范圍總和

CMTimeRange unionRange = CMTimeRangeGetUnion(range, rangeTime);
    CMTimeRangeShow(unionRange);
//{{5/1 = 5.000}, {7/1 = 7.000}}

3、轉(zhuǎn)換為對象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、轉(zhuǎn)換成字典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}}
*/

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容