2015-06-07 3 views
0

У меня есть AVQueuePlayer с массивом URL-адресов видео, которые мне нужно играть один за другим. Все отлично работает, пока я не попытаюсь добавить наблюдателя для отслеживания начала каждого видео.Сбой AVQueuePlayer, когда я пытаюсь наблюдать за запуском следующего видео: AVPlayerItem был освобожден от наблюдателей

Чтобы сделать 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]; 
} 

До сих пор это работает, как ожидалось - видео играть один за другим. Теперь мне также нужно знать сразу, когда начинается воспроизведение видео, поэтому я могу обновить метку в пользовательском интерфейсе с именем файла.

Вот как я добавить 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; 
    } 
    } 
} 

Когда я запускаю это, первое видео прекрасно воспроизводится. Он врежется в [player advanceToNextItem]; в nextVideoOrExit

В аварии:

2015-06-07 13: 31: 52,017 APPNAME [7375: 1775566] *** Нагрузочного приложения из-за до неперехваченного исключения 'NSInternalInconsistencyException', причины : ' экземпляр 0x17001bea класса AVPlayerItem был освобожден, в то время как ключ наблюдателей по-прежнему был зарегистрирован вместе с ним. Текущая наблюдение информация: (Контекст: 0x1001da910, свойство: 0x17065b4e0> )»

Если я закомментируйте [player advanceToNextItem]; линии не врезаться, но это также не играет второе видео в списке.

Я не уверен, где я должен удалить наблюдателя (или, если есть лучший способ определить, когда видео начинает играть.

Любые советы? Спасибо!

+1

Вам необходимо удалитьОбсервер, чтобы сбалансировать каждый вызов addObserver. Вы можете поместить removeObserver в playerItemDidReachEnd: – amergin

ответ

0

По AVFoundation Programming Guide вы можно использовать КВО для контроля значения самого проигрывателя вместо каждого отдельного элемента:

  • Если пользователь использует многозадачность, чтобы переключиться на другое приложение, ставки игрока собственности ш плохое падение до 0.0.

  • Игрок currentItem Изменения свойств в качестве элемента игрока создаются для потокового потока HTTP.

  • Состояние игрока или игрока Состояние может измениться, если по какой-либо причине воспроизведение завершится неудачно.