【问题标题】:AVPlayer replaceCurrentItemWithPlayerItem breaking UIViewAnimationAVPlayer replaceCurrentItemWithPlayerItem 打破 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 中断?

干杯, 铅

【问题讨论】:

    标签: ios animation uiview 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] 通知我的委托控制器它可以开始淡入。 太糟糕了,因为这个问题,我的简单代码变得有点复杂。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-12
      • 2021-06-01
      • 1970-01-01
      • 2020-02-10
      • 1970-01-01
      • 2013-02-22
      • 1970-01-01
      • 2012-09-16
      相关资源
      最近更新 更多