3

I am using AVQueuePlayer to play a few videos, everything works fine in iOS 6 & 7. However, in iOS 8, when the current AVPlayerItem finishes playing the next video does not play. Placing an observer on the queue's currentItem property shows the the queue has the next video set as its current item as expected, it just does not play (even with explicit play calls).

Does anyone have any insight into what might be happening and how to fix it? Has anyone else come across this issue?

  • Exactly the same problem here, but with audio only. I don't know what I am missing... – sexyslippers69 Nov 09 '14 at 04:01
  • +1, seeing this sporadically (seemingly quite rare and with HTTP Live Streaming items only), the existing answers don't seem applicable for me. And of course, I'm manipulating AVQueuePlayer from the main thread only. – Andrey Tarantsov Apr 13 '15 at 09:49

3 Answers3

1

I had exactly the same issue and I wasted ten hours on this...
But it fixed now by adding the "insertItem" method into the main thread.

So I have my player as a property :

@property AVQueuePlayer * player;

I just init it like this :

_player = [[AVQueuePlayer alloc] init];

And here is my method to add items from a path :

- (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];
   });
}

So its working but I don't really understand why... So if someone has an answer...

But also if this doesn't work for you, try to add an observer to your player (and/or your playerItem). You can add an observer like that :

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

And catch it with this method :

- (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");
      }
   }
}

Let me know if this work for you.

0

The avplayer should always be accessed on the main thread. This is nothing new to iOS8 but perhaps Apple changed how threads are used so you're seeing the issue more often than in iOS7.

To ensure safe access to a player’s nonatomic properties while dynamic changes in playback state may be reported, you must serialize access with the receiver’s notification queue. In the common case, such serialization is naturally achieved by invoking AVPlayer’s various methods on the main thread or queue.

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

Oren
  • 5,055
  • 3
  • 34
  • 52
0

I had the same problem. After several hours of trial, I found that if some of the items in queue have different encryption methods, the player would stall.

For example, if the player just finished playing an encrypted stream, and the next item in queue was unencrypted, the player is not going to move on to the next item.