AVQueuePlayer AVPlayerItemDidPlayToEndTimeNotification无法调用

时间:2013-12-16 12:49:51

标签: ios objective-c ios7 avplayer avqueueplayer

我使用AVQueuePlayer循环遍历AVPlayerItems数组。 我循环它的方式,我听AVPlayerItemDidPlayToEndTimeNotification,每次调用时,我将当前对象添加到队列的末尾。 继承人代码:

    viewWillAppear
{
    ...

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

        [_queuePlayer play];
}
- (void)playerItemDidReachEnd:(NSNotification *)notification {
    AVPlayerItem *p = [notification object];
    AVPlayerItem *fakeNew = [[AVPlayerItem alloc] initWithAsset:p.asset];
    if (_queuePlayer.items.count == 1)
    {
        [p seekToTime:kCMTimeZero];
        [_queuePlayer play];
    }
    else
    {
        [_queuePlayer insertItem:fakeNew afterItem:[_queuePlayer.items lastObject]];
    }
    NSLog(@"array of items to play:%lu", (unsigned long)_queuePlayer.items.count);

}

问题是,该方法仅针对播放的第一个视频调用,之后,该方法停止被调用,因此,例如,如果我在阵列中有2个电影,它将同时播放它们+第一个再次,任何想法为什么会发生这种情况?

更多信息: 还尝试每次制作一个新玩家并将其设置为图层。未能多次发送通知

- (void)playerItemDidReachEnd:(NSNotification *)notification {
    AVPlayerItem *p = [notification object];
    [self.playList removeObjectAtIndex:0];
    [self.playList addObject:p];
    AVPlayer *newPlayer = [[AVPlayer alloc] initWithPlayerItem:[self.playList objectAtIndex:0]];
    _player = newPlayer;
    self.AVPlayerLayerView.layer.player = self.player;
    [_player play];

}

2 个答案:

答案 0 :(得分:1)

经过大量的捣乱,显然无论出于何种原因,视图每次都未注册为观察者,我只是在每次通知后删除并添加了观察者:

- (void)playerItemDidReachEnd:(NSNotification *)notification {
    AVPlayerItem *p = [notification object];
    AVPlayerItem *fakeNewItem = [[AVPlayerItem alloc] initWithAsset:p.asset];
    [self.playList removeObjectAtIndex:0];
    [self.playList addObject:fakeNewItem];
    AVPlayer *newPlayer = [[AVPlayer alloc] initWithPlayerItem:[self.playList objectAtIndex:0]];
    _player = newPlayer;
    self.AVPlayerLayerView.layer.player = self.player;
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(playerItemDidReachEnd:)
                                                 name:AVPlayerItemDidPlayToEndTimeNotification
                                               object:[_player currentItem]];
    [_player play];

}

答案 1 :(得分:0)

有一个干净的方法来解决这个问题。我接下来用下一段代码

首先,您必须添加在复制时间发生变化时从AVPlayer接收反馈所需的代码。

- (void)addPeriodicTimeObserverForReproductionChanges {
    @weakify(self);
    [self.player 
    addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(kBQDefaultTimeIntervalReproductionChanges, NSEC_PER_SEC) 
    queue:self.eventsQueue
    usingBlock:^(CMTime time) {
    @strongify(self);
    [self dispatchBlockOnMainQueue:^{
        if ([self.delegate respondsToSelector:@selector(playerItemController:didChangeReproductionTime:)])
             [self.delegate playerItemController:self
                       didChangeReproductionTime:time];

         [self checkForItemPlayToEnd];
     }]; 
 }];

}

- (void)checkForItemPlayToEnd 
{
    CMTime durationScaled = CMTimeConvertScale(self.duration,self.player.currentTime.timescale, kCMTimeRoundingMethod_Default);

    if (CMTIME_COMPARE_INLINE(durationScaled, ==, self.player.currentTime)) {
        [self playerDidFinishReproducingItem];
    }
}