AVFoundation 的时间处理

媒体时间处理的背景

AVPlayer 与AVPlayerItem都是基于时间的对象,但是在我们使用他们的功能之前,需要了解AVFoundation框架呈现时间的方式。
人们习惯于用日子、小时、分钟、秒来表示时间,而在开发人员中则把时间精确到毫秒、纳秒。所以用一个双精度浮点型数值来表示时间也算是合情合理。在 iOS 开发中,通常使用 NSTimeInterval 来表示一个时间,其实就是简单的对double进行了typedef定义。不过使用浮点型数据表示时间存在一些问题,因为浮点型数据在进行运算会导致结果不精确的情况。当进行时间的累加时这些不精确的情况就会非常严重,经常导致时间的明显偏移,是的媒体的多个数据流几乎无法实现同步。此外以浮点型数据呈现时间无法做到自我描述,这就导致在使用不同时间轴进行比较和运算时比较困难。AVFoundation 使用一种可靠性更高的方式来展示时间信息,这就是基于CMTime 的数据结构。

CMTime 的结构
AVFoundation 是基于 core Media 的高层封装,core Media 是基于 c的底层框架,提供了处理 MAC和iOS媒体栈的关键功能,这些功能大多都是在后台运行的不可见功能,不过我们经常能够接触到的部分就是他的数据结构CMTime。CMTime 为时间的正确表示给出了结构,即分数值的方式。

 

public struct CMTime {

    
    public var value: CMTimeValue /*! @field value The value of the CMTime. value/timescale = seconds. */

    /** @field value The value of the CMTime. value/timescale = seconds. */
    public var timescale: CMTimeScale /*! @field timescale The timescale of the CMTime. value/timescale = seconds.  */

    /** @field timescale The timescale of the CMTime. value/timescale = seconds.  */
    public var flags: CMTimeFlags /*! @field flags The flags, eg. kCMTimeFlags_Valid, kCMTimeFlags_PositiveInfinity, etc. */

    /** @field flags The flags, eg. kCMTimeFlags_Valid, kCMTimeFlags_PositiveInfinity, etc. */
    public var epoch: CMTimeEpoch /*! @field epoch Differentiates between equal timestamps that are actually different because
                                                 of looping, multi-item sequencing, etc.  
                                                 Will be used during comparison: greater epochs happen after lesser ones. 
                                                 Additions/subtraction is only possible within a single epoch,
                                                 however, since epoch length may be unknown/variable. */

    public init()

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

的最关键的两个变量value和 timescale。value 是一个 64位整数类型值,timescale 是一个32位整数类型值,在时间的呈现样式中分别充当分子和分母的作用。

 

public typealias CMTimeValue = Int64
public typealias CMTimeScale = Int32

建立以分数值来表示时间的方式刚开始会有些不太适应,当开发中不断使用之后,就慢慢开始顺手,开始习惯了。

CMTime 使用
下面使用swift来对CMTime 的基本操作进行个演示
创建

 

// 第一个参数为秒数4,第二个参数为时间刻度字段,最终可得出 time.value = 8,time.timescale = 2,
let time1  = CMTimeMakeWithSeconds(4, preferredTimescale: 2)
let seconds = CMTimeGetSeconds(time1)//4
print("seconds:\(seconds),time.value:\(time1.value), time.timescale\(time1.timescale)") // seconds:4,time.value:8,time.timescale:2

let time2 = CMTimeMake(value: 6, timescale: 3)
let seconds2 = CMTimeGetSeconds(time2)//2
print("seconds:\(seconds2),time.value:\(time2.value), time.timescale\(time2.timescale)") // seconds:2,time.value:6,time.timescale:3

比较
let time1  = CMTimeMakeWithSeconds(4, preferredTimescale: 2)
let time2 = CMTimeMake(value: 6, timescale: 3)

print(time1 > time2)//true
print(time1 <= time2)//false
print(time1 == time2)//false
print(time1 != time2)//true

运算
let time1  = CMTimeMakeWithSeconds(4, preferredTimescale: 2)
let time2 = CMTimeMake(value: 6, timescale: 3)

// 相加
let time3 = time1 + time2// time3 = 8/2 + 6/3 = 24/6 + 12/6 = 36/6
print("value:\(time3.value), timescale:\(time3.timescale)")// value:36, timescale:6

// 相减
let time4 = time1 - time2// time3 = 8/2 - 6/3 = 24/6 - 12/6 = 12/6
print("value:\(time4.value),timescale:\(time4.timescale)")

除了上面这些使用方法以外,CMTime 还提供了大量实用的函数存在于 CMTime.h文件中,本人也还在学习中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值