Ios5 AVPlayer observeValueForKeyPath

Ios5 AVPlayer observeValueForKeyPath,ios5,audio-streaming,avplayer,avaudiosession,addobserver,Ios5,Audio Streaming,Avplayer,Avaudiosession,Addobserver,我有一个播放流内容的音频应用程序。问题是有时,当信号弱时,它停止播放。网络仍然可以访问,但缓冲区似乎已空运行 我尝试实现一个观察器来监视玩家的状态变化,但它不起作用,该方法从未被调用 作为一种特殊性,AVPlayer实例位于AppDelegate中,因为我有多个视图,播放器必须继续播放显示的任何视图。下面是一段示例代码: - (void)viewDidLoad { [super viewDidLoad]; isPlaying = false;

我有一个播放流内容的音频应用程序。问题是有时,当信号弱时,它停止播放。网络仍然可以访问,但缓冲区似乎已空运行

我尝试实现一个观察器来监视玩家的状态变化,但它不起作用,该方法从未被调用

作为一种特殊性,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];

}
有没有人知道为什么不举办这个活动?我在方法中有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];
}
一定要把所有东西都放在我做的地方,否则它可能不起作用