鉴于已从资产中读取的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)
}
}
而不是计算新值,而是调整时间戳。
答案 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之间