Can anyone suggest a method by which you can achieve a completely smooth and seamless looping of a video clip in iOS? I have tried two methods, both of which produce a smal
To see an example that shows seamless looping of a background video (from an animated GIF) and switching between a pair of foreground character animations (with alpha channel), have a look at seamless-video-looping-on-ios. I tried to use AVPlayer in the past and had to give up on AVPlayer related solutions as they did not work well enough. See this SO question also iphone-smooth-transition-from-one-video-to-another.
I just got this working on my iPad 3 running iOS 5.1.1, base SDK iOS 5.1
When setting up the movie player, set the repeat mode to MPMovieRepeatModeNone then add the notification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(moviePlayerDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:self.moviePlayer];
Then set up your selector to filter when the movie finishes playing
- (void)moviePlayerDidFinish:(NSNotification *)note {
if (note.object == self.moviePlayer) {
NSInteger reason = [[note.userInfo objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey] integerValue];
if (reason == MPMovieFinishReasonPlaybackEnded) {
[self.moviePlayer play];
}
}
}
Apple made some large changes to how the MPMoviePlayerController handles loading movie files when they changed from iOS 4 to iOS 5, so I do not know if this method will work when they release iOS 6
I investigated the same problem as reported by the original poster (small pause in the loop that was breaking the seamlessness). By luck I had another video sample that didn't had this behavior and found the explanation/different only later:
The sound track.
I suspect a very slow sound initialisation (routing?).
Removing the sound track was the easiest solution for me (no sound needed) but I will have to dig further (audio mixing options and testing the solution that have been posted in this thread).
Eric
To avoid the gap when the video is rewound, using multiple copies of the same asset in a composition worked well for me.
AVURLAsset *tAsset = [AVURLAsset assetWithURL:tURL];
CMTimeRange tEditRange = CMTimeRangeMake(CMTimeMake(0, 1), CMTimeMake(tAsset.duration.value, tAsset.duration.timescale));
AVMutableComposition *tComposition = [[[AVMutableComposition alloc] init] autorelease];
for (int i = 0; i < 100; i++) { // Insert some copies.
[tComposition insertTimeRange:tEditRange ofAsset:tAsset atTime:tComposition.duration error:nil];
}
AVPlayerItem *tAVPlayerItem = [[AVPlayerItem alloc] initWithAsset:tComposition];
AVPlayer *tAVPlayer = [[AVPlayer alloc] initWithPlayerItem:tAVPlayerItem];
I can concur @SamBrodkin's findings.
[[NSNotificationCenter defaultCenter]
addObserver: self
selector: @selector(myMovieFinishedCallback:)
name: MPMoviePlayerPlaybackStateDidChangeNotification
object: m_player];
and
-(void) myMovieFinishedCallback: (NSNotification*) aNotification
{
NSLog( @"myMovieFinishedCallback: %@", aNotification );
MPMoviePlayerController *movieController = aNotification.object;
NSLog( @"player.playbackState = %d", movieController.playbackState );
}
fixed the non-looping issue on iOS 5 for me too.