AVPlayer replaceCurrentItemWithPlayerItem 打破 UIViewAnimation
Posted
技术标签:
【中文标题】AVPlayer replaceCurrentItemWithPlayerItem 打破 UIViewAnimation【英文标题】:AVPlayer replaceCurrentItemWithPlayerItem breaking UIViewAnimation 【发布时间】:2012-07-31 16:07:04 【问题描述】:我有两个交叉淡入淡出的视图控制器,它们都在它们的子视图中播放视频。视图 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 中断?
干杯, 铅
【问题讨论】:
【参考方案1】:事实证明这是加载 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] 通知我的委托控制器它可以开始淡入。 太糟糕了,因为这个问题,我的简单代码变得有点复杂。
【讨论】:
以上是关于AVPlayer replaceCurrentItemWithPlayerItem 打破 UIViewAnimation的主要内容,如果未能解决你的问题,请参考以下文章