Currently I am working on an App, where I want to play a video really fast, up to 20 times of the normal play rate. I just realized now, that AVPlayer
of AVFoundation
just supports a playback rate of 2.0 . With a higher rate the video doesn't play fluently anymore.
Do you have any suggestions about other video frameworks, which you could recommend in order to solve my problem?
Thank you very much in advance!
myAVPlayer.currentItem.audioTimePitchAlgorithm
has default value
AVAudioTimePitchAlgorithmLowQualityZeroLatency
available rates for this mode: {0.5, 0.666667, 0.8, 1.0, 1.25, 1.5, 2.0}
change audioTimePitchAlgorithm
to
myAVPlayer.currentItem.audioTimePitchAlgorithm = AVAudioTimePitchAlgorithmVarispeed
rates from 0,03125x to 32x
/*! @abstract Values for time pitch algorithm @constant
AVAudioTimePitchAlgorithmLowQualityZeroLatency
Low quality, very inexpensive. Suitable for brief fast-forward/rewind effects, low quality voice.
Rate snapped to {0.5, 0.666667, 0.8, 1.0, 1.25, 1.5, 2.0}.
@constant AVAudioTimePitchAlgorithmTimeDomain
Modest quality, less expensive. Suitable for voice.
Variable rate from 1/32 to 32.
@constant AVAudioTimePitchAlgorithmSpectral
Highest quality, most computationally expensive. Suitable for music.
Variable rate from 1/32 to 32.
@constant AVAudioTimePitchAlgorithmVarispeed
High quality, no pitch correction. Pitch varies with rate.
Variable rate from 1/32 to 32.
*/
In case someone is still stuck with this and wants AVPlayer
to play a video faster than 2.0:
You'll need to create an AVMutableComposition
and scale the time range to the desired one. After doing that, you can further multiply it using AVPlayer
's playback rate, up to 2x.
This SO answer explains how to do it.
Here's a Swift version:
let asset = AVPlayerItem(url: yourURL).asset
let newRate = 10.0
let composition = AVMutableComposition()
let assetTimeRange = CMTimeRangeMake(kCMTimeZero, asset.duration)
do {
try composition.insertTimeRange(assetTimeRange, of: asset, at: kCMTimeZero)
let destinationTimeRange = CMTimeMultiplyByFloat64(asset.duration, 1/newRate)
composition.scaleTimeRange(assetTimeRange, toDuration: destinationTimeRange)
let newPlayerItem = AVPlayerItem(asset: composition)
yourAVPlayer.replaceCurrentItem(with: newPlayerItem)
} catch {
// Handle the error
print("Inserting time range failed. ", error)
}