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

Ios 如何知道何时将AVPlayerItem缓冲到歌曲结尾,ios,objective-c,avplayer,avplayeritem,Ios,Objective C,Avplayer,Avplayeritem,我正在尝试确定判断AVPlayerItem是否缓冲到流末尾的最佳方法。不仅缓冲区已满,而且缓冲区包含播放项目其余部分所需的所有内容,无需额外缓冲。AVPlayerItem提供了一个is isplaybackufferfull调用,但这并没有告诉我在该项完成播放之前是否需要进行任何额外的缓冲 我目前的计划是将其与preferredForwardBufferDuration结合起来,检查项目是否需要更多缓冲区,但这是最好的方法吗 例如: - (void)observeValueForKeyPath:

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

我目前的计划是将其与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
    }
}

我找到了一个很好的解决方案,可以在下面看到。问题中提出的解决方案并没有很好地工作,因为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
    }
}