AVAsset 视频调整时长
AVAsset video adjust duration
鉴于已从资产中读入的 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([=10=].index)
return CMTimeMakeWithSeconds(seconds, self.asset.duration.timescale)
}
}
但这似乎不起作用,输出的资产实际上是长度的两倍,而不是一半。谁能指出我哪里出错了?
编辑:
感谢@sschale,这是我的最终答案:
func adjustTimeStampsForBuffers(buffers: [CMSampleBuffer]) -> [CMTime] {
return buffers.map {
let time = CMSampleBufferGetPresentationTimeStamp([=11=])
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
鉴于已从资产中读入的 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([=10=].index)
return CMTimeMakeWithSeconds(seconds, self.asset.duration.timescale)
}
}
但这似乎不起作用,输出的资产实际上是长度的两倍,而不是一半。谁能指出我哪里出错了?
编辑:
感谢@sschale,这是我的最终答案:
func adjustTimeStampsForBuffers(buffers: [CMSampleBuffer]) -> [CMTime] {
return buffers.map {
let time = CMSampleBufferGetPresentationTimeStamp([=11=])
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