Looping movie playback on the iPhone

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?!)

Well.. no.

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..
picture-27

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:

picture-28

note the timeline at the bottom. Now hit Command-A to select the entire clip.

picture-29

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)
picture-30

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:

beforeafter

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.

This entry was posted in code, iPhone. Bookmark the permalink.

14 Responses to Looping movie playback on the iPhone

  1. intw7 says:

    MPMoviePlayerController is very limited in use, even with loops. you still can not set the position, pause, or disable movie audio or use your own sound. it is better to extract the images from a movie, then use a looped image hack.

  2. jmclaren says:

    I tried this, and when I cut and paste the movie, I get a movie file twice the size, whether I use mov or m4v format. What Encoding did you use? I am using the pc version of qtp.

  3. Ben says:

    Hey jmclaren,

    hmm.. that is a good question.. as far as encodeing, the movie started out as m4v, and when i saved as a self contained movie, it ends up with a .mov (tho, presumably it is still m4v under the covers)

    I guess the only advice I could give is be sure to follow the steps precisely, and if that still doesn’t work, try it on your mac. (presuming you have access to a mac if you are doing iPhone work)

    That probably is not very helpful :-) good luck!
    -B

  4. earblast says:

    Hi

    I’m able to do as you suggest, however, mediaplayer does not support a .mov file. So I wasn’t able to get the movie to play. Did your test case play on the iPhone?

    THANKS

  5. Ben says:

    Hey Earblast,

    .mov is just a generic wrapper, what matters is what compression your movie is using under that. just change the extension to m4v and see how that works. (presuming you are using m4v to start with)

    Cheers!
    -B

  6. Ben says:

    Hey Earblast,

    I just went and double checked my code, and i just left them as .mov files, and they worked fine. As I mentioned, they started out as m4v, i went through the process described above, and ended up with .mov files and they work just fin in the media player.

    good luck!
    -B

  7. earblast says:

    Hey

    I just tried again and it worked great – brilliant and THANKS!

  8. satori425 says:

    I just tried this as well – and would like to say thanks!

    I’ve been trying to figure this out for a while, you came up with a surprisingly elegant workaround here.

  9. Ben says:

    Hey Satori!

    Thanks for the nice comments! Although I did not come up with this solution, that honor remains with the developer on the Apple Dev Forums that I got the idea (and most of the instructions) from. I am not posting his name because that site is all confidential and stuff, but he(or she) deserves the credit :-) I merely re-posted out here in the public world so that google can find it :-)

    Cheers!
    -ben

  10. crunchie says:

    Ben.

    I had high hopes for your method, but I am pretty sure that the reason your movie didn’t get any bigger is because of the source material used. The picture above shows essentially a 2 colour movie which could be massively compressed. Using a movie with audio and a lot of colors / animation saw my movie going from 0.7seconds (1.9mb) to just over 4:28mins (69.89mb) if you do the math, it appears that the source is simply duplicated.

    Back to the drawing board for me :S

  11. Ben says:

    Hey Crunchie,

    I think you may have missed a step somewhere in there. I will totally admit to probably not explaining it perfectly, but I have used this technique with full motion, high quality audio, etc.. with similar results. (ie a fractional increase in size for each loop added)

    I do know that my screenshots are from a now very obsolete version of quicktime, but the basics are the same. (and I think that you can do it now without a ‘pro’ version of quicktime player, if there even is such a thing anymore.

    Cheers and good luck!
    -B

  12. crunchie says:

    Ben,

    Do you have any examples of a high quality movie that you have done this with please? I have tried repeatidly, going over your steps as carefully as possible, but everytime the movie gets much bigger

  13. drthompsen says:

    In version 3.2 of the SDK, the MPMoviePlayerController class includes a new constant, MPMovieRepeatMode, which looks like it could be set to repeat a video. Have you had a chance to play with this yet?

  14. Ben says:

    DrThompsen,

    I havent had a chance to play with that yet, I would be interested to know if it handles it seamlessly (like a straight cut) or does some fade in/out jiggery-pokery :-)

    Also, I should mention with respect to Crunchie’s comments above, I did just do this, and I realized that the process has changed slightly. After going through the process above you end up with files that are in mp4 format but are labeled with the generic .mov extension. These will NOT play on the device (which is lame) however, just change the extension to .m4v and they work fine.

    Cheers!
    -B

Leave a Reply