2012-06-22 16 views
7

Necesito crear algo así como un bucle infinito en mi AVQueuePlayer. Especialmente, quiero reproducir toda NSArray de AVPlayerItem s una vez que el último componente termine de reproducirse.Reproducir elementos en AVQueuePlayer después del último

Debo admitir que en realidad no tengo ni idea de cómo lograr esto y espero que pueda darme algunas pistas.

+0

¿Estás atascado en este punto o solo necesitas crearlo desde el punto de partida? – Dhruv

+0

De hecho, ahora cómo crearlo y reproducir todos los AVQueuePlayers, ahora estoy buscando reiniciar el reproductor cuando termine el último QVPlayerItem. – Edelweiss

+0

'- (void) playVideoAtIndex: (NSInteger) índice { [self performSelector: @selector (setObservationInfo)]; currentIndex = index; AVPlayerItem * videoItem = [AVPlayerItem playerItemWithURL: [NSURL fileURLWithPath: [arrVideoList objectAtIndex: index]]]; } ' donde es necesario comprobar, ' si (currentIndex <[recuento arrVideoList] -1) { currentIndex ++; } else { currentIndex = 0; } [self playVideoAtIndex: currentIndex]; ' – Dhruv

Respuesta

1

Esto es más o menos desde cero. Los componentes son:

  1. Cree una cola que sea un NSArray de AVPlayerItems.
  2. A medida que se agrega cada elemento a la cola, configure un observador NSNotificationCenter para que se active cuando el video llegue al final.
  3. En el selector del observador, dile al AVPlayerItem que deseas que vuelva al principio, luego dile al jugador que juegue.

(NOTA: El AVPlayerDemoPlaybackView proviene de la "AVPlayerDemo" Apple muestra simplemente una subclase de UIView con un colocador.)

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

eso es todo! Avíseme si algo necesita una explicación más detallada.

+0

¿Qué debo hacer si agrego 3 videos adicionales en el reproductor? Y después de completar los 3 videos, el último video se reproducirá en el ciclo infinito –

+0

La lógica aquí no obtiene el comportamiento deseado del OP. Rota el último elemento, no toda la matriz de elementos del jugador. – Joey

+0

Gracias funcionó para mí .. –

0

Descubrí una solución para recorrer todos los videos de mi cola de videos, no solo uno. En primer lugar me inicializa mi 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]; 
} 

Cuando la notificación se publica

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

mejor forma de bucle una secuencia de videos en AVQueuePlayer.

observe para cada elemento de jugador en AVQueuePlayer.

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

en cada video siguiente inserte el elemento actual de nuevo para ponerlo en cola para la reproducción. asegúrese de buscar cero para cada artículo. después de advanceToNextItem, el AVQueuePlayer eliminará el elemento actual de la cola.

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