2012-06-22 45 views
7

我需要在我AVQueuePlayer創造的東西就像一個無限循環。特別是,我想在最後一個組件完成播放後重播整個NSArrayAVPlayerItem重播項目後最後

我必須承認,我居然沒有任何想法如何做到這一點,希望你能給我一些線索。

+0

您是否堅持了這一點,或者您只是需要從出發點創建它? – Dhruv

+0

我現在實際上是如何創建它並播放所有的AVQueuePlayers,我現在正在尋找最後一次QVPlayerItem完成時重新啓動播放器。 – Edelweiss

+0

' - (無效)playVideoAtIndex:(NSInteger的)索引{ [自performSelector:@selector(setObservationInfo)]; currentIndex = index; AVPlayerItem * videoItem = [AVPlayerItem playerItemWithURL:[NSURL fileURLWithPath:[arrVideoList objectAtIndex:index]]];; [AVPlayerItem playerItemWithURL:[NSURL fileURLWithPath:[arrVideoList objectAtIndex:index]]]; }' 在需要檢查, '如果(CURRENTINDEX <[arrVideoList計數] -1) { CURRENTINDEX ++; } else { currentIndex = 0; } [self playVideoAtIndex:currentIndex];' – Dhruv

回答

1

這是從零開始。這些組件是:

  1. 創建一個隊列,它是AVPlayerItems的NSArray。
  2. 當每個項目都添加到隊列中時,設置一個NSNotificationCenter觀察器,當視頻到達結尾時喚醒。
  3. 在觀察者的選擇,告訴你要循環回去的開頭,然後告訴玩家玩AVPlayerItem。

(注:AVPlayerDemoPlaybackView來自蘋果 「AVPlayerDemo」 樣品只需帶一個setter的UIView的子類。)

BOOL videoShouldLoop = YES; 
NSFileManager *fileManager = [NSFileManager defaultManager]; 
NSMutableArray *videoQueue = [[NSMutableArray alloc] init]; 
AVQueuePlayer *mPlayer; 
AVPlayerDemoPlaybackView *mPlaybackView; 

// You'll need to get an array of the files you want to queue as NSARrray *fileList: 
for (NSString *videoPath in fileList) { 
    // Add all files to the queue as AVPlayerItems 
    if ([fileManager fileExistsAtPath: videoPath]) { 
     NSURL *videoURL = [NSURL fileURLWithPath: videoPath]; 
     AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL: videoURL]; 
     // Setup the observer 
     [[NSNotificationCenter defaultCenter] addObserver: self 
               selector: @selector(playerItemDidReachEnd:) 
                name: AVPlayerItemDidPlayToEndTimeNotification 
                object: playerItem]; 
     // Add the playerItem to the queue 
     [videoQueue addObject: playerItem]; 
    } 
} 
// Add the queue array to the AVQueuePlayer 
mPlayer = [AVQueuePlayer queuePlayerWithItems: videoQueue]; 
// Add the player to the view 
[mPlaybackView setPlayer: mPlayer]; 
// If you should only have one video, this allows it to stop at the end instead of blanking the display 
if ([[mPlayer items] count] == 1) { 
    mPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone; 
} 
// Start playing 
[mPlayer play]; 


- (void) playerItemDidReachEnd: (NSNotification *)notification 
{ 
    // Loop the video 
    if (videoShouldLoop) { 
     // Get the current item 
     AVPlayerItem *playerItem = [mPlayer currentItem]; 
     // Set it back to the beginning 
     [playerItem seekToTime: kCMTimeZero]; 
     // Tell the player to do nothing when it reaches the end of the video 
     // -- It will come back to this method when it's done 
     mPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone; 
     // Play it again, Sam 
     [mPlayer play]; 
    } else { 
     mPlayer.actionAtItemEnd = AVPlayerActionAtItemEndAdvance; 
    } 
} 

這就是它!讓我知道一些事情需要進一步的解釋。

+0

如果我在播放器中添加3video,我應該怎麼做?並且在所有3video完成後,最後一個視頻將在無限循環中播放 –

+0

此處的邏輯不會獲得OP的期望行爲。它循環最後一個項目而不是整個玩家項目的數組。 – Joey

+0

謝謝你爲我工作.. –

0

我想通了,我的視頻隊列在所有的影片循環播放的解決方案,而不是一個。首先,我初始化我AVQueuePlayer

- (void)viewDidLoad 
{ 
    NSMutableArray *vidItems = [[NSMutableArray alloc] init]; 
    for (int i = 0; i < 5; i++) 
    { 
     // create file name and make path 
     NSString *fileName = [NSString stringWithFormat:@"intro%i", i]; 
     NSString *path = [[NSBundle mainBundle] pathForResource:fileName ofType:@"mov"]; 
     NSURL *movieUrl = [NSURL fileURLWithPath:path]; 
     // load url as player item 
     AVPlayerItem *item = [AVPlayerItem playerItemWithURL:movieUrl]; 
     // observe when this item ends 
     [[NSNotificationCenter defaultCenter] addObserver:self 
               selector:@selector(playerItemDidReachEnd:) 
                name:AVPlayerItemDidPlayToEndTimeNotification 
                object:item]; 
     // add to array 
     [vidItems addObject:item]; 


    } 
    // initialize avqueueplayer 
    _moviePlayer = [AVQueuePlayer queuePlayerWithItems:vidItems]; 
    _moviePlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone; 

    // create layer for viewing 
    AVPlayerLayer *layer = [AVPlayerLayer playerLayerWithPlayer:_moviePlayer]; 

    layer.frame = self.view.bounds; 
    layer.videoGravity = AVLayerVideoGravityResizeAspectFill; 
    // add layer to uiview container 
    [_movieViewContainer.layer addSublayer:layer]; 
} 

當通知發佈

- (void)playerItemDidReachEnd:(NSNotification *)notification { 
    AVPlayerItem *p = [notification object]; 

    // keep playing the queue 
    [_moviePlayer advanceToNextItem]; 
    // if this is the last item in the queue, add the videos back in 
    if (_moviePlayer.items.count == 1) 
    { 
     // it'd be more efficient to make this a method being we're using it a second time 
     for (int i = 0; i < 5; i++) 
     { 
      NSString *fileName = [NSString stringWithFormat:@"intro%i", i]; 
      NSString *path = [[NSBundle mainBundle] pathForResource:fileName ofType:@"mov"]; 
      NSURL *movieUrl = [NSURL fileURLWithPath:path]; 

      AVPlayerItem *item = [AVPlayerItem playerItemWithURL:movieUrl]; 

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

      // the difference from last time, we're adding the new item after the last item in our player to maintain the order 
      [_moviePlayer insertItem:item afterItem:[[_moviePlayer items] lastObject]]; 
     } 
    } 
} 
0

最好的辦法循環的AVQueuePlayer視頻序列。

觀察在AVQueuePlayer每個playeritem。

queuePlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone; 
for(AVPlayerItem *item in items) { 
    [[NSNotificationCenter defaultCenter] addObserver:self 
      selector:@selector(nextVideo:) 
      name:AVPlayerItemDidPlayToEndTimeNotification 
      object:item ]; 
} 
每個

nextVideo再次插入CURRENTITEM排隊它進行播放。確保爲每個項目尋求零。在advanceToNextItem之後,AVQueuePlayer將從隊列中移除currentItem。

-(void) nextVideo:(NSNotification*)notif { 
    AVPlayerItem *currItem = notif.userInfo[@"object"]; 
    [currItem seekToTime:kCMTimeZero]; 
    [queuePlayer advanceToNextItem]; 
    [queuePlayer insertItem:currItem afterItem:nil]; 
}