AVAsset视频调整持续时间

时间:2016-05-30 05:35:39

标签: ios swift avfoundation

鉴于已从资产中读取的CMSampleBuffers列表,我想调整资产的持续时间,使其长度为原始的一半(速度的两倍)。

目前我生成新时间戳的功能如下:

func adjustTimeStampsForBuffers(buffers: [CMSampleBuffer]) -> [CMTime] {
    let frameCount = buffers.count
    // self.duration is CMTimeGetSeconds(asset.duration)
    let increment = Float(self.duration / 2) / Float(frameCount)
    return Array(0.stride(to: frameCount, by: 1)).enumerate().map {
        let seconds: Float64 = Float64(increment) * Float64($0.index)
        return CMTimeMakeWithSeconds(seconds, self.asset.duration.timescale)
    }
}
然而,这似乎不起作用,输出的资产实际上是长度的两倍,而不是一半。任何人都可以指出我出错的地方吗?

编辑:

感谢@sschale,这是我的最终答案:

func adjustTimeStampsForBuffers(buffers: [CMSampleBuffer]) -> [CMTime] {
    return buffers.map {
        let time = CMSampleBufferGetPresentationTimeStamp($0)
        return CMTimeMake(time.value, time.timescale * 2)
    }
}

而不是计算新值,而是调整时间戳。

1 个答案:

答案 0 :(得分:1)

根据我对docs的阅读,看起来self.asset.duration.timescale可能是此处的关键,因为更改它会影响整个文件(如果我理解你的参考' 39;重新确定时间刻度是针对整个文件的,或者你需要在每个缓冲区中调整它。)

有关详细信息,请参阅here

相关部分:

  

CMTime表示为有理数,带有分子(a   int64_t value)和分母(int32_t时间刻度)。   从概念上讲,时间刻度指定了每秒的分数   分子中的单位占用。因此,如果时间刻度是4,则每个单位   代表四分之一秒;如果时间刻度是10,每个单位   代表十分之一秒,依此类推。除了简单   时间值,CMTime可以表示非数字值:+无穷大,    - 无限,无限期。使用标志CMTime表示时间是否在某个时间点被舍入。

     

CMTimes包含一个纪元号,通常设置为0,但也可以   用于区分不相关的时间表:例如,它可能是   每次通过表示循环递增,以区分   在循环0中的时间N与循环1中的时间N之间