Правильное отображение и отключение полноэкранного MPMoviePlayerController в iOS 3.2 (iPad) - PullRequest
22 голосов
/ 13 июля 2010

У меня возникли проблемы с отображением полноэкранного фильма в приложении для iPad, а затем разрешением пользователю отклонить его с помощью кнопки «Готово» или «не полноэкранного» на элементах управления проигрывателя.

Изначально я использовал MPMoviePlayerViewController для презентации фильма, но я не получал полноэкранные уведомления о входе / выходе от объекта MPMoviePlayerController, поэтому я сам переключился на это.

Я могу сделать фильмотображаются в полноэкранном режиме (хотя переход неактивный), но при нажатии кнопок «Готово» или «не полноэкранный» игрок не предпринимает никаких действий.Я разместил свой код ниже:

- (void)startPlayingMovieWithURLString:(NSString *)movieURLString {
    // I get all of these callbacks **EXCEPT** the "willExitFullScreen:" callback.
    [[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(didFinishPlayback:) name:MPMoviePlayerPlaybackDidFinishNotification object:nil];

    [self.moviePlayerController setContentURL:someExistingURL];

        // "self" is a UIViewController subclass, and is presented as a "fullscreen" modal view controller from its parent
        // I'm setting the movie player's view's frame to take up the full rectangle of my view controller, but really I want the movie to be completely removed when the user presses "done" (that is, removed from the view hierarchy). Not sure when/where to do this.
    self.moviePlayerController.view.frame = self.view.frame;
    [self.view addSubview:self.moviePlayerController.view];
    [self.moviePlayerController setFullscreen:YES animated:YES];

}

А вот код для моего обратного вызова didFinish

- (void)didFinishPlayback:(NSNotification *)notification {
        // This ends up recursively telling the player that playback ended, thus calling this method, thus…well you get the picture.
        // What I'm trying to do here is just make the player go away and show my old UI again.
    [self.moviePlayerController setFullscreen:NO animated:YES];
}

Так что, очевидно, я делаю что-то не так, но я был вверх и вниздокументация, и я не могу понять, как заставить фильм просто уйти.Я подумал, что это будет более интуитивно, чем это.Что я делаю не так?

Ответы [ 2 ]

66 голосов
/ 13 июля 2010

Вот как работают события -> уведомления:

  • Пользователь нажимает кнопку «Готово»

    • MPMoviePlayerWillExitFullscreenNotification
    • MPMoviePlayerDidExitFullscreenNotification
  • Пользователь нажимает кнопку «Оставить полноэкранный» на транспорте

    • MPMoviePlayerWillExitFullscreenNotification
    • MPMoviePlayerDidExitFullscreenNotification
    • Обратите внимание, что воспроизведение не останавливается
  • Фильм подходит к концу

    • MPMoviePlayerPlaybackDidFinishNotification с MPMoviePlayerPlaybackDidFinishReasonUserInfoKey, установленным на MPMovieFinishReasonPlaybackEnded
    • Если вы позвоните setFullscreen:NO animated:YES на свой экземпляр MoviePlayerController из этого уведомления, вы получите уведомления WillExit и DidExit.
    • Обратите внимание, что вы не получите уведомление PlaybackDidFinish, когда пользователь нажимает кнопки Готово или Оставить полноэкранный режим.

Поэтому, как правило, если вы хотите избавиться от представления MoviePlayer, вам нужно поместить [self.moviePlayerController.view removeFromSuperview] в обработчик уведомлений DidExitFullscreen. WillExitFullscreen слишком рано.

Вот мой код:

- (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];
    self.movieController.view.frame = self.view.frame;
    [self.view addSubview:movieController.view];
    [self.movieController setFullscreen:YES animated:YES];
    [self.movieController play];
}
0 голосов
/ 10 ноября 2012

Да. Замечательно. Есть действительно упомянутые выше уведомления ...

Однако, нет никакого MPMoviePlayerPlaybackWillFinishNotification почему-то !!! Это действительно проблема.

Когда вы вызываете проигрыватель фильмов как модальный (независимо от того, какой из следующих методов использовал presentViewController / presentModalViewController / presentVideoController), если вы определили .fullScreen = YES, не ожидается вызов MPMoviePlayerWillExitFullscreenNotification уведомлений вообще (очевидно, поскольку мы не входим / не выходим из полноэкранного режима, а только отображаем / отклоняем контроллер).

Но на самом деле нет никаких уведомлений о том, что видео собирается закончить и закрыть. Это необходимо (помимо любых других возможных ситуаций), чтобы поймать момент, когда начинается переход на увольнение. (Переход, конечно, начинается до вызова MPMoviePlayerPlaybackDidFinishNotification ). И, в то же время, application: supportInterfaceOrientationsForWindow: для ранее показанного контроллера вызывается до уведомления, и нет никакого способа сказать AppDelegate, что наш текущий контроллер должен быть показан уже в другой ориентации.

Итак, поскольку мое видео полноэкранное, а также без каких-либо элементов управления (это своего рода вступление, поэтому я просто пока не закончу) мое решение состояло в том, чтобы просто иметь таймер, который проверяет каждый короткий тик (0,1 секунды) ) какова текущая позиция видео ... и она близка к концу, тогда это момент для моего собственного уведомления.

...