1. Implement SHBQueuePlayer third party class 
you can download from github:
https://github.com/jiutianhuanpei/SHBQueuePlayer

2. Implement AVPlayerViewController class 

3. The below function is used for set urls for play video.

- (void)setUrls:(NSMutableArray *)urls index:(NSInteger)index
{
    [_playedUrls removeAllObjects];
    [_nextUrls removeAllObjects];
    
    if (urls.count == 0 || urls == nil) {
        [_qPlayer removeAllItems];
        return;
    }
    
    if (index > urls.count) {  
        index = urls.count;
    }
    
    [_playedUrls addObjectsFromArray:[urls subarrayWithRange:NSMakeRange(0, index)]];
    [_nextUrls addObjectsFromArray:[urls subarrayWithRange:NSMakeRange(index, urls.count - index)]];
    [_qPlayer removeAllItems];
    _arrCurrVideos = [NSMutableArray arrayWithArray:urls];
    
    [self createMutableCompositionWithUrls:urls];
    
}

4. Implement AVMutableComposition for adding the videos one after another to resolve the black screen between two videos in Play All.

//  avset ---> avplateritem ----> avplayer
-(void)createMutableCompositionWithUrls:(NSMutableArray *)urls
{
    if (playerTimer)
        [playerTimer invalidate];
    
    if (mixComposition) {
        mixComposition = nil;
        videoTrack = nil;
        audioTrack = nil;
    }
    
    mixComposition = [[AVMutableComposition alloc] init];
    
    videoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo
                                                                        preferredTrackID:kCMPersistentTrackID_Invalid];
    audioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio
                                                                        preferredTrackID:kCMPersistentTrackID_Invalid];
    
    arrVideoDurations = [[NSMutableArray alloc]init];
    
    insertTime = kCMTimeZero;

    for (id object in urls)
    {
        NSDictionary *options = @{AVURLAssetPreferPreciseDurationAndTimingKey:@YES};
        AVURLAsset *asset = [AVURLAsset URLAssetWithURL:object options:options];
        
        
        AVAssetTrack *videoAsset = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
        
        CMTimeRange timeRange = CMTimeRangeMake(kCMTimeZero, videoAsset.timeRange.duration);
        
        [videoTrack insertTimeRange:timeRange
                            ofTrack:videoAsset
                             atTime:insertTime
                              error:nil];
        
        [audioTrack insertTimeRange:timeRange
                            ofTrack:[[asset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]
                             atTime:insertTime
                              error:nil];
        
        insertTime = CMTimeAdd(insertTime,asset.duration);
        [arrVideoDurations addObject:[NSString stringWithFormat:@"%f",CMTimeGetSeconds(insertTime)]];

    }
    
//    CMTime videoDuration;
    videoComposition = [[AVPlayerItem alloc] initWithAsset:mixComposition];
    if (_qPlayer.items > 0)
    {
        [_qPlayer replaceCurrentItemWithPlayerItem:videoComposition];
    }
    else
    {
        if ([_qPlayer canInsertItem:videoComposition afterItem:nil])
        {
            [_qPlayer insertItem:videoComposition afterItem:nil];
        }
    }
    if (_currMovieTime.value != 0)
    {
        [videoComposition seekToTime:_currMovieTime];
        [self showIntialLabel];
    }
    else
    {
        currIndex = 0;
    }
    [self play];

    dispatch_async(dispatch_get_main_queue(), ^{
        [self resetTimer];
    });
}

// 

//updateVideoLabel - This is for update information which is display on custom view where we play video
-(void)updateVideoLabel
{
    if (_isPlaying == true) {
//        NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
//        numberFormatter.numberStyle = NSNumberFormatterDecimalStyle;
        NSLog(@"Value of currIndex %d",currIndex);
        NSLog(@"Total values is array: %lu",(unsigned long)arrVideoDurations.count);
        float value;
        if(currIndex value)
            {
                NSLog(@"Label changed");
                
                dispatch_async(dispatch_get_main_queue(), ^{
                    if ([_delegate respondsToSelector:@selector(queuePlayerEndPlayed:)])
                    {
                        if (isRestarted) {
                            [_delegate queuePlayerEndPlayed:0];
                            isRestarted = false;
                        }
                        else
                        {
                            currIndex++;
                            [_delegate queuePlayerEndPlayed:currIndex];
                        }
                        NSLog(@"Label changed in movie ***** updateVideoLabel *******");

                    }
                });
              
            }
        }
        NSLog(@"Current video start time: %f Player time value: %f",value,CMTimeGetSeconds(videoComposition.currentTime));
    }
}

//playerItemDidEndPlay - called when one movie gets play Completed
- (void)playerItemDidEndPlay:(NSNotification *)tifi {
    _isPlaying = false;
    NSLog(@"Player did complete movie");
    if ([ServerConnection sharedConnection].isPlaying) {
        
        [self stopTimer];
        _currMovieTime = kCMTimeZero;
        currIndex = 0;
        isRestarted = YES;
        if ([_delegate respondsToSelector:@selector(queuePlayerEndPlayed:)])
        {
            NSLog(@"Label changed in movie ***** playerItemDidEndPlay*******");
            [_delegate queuePlayerEndPlayed:0];
        }
        if (_arrCurrVideos.count  %f",CMTimeGetSeconds(videoComposition.currentTime));
                [self play];
            });
        }
       
        
    }
}

// Show Initial Label
-(void)showIntialLabel
{
    int currVideo = 0;
    NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
    numberFormatter.numberStyle = NSNumberFormatterDecimalStyle;
    
//    @try {
    
        for (int i = 0; i < arrVideoDurations.count; i++) {
            
            if(currVideo value)
                {
                    if ([_delegate respondsToSelector:@selector(queuePlayerEndPlayed:)])
                    {
                        NSLog(@"Label changed in movie ***** showIntialLabel *******");

                        [_delegate queuePlayerEndPlayed:currVideo];
                        return;
                    }
                    currVideo++;
                }
            }
        }
}


//reset Timer
-(void)resetTimer
{
    //for changing video players
    playerTimer = [NSTimer scheduledTimerWithTimeInterval:0.1
                                                   target:self
                                                 selector:@selector(updateVideoLabel)
                                                 userInfo:nil
                                                  repeats:YES];
    NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
    [runLoop addTimer:playerTimer forMode:NSDefaultRunLoopMode];
    
}

//Stop Timer
-(void)stopTimer
{
    if (playerTimer) {
        [playerTimer invalidate];
    }
}


You may also like

Leave a Reply