给定从 Assets 读取的 CMSampleBuffers
列表,我想调整 Assets 的持续时间,使其长度为原始 Assets 的一半(速度的两倍)。
目前我用于生成新时间戳的函数如下所示:
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)
}
}
不是计算新值,而是调整时间戳。
最佳答案
基于我对 docs 的阅读,看起来 self.asset.duration.timescale
可能是这里的关键,因为更改它会影响整个文件(如果我理解您正在制作的引用,该时间刻度是为了整个文件,或者您可能需要在每个缓冲区中调整它)。
参见 here还可以了解更多信息。
相关部分:
A CMTime is represented as a rational number, with a numerator (an int64_t value), and a denominator (an int32_t timescale). Conceptually, the timescale specifies the fraction of a second each unit in the numerator occupies. Thus if the timescale is 4, each unit represents a quarter of a second; if the timescale is 10, each unit represents a tenth of a second, and so on. In addition to a simple time value, a CMTime can represent non-numeric values: +infinity, -infinity, and indefinite. Using a flag CMTime indicates whether the time been rounded at some point.
CMTimes contain an epoch number, which is usually set to 0, but can be used to distinguish unrelated timelines: for example, it could be incremented each time through a presentation loop, to differentiate between time N in loop 0 from time N in loop 1
关于ios - AVAsset 视频调整时长,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37518249/