首页 文章

当我尝试观察下一个视频的开始时AVQueuePlayer崩溃:AVPlayerItem被观察者释放

提问于
浏览
0

我有一个AVQueuePlayer,其中包含一系列视频网址,我需要一个接一个地播放 . 一切都很好,直到我尝试添加一个观察者来跟踪每个视频的开始 .

为了让AVQueuePlayer自动前进到下一个视频,我有这个:

[[NSNotificationCenter defaultCenter] addObserver:self           
                                         selector:@selector(playerItemDidReachEnd:) 
                                             name:AVPlayerItemDidPlayToEndTimeNotification 
                                           object:[playerItems lastObject]];


- (void)playerItemDidReachEnd:(NSNotification *)notification {
  [self nextVideoOrExit];
}

- (void)nextVideoOrExit
{
  if ([player.items count] == 1)
    [self shutdown];
  else
    [player advanceToNextItem];
}

- (void)shutdown
{
  [player removeAllItems];
  [self dismissPlayerView];
}

到目前为止,这是按预期工作 - 视频一个接一个播放 . 现在我还需要立即知道视频何时开始播放,以便我可以使用文件名更新UI中的标签 .

以下是我添加AVPlayerItems和用于跟踪下一个视频播放时间的观察者的方法:

for (Tag *tag in self.tagsWithVideos) {
    tagUrlToTag[tag.video.url] = tag;
    NSURL *url = [[NSURL alloc] initWithString:tag.video.url];
    AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:url options:nil];
    AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithAsset:asset];
    [player insertItem:playerItem afterItem:nil];

    [playerItems addObject:playerItem];

    [playerItem addObserver:self
             forKeyPath:@"status"
                options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
                context:@"AVPlayerStatus"];
    NSLog(@"LOADING ANOTHER VID");
  };

以下是我处理观察者的方式:

- (void)observeValueForKeyPath:(NSString *)path
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context {

  if (context == @"AVPlayerStatus") {

    AVPlayerStatus status = [[change objectForKey:NSKeyValueChangeNewKey] integerValue];
    switch (status) {
      case AVPlayerStatusUnknown: {

      }
        break;

      case AVPlayerStatusReadyToPlay: {
        NSLog(@"AVPlayerStatusReadyToPlay");
      }
        break;
    }
  }
}

当我运行它时,第一个视频播放正常 . 它在 nextVideoOrExit[player advanceToNextItem]; 崩溃

碰撞:

2015-06-07 13:31:52.017 AppName [7375:1775566] ***由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'AVPlayerItem类的实例0x17001bea0已取消分配,而键值观察者仍在其中注册 . 当前观察信息:(上下文:0x1001da910,属性:0x17065b4e0>)'

如果我注释掉 [player advanceToNextItem]; 行,它就不会播放列表中的第二个视频 .

我不确定我应该删除观察者的位置(或者是否有更好的方法来识别视频何时开始播放 .

有什么建议?谢谢!

1 回答

  • 1

    根据AVFoundation Programming Guide,您可以使用KVO监控播放器本身的值而不是每个项目:

    • 如果用户使用多任务处理切换到其他应用程序,则播放器的 rate 属性将降至0.0 .

    • 玩家的 currentItem 属性会随着为HTTP直播流创建的玩家项目而更改 .

    • 如果由于某种原因播放失败,播放器或播放器项目的 status 属性可能会发生变化 .

相关问题