Как узнать, когда AVPlayerItem буферизуется до конца песни

Я пытаюсь определить лучший способ узнать, буферизуется ли AVPlayerItem до конца потока. Не только то, что буфер заполнен, но и то, что буфер содержит все необходимое для воспроизведения остальной части элемента без дополнительной буферизации. AVPlayerItem предлагает вызов isPlaybackBufferFull, но это не говорит мне, нужна ли какая-либо дополнительная буферизация до завершения воспроизведения элемента.

Мой текущий план состоит в том, чтобы совместить это с selectedForwardBufferDuration, чтобы проверить, нужно ли элементу когда-либо буферизовать больше, но лучший ли это способ?

Например:

- (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
        }
    }
}

person Shackleford    schedule 26.04.2017    source источник


Ответы (1)


Я нашел довольно хорошее решение этой проблемы, которое можно увидеть ниже. Предлагаемое решение, написанное в вопросе, на самом деле не сработало, потому что для 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
    }
}
person Shackleford    schedule 25.07.2017