AVQueuePlayer не переходит к следующему элементу в iOS 8

Я использую AVQueuePlayer для воспроизведения нескольких видео, все работает нормально в iOS 6 и 7. Однако в iOS 8, когда текущий AVPlayerItem заканчивает воспроизведение, следующее видео не воспроизводится. Размещение наблюдателя в свойстве currentItem очереди показывает, что очередь имеет следующее видео, установленное в качестве текущего элемента, как и ожидалось, но оно просто не воспроизводится (даже с явными вызовами воспроизведения).

Есть ли у кого-нибудь понимание того, что может происходить и как это исправить? Кто-нибудь еще сталкивался с этой проблемой?


person Patchy Projects    schedule 07.11.2014    source источник
comment
Точно такая же проблема, но только со звуком. Я не знаю, чего мне не хватает...   -  person audric    schedule 09.11.2014
comment
+1, видя это время от времени (казалось бы, довольно редко и только с элементами HTTP Live Streaming), существующие ответы не кажутся мне применимыми. И, конечно же, я управляю AVQueuePlayer только из основного потока.   -  person Andrey Tarantsov    schedule 13.04.2015


Ответы (3)


У меня была точно такая же проблема, и я потратил на это десять часов...
Но теперь это исправлено путем добавления метода "insertItem" в основной поток.

Итак, у меня есть свой плеер как свойство:

@property AVQueuePlayer * player;

Я просто запускаю его так:

_player = [[AVQueuePlayer alloc] init];

И вот мой метод добавления элементов из пути:

- (void)addInQueuePlayerFile:(NSString *)path {
   AVAsset * asset = [AVAsset assetWithURL:[[NSURL alloc] initFileURLWithPath:path]];
   AVPlayerItem * playerItem = [AVPlayerItem playerItemWithAsset:asset];

   dispatch_async(dispatch_get_main_queue(), ^{
      [_player insertItem:playerItem afterItem:nil];
   });
}

Так что это работает, но я действительно не понимаю, почему... Так что, если у кого-то есть ответ...

Но также, если это не работает для вас, попробуйте добавить наблюдателя к вашему игроку (и/или вашему playerItem). Вы можете добавить наблюдателя следующим образом:

[_player addObserver:self forKeyPath:@"status" options:0 context:nil]

И поймать его с помощью этого метода:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
   if (object == _player && [keyPath isEqualToString:@"status"]) {
      if (_player.status == AVPlayerStatusFailed) {
         NSLog(@"AVPlayer Failed");
      } else if (_player.status == AVPlayerStatusReadyToPlay) {
         NSLog(@"AVPlayer item Ready to Play");
      } else if (_player.status == AVPlayerStatusUnknown) {
         NSLog(@"AVPlayer item Unknown");
      }
   }
}

Дайте мне знать, если это работает для вас.

person Julien Benichou    schedule 10.11.2014

Доступ к avplayer всегда должен быть в основном потоке. В этом нет ничего нового для iOS8, но, возможно, Apple изменила способ использования потоков, поэтому вы сталкиваетесь с этой проблемой чаще, чем в iOS7.

Чтобы обеспечить безопасный доступ к неатомарным свойствам проигрывателя, когда могут сообщаться динамические изменения в состоянии воспроизведения, вы должны сериализовать доступ с помощью очереди уведомлений получателя. В общем случае такая сериализация естественным образом достигается путем вызова различных методов AVPlayer в основном потоке или очереди.

https://developer.apple.com/library/ios/documentation/AVFoundation/Reference/AVPlayer_Class/index.html

person Oren    schedule 18.11.2014

У меня такая же проблема. После нескольких часов испытаний я обнаружил, что если некоторые элементы в очереди имеют разные методы шифрования, проигрыватель зависает.

Например, если проигрыватель только что закончил воспроизведение зашифрованного потока, а следующий элемент в очереди оказался незашифрованным, проигрыватель не перейдет к следующему элементу.

person Kelvin Hong    schedule 13.07.2015