如何知道 AVPlayerItem 何时缓冲到歌曲结尾

How to know when AVPlayerItem is buffered to the end of a song

我正在尝试确定判断 AVPlayerItem 是否缓冲到流末尾的最佳方法。不仅缓冲区已满,而且缓冲区包含播放项目其余部分所需的一切,无需额外缓冲。 AVPlayerItem 提供了一个 isPlaybackBufferFull 调用,但这并没有告诉我在完成播放之前是否需要进行任何额外的缓冲。

我目前的计划是将其与 preferredForwardBufferDuration 结合使用,以检查项目是否需要缓冲更多,但这是最好的方法吗?

例如:

- (void)observeValueForKeyPath:(NSString*)aKeyPath ofObject:(id)aObject change:(NSDictionary*)aChange context:(void*)aContext
{
    if( [aKeyPath isEqualToString:@"playbackBufferFull"] )
    {
        CMTime theBufferTime = CMTimeMakeWithSeconds( self.currentItem.preferredForwardBufferDuration, 1 );
        CMTime theEndBufferTime = CMTimeAdd( self.currentItem.currentTime, theBufferTime );
        if( CMTimeCompare( theEndBufferTime, self.currentItem.duration ) >= 0 )
        {
            // Buffered to the end
        }
    }
}

我找到了一个很好的解决这个问题的方法,如下所示。问题中提出的解决方案并没有真正发挥作用,因为 preferredForwardBufferDuration 默认设置为 0,这几乎使解决方案不可行。

以下代码运行良好。我在计时器上每秒调用一次。

auto theLoadedRanges = self.currentItem.loadedTimeRanges;

CMTime theTotalBufferedDuration = kCMTimeZero;
for( NSValue* theRangeValue in theLoadedRanges )
{
    auto theRange = [theRangeValue CMTimeRangeValue];
    theTotalBufferedDuration = CMTimeAdd( theTotalBufferedDuration, theRange.duration );
}

auto theDuration = CMTimeGetSeconds( self.currentItem.duration );
if( theDuration > 0 )
{
    float thePercent = CMTimeGetSeconds( theTotalBufferedDuration ) / theDuration;
    if( thePercent >= 0.99f )
    {
        // Fully buffered
    }
}