首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AVPlayer observeValueForKeyPath

AVPlayer observeValueForKeyPath
EN

Stack Overflow用户
提问于 2012-08-02 04:44:21
回答 2查看 1.9K关注 0票数 1

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

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

作为一个特例,AVPlayer实例在AppDelegate中,因为我有多个视图,播放器必须继续播放所显示的任何视图。下面是一段示例代码:

代码语言:javascript
复制
- (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];

}

有没有人知道为什么这个事件没有被引发?我在方法中有两个警报,但没有人被触发,这意味着它不会进入方法中。所有这一切的目标将是尝试实现一种方法,以便玩家在发生这种情况时重新启动它。

谢谢!

EN

回答 2

Stack Overflow用户

发布于 2013-03-15 06:06:34

在创建要观察的对象之前,您正在尝试添加观察者。您只是向nil对象发送了一条消息。

在调用-addObserver:forKeyPath:options:context:之前先调用-initPlayer

票数 1
EN

Stack Overflow用户

发布于 2016-01-26 09:21:46

下面是可以工作的代码。

要声明可观察的AVPlayer对象,请执行以下操作:

代码语言:javascript
复制
@interface APLViewController ()
{
    AVPlayer *_player;
}

要分配和初始化AVPlayer:

代码语言:javascript
复制
- (void)viewDidLoad
{
[super viewDidLoad];

 _player = [[AVPlayer alloc] init];
}

要添加观察者,请执行以下操作:

代码语言:javascript
复制
- (void)viewWillAppear:(BOOL)animated
{
    [self addObserver:self forKeyPath:@"player.currentItem.status" options:NSKeyValueObservingOptionNew context:AVPlayerItemStatusContext];
    [self addTimeObserverToPlayer];

    [super viewWillAppear:animated];
}

要处理观察者:

代码语言:javascript
复制
- (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];
    }
}

要删除观察者,请执行以下操作:

代码语言:javascript
复制
- (void)viewWillDisappear:(BOOL)animated
{
    [self removeObserver:self forKeyPath:@"player.currentItem.status" context:AVPlayerItemStatusContext];
    [self removeTimeObserverFromPlayer];

    [super viewWillDisappear:animated];
}

一定要把所有东西都放在我做过的地方,否则它可能无法工作。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11767283

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档