MPMoviePlayerController переключения фильмов вызывает белую вспышку - PullRequest
8 голосов
/ 30 декабря 2010

У меня есть небольшой UIView, который отображает повторяющийся фильм. Когда пользователь нажимает кнопку, другой фильм загружается и отображается в том же UIView.

Проблема заключается в том, что между удалением первого фильма и отображением второго происходит "секундная" вспышка ". Есть ли, чтобы удалить это?

- (void) setUpMovie:(NSString*)title {
NSString *url = [[NSBundle mainBundle] pathForResource:title ofType:@"mp4"];

MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:url]];
[[player view] setFrame:self.movieView.bounds];
[self.movieView addSubview:player.view];
if ([title isEqualToString:@"Bo_idle_02"]) {
    [player setRepeatMode:MPMovieRepeatModeOne];
} else {
    [player setRepeatMode:MPMovieRepeatModeNone];
}
[player setControlStyle:MPMovieControlStyleNone];
[player play];
}

- (void) startDanceAnimation { [self setUpMovie:@"Bo_dance_02"]; return; }

Ответы [ 4 ]

4 голосов
/ 24 февраля 2011

Мне удалось изменить мои фильмы без белой вспышки, используя AVFoundation, как предлагалось ранее.Приведенный ниже код sudo, надеюсь, он кому-нибудь поможет:)

Справочные документы по яблокам можно найти здесь, и я использовал их для получения большей части моей информации: http://developer.apple.com/library/ios/#documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/00_Introduction.html#//apple_ref/doc/uid/TP40010188-CH1-SW3

Первое, что я сделал, былодобавьте следующий класс, названный PlayerView (не могу вспомнить, где я получил его извините) к моему проекту.Это подкласс UIView и представление, в котором будет отображаться фильм. Как только вы добавите его в свой проект, откройте UI Builder, добавьте новый вид к существующему xib и измените его класс на PlayerView.Подключите это с помощью IBOutlet.Еще раз помните, что это представление, которое будет отображать фильм.

PlayerView.h


#import 
#import 
#import 

@interface PlayerView : UIView {
    AVPlayer *player;
}

@property (nonatomic,retain) AVPlayer *player;

@end

PlayerView.m


#import "PlayerView.h"


@implementation PlayerView
@synthesize player;

+ (Class)layerClass {
    return [AVPlayerLayer class];
}
- (AVPlayer*)player {
    return [(AVPlayerLayer *)[self layer] player];
}
- (void)setPlayer:(AVPlayer *)player {
    [(AVPlayerLayer *)[self layer] setPlayer:player];
}

- (void) dealloc {
    [super dealloc];
    [player release];
}

@end

В ViewContoller, который отображает фильмы, которые яиметь следующее:

DisplayMovies.h


#import 
#import 
@class PlayerView;

@interface DisplayMovies : UIViewController {
IBOutlet AVPlayer *player;
AVPlayerItem *movieOneItem;
AVPlayerItem *movieTwoItem;
}
@property (nonatomic, retain) AVPlayer *player;
@property (retain) AVPlayerItem *movieOneItem;
@property (retain) AVPlayerItem *movieTwoItem;

DisplayMovies.m


@implementation DisplayMovies
@synthesize player, movieOneItem, movieTwoItem;

- (void)viewDidLoad {
// load the two movies
NSURL *movieOneItemURL = [[NSBundle mainBundle] URLForResource:@"movieOne" withExtension:@"mp4"];
    AVURLAsset *movieOneItemAsset = [AVURLAsset URLAssetWithURL:movieOneItemURL options:nil];
    self.movieOneItem = [AVPlayerItem playerItemWithAsset:movieOneItemAsset];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(movieOneItemDidReachEnd:)
                                                 name:AVPlayerItemDidPlayToEndTimeNotification
                                               object:self.movieOneItem];

NSURL *movieTwoItemURL = [[NSBundle mainBundle] URLForResource:@"movieTwo" withExtension:@"mp4"];
    AVURLAsset *movieTwoItemAsset = [AVURLAsset URLAssetWithURL:movieTwoItemURL options:nil];
    self.movieTwoItem = [AVPlayerItem playerItemWithAsset:movieTwoItemAsset];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(movieTwoItemDidReachEnd:)
                                                 name:AVPlayerItemDidPlayToEndTimeNotification
                                               object:self.movieTwoItem];
    [self.player play];
}


- (void) movieOneItemDidReachEnd:(NSNotification*)notification {
// play movie two once movie one finishes
    [self.player seekToTime:kCMTimeZero];
    [self.player replaceCurrentItemWithPlayerItem:self.movieTwoItem];
    [self.player play];
}

- (void) movieTwoItemDidReachEnd:(NSNotification*)notification {
// play movie one once movie two finishes
    [self.player seekToTime:kCMTimeZero];
    [self.player replaceCurrentItemWithPlayerItem:self.movieOneItem];
    [self.player play];
}

2 голосов
/ 03 мая 2011

Приведенное выше решение не сработало для меня. Я все еще получал короткие вспышки между треками. Я смог решить эту проблему, создав два представления, каждое со своим собственным AVPlayer. Я заставляю их обоих играть, а затем переключаюсь между ними, скрывая вид сверху. Это избавило от вспышки, и я смог анимировать переход между двумя дорожками, скрыв вид сверху, установив его альфа в 0.0 вместо использования setHidden. Вот мой код:

    AVPlayerItem *theAsset = [self generatePlaylistAssetWithVideoOne];  //In my app this returns an AVPlayer Item

    layerView1 = [[VideoLayerView alloc] initWithFrame:CGRectMake(-50, 0, 580, 320)];  //VideoLayerView is a subclass of UIView with the video layer stuff added in.

    [layerView1 setPlayer:thePlayer];

    [thePlayer play];

    [self.view addSubview:layerView1];



    AVPlayerItem *theAsset2 = [self generatePlaylistAssetWithVideoTwo];

    [thePlayer2 setActionAtItemEnd:AVPlayerActionAtItemEndNone];

    layerView2 = [[VideoLayerView alloc] initWithFrame:CGRectMake(-50, 0, 580, 320)];

    [layerView2 setPlayer:thePlayer2];

    [thePlayer2 play];

    [self.view addSubview:layerView2];

Затем для анимации между видео, которые я использовал:

    if (water)  //Water is a BOOL set up earlier in the file
{



    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.5];

    ///DO STUFF
    [layerView2 setAlpha:0];


    [UIView commitAnimations];


    water = NO;
}
else
{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.5];

    ///DO STUFF
    [layerView2 setAlpha:1.0];

    [UIView commitAnimations];

    water = YES;
}

Чтобы изменить видео, вам просто нужно установить скрытый вид, чтобы начать воспроизведение того, что вы хотите, а затем выполнить переключение после вспышки.

1 голос
/ 10 февраля 2011

Мне еще нужно вернуться к этому проекту, но я получил еще несколько советов. Я вернусь к работе над этим проектом через две недели, надеюсь, я дам вам знать, какое решение сработало (скрестив пальцы) для меня. А пока вот мои варианты:

1. Вы не сможете использовать MPMoviePlayerController для переключения фильма без вспышки.

В качестве альтернативы вы можете использовать AV Foundation. AVPlayer -replaceCurrentItemWithPlayerItem: метод будет плавно переходить от старого элемента проигрывателя к новому без вспышек.

Для получения дополнительной информации о программировании с помощью AV Foundation см. «Руководство по программированию AV Foundation», которое вы можете найти здесь:

http://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/AVFoundationPG/

2. Вы можете объединить все свои фильмы в один (большой) фильм, а затем использовать свойства MPMediaPlayback currentPlaybackTime / endPlaybackTime, чтобы «выбрать» и воспроизвести нужный фильм (в большом фильме). Если вы используете эту технику, вам также нужно убедиться, что в момент времени, когда начинается новый фильм, есть ключевой кадр.

3. В качестве альтернативы, создайте один объект MPMoviePlayerController, используйте -setContentURL: для установки нового URL-адреса фильма и используйте свойство backgroundView для более плавного перехода. Размер backgroundView автоматически изменяется с помощью свойства view, но он будет скрыт до предварительной загрузки фильма. Вы можете поместить черный вид за оба просмотра фильма, а затем сделать backgroundColor backgroundColor = black, что должно сделать его более плавным.

Надеюсь, это поможет.

0 голосов
/ 25 сентября 2014

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

...