2013-12-16 2 views
0

AVQueuePlayerAVPlayerItems의 배열을 통해 루프를 사용하여 메신저를 호출하지 못했습니다. 내가 루핑하는 방식은 AVPlayerItemDidPlayToEndTimeNotification이고, 호출 될 때마다 현재 오브젝트를 큐의 끝에 추가합니다. 을 heres 코드 :AVQueuePlayer 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); 

} 

문제는 방법은, 그 후, 메서드를 호출하기 중지 만 재생되는 첫 번째 비디오 요구되는, 예를 들면 내가 배열이 영화가 있다면 그래서, 두 가지 + 첫 번째 또 다시 재생할 것입니다. 왜 이런 일이 일어 났습니까?

추가 정보 : 도 매번 새로운 플레이어를 만들어 레이어에 설정하려고했습니다. 어떤 이유로, 때마다 관찰자로 등록되지 않은 뷰에 대해 분명히, 그냥 같은

- (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]; 

} 

답변

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]; 

} 
+0

, 따라서 당신은뿐만 아니라 currentItem, 그 배열의 각 playerItem에 대한 AVPlayerItemDidPlayToEndNotification 등록해야 – ambientlight

0

이 문제를 해결하기위한 명확한 접근 방법입니다. 다음 코드를 사용하여 접근했습니다.

먼저 재생 시간이 변경되면 AVPlayer에서 피드백을 수신하는 데 필요한 코드를 추가해야합니다. 당신이 AVPlayerItem에 대한 통지를 저항하고, 당신이 배열을 가진 AVQueuePlayer을 초기화되기 때문에

- (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]; 
    } 
} 
관련 문제