I have an audio player that I'm building using AVPlayer.
Currently, I keep the player
instance around and when I need to swap tracks (either from a manual selection or the track has reached the end) I create a new AVPlayerItem
and I call replaceCurrentItemWithPlayerItem
with the new item.
According to the docs, replaceCurrentItemWithPlayerItem
is an asynchronous operation, so I also observe the currentItem key path of the player. When that gets called, I tell my player to play.
Here is the relevant code:
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:asset];
[playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:CHStreamingAudioPlayer_PlayerItemStatusChangedContext];
if (!_player) {
_player = [[AVPlayer alloc] initWithPlayerItem:playerItem];
[_player addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:CHStreamingAudioPlayer_PlayerStatusChangedContext];
[_player addObserver:self forKeyPath:@"currentItem" options:NSKeyValueObservingOptionNew context:CHStreamingAudioPlayer_PlayerCurrentItemChangedContext];
} else {
[_player replaceCurrentItemWithPlayerItem:playerItem];
}
And here is the key value observation callback:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if (context == CHStreamingAudioPlayer_PlayerCurrentItemChangedContext) {
NSLog(@"Player's current item changed! Change dictionary: %@", change);
if (_player.currentItem) {
[self play]; //<---- doesn't get called
}
} else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
On iOS 4.3.3 (and iOS 5) my key observation method is called but _player.currentItem
is always nil
. On 4.2.1 and 4.3.2 this property contains the actual value. This method is never called again. So in essence, replacing seems to always fail.
This seems like a bug, but perhaps I'm doing something wrong.
I had this issue with iOS 5 (including 5.0.1). It used to work fine on iOS 4.x.
There are two ways to workaround this, release and recreate your AVPlayer
with the desired AVPlayerItem
s each time you need to swap tracks. Or, simply call replaceCurrentItemWithPlayerItem:
on the main thread.
I tried both options and they worked fine.
Credits to: Apple Developer Forums
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With