startupthekid startupthekid - 1 year ago 124
iOS Question

AVAsset video adjust duration

Given a list of

that have been read in from an asset, I want to adjust the duration of the asset so that it's half length (twice the speed) of the original.

Currently my function for generating new time stamps looks like:

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)

however this doesn't seem to work and the outputted assets are in fact twice the length, not half. Can anybody point out where I'm going wrong?


Thanks to @sschale, here's my final answer:

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

Instead of calculating new values, the timestamp is adjusted instead.

Answer Source

Based on my reading of the docs, it looks like that self.asset.duration.timescale may be the key here, as changing it will influence the whole file (if I'm understanding the reference you're making that that timescale is for the whole file, or maybe you need to adjust it in each of the buffers).

See here for more info as well.

Relevant section:

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