-->

Increase the maximum play rate of AVPlayer

2019-03-01 14:16发布

问题:

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!

回答1:

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.
*/



回答2:

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)
}