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