MPMoviePlayerController切换电影导致白色闪光
我有一个小UIView,显示一个重复的电影。 当用户点击一个button时,另一个电影被加载并显示在相同的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; }
如前所述,我设法使用AVFoundation来更换我的电影,而不使用白色闪光灯。 下面的sudo代码,希望它有助于某人:)
苹果参考文档可以在这里find,我用它们来获取我的大部分信息: http : //developer.apple.com/library/ios/#documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/00_Introduction.html#//apple_ref / DOC / UID / TP40010188-CH1-SW3
我做的第一件事是添加下面的类,称为PlayerView(不记得我对不起)在我的项目。 它是UIView的一个子类,也是电影将被显示的视图。一旦你将它添加到你的项目打开的UI生成器,添加一个新的视图到现有的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]; }
上面的解决scheme不适合我。 我仍然在短暂的闪光之间。 我能够通过创build两个视图来解决这个问题,每个视图都有自己的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];
然后在我使用的video之间进行animation处理:
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; }
要更改video,只需设置隐藏视图即可开始播放您想要的video,然后在闪光灯之后进行切换。
我仍然需要回到这个项目,但我收到了更多的build议。 我希望能够在两周内回来参与这个项目的工作,所以我会让你知道哪个解决scheme对我有用。 同时这里是我的select:
1.您将无法使用MPMoviePlayerController在没有闪光灯的情况下切换电影。
作为替代,您可以使用AV基金会。 AVPlayer -replaceCurrentItemWithPlayerItem:方法将无缝地从旧玩家项目转换到新玩家项目而不闪烁。
有关使用AV Foundation进行编程的更多信息,请参阅“AV Foundation编程指南”,您可以在这里find:
http://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/AVFoundationPG/
2.您可以将所有电影合并成一个(大)电影,然后使用MPMediaPlayback currentPlaybackTime / endPlaybackTime属性“select”并播放所需的电影(在大电影中)。 如果你使用这种技术,你还需要确保在新电影开始的时候有一个关键帧。
3.或者,创build一个MPMoviePlayerController对象,使用-setContentURL:设置新的电影URL,并利用backgroundView属性进行更加无缝的转换。 backgroundView自动resize与视图属性,但它会被隐藏之前,电影预加载。 您可以在两个电影视图之后放置黑色视图,然后使backgroundView的backgroundColor = black,这应该使其显得更加无缝。
希望这可以帮助。
在iOS 6中查找解决schemehttp://joris.kluivers.nl/blog/2010/01/04/mpmovieplayercontroller-handle-with-care/您需要使用[self.moviePlayer prepareToPlay]; 并抓住MPMoviePlayerReadyForDisplayDidChangeNotification使用[self.moviePlayer play];