Обработка потоковых событий с помощью AVPlayer
Я создаю приложение, которое воспроизводит аудиопоток (из webradio).
Я использую AVPlayer
для этого.
1) Я хотел бы знать, как вы будете обрабатывать буферизацию AVPlayer's
, когда соединение будет медленным или когда пользователь просто щелкнет "играть". Я хочу обнаружить, что AVPlayer
является "буферизацией" для отображения UIActivityIndicatorView
.
2) Тот же вопрос во время работы в фоновом режиме. Что делать, если буферизация в этом случае?
Спасибо!
Ответы
Ответ 1
Для первого вопроса
Вы можете сослаться на мой ответ по этому вопросу Поток потока iOS avplayer вышел из буфера
Для второго
Вот как я решил эту же проблему:
Внутри, где вы обрабатываете событие для пустого буфера, добавьте этот код:
if (object == playerItem && [keyPath isEqualToString:@"playbackBufferEmpty"])
{
if (playerItem.playbackBufferEmpty) {
[[NSNotificationCenter defaultCenter] postNotificationName:@"message" object:@"Buffering..."];
if([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground)
{
task = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^(void) {
}];
}
}
}
Теперь вам нужно будет остановить эту фоновое задание после того, как буфер снова будет готов:
if (object == playerItem && [keyPath isEqualToString:@"playbackLikelyToKeepUp"])
{
if (playerItem.playbackLikelyToKeepUp)
{
[player play];
if([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground)
{
[[UIApplication sharedApplication] endBackgroundTask:task];
task = 0;
}
}
}
ps: задача объявлена в моем файле .h как UIBackgroundTaskIdentifier task;
Ответ 2
Я нашел решение этой проблемы.
if (self.avPlayer.currentItem.playbackLikelyToKeepUp == NO)
{
// Show activity indicator
}
Ответ 3
Для Swift 3
Это отлично работает для меня, возможно, это может помочь, вызовите self?.bufferState()
внутри addPeriodicTimeObserver
private func bufferState() {
if let currentItem = self.avPlayer.currentItem {
if currentItem.status == AVPlayerItemStatus.readyToPlay {
if currentItem.isPlaybackLikelyToKeepUp {
print("Playing ")
} else if currentItem.isPlaybackBufferEmpty {
print("Buffer empty - show loader")
} else if currentItem.isPlaybackBufferFull {
print("Buffer full - hide loader")
} else {
print("Buffering ")
}
} else if currentItem.status == AVPlayerItemStatus.failed {
print("Failed ")
} else if currentItem.status == AVPlayerItemStatus.unknown {
print("Unknown ")
}
} else {
print("avPlayer.currentItem is nil")
}
}
Ответ 4
Попробуйте следующее:
AVPlayerItem* mPlayerItem;
if(context == AVPlayerDemoPlaybackViewControllerCurrentItemBufferEmptyContext)
{
if (object == self.mPlayerItem && [path isEqualToString:@"playbackBufferEmpty"])
{
if (self.mPlayerItem.playbackBufferEmpty)
{
playBufferEmpty = TRUE;
[indicator startAnimating];
[vidStreaminglabel setText:@"Buffering..."];
[vidStreaminglabel setHidden:NO];
}
}
}
else if(context == AVPlayerDemoPlaybackViewControllerCurrentItemPlayBackBufferFullContext)
{
if (object == mPlayerItem && [path isEqualToString:@"playbackBufferFull"]){
if (self.mPlayerItem.playbackBufferFull) {
[mPlayer play];
}
}
}
else if (context == AVPlayerDemoPlaybackViewControllerCurrentItemPlayBackLikelyToKeepUpContext)
{
if (object == mPlayerItem && [path isEqualToString:@"playbackLikelyToKeepUp"])
{
if(self.mPlayerItem.playbackLikelyToKeepUp)
{
// Autoplay after buffer
if(!(mRestoreAfterScrubbingRate != 0.f || [self.mPlayer rate] != 0.f))
{
if (self.presentingViewController) {
[mPlayer play];
}
playBufferEmpty = FALSE;
[indicator stopAnimating];
[vidStreaminglabel setHidden:YES];
}
}
}
}