views:

1202

answers:

2

I'm using the first answer from http://stackoverflow.com/questions/3130363/ios-4-mpmovieplayercontroller

to try and get MPMoviePlayerController to play. In the simulator (iPhone device with iOS4), I hear sound but no video. On the device (iPhone 3GS and iOS4), I don't get anything. Here's my code:

MPMoviePlayerController *moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:moviePath]];
moviePlayer.movieControlMode = MPMovieControlModeDefault;

if ([moviePlayer respondsToSelector:@selector(view)]) {

moviePlayer.controlStyle = MPMovieControlStyleFullscreen; [moviePlayer.view setFrame:self.view.bounds]; [self.view addSubview:moviePlayer.view]; }

[moviePlayer play];

Any ideas what I'm doing wrong?

A: 

For MPMoviePlayerController view is a property, not a method, so you can't use respondsToSelector: on it if it doesn't have methods synthesized or written for it (i.e. is declared @dynamic). Which I think is true for most readonly properties in UIKit.

jshier
Any @property will have a corresponding getter method.
drawnonward
Obviously not, as `respondsToSelector:` will always return false with dynamic properties.
jshier
+1  A: 

I just tested the following code on iOS4 + iPhone 4 (and a 3GS)—it works fine. At first blush, I think your code's problem is not calling setFullscreen:animated on your MPMoviePlayerController instance.

- (void)willEnterFullscreen:(NSNotification*)notification {
    NSLog(@"willEnterFullscreen");
}

- (void)enteredFullscreen:(NSNotification*)notification {
    NSLog(@"enteredFullscreen");
}

- (void)willExitFullscreen:(NSNotification*)notification {
    NSLog(@"willExitFullscreen");
}

- (void)exitedFullscreen:(NSNotification*)notification {
    NSLog(@"exitedFullscreen");
    [self.movieController.view removeFromSuperview];
    self.movieController = nil;
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)playbackFinished:(NSNotification*)notification {
    NSNumber* reason = [[notification userInfo] objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey];
    switch ([reason intValue]) {
        case MPMovieFinishReasonPlaybackEnded:
            NSLog(@"playbackFinished. Reason: Playback Ended");         
            break;
        case MPMovieFinishReasonPlaybackError:
            NSLog(@"playbackFinished. Reason: Playback Error");
            break;
            case MPMovieFinishReasonUserExited:
            NSLog(@"playbackFinished. Reason: User Exited");
            break;
        default:
            break;
    }
    [self.movieController setFullscreen:NO animated:YES];
}

- (void)showMovie {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willEnterFullscreen:) name:MPMoviePlayerWillEnterFullscreenNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willExitFullscreen:) name:MPMoviePlayerWillExitFullscreenNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(enteredFullscreen:) name:MPMoviePlayerDidEnterFullscreenNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(exitedFullscreen:) name:MPMoviePlayerDidExitFullscreenNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:MPMoviePlayerPlaybackDidFinishNotification object:nil];

    NSURL* movieURL =  [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"tron" ofType:@"mov"]];
    self.movieController = [[MPMoviePlayerController alloc] initWithContentURL:movieURL];
    if ([self.movieController respondsToSelector:@selector(view)]) {
        self.movieController.view.frame = self.view.frame;
        [self.view addSubview:movieController.view];
        [self.movieController setFullscreen:YES animated:YES];
    }
    [self.movieController play];
}

// This method is set as the action for an on-screen button
- (void)movieTime:(id)sender {
    [self showMovie];
}
Art Gillespie
Not working on iOS4 with iPhone 3GS. In the debugger, it gets to the self.movieController.view.frame line and skips over the next two.
4thSpace
If I read that correctly, you're saying execution gets to the first line *inside* the if block but skips the next two? Seems highly unlikely. Let me dig out one of our 3GS testing units...
Art Gillespie
... yep, works here with a 3GS running iOS4. One thing that may make a difference is the context—in my app that code is called from an event handler, not in `viewDidLoad`
Art Gillespie
I've edited my original answer with all the related code from the `UIViewController` instance.
Art Gillespie
Thanks. Now when I put your updated code in, I get an error on self.view. The file I'm in is of type NSObject. it is called from a UIView. Does the NSObject file need to create a view to put the video player on? Also, where are you disposing of all the player allocs? I alloc every time a video is played.
4thSpace
All of this code expects to be in a `UIViewController` subclass. If your code is in a subclass of `NSObject`, that's been the problem since the start.
Art Gillespie
Ah. I want to contain all of the movie management to a class. Is there a way to keep it in the class and still be able to use it? Or does it have to get spread out into the UIViewController?
4thSpace
That shouldn't be a problem, just pass the view you want to embed to your movie management class (or provide an accessor that lets other classes get at the movie's view member.)I'm just saying that there is no self.view member if you're not in a subclass of UIViewController and that's why none of my code or your original code is working.
Art Gillespie
Passing view to class works. Thanks.
4thSpace
Do you know of a way I can tests that this will work on iOS3? There isn't a simulator for iOS3 in xcode.
4thSpace