iosobjective-cvideoavplayerplayback

Jerky playback from avplayer on Applying Rate greater than 2x


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 ?


Solution

  • 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 .