应用率大于2倍的avplayer播放

时间:2016-11-09 11:35:39

标签: ios objective-c video avplayer playback

我想调整Avplayer费率,我可以帮助

  $(document).ready(function(){
    $('.collapsible').collapsible();
  });

同样禁用音轨,当它小于2.0时运行良好。 但是当我们应用它大于2X时,会导致Choppy或jerky视频。

当我搜索这个时 - 我发现这个链接暗示了同样的行为

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

  

以高于2.0的速率播放可能会导致数据速率或其他处理要求时出现抖动或不连贯的播放   以指定速率播放超出了AVFoundation的能力   赶上。在这些情况下,AVPlayer会自动降低质量   回放以便跟上,采用一层后备   策略取决于当前的条件。一层退化   是解码和显示视频子流中的I帧,和   这确实看起来很不稳定。

任何人都可以帮忙,如果是这样的话,我会用什么方法来达到目的?

4 个答案:

答案 0 :(得分:7)

由于@Rhythmic建议可以实施这些方法,但这些都很麻烦。我用谷歌搜索了更多,找到了一种方法,它的工作非常精细,没有混蛋或波涛汹涌。

只是不设置费率,设置这样的费率。首先创建AVPlayer,AVPlayerItem和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];

此代码甚至可以轻松支持超过2倍或4倍的速度。

答案 1 :(得分:1)

你可以尝试一些事情:

  1. 降低视频的帧率
  2. 为您的视频添加更多I帧(考虑到QA-1772's advice,这可能会略显不正常)
  3. 以较低分辨率解码(或更好地?编码)视频
  4. 降低视频的比特率
  5. 衡量实时AVAssetReader可以解码的速度和&如果您认为某些表现在传输过程中丢失,请使用您自己的AVPlayer + Metal路径替换AVAssetReader。如果走这条路,也不要忘记考虑音频。

答案 2 :(得分:0)

这似乎是AVFoundation中的一个错误。对于许多视频来说,可以以快速的速度播放,在大多数情况下,它并没有。例如,可以使用AVPlayerView的浮动控制器样式来显示快进按钮。重复单击此按钮可以实现流畅,快速的播放,只需设置AVPlayer.rate即可。

在我对this question的回答中,我解释了此问题的解决方法。

答案 3 :(得分:0)

感谢Kshitij Godara。

已转换为 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()