天天看點

AVFoundation架構解析看這裡(4)- CMTime

前言

AVFoundation

架構是ios中很重要的架構,所有與視訊音頻相關的軟硬體控制都在這個架構裡面,接下來這幾篇就主要對這個架構進行介紹和講解。

便于讀者查閱這個AVFoundation架構系列,在此提供目錄直通車。

AVFoundation架構解析目錄

AVFoundation架構解析目錄

AVFoundation架構解析目錄

本章導讀

CMTime是貫徹整個iOS音視訊開發的基本資料結構,是以我們有必要在單獨拿出來,詳細介紹。本章主要介紹CMTime和CMTimeRange,為後面的視訊操作奠定基礎。

CMTime

通常我們認為時間的呈現格式應該是浮點資料,我們一般使用NSTimeInterval,實際上它是簡單的雙精度double類型,隻是typedef了一下,但是由于浮點型資料計算很容易導緻精度的丢失,在一些要求高精度的應用場景顯然不适合,于是蘋果在Core Media架構中定義了CMTime資料類型作為時間的格式,結構如下:

public struct CMTime {
    public var value: CMTimeValue
    public var timescale: CMTimeScale 
    public var flags: CMTimeFlags 
    public var epoch: CMTimeEpoch

    public init()
    public init(value: CMTimeValue, timescale: CMTimeScale, flags: CMTimeFlags, epoch: CMTimeEpoch)
}           

複制

  • CMTimeValue

    64位有符号整型變量

public typealias CMTimeValue = Int64           

複制

  • CMTimeScale

    32位有符号整型變量

public typealias CMTimeScale = Int32           

複制

  • CMTimeEpoch

    64位有符号整型變量

public typealias CMTimeEpoch = Int64           

複制

  • CMTimeFlags

    CMTimeFlags是一個位掩碼用以表示時間的指定狀态,比如判斷資料是否有效、不确定或是否出現舍入值等。

顯然,CMTime定義是一個C語言的結構體,專門用來表示影片時間的類别。CMTime是以分數的形式表示時間,value表示分子,timescale表示分母。

CMTime建立

  • public func CMTimeMake(value: Int64, timescale: Int32) -> CMTime

    value表示目前第幾幀,timescale表示每秒鐘多少幀,播放時間為value/timescale,例如建立一個代表5s的CMTime表達式有下面幾種不同的方式:

let time1 = CMTimeMake(value: 5, timescale: 1)
let time2 = CMTimeMake(value: 3000, timescale: 600)
let time3 = CMTimeMake(value: 5000, timescale: 1000)           

複制

在處理視訊内容時常見的時間刻度為600,這是大部分常用視訊幀率24FPS、25FPS、30FPS的公倍數。音頻資料常見的時間刻度就是采樣率,比如44 100(44.1kHZ)或48 000(kHZ)。

  • public func CMTimeMakeWithSeconds(_ seconds: Float64, preferredTimescale: Int32) -> CMTime

    seconds表示當時的時間,機關為s,preferredTimescale表示時間精度。

    其中,preferredTimeScale為時間尺度。

let seconds: Float64 = 3
        let preferredTimeScale: Int32 = 600
        let time = CMTimeMakeWithSeconds(seconds, preferredTimescale: preferredTimeScale)           

複制

表示每秒幀率為600,目前時間為3s。

CMTime計算

  • 相加 CMTimeAdd
  • 相減 CMTimeSubtract
  • 想乘 CMTimeMultiply
  • 比較大小 CMTimeCompare

CMTimeRange

Core Media架構裡時間範圍的資料類型。

public struct CMTimeRange {
    public var start: CMTime
    public var duration: CMTime

    public init()
    public init(start: CMTime, duration: CMTime)
}           

複制

start表示時間的起點的CMTime值,duratin表示時間範圍的持續時長的CMTime值。一般使用CMTimeRangeMake和CMTimeRangeFromTimeToTime建立如下:

let time1 = CMTimeRangeMake(start: startTime, duration: durationTime)
let time2 = CMTimeRangeFromTimeToTime(start: startTime, end: endTime)           

複制

CMTimeRange的計算:

let start1 = CMTime.zero
        let end1 = CMTimeMake(value: 5, timescale: 1)
        
        let start2 = CMTimeMake(value: 2, timescale: 1)
        let end2 = CMTimeMake(value: 5, timescale: 1)
        
        let range1 = CMTimeRangeFromTimeToTime(start: start1, end: end1)
        let range2 = CMTimeRangeFromTimeToTime(start: start2, end: end2)
        
        //時間範圍是否包含某個時間點
        let isContainTime = range1.containsTime(start2)          //true
        //時間範圍是否包含另一個時間範圍
        let isContainRange = range1.containsTimeRange(range2)    //false
        //兩個時間範圍取交集
        let intersectionRange = CMTimeRangeGetIntersection(range1, otherRange: range2)
        //兩個時間範圍取合集
        let unionRange = CMTimeRangeGetUnion(range1, otherRange: range2)           

複制