ios - 当我尝试观察下一个视频的开始时 AVQueuePlayer 崩溃 : AVPlayerItem was deallocated with observers

标签 ios objective-c video avplayer avqueueplayer

我有一个 AVQueuePlayer,其中包含我需要一个接一个播放的视频 URL 数组。一切正常,直到我尝试添加观察者来跟踪每个视频的开始。

为了让 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] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'An instance 0x17001bea0 of class AVPlayerItem was deallocated while key value observers were still registered with it. Current observation info: ( Context: 0x1001da910, Property: 0x17065b4e0> )'

如果我注释掉 [player advanceToNextItem]; 行它不会崩溃,但它也不会播放列表中的第二个视频。

我不确定应该在哪里移除观察者(或者是否有更好的方法来确定视频何时开始播放。

有什么建议吗?谢谢!

最佳答案

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

  • 如果用户使用多任务切换到不同的应用程序,播放器的 rate 属性将降至 0.0。

  • 播放器的 currentItem 属性在为 HTTP 直播流创建播放器项目时发生变化。

  • 如果由于某种原因播放失败,播放器或播放器项目的状态属性可能会改变。

关于ios - 当我尝试观察下一个视频的开始时 AVQueuePlayer 崩溃 : AVPlayerItem was deallocated with observers,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30698219/

相关文章:

ios - 如何以编程方式在 iOS 中添加图标覆盖?

ios - UIPickerView 无法显示 JSON 数组数据

video - YouTube是否真的在 channel 上显示了观看次数最多的视频?

android - 使用参数 'pan' 初始化过滤器 'stereo:c0<c0+c2:c1<c1+c3' 时出错

c# - 在 C# 中处理视频源的资源

ios - 有什么办法知道是否通过 Apple Music 下载了歌曲?

iphone - 应用程式可在iOS 6上运作,但无法在iOS 5上运作

ios - 如何在 iPhone 上退出 Google+

objective-c - 如何在 Cocoa 中从 MP3 文件中提取 ID 标签?

html - 无法在 IOS 9 的 UIWebView 中选择下拉菜单