最后一次在AVQueuePlayer中重播项目

我需要在我的AVQueuePlayer创建类似无限循环的AVQueuePlayer 。 特别是,我想在最后一个组件完成播放后重播AVPlayerItem的整个NSArray

我必须承认,我实际上并不知道如何实现这一点,并希望你能给我一些线索。


这是从头开始。 这些组件是:

  • 创建一个是AVPlayerItems的NSArray的队列。
  • 当每个项目被添加到队列中时,设置一个NSNotificationCenter观察者以在视频到达结束时唤醒。
  • 在观察者的选择器中,告诉AVPlayerItem你想循环回去开始,然后告诉玩家玩。
  • (注意:AVPlayerDemoPlaybackView来自Apple的“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;
        }
    }
    

    而已! 让我知道一些事情需要进一步的解释。


    在AVQueuePlayer中循环视频序列的最佳方式。

    观察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];
    }
    

    我想出了一个解决方案来循环播放视频队列中的所有视频,而不仅仅是一个。 首先我初始化了我的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]];
            }
        }
    }
    
    链接地址: http://www.djcxy.com/p/60749.html

    上一篇: Replay items in AVQueuePlayer after last

    下一篇: Does the android dalvik vm use escape analysis optimization?