Reputation: 441
Just as what I explain above, If I start the app and first turn off the wifi and then try to play a music with AVPlayer
, I will receive a AVPlayerItemStatusFailed
, but after that, I can no longer receive any KVO callback
even if I turn on the wifi again.
On the other situation, if I run the app and first to turn on wifi and play, I can receive AVPlayerItemStatusReadyToPlay
and after that, I can continue to receive KVO callback
even if I turn wifi off...
So how to fix the first situation??
@interface ViewController ()
@property (strong, nonatomic) AVPlayer *player;
@property (assign, nonatomic) NSInteger index;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (IBAction)buttonPressed:(UIButton *)sender {
[self.player.currentItem removeObserver:self forKeyPath:@"status"];
NSLog(@"removed %@", self.player.currentItem);
AVPlayerItem *item = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:self.urls[self.index]]];
[item addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
NSLog(@"added %@", item);
[self.player replaceCurrentItemWithPlayerItem:item];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
if ([keyPath isEqualToString:@"status"]) {
if ([object isMemberOfClass:[AVPlayerItem class]]) {
AVPlayerItem *playerItem = (AVPlayerItem *)object;
switch (playerItem.status) {
case AVPlayerItemStatusFailed:
NSLog(@"failed");
break;
case AVPlayerItemStatusReadyToPlay:
NSLog(@"ready");
break;
case AVPlayerItemStatusUnknown:
NSLog(@"unknown");
break;
}
}
}
}
- (AVPlayer *)player {
if (!_player) {
_player = [[AVPlayer alloc] init];
}
return _player;
}
- (NSArray *)urls {
return @[@"https://of92d29bn.qnssl.com/record1.m4a", @"https://of92d29bn.qnssl.com/record2.m4a"];
}
- (NSInteger)index {
if (_index == 0) {
_index = 1;
} else {
_index = 0;
}
return _index;
}
This is all my code.
Upvotes: 1
Views: 403
Reputation: 3041
I had the same issue and found a solution:
Reset current item to nil before using the new one:
[self.player replaceCurrentItemWithPlayerItem:nil];
[self.player replaceCurrentItemWithPlayerItem:item];
This doesn't make much sense, and there's probably a bug in AVPlayer's implementation somewhere. But this worked for me.
Upvotes: 1