Вопрос по avfoundation, avqueueplayer, iphone, ios, avplayer – Воспроизведение элементов в AVQueuePlayer после последнего

7

Мне нужно создать что-то вроде бесконечного цикла в моемAVQueuePlayer, Особенно, я хочу переиграть весьNSArray изAVPlayerItemПосле завершения воспроизведения последнего компонента.

Я должен признать, что на самом деле не имею ни малейшего представления, как этого добиться, и надеюсь, что вы сможете дать мне некоторые подсказки.

Так вы используете массив с видео? Этот массив содержит путь к видео, верно? Edelweiss
Вы застряли в этой точке или вам просто нужно создать ее с начальной точки? Dhruv
Сейчас я действительно знаю, как его создать и воспроизвести все AVQueuePlayers, теперь я ищу перезапуск плеера, когда последний QVPlayerItem завершен. Edelweiss
Да, точно, вам просто нужно пройти путь, и когда вы получите последний, вы можете вернуться к первому индексу. Dhruv
-(void) playVideoAtIndex:(NSInteger)index{ [self performSelector:@selector(setObservationInfo)]; currentIndex = index; AVPlayerItem *videoItem = [AVPlayerItem playerItemWithURL:[NSURL fileURLWithPath:[arrVideoList objectAtIndex:index]]]; }  где нужно проверить,if (currentIndex < [arrVideoList count]-1) { currentIndex++; } else { currentIndex = 0; } [self playVideoAtIndex:currentIndex]; Dhruv

Ваш Ответ

3   ответа
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]];
        }
    }
}
2

наблюдать за каждым игроком в AVQueuePlayer.

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

на каждом следующем видео вставьте currentItem снова, чтобы поставить его в очередь для воспроизведения. убедитесь, что стремитесь к нулю для каждого элемента. после advanceToNextItem AVQueuePlayer удалит currentItem из очереди.

-(void) nextVideo:(NSNotification*)notif {
    AVPlayerItem *currItem = notif.userInfo[@"object"];
    [currItem seekToTime:kCMTimeZero];
    [queuePlayer advanceToNextItem];
    [queuePlayer insertItem:currItem afterItem:nil];
}
Это сработало для меня после измененияnotif.userInfo[@"object"] вnotif.object (iOS 9).
2

Create a queue that is an NSArray of AVPlayerItems. As each item is added to the queue, set up a NSNotificationCenter observer to wake up when the video reaches the end. In the observer's selector, tell the AVPlayerItem that you want to loop to go back the the beginning, then tell the player to play.

(ПРИМЕЧАНИЕ. AVPlayerDemoPlaybackView взят из примера Apple «AVPlayerDemo». Просто подкласс 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;
    }
}

Вот и все! Дайте мне знать, что-то требует дальнейшего объяснения.

Логика здесь не позволяет получить желаемое поведение OP. Зацикливает последний элемент, а не весь массив элементов игрока.
Спасибо, это сработало для меня ..
Что я должен сделать, если я добавлю 3видео в проигрыватель. И после завершения всех 3видео последнее видео будет проигрываться в бесконечном цикле

Похожие вопросы