簡體   English   中英

在應用速率大於 2 倍時從 avplayer 播放生澀

[英]Jerky playback from avplayer on Applying Rate greater than 2x

我想調整 Avplayer rate ,我可以在

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

還禁用了音軌,當它小於 2.0 時運行良好。 但是當我們應用它大於 2X 時,它會導致視頻斷斷續續或生澀。

當我用谷歌搜索這個時 - 我發現這個鏈接暗示了相同的行為

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

當以指定速率播放的數據速率或其他處理要求超過 AVFoundation 的能力時,以大於 2.0 的速率播放可能會導致播放不穩定或斷斷續續。 在這些情況下,AVPlayer 會自動降低播放質量以跟上,根據當時的條件采用一系列后備策略。 一層降級是在視頻子流中僅解碼和顯示 I 幀,這確實看起來很不穩定。

如果是這樣的話,任何人都可以提供幫助,而不是我應該使用什么方法來實現相同的目標?

正如@Rhythmic所建議的,這些方法可以實現,但是這些都有點麻煩。 我在Google上進行了更多搜索,找到了一種方法,它工作得很好,沒有混響或斷斷續續。

只是不設置速率,就這樣設置速率。 首先創建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. 降低視頻的幀率
  2. 在您的視頻中添加更多I幀(考慮到QA-1772的建議 ,這可能有點不正確)
  3. 以較低的分辨率解碼(或更好?編碼)視頻
  4. 降低視頻的比特率
  5. 如果您認為某些性能在傳輸中丟失,請測量比實時AVAssetReader可以解碼的速度快多少,並用您自己的Metal + AVAssetReader路徑替換AVPlayer 如果您走這條路,也不要忘記考慮音頻。

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

這似乎是AVFoundation中的錯誤。 可以在那里,在大多數情況下,它不會在快的速率播放平滑了很多視頻。 例如,可以使用AVPlayerView的浮動控制器樣式來顯示一個快進按鈕。 重復單擊此按鈕可實現流暢,快速的播放,而僅設置AVPlayer.rate則不會。

在對這個問題的回答中,我解釋了此問題的解決方法。

如果要切換0~4的速率,可以初始化一個已經縮放duration為1/2的AVMutableComposition,然后在播放時將速率設置為0~2。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM