我有一个播放流内容的音频应用程序。问题是,有时,当信号很弱时,它会停止播放。网络仍可访问,但缓冲区似乎已空运行。
我尝试实现一个观察器来监视玩家的状态变化,但是它不起作用,这个方法从来没有被调用过。
作为一个特例,AVPlayer实例在AppDelegate中,因为我有多个视图,播放器必须继续播放所显示的任何视图。下面是一段示例代码:
- (void)viewDidLoad
{
[super viewDidLoad];
isPlaying = false;
playButton.enabled = NO;
//Add en observer for reachability change
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reachabilityChanged:)
name:kReachabilityChangedNotification
object:nil];
//Adding the observer for player's status change
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[delegate.player addObserver:self forKeyPath:@"status" options:0 context:playerStatusContext];
[self initPlayer];
}
//Event raised whenever the current status of the player change
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
UIAlertView *alert = [UIAlertView alloc];
NSString *chaineConcat = @"Entering observer method..."];
[alert initWithTitle:@"Test" message:chaineConcat delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
if (context == playerStatusContext) {
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSString *statusPlayer = nil;
if (object == delegate.player && [keyPath isEqualToString:@"status"]) {
if (delegate.player.status == AVPlayerStatusReadyToPlay) {
statusPlayer = @"Everything's OK";
} else if (delegate.player.status == AVPlayerStatusFailed) {
statusPlayer = @"Houston, we have a problem";
}
}
[self syncUI];
UIAlertView *alert = [UIAlertView alloc];
NSString *chaineConcat = [NSString stringWithFormat:@"%@/%@/", @"Player status' is ", statusPlayer];
[alert initWithTitle:@"Test" message:chaineConcat delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
}else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
return;
}
- (void) initPlayer {
// Load the array with the sample file
NSString *urlAddress = @"http://MYSTREAMURL";
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
//Create a URL object.
delegate.urlStream = [NSURL URLWithString:urlAddress];
//Reinit AVPlayer
delegate.player = [AVPlayer playerWithURL:delegate.urlStream];
}有没有人知道为什么这个事件没有被引发?我在方法中有两个警报,但没有人被触发,这意味着它不会进入方法中。所有这一切的目标将是尝试实现一种方法,以便玩家在发生这种情况时重新启动它。
谢谢!
发布于 2013-03-15 06:06:34
在创建要观察的对象之前,您正在尝试添加观察者。您只是向nil对象发送了一条消息。
在调用-addObserver:forKeyPath:options:context:之前先调用-initPlayer。
发布于 2016-01-26 09:21:46
下面是可以工作的代码。
要声明可观察的AVPlayer对象,请执行以下操作:
@interface APLViewController ()
{
AVPlayer *_player;
}要分配和初始化AVPlayer:
- (void)viewDidLoad
{
[super viewDidLoad];
_player = [[AVPlayer alloc] init];
}要添加观察者,请执行以下操作:
- (void)viewWillAppear:(BOOL)animated
{
[self addObserver:self forKeyPath:@"player.currentItem.status" options:NSKeyValueObservingOptionNew context:AVPlayerItemStatusContext];
[self addTimeObserverToPlayer];
[super viewWillAppear:animated];
}要处理观察者:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if (context == AVPlayerItemStatusContext) {
AVPlayerStatus status = [change[NSKeyValueChangeNewKey] integerValue];
switch (status) {
case AVPlayerItemStatusUnknown:
break;
case AVPlayerItemStatusReadyToPlay:
self.playerView.presentationRect = [[_player currentItem] presentationSize];
break;
case AVPlayerItemStatusFailed:
[self stopLoadingAnimationAndHandleError:[[_player currentItem] error]];
break;
}
}
else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}要删除观察者,请执行以下操作:
- (void)viewWillDisappear:(BOOL)animated
{
[self removeObserver:self forKeyPath:@"player.currentItem.status" context:AVPlayerItemStatusContext];
[self removeTimeObserverFromPlayer];
[super viewWillDisappear:animated];
}一定要把所有东西都放在我做过的地方,否则它可能无法工作。
https://stackoverflow.com/questions/11767283
复制相似问题