我有一个显示重复电影的小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; }
答案 0 :(得分:4)
如前所述,我设法使用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];
}
答案 1 :(得分:2)
上面发布的解决方案对我不起作用。我仍然在曲目之间短暂闪烁。我能够通过创建两个视图来解决问题,每个视图都有自己的AVPlayer。我将它们设置为播放,然后通过隐藏顶视图在它们之间切换。这摆脱了闪光,我能够通过将其alpha设置为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;
}
要更改视频,您只需将隐藏视图设置为开始播放所需内容,然后在闪光后进行切换。
答案 2 :(得分:1)
我仍然需要回到这个项目,但我收到了更多建议。希望两个星期后我将重新开始这个项目的工作,所以我会让你知道哪种解决方案适用于我(手指交叉)。同时,这是我的选择:
1。 您将无法使用MPMoviePlayerController在没有闪光灯的情况下切换电影。
作为替代方案,您可以使用AV Foundation。 AVPlayer -replaceCurrentItemWithPlayerItem:方法将从旧的播放器项无缝转换到新的播放器项而不闪烁。
有关使用AV Foundation进行编程的更多信息,请参阅“AV基础编程指南”,您可以在此处找到:
http://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/AVFoundationPG/
2。 您可以将所有电影合并为单个(大)电影,然后使用MPMediaPlayback currentPlaybackTime / endPlaybackTime属性“选择”并播放所需的电影(在大型电影中)。如果你使用这种技术,你还需要确保新电影开始时的关键帧。
3。 或者,创建一个MPMoviePlayerController对象,使用-setContentURL:设置新的影片URL,并利用backgroundView属性进行更无缝的过渡。 backgroundView将使用view属性自动调整大小,但在预加载影片之前将隐藏它。您可以在两个电影视图后面放置一个黑色视图,然后使backgroundView的backgroundColor = black,这样可以使它看起来更加无缝。
希望这有帮助。
答案 3 :(得分:0)
在iOS 6中找到解决方案http://joris.kluivers.nl/blog/2010/01/04/mpmovieplayercontroller-handle-with-care/,您需要使用[self.moviePlayer prepareToPlay];并捕获MPMoviePlayerReadyForDisplayDidChangeNotification以使用[self.moviePlayer play];