2012-07-31 2 views
0

두 개의 크로스 페이딩 뷰 컨트롤러를 사용하여 둘 다 서브 뷰에서 비디오를 재생하고 있습니다. 보기 A의 비디오는 페이드 인이 시작되면 재생이 시작되고 페이드 아웃이 끝나면 멈 춥니 다. 보기 B의 비디오는 페이드 인 (fade-in)에서 시작하고 페이드 아웃 (fade-out) 후에 멈 춥니 다. 기본적인 것들. 나는 MPMoviePlayerController와 함께 잘 작동하도록 만들었지 만, AVFoundationFramework에서 AVPlayer로 이동하게하는 오디오 페이드 인/아웃을 원했습니다. 기본적으로 모든 것이 잘 작동하는 것처럼 보였지만 스위치로 인해 페이드 인이 중단되는 것으로 나타났습니다. 뷰 B 알파는 0에서 1로 점프하고 UIView animateWithDuration의 완료 블록은 false 값으로 호출됩니다. loadView 메소드에서 AVPlayer 객체의 replaceCurrentItemWithPlayerItem : 메서드를 호출 할 때만 발생하는 것으로 나타났습니다.AVPlayer replaceCurrentItemWithPlayerItem breaking UIViewAnimation

크로스 페이드 코드는 다음과 같습니다

- (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]; 

    //.... 
} 

사람이 애니메이션의 파괴의 원인이 무엇인지 알고 있나요? crossview가 시작되기 전에 loadView가 호출되기 때문에 애니메이션 중 뷰에서 아무 것도 변경하지 않습니다. MPMoviePlayerController와 동일한 코드가 작동하여 AVPlayer로 중단 될 수 있습니다.

건배, PB

답변

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]를 통지 내 페이드 인을 시작할 수있는 컨트롤러를 위임하십시오. 이 간단한 문제로 인해 간단한 코드가 좀 복잡해졌습니다.