Skip to main content

iOS Dev: Dismissing MPMoviePlayerViewController

Image

If you have used the MPMoviePlayerViewController to play videos in iOS, chances are you have gotten a little frustrated by its rigidness. A couple of issues I personally encountered were:
  • When presented modally, the view controller did not respect the modal transition style I had chosen for it.
  • When the video finished playing, the view controller dismissed itself automatically. I wanted it to remain visible until the user pressed the Done button.
A couple of hours of browsing for the solution to no avail, I decided to try out sort of a hack, which turned out to work great.
 The trick is to remove the MPMoviePlayerViewController instance from the MPMoviePlayerPlaybackDidFinishNotification notification observers, and instead handle it yourself. Seems like this view controller listens to this notification and auto dismisses itself when it’s fired.
In my application, I present a thumbnail of the video. When touched, the video is played.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
- (void)playVideo:(NSString*)aVideoUrl
{
    // Initialize the movie player view controller with a video URL string
    MPMoviePlayerViewController *playerVC = [[[MPMoviePlayerViewController alloc] initWithContentURL:[NSURLURLWithString:aVideoUrl]] autorelease];

    // Remove the movie player view controller from the "playback did finish" notification observers
    [[NSNotificationCenterdefaultCenter] removeObserver:playerVC
                                                    name:MPMoviePlayerPlaybackDidFinishNotification
                                                  object:playerVC.moviePlayer];

    // Register this class as an observer instead
    [[NSNotificationCenterdefaultCenter] addObserver:self
                                             selector:@selector(movieFinishedCallback:)
                                                 name:MPMoviePlayerPlaybackDidFinishNotification
                                               object:playerVC.moviePlayer];

    // Set the modal transition style of your choice
    playerVC.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;

    // Present the movie player view controller
    [selfpresentModalViewController:playerVC animated:YES];

    // Start playback
    [playerVC.moviePlayer prepareToPlay];
    [playerVC.moviePlayer play];
}
In the code above, an instance of MPMoviePlayerViewController is created, and then removed from the observers of the MPMoviePlayerDidFinishNotification immediately; in its place, the current class is added as an observer, with a selector named movieFinishedCallback: (described below).
In addition, the modalTransitionStyle property of the view controller is set. The documentation suggests you to use the presentMoviePlayerViewControllerAnimated method to present it, in order to use the standard movie player transition. But if you want to use different transition, you must use the regular presentModalViewController method.
Back to the observer notification. Now that the view controller is no longer an observer, it won’t dismiss itself, ever, even if the Done button is pressed. So you must implement the code to dismiss it.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- (void)movieFinishedCallback:(NSNotification*)aNotification
{
    // Obtain the reason why the movie playback finished
    NSNumber*finishReason = [[aNotification userInfo] objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey];

    // Dismiss the view controller ONLY when the reason is not "playback ended"
    if([finishReason intValue] != MPMovieFinishReasonPlaybackEnded)
    {
        MPMoviePlayerController *moviePlayer = [aNotification object];

        // Remove this class from the observers
        [[NSNotificationCenterdefaultCenter] removeObserver:self
                                                        name:MPMoviePlayerPlaybackDidFinishNotification
                                                      object:moviePlayer];

        // Dismiss the view controller
        [selfdismissModalViewControllerAnimated:YES];
    }
}
In my case, my original problem was that I wanted the video to stay visible until the user deliberately pressed the Done button. In the code above, the notification’s “playback finished reason” is examined: if the video playback ended normally, then the notification is ignored; if the video playback ended for another reason (i.e. an error or the user exited), then the view controller is dismissed.
As an added bonus, by dismissing the view controller using the dismissModalViewControllerAnimated: method, the modal transition style set earlier is respected.
The code is kinda messy, but I hope you get the idea. Perhaps it would be desirable to encapsulate this code by extending the MPMoviePlayerViewController class.
Reference Source : Here
Image
Thanks :)
KeepCoding:)


Comments

Popular posts from this blog

WPF-MVVM: RelayCommand Implementation

In WPF if we are implementing MVVM pattern then we need to play with Command rather than Events. You can use ICommand interface to create each command class. Implementation of ICommand in a class gives you CanExecute(), Execute() methods which take part in the action performed by Command.   Rather than making Command Class for each Command we can implement a generic Relay Command to get Command. Below is a RelayCommand class that we will implement.   ///   <summary>      ///  To register commands in MMVM pattern      ///   </summary>      class   RelayCommands  :  ICommand     {          readonly   Action < object > _execute;          readonly   Predicate < object > _canExecute;  ...

.Net List with Changed event

Sometimes we need a List which can notify user when an item is added. Here is the way that you can implement a generic ArrayList which notifies user at the time of an element is added.   using  System; using  System.Collections; namespace  ArchiveData.Logging {    // A delegate type for hooking up change notifications.    public   delegate   void   ChangedEventHandler ( object  sender,  EventArgs  e);    public   class   ListWithChangedEvent  :  ArrayList   {      // An event that clients can use to be notified whenever the      // elements of the list change.      public   event   ChangedEventHandler  Changed;      public   object  NewlyAddedItem {...

What is DispatcherTimer in wpf?

DispatcherTimer When you want to set a timer working with GUI, you always come across threading problem. The problem is that if you want to send some changes to UI that is constantly/continuously changing then that will make your UI unresponsive or in other words it will hang your UI.   To overcome from this situation, WPF gives us DispatcherTimer threading functionality that will take care of such continuously changing processing on UI thread and that will not hang your UI. We can accomplish same scenario in Win Form , through System.Windows.Forms.Timer and in WPF it is System.Windows.Threading.DispatcherTimer .   Difference between DispatcherTimer and Regular timer (System.Timers.Timer) DispatcherTimer is the regular timer. It fires its Tick event on the UI thread, you can do anything you want with the UI. System.Timers.Timer is an asynchronous timer, its Elapsed event runs on a thread pool thread. You have to be very careful in your event handler...