AVQueuePlayer: completes the last item in the queue (and removes the hiccups) or loop the last seconds of the video
I am using AVQueuePlayer to play videos sequentially (although I have hiccups between games). Now I would like to:
1) Complete the last element in this sequence (not complete).
2) That being said, I would also like to eliminate the hiccups.
Below is my code to play the video sequence. How could I achieve my 2 goals?
[super viewDidLoad];
NSString *secondVideoPath = [[NSBundle mainBundle] pathForResource:@"vid_1" ofType:@"mov"];
NSString *firstVideoPath = [[NSBundle mainBundle] pathForResource:@"vid_2" ofType:@"mov"];
AVPlayerItem *firstVideoItem = [AVPlayerItem playerItemWithURL:[NSURL fileURLWithPath:firstVideoPath]];
AVPlayerItem *secondVideoItem = [AVPlayerItem playerItemWithURL:[NSURL fileURLWithPath:secondVideoPath]];
queuePlayer = [AVQueuePlayer queuePlayerWithItems:[NSArray arrayWithObjects:firstVideoItem, secondVideoItem,nil]];
AVPlayerLayer *layer = [AVPlayerLayer playerLayerWithPlayer:queuePlayer];
avPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;
layer.frame = CGRectMake(0, 0, 1024, 768);
[self.view.layer addSublayer:layer];
[queuePlayer play];
Another method I am thinking of is playing a lengthy video and looping the last few seconds. Perhaps I could have avoided the hiccups too. Will this approach be achievable? If so, how to adapt the code below (which plays 1 video)?
[super viewDidLoad];
NSString *filepath = [[NSBundle mainBundle] pathForResource:@"vid_long" ofType:@"mov"];
NSURL *fileURL = [NSURL fileURLWithPath:filepath];
avPlayer = [AVPlayer playerWithURL:fileURL];
AVPlayerLayer *layer = [AVPlayerLayer playerLayerWithPlayer:avPlayer];
avPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;
layer.frame = CGRectMake(0, 0, 1024, 768);
[self.view.layer addSublayer: layer];
[avPlayer play];
source to share
Here is a solution to play video in a loop: -
queuePlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;
int k=0;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(itemPlayEnded:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[queuePlayer currentItem]];
- (void)itemPlayEnded:(NSNotification *)notification
{
k++;
if(k<10-15 times)
{
AVPlayerItem *p = [notification object];
[p seekToTime:kCMTimeZero];
}
}
Edited answer: - The above answer reproduces the same files, but it works for me. It plays the last added file in a loop:
- (void)itemPlayEnded1:(NSNotification *)notification
{
NSString *secondVideoPath = [[NSBundle mainBundle] pathForResource:@"video2" ofType:@"mp4"];
k=0;
AVPlayerItem *secondVideoItem = [AVPlayerItem playerItemWithURL:[NSURL fileURLWithPath:secondVideoPath]];
// AVPlayerItem *p = [notification object];
NSMutableArray *currentItemArray = [NSMutableArray arrayWithObjects:secondVideoItem,nil];
AVQueuePlayer* queuePlayer = [[AVQueuePlayer alloc] initWithItems:currentItemArray];
[queuePlayer play];
queuePlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;
AVPlayerLayer *layer = [AVPlayerLayer playerLayerWithPlayer:queuePlayer];
avPlayer.actionAtItemEnd = AVPlayerItemStatusReadyToPlay;
layer.frame = CGRectMake(0, 0, 1024, 768);
[self.view.layer addSublayer:layer];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(itemPlayEnded:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[queuePlayer currentItem]];
}
source to share
The best way I could find is this
watch every player in AVQueuePlayer.
queuePlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;
for(AVPlayerItem *item in items) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(nextVideo:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:item ];
}
in each nextVideo, re-insert currentItem to queue it for playback. don't forget to find zero for each item. after advanceToNextItem AVQueuePlayer will remove currentItem from queue. we just paste.
-(void) nextVideo:(NSNotification*)notif {
AVPlayerItem *currItem = notif.userInfo[@"object"];
[currItem seekToTime:kCMTimeZero];
[queuePlayer advanceToNextItem];
[queuePlayer insertItem:currItem afterItem:nil];
}
source to share
The only way I've found this actually reliable is to use Apple's Use AVQueuePlayer to demonstrate loop playback . You need to add your own code to play the initial video and then loop over another, but this method works better than any other I've tried.
source to share