I am trying to start a new video with no delay as soon as the first video ends. I tried using the AVQueuePlayer but there is some delay when the first video ends and the second starts.
I need this to be sample synchronous. ie if video 1 is 10.25 seconds long then when I have been playing for 11.5 seconds video 2 should be 1.25 seconds in.
I have been experimenting with keeping 3 AVPlayer objects where I preRoll each player using the same master clock. I am then trying to intercept the AVPlayerItemDidPlayToEndTimeNotification
and then calling setRate:time:atHostTime:
to start the next video going. However I'm not getting any video playing.
I pre-roll my videos using the following code:
- (void) preRollPlayer: (AVPlayer*) pPlayer withMasterClock: (CMClockRef) masterClock atTime: (NSTimeInterval) time
{
[pPlayer setRate: 0.0f];
[pPlayer play];
[pPlayer seekToTime: CMTimeMakeWithSeconds( time, 1000000 ) toleranceBefore: kCMTimeZero toleranceAfter: kCMTimeZero];
[pPlayer setMasterClock: masterClock];
__block volatile int32_t completed = 0;
[pPlayer prerollAtRate: 1.0f completionHandler: ^( BOOL finished )
{
OSAtomicIncrement32( &completed );
}];
while( completed == 0 )
{
[NSThread sleepForTimeInterval: 0.01];
}
}
I then call preRoll as follows:
if ( pAudioVideoEntry.beforeVideoReader )
{
[self preRollPlayer: pAudioVideoEntry.beforeVideoReader.player withMasterClock: hostClock atTime: currentTime];
}
{
[self preRollPlayer: pAudioVideoEntry.videoReader.player withMasterClock: hostClock atTime: currentTime];
}
if ( pAudioVideoEntry.afterVideoReader )
{
[self preRollPlayer: pAudioVideoEntry.afterVideoReader.player withMasterClock: hostClock atTime: currentTime];
}
I finally start the video as follows:
[pAudioVideoEntry.beforeVideoReader.player setRate: 1.0f time: kCMTimeZero atHostTime: syncTime];
pAudioVideoEntry.playingPlayer = pAudioVideoEntry.beforeVideoReader.player;
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector( beforeVideoEnded: )
name: AVPlayerItemDidPlayToEndTimeNotification
object: pAudioVideoEntry.beforeVideoReader.playerItem];
What is odd is that I do not hear the audio, the notification is never sent and every call to my AVPlayerItem
's output AVPlayerItemVideoOutput
's hasNewPixelBufferForItemTime
returns false. So I'm guessing the video has not started. Any ideas why?