Ios5 AVPlayer observeValueForKeyPath
我有一个播放流内容的音频应用程序。问题是有时,当信号弱时,它停止播放。网络仍然可以访问,但缓冲区似乎已空运行 我尝试实现一个观察器来监视玩家的状态变化,但它不起作用,该方法从未被调用 作为一种特殊性,AVPlayer实例位于AppDelegate中,因为我有多个视图,播放器必须继续播放显示的任何视图。下面是一段示例代码:Ios5 AVPlayer observeValueForKeyPath,ios5,audio-streaming,avplayer,avaudiosession,addobserver,Ios5,Audio Streaming,Avplayer,Avaudiosession,Addobserver,我有一个播放流内容的音频应用程序。问题是有时,当信号弱时,它停止播放。网络仍然可以访问,但缓冲区似乎已空运行 我尝试实现一个观察器来监视玩家的状态变化,但它不起作用,该方法从未被调用 作为一种特殊性,AVPlayer实例位于AppDelegate中,因为我有多个视图,播放器必须继续播放显示的任何视图。下面是一段示例代码: - (void)viewDidLoad { [super viewDidLoad]; isPlaying = false;
- (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];
}
有没有人知道为什么不举办这个活动?我在方法中有2个警报,但没有人被触发,这意味着它没有进入方法。所有这一切的目标都是试图实现一种方法,让玩家在这种情况下控制它
谢谢 您试图在创建要观察的对象之前添加观察者。您只是在向
nil
对象发送消息。在调用之前调用
-initPlayer
-addObserver:forKeyPath:options:context: 您试图在创建要观察的对象之前添加观察者。您只是在向nil
对象发送消息。在调用之前调用
-initPlayer
-addObserver:forKeyPath:options:context: 以下是有效的代码
要声明可观察的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];
}
要处理观察者:
- (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];
}
要删除观察员,请执行以下操作:
- (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];
}
一定要把所有东西都放在我做过的地方,否则它可能不起作用。以下是有效的代码 要声明可观察的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];
}
要处理观察者:
- (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];
}
要删除观察员,请执行以下操作:
- (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];
}
一定要把所有东西都放在我做的地方,否则它可能不起作用