我有两个交叉淡入淡出的视图控制器,它们都在各自的子视图中播放视频。视图A中的视频在淡入开始时开始播放,在淡出结束时停止。视图B中的视频在淡入时开始,在淡出后停止。基本的东西。我让它在MPMoviePlayerController上工作得很好,但我也想做音频淡入/淡出,这迫使我使用AVFoundationFramework的AVPlayer。基本上,一切似乎都很正常,但我注意到开关导致淡入中断。视图B alpha从0跳到1,UIView animateWithDuration的补全块被调用,值为false。我注意到只有当我在loadView方法中调用AVPlayer对象上的replaceCurrentItemWithPlayerItem:方法时,才会发生这种情况。
交叉淡入淡出代码如下所示:
- (void)pushViewController:(UIViewController *)viewController duration:(float)duration
{
float halfFadeInOutTime = duration/2.0;
viewController.view.alpha = 0.0;
UIView *tmpView = self.view;
[viewController viewWillAppear:YES];
//start fading out the first view
[UIView animateWithDuration:halfFadeInOutTime
delay:0
options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionAllowUserInteraction
animations:^{
tmpView.alpha = 0.0;
}
completion:^(BOOL finished){
if( finished ){
if( [self respondsToSelector:@selector(fadeOutFinished:)] ){
[self fadeOutFinished:duration];
}
[self.navigationController pushViewController:viewController animated:NO];
//start fading in with the second view
[UIView animateWithDuration:halfFadeInOutTime
delay:0
options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionAllowUserInteraction
animations:^{
viewController.view.alpha = 1.0;
}
completion:^(BOOL finished2){
if( finished2 ){
if( [((CrossfadeableViewController*)viewController) respondsToSelector:@selector(fadeInFinished:)] ){
[((CrossfadeableViewController*)viewController) fadeInFinished:duration];
}
}
}
];
if( [((CrossfadeableViewController*)viewController) respondsToSelector:@selector(fadeInStarted:)] ){
[((CrossfadeableViewController*)viewController) fadeInStarted:duration];
}
}
}
];
if( [self respondsToSelector:@selector(fadeOutStarted:)] ){
[self fadeOutStarted:duration];
}
}loadView中与AVPlayer相关的代码如下所示
- (void) loadView
{
[super loadView]
//...
/*
* Variables of type:
* UIView *videoPlaceholder;
* AVURLAsset *asset;
* AVPlayerItem *playerItem;
* AVPlayer *player;
* AVPlayerLayer *playerLayer;
*/
videoPlaceholder = [[UIView alloc] initWithFrame:_frame];
playerLayer = [[AVPlayerLayer alloc] init];
[playerLayer setFrame:videoPlaceholder.frame];
playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
player = [[AVPlayer alloc] init];
NSString *_url = [[NSBundle mainBundle] pathForResource:[_videoFilename stringByDeletingPathExtension] ofType:[_videoFilename pathExtension]];
if( _url != nil ){
NSURL *url = [NSURL fileURLWithPath:_url];
asset = [AVURLAsset URLAssetWithURL:url options:nil];
playerItem = [AVPlayerItem playerItemWithAsset:asset];
[player replaceCurrentItemWithPlayerItem:playerItem];
[player seekToTime:kCMTimeZero];
[player setActionAtItemEnd:AVPlayerActionAtItemEndNone];
}
playerLayer.player = player;
[videoPlaceholder.layer addSublayer:playerLayer];
[self.view addSubview:videoPlaceholder];
//....
}有没有人知道是什么原因导致动画中断?我不会在交互过程中更改视图中的任何内容,因为在交叉淡入淡出开始之前会调用loadView。是什么原因导致相同的代码在MPMoviePlayerController上工作,而在AVPlayer上中断?
干杯,PB
发布于 2012-08-15 17:56:48
事实证明,这是加载AVPlayerItem时出现的问题。我必须等到电影被加载,否则动画淡入就会坏掉。
用于等待视频加载完成的示例代码:
- (void)observeValueForKeyPath:(NSString*) path
ofObject:(id)object
change:(NSDictionary*)change
context:(void*)context {
if (context == AVPlayerDemoPlaybackViewControllerStatusObservationContext) {
AVPlayerStatus status = [[change objectForKey:NSKeyValueChangeNewKey] integerValue];
if (status == AVPlayerStatusReadyToPlay) {
if( [self.videoStateChangeDelegate respondsToSelector:@selector(videoStateChangedToReadyForPlayback)] ){
[self.videoStateChangeDelegate videoStateChangedToReadyForPlayback];
}
[self.player play];
}
}
}其中self.videoStateChangeDelegate videoStateChangedToReadyForPlayback通知我的代理控制器它可以开始淡入。由于这个问题,我的简单代码变得有点复杂,这太糟糕了。
https://stackoverflow.com/questions/11744409
复制相似问题