2012-06-22 12 views
7

Ho bisogno di creare qualcosa come un ciclo infinito nel mio AVQueuePlayer. Soprattutto, voglio riprodurre l'intero NSArray di AVPlayerItem s una volta che l'ultimo componente ha finito di suonare.Riprodurre gli elementi in AVQueuePlayer dopo l'ultimo

Devo ammettere che in realtà non ho idea di come raggiungere questo obiettivo e spero che tu possa darmi qualche indizio.

+0

Sei bloccato a questo punto o hai solo bisogno di crearlo dal punto di partenza? – Dhruv

+0

In realtà ora come crearlo e riprodurre tutti gli AVQueuePlayers, ora sto cercando di riavviare il player quando l'ultimo QVPlayerItem è terminato. – Edelweiss

+0

'- (void) playVideoAtIndex: indice (NSInteger) { [self PerformSelector: @selector (setObservationInfo)]; currentIndex = index; AVPlayerItem * videoItem = [AVPlayerItem playerItemWithURL: [NSURL fileURLWithPath: [arrVideoList objectAtIndex: index]]]; } ' in cui è necessario controllare, ' if (currentIndex <[count arrVideoList] -1) { currentIndex ++; } altro { currentIndex = 0; } [auto playVideoAtIndex: currentIndex]; ' – Dhruv

risposta

1

Questo è praticamente da zero. I componenti sono:

  1. Creare una coda che è un NSArray di AVPlayerItems.
  2. Come ogni elemento aggiunto alla coda, impostare un osservatore NSNotificationCenter per svegliarsi quando il video raggiunge la fine.
  3. Nel selettore dell'osservatore, dire all'AVPlayerItem che si desidera eseguire il ciclo per tornare all'inizio, quindi dire al lettore di giocare.

(NOTA: L'AVPlayerDemoPlaybackView viene dalla Apple "AVPlayerDemo" campione Semplicemente una sottoclasse di UIView con un setter.)

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

Questo è tutto! Fammi sapere che qualcosa ha bisogno di ulteriori spiegazioni.

+0

Cosa devo fare se aggiungo 3video aggiunto nel lettore. Dopo il completamento di tutti i 3video, l'ultimo video verrà riprodotto in loop infinito –

+0

La logica qui non ottiene il comportamento desiderato dell'OP. Fa scorrere l'ultimo elemento, non l'intera serie di elementi del giocatore. – Joey

+0

Grazie, ha funzionato per me .. –

0

Ho trovato una soluzione per il loop su tutti i video nella mia coda video, non solo uno. Per prima cosa ho inizializzato il mio 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]; 
} 

Quando la notifica è pubblicato

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

miglior modo per bloccare una sequenza di video in AVQueuePlayer.

osservare per ciascun giocatore in AVQueuePlayer.

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

su ogni prossimoVideo inserire nuovamente l'oggetto corrente per accodarlo per la riproduzione. assicurati di cercare zero per ogni oggetto. dopo advanceToNextItem, AVQueuePlayer rimuoverà l'oggetto corrente dalla coda.

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