Jerky playback from avplayer on Applying Rate greater than 2x

流过昼夜 提交于 2019-11-30 21:08:06

问题


I want to tweak Avplayer rate , I able to do with help of

[_avplayer play];
[_avplayer setRate:1.5];

Also disabled audio tracks , it is running good when it is less than 2.0. But when we apply it greater than 2X it results in Choppy or jerky video.

When i googled about this - I found this one link suggesting same behaviour

https://developer.apple.com/library/content/qa/qa1772/_index.html

Playing at rates greater than 2.0 can result in jerky or choppy playback when the data rate or other processing requirements of playing at the specified rate exceeds the ability of AVFoundation to keep up. In those cases, AVPlayer automatically degrades the quality of playback in order to keep up, employing a tier of fallback strategies depending on prevailing conditions. One tier of degradation is to decode and display only I-frames within the video substream, and this can indeed appear to be choppy.

Can any one help like if it so , than what approach shall i use to achieve same ?


回答1:


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 .




回答2:


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.



回答3:


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



回答4:


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.



来源:https://stackoverflow.com/questions/40506059/jerky-playback-from-avplayer-on-applying-rate-greater-than-2x

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