views:

1009

answers:

7

I have a long movie that I'll be putting in an app, and I wanted to know what the best way to put the user back to the point they left off. Can someone point me in the right direction?

So if the user is watching the film, hit done, is there a notification of the current time or something that I can store and load the instance again with that time?

Thanks!

+2  A: 

This question duplicates or is related to the following other questions here:

To reiterate the answers from those questions, there is no current public API to start a movie at a specific frame or point in time. While there are private APIs available (-currentTime and -setCurrentTime), they are subject to change and will get your app rejected during the approval process.

shek
I think it's unfair to state "they will get your app rejected". If you code carefully you can leverage these things in a safe way, and your app will not get rejected if it has a decent fallback (or at least doesn't crash). There are tons of apps in the store with grey uses of the API.
Kendall Helmstetter Gelner
During the app review process, Apple checks to the use of private APIs. If found to be using a private API, your app will be rejected. While there are certainly apps that make use of private APIs and slip through the review cracks, it should not be recommended to take advantage of private APIs, especially when they could change in a future OS update and cause your app to break.It would not be beneficial to a proposed answer on StackOverflow to recommend the use of any private APIs.
shek
Thanks very much for your help, shek! It's appreciated.
Angelfilm Entertainment
+4  A: 

I've found an OS 3.0 technique that doesn't make use of private API components.

You can register to receive MPAVControllerTimeDidJumpNotification notifications and grab the MPAVControllerTimeParameter NSNumber out of that notification's userInfo Dictionary.

For example, just before you start playback register to receive the notifications:

#define MPAVControllerTimeDidJumpNotification @"MPAVControllerTimeDidJumpNotification"

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleTimeChanged:) name:MPAVControllerTimeDidJumpNotification object:nil];

Then start the movie playing. Add a method that will be called for each time change as the movie plays:

-(void)handleTimeChanged:(NSNotification *)notification
{
    NSDictionary * userInfo = notification.userInfo;
    int lastPositionInSeconds = [[userInfo valueForKey:@"MPAVControllerTimeParameter"] intValue];
    NSLog( @"Last time was %d", lastPositionInSeconds );
}

And when the movie stops playing (you know this by listening for MPMoviePlayerPlaybackDidFinishNotification notifications) stop listening for the MPAVControllerTimeDidJumpNotification notifications.

Jason
Jason, this is great. Extremely helpful.
Angelfilm Entertainment
So to finish up, then you could store the lastPositionInSeconds, in a sql db, and when the user goes back to the video, you could set: moviePlayerController.initialPlaybackTime = lastPositionInSeconds;And that should work fine. Thanks again!
Angelfilm Entertainment
A: 

This is another question in this branch to Jason. Jason, Could you give us a hint to an analogous event, but it should be activated during a movie play back. I need it to make a progress bar that will be displaying current time of the movie.

Thank you!

Slava TLM
A: 

Slava,

I actually watched for all events getting fired by the system during movie playback and didn't see anything else that might help. That MPAVControllerTimeDidJumpNotification does get fired periodically during playback, but not as often as, say, every second. It may get fired for each keyframe, but I'm not sure about that.

Jason
Jason, when I was trying this I noticed that when the user hit the done button, say they're halfway through the video:2009-07-31 10:36:04.297 VideoApp[2398:207] Last time was 522009-07-31 10:36:11.933 VideoApp[2398:207] Last time was 602009-07-31 10:36:11.952 VideoApp[2398:207] Movie ended: Last time was 02009-07-31 10:36:12.597 VideoApp[2398:207] Last time was 0They always seem to get 0 at the end. So there isn't a good way to tell if the movie actually ended, or they hit the done button. Any ideas on how to fix that?
Angelfilm Entertainment
I hadn't correctly stopped listening when I thought I had. I see that you still get one final output before the done notification is called. Thanks again!
Angelfilm Entertainment
+1  A: 
    `NSDictionary * userInfo = notification.userInfo;
    int lastPositionInSeconds = [[userInfo valueForKey:@"MPAVControllerTimeParameter"] intValue];
`// saving an NSInteger
    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
    [prefs setInteger:lastPositionInSeconds forKey:@"currentMovieTime"];

    // getting an NSInteger
     NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
     NSInteger myInt = [prefs integerForKey:@"currentMovieTime"]; // default is zero if nil
        currentMovieTime = myInt;
        self.streamMoviePlayer.initialPlaybackTime = currentMovieTime;

You can use this to set/get the variable and use that to start the movie at the right time. This will work even if the user restarts their phone or restarts the application.

Angelfilm Entertainment
A: 

Hi, great hint. However I added this to the MoviePlayer sample and all I get are notifications at the beginning and the end, so e.g. 0, 22, 0. Nothing inbetween :( Frank

I believe it is based on keyframes, so you should make sure the video you are using has proper keyframes every 30 frames or so, so you'll get the best response from this method.
Angelfilm Entertainment
A: 

This is very useful. However, it seems that if i stop listening for MPAVControllerTimeDidJumpNotification during MPMoviePlayerPlaybackDidFinishNotification, the time is incorrect. Any suggestion on how it should be done?

Dave
You should post follow-up questions as a separate thread, notas an answer. After all, it doesn't really answer *this*question. Also more people would see it and try to answer if you post it asyour own question.
sth