Подтвердить что ты не робот

Правильное отображение и удаление полноэкранного MPMoviePlayerController в iOS 3.2 (iPad)

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

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

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

- (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 view 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];
}

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

4b9b3361

Ответ 1

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

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

    • 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];
}

Ответ 2

Да. Это здорово. Есть действительно уведомления, упомянутые выше...

Тем не менее, нет MPMoviePlayerPlaybackWillFinishNotification несколько позже!!! Это действительно проблема.

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

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

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