MPMoviePlayerController вызывает вспышку черного цвета в начале видео

Фильм воспроизводится нормально, но прямо перед воспроизведением появляется быстрая черная вспышка. Является ли это причудой, вызванной установкой стиля управления в MPMovieControlStyleNone?

NSString *url = [[NSBundle mainBundle] pathForResource:@"00" ofType:@"mov"];
MPMoviePlayerController *player = [[MPMoviePlayerController alloc] 
    initWithContentURL:[NSURL fileURLWithPath:url]];

[[NSNotificationCenter defaultCenter]
    addObserver:self
    selector:@selector(movieFinishedCallback:)
    name:MPMoviePlayerPlaybackDidFinishNotification
    object:player];

//---play video in implicit size---
player.view.frame = CGRectMake(80, 64, 163, 246);
[self.view addSubview:player.view];

// Hide video controls
player.controlStyle =  MPMovieControlStyleNone;

//---play movie---
[player play];

person Marsman    schedule 18.11.2010    source источник


Ответы (8)


У меня только что была эта проблема, и я исправил ее, добавив наблюдателя в NSNotificationCenter по умолчанию, чтобы узнать, когда фильм был полностью готов к воспроизведению, а ЗАТЕМ добавив представление в качестве подвида к моему основному представлению.

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkMovieStatus:) name:MPMoviePlayerLoadStateDidChangeNotification object:nil];

...

if(moviePlayer.loadState & (MPMovieLoadStatePlayable | MPMovieLoadStatePlaythroughOK))
{
    [pageShown.view addSubview:moviePlayer.view];
    [moviePlayer play];
}
person Marty    schedule 03.07.2012
comment
Я думал о чем-то подобном, спасибо за быстрое отслеживание моих идей... все остальные приведенные выше предложения не работают для моего устаревшего кода, +1 ~!! - person dklt; 18.07.2012
comment
хотя, может быть, было бы лучше сначала вызвать play, а затем добавить подвид? Я не знаю, достаточно ли задержки после того, как игра объявлена, и поможет ли это. - person Marty; 19.07.2012
comment
Это работает? Я пробовал это 2 раза, и это не работает для меня. - person coolcool1994; 14.08.2015
comment
вам нужно вызвать prepareToPlay, чтобы фактически получить MPMoviePlayerLoadStateDidChangeNotification (изменить с iOS6?) - person Lorenz03Tx; 27.07.2016

В mpmoviewplayer для iOS 6 добавлено новое свойство: readyForDisplay.

это то, с чем я играю, и пока все хорошо:

  1. создать mpmovieplayer, добавить на сцену, скрыть его.
  2. добавить уведомление о состоянии воспроизведения на movieController
  3. подождите, пока displayState изменится, и когда он будет готов, покажите видеоконтроллер:

    - (void)moviePlayerPlayState:(NSNotification *)noti {
    
    if (noti.object == self.movieController) {
    
        MPMoviePlaybackState reason = self.movieController.playbackState;
    
         if (reason==MPMoviePlaybackStatePlaying) {
    
                 [[NSNotificationCenter defaultCenter] removeObserver:self name: MPMoviePlayerPlaybackStateDidChangeNotification object:nil];
    
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
    
                while (self.movieController.view.hidden)
                {
                    NSLog(@"not ready");
                    if (self.movieController.readyForDisplay) {
    
                     dispatch_async(dispatch_get_main_queue(), ^(void) {
                         NSLog(@"show");
                         self.movieController.view.hidden=NO;
                     });
    
                    }
                    usleep(50);
                }
            });
         }
    
    }
    

    }

Когда состояние воспроизведения изменяется на MPMoviePlaybackStatePlaying, мы начинаем проверять изменение readyDisplayState.

person yeahdixon    schedule 18.10.2013

Очевидно, в прямоугольнике фильма появляется черная вспышка, пока фильм не загрузится достаточно, чтобы можно было начать воспроизведение. Вот мой обходной путь:

  1. Создайте UIImageView и поместите в него MPMoviePlayerController. Таким образом, вы можете установить альфа на 0.

  2. Как только вы позвоните [player play]; чтобы воспроизвести видео, установите таймер на 0,5 секунды.

  3. Когда время закончится, измените альфу на 1.

Это сделает игрока невидимым на 1/2 секунды (что скрывает черную вспышку).

person Marsman    schedule 03.12.2010
comment
У меня тоже была эта проблема. Но это решение сложное, поскольку вы не знаете, сколько времени MPMobilePlayerController требуется для рендеринга видео. Таким образом, он скроет, конечно, черную вспышку, а также начало видео. Лучший ответ: stackoverflow.com/a/28079496/2327367 - person LastMove; 09.09.2015

Создать видео без addSubview и инструкции по воспроизведению:

    NSString *filepath   =   [[NSBundle mainBundle] pathForResource:@"video" ofType:@"mp4"];
    NSURL    *fileURL    =   [NSURL fileURLWithPath:filepath];
    MPMoviePlayerController *moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:fileURL];
    [moviePlayerController.view setFrame:CGRectMake(80, 64, 163, 246)];
    moviePlayerController.controlStyle = MPMovieControlStyleNone;

Подготовьте видео к воспроизведению и добавьте уведомление:

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkMovieStatus:) name:MPMoviePlayerLoadStateDidChangeNotification object:nil];
    [moviePlayerController prepareToPlay];

Создайте функцию checkMovieStatus с инструкциями addSubview и воспроизведения:

- (void)checkMovieStatus:(NSNotification *)notification {
    if(moviePlayerController.loadState & (MPMovieLoadStatePlayable | MPMovieLoadStatePlaythroughOK)) {
        [self.view addSubview:moviePlayerController.view];
        [moviePlayerController play];
    }
}
person Alessandro Pirovano    schedule 04.12.2013
comment
вам нужно вызвать prepareToPlay, чтобы получить обратный вызов MPMoviePlayerLoadStateDidChangeNotification (изменить с iOS6?) - person Lorenz03Tx; 27.07.2016

Или просто измените цвет представления, это то, что вы на самом деле видите...

player.view.backgroundColor = [UIColor colorWithRed:1 зеленый:1 синий:1 альфа:0];

person ddeaco    schedule 17.07.2011
comment
Я использовал [UIColor clearColor], который делает то же самое, и он работал отлично. Теперь я вижу UIImageView, который у меня был в фоновом режиме, и нет черной вспышки. - person christophercotton; 14.10.2011

Я считаю, что черная вспышка может быть связана со свойством movieSourceType MPMoviePlayerController.

Если вы не установите его, по умолчанию используется значение MPMovieSourceTypeUnknown, что приводит к задержке пользовательского интерфейса до загрузки файла.

Попробуйте добавить эту строку:

player.movieSourceType = MPMovieSourceTypeFile;

Сразу после инициализации плеера.

person talkol    schedule 19.06.2012
comment
установка для movieSourceType значения MPMovieSourceTypeFile не помогает - person RainChen; 30.06.2014
comment
Я уже использовал SourceType, но чтобы избежать черного экрана, нужно поставить его сразу после инициализации плеера. Спасибо! - person danielsalare; 17.07.2015

Чтобы избежать черной вспышки, используйте MPMoviePlayerViewController вместо MPMoviePlayerController. Я думаю, что этот класс создает фон при отображении, а не при загрузке видео (как это делает MPMoviePlayerController).

Перед добавлением moviePlayerViewController.moviePlayer.view в представление отображения вам необходимо добавить белое подпредставление (или подпредставление, подходящее для вашего контента) в backgroundView, например:

[moviePlayerViewController.moviePlayer.view setFrame:[displayView bounds]];

UIView *movieBackgroundView = [[UIView alloc] initWithFrame:[displayView bounds]];
movieBackgroundView.backgroundColor = [UIColor whiteColor];
[moviePlayerViewController.moviePlayer.backgroundView addSubview:movieBackgroundView];
[movieBackgroundView release];
person Ricardo Sanchez-Saez    schedule 24.04.2012

Хорошее решение здесь http://joris.kluivers.nl/blog/2010/01/04/mpmovieplayercontroller-handle-with-care/ с iOS 6 нужно использовать [self.moviePlayer prepareToPlay]; и поймать MPMoviePlayerReadyForDisplayDidChangeNotification для использования [self.moviePlayer play];

person user2557885    schedule 25.09.2014
comment
Это было решением для меня. Использование правильного события кажется правильным способом решить эту проблему, я напишу учебник и опубликую его здесь о том, как это реализовать. - person newshorts; 05.08.2015
comment
ОБНОВЛЕНИЕ — вот ссылка на руководство, объясняющее это более подробно: iwearshorts.com /блог/ - person newshorts; 05.08.2015