OK, so.. on the iPhone you can playback movies and it is very very simple. (i really like how simple it is). However with that simplicity comes some pretty major drawbacks. Most of the drawbacks have to do with the fact that your program has very little control over how the movie gets played back.
And the big one that seems to cause everyone much pain is the fact that you cannot loop your movies. (well, you can.. kinda, but it is fraught with pitfalls and rats nests of code and workarounds..)
a better solution is to provide a movie that is already looped a bunch of times and just play that back.
Wait! Wont that take up huge amounts of oh-so-precious application storage space?! (possibly pushing you over the 10MB over-the-air limit?!)
Not if you do it right.
Thanks to a very clever dev on the apple iphone dev forums, I was able to discover the solution,(and by ‘discover’ i mean I read his post, and then went and tried what he said and it worked) and I am going to repeat it here for anyone who may be using google to find their answers.
First off, let me be clear. I am talking about using the MPMoviePlayerController object to play back a movie. (not some hacked-together frame-animator).
The big problem with looping using the MPMoviePlayerController is that well; you cant. If you have a clip that is, say 10 seconds long, and you play it, you will get a nice fade in effect, the clip will play, and then it will fade out nicely. If you want to loop that clip, then you basically press play right away and it plays again, fading from black again, and making a horrible break in your clip and showing whatever view was behind the movie when you played it. There are some really craptacular workarounds that some people have suggested (and I have tried). Mostly these involve various strategies for using the image from the first frame or last frame and puting it up in a view behind the player so that when it fades out you still see the last frame (so you cant tell that it faded out) and then you can call the player again and it will fade in and play and it is kinda not very seamless in a crappy way.
Ok, so that is the problem. The solution is to provide a self-referencing movie file that has a whole bunch of loops in it. The self-referential movie will only be slightly larger than a single clip of the movie because it is simply referencing the original video material over and over again, so you can make a clip that loops your 10 second video 100 times and is only a few K bigger than the original clip.
How do we do this?
We are going to use Quicktime Player. I am fairly sure that you need to have a pro version of quicktime player for this to work as well (I do, it is only $30, and if you are doing any kind of video for your app, you are probably using FCP or FCPExpress anyway, so you probably have it too)
OK, so you are going to open your movie in Quicktime player. (I am presupposing that your movie is already in a nice iPhone-friendly format). Now you are going to immediately re-save this movie using file-> save as..
and here is the important bit: be sure to check: ‘Save as self contained movie’.
ok, now you will have a version of your movie but with a nice generic .mov extension. and your Quicktime window will look something like:
note the timeline at the bottom. Now hit Command-A to select the entire clip.
then just hit Command-C to copy it to the clipboard.. and then Command – V to paste it as many times as you think appropriate.
(this is 4:31 worth of 6 seconds looped)
then save it, add it to your xCode project and play it like you would your first clip.
Here is the size increase I got:
let’s see here.. 6 seconds into 4:38 is about 46 loops. I got that in about 75k worth of space. not bad really. So each loop takes a little less than 2k. I think that is a fair tradeoff.
OK, so that is great! now you can loop to your heart’s content. However, how do you just play it once? well, I dont have a good answer for that. there are a few things you can do: the easiest is to have a non-looping version and just play that, the second, less-easy is to kick off a timer that stops the playback after a single-play worth of time has gone by.