Jerky playback from avplayer on Applying Rate greater than 2x

非 Y 不嫁゛ 提交于 2019-12-01 01:41:09

As @Rhythmic suggested these ways can be implemented but these all are kind of hassle . I googled it more and found a way and it is working very fine no jerk or choppy .

Just do not set rate , set Rate like this . First create instance of AVPlayer , AVPlayerItem and AVAsset .

  AVMutableComposition *composition = [AVMutableComposition composition];
        NSError *error = nil;
        [composition insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration)
                             ofAsset:asset
                              atTime:kCMTimeZero error:&error];
        [composition scaleTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration)
                         toDuration:CMTimeMultiplyByFloat64(asset.duration, 1 / rate)];
        AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:composition];
        self.avRefPlayer = [AVPlayer playerWithPlayerItem:playerItem];

        self.avRefPlayerLayer = [AVPlayerLayer layer];

        [self.avRefPlayerLayer setPlayer:self.avRefPlayer];
        [self.avRefPlayerLayer setFrame:_refrencedView.bounds];
        [self.avRefPlayerLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];

this code can even support more than 2x or 4x speed easily .

You could try a few things:

  1. lower the framerate of your video
  2. add more I-frames to your video (this may be slightly perverse, considering QA-1772's advice)
  3. decode (or better? encode) the video at a lower resolution
  4. lower the bitrate of the video
  5. measure how much faster than realtime AVAssetReader can decode at & replace AVPlayer with your own Metal + AVAssetReader path if you think that some performance has gotten lost in transit. Don't forget to consider audio, too, if you take this path.

Thanks to Kshitij Godara.

Converted to Swift 4.

let timeRange = CMTimeRangeMake(kCMTimeZero, CMTime(seconds: videoDuration, preferredTimescale: 1))
let composition = AVMutableComposition()
try composition.insertTimeRange(timeRange,
                               of: asset,
                               at: kCMTimeZero)
composition.scaleTimeRange(timeRange, toDuration: CMTimeMultiplyByFloat64(asset.duration, Float64(1.0 / rate)))
let playerItem = AVPlayerItem(asset: composition)
let player = AVPlayer(playerItem: playerItem)
player.play()
Jamborino

This seems to be a bug in AVFoundation. It can play smoothly at fast rates for many videos where, under most circumstances, it doesn't. For example, one can use AVPlayerView's floating controller style to expose a fast-forward button. Clicking this button repeatedly results in smooth, fast playback where simply setting AVPlayer.rate does not.

In my answer to this question I explain a workaround for this problem.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!