2012-07-31 7 views
0

J'ai deux contrôleurs de vue de fondu enchaînés qui lisent la vidéo dans leurs sous-vues. La vidéo en vue A commence à jouer lorsque le fondu commence et s'arrête lorsque le fondu se termine. La vidéo dans la vue B commence à fondu et s'arrête après fondu. Trucs de base. Je l'ai fait fonctionner très bien avec MPMoviePlayerController, mais je voulais aussi faire un fondu audio in/out qui m'a forcé à aller avec l'AVPlayer de AVFoundationFramework. Fondamentalement, tout semblait fonctionner correctement, mais j'ai remarqué que le commutateur a provoqué la rupture du fondu. La vue B alpha saute de 0 à 1 et le bloc d'achèvement de UIView animateWithDuration est appelé avec une valeur fausse. J'ai remarqué que cela se produit uniquement lorsque j'appelle la méthode replaceCurrentItemWithPlayerItem: sur l'objet AVPlayer lors de la méthode loadView.AVPlayer replaceCurrentItemWithPlayerItem rupture UIViewAnimation

Le code crossfading ressemble à ceci:

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

Le code lié à AVPlayer loadview ressemble à ceci

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

    //.... 
} 

Est-ce que quelqu'un sait ce qui peut provoquer la rupture de l'animation? Je ne change rien dans les vues pendant l'aniation puisque loadView est appelé avant le début du crossfade. Et qu'est-ce qui peut faire que le même code fonctionne avec MPMoviePlayerController et casse avec AVPlayer?

Cheers, PB

Répondre

1

Il se trouve que c'était un problème avec le AVPlayerItem en cours de chargement. Je devais attendre que le film a obtenu chargé - sinon le fondu animé en éclaté

l'exemple de code pour attendre que la vidéo a fait le chargement:

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

où l'informe [self.videoStateChangeDelegate videoStateChangedToReadyForPlayback] mon Délégué contrôleur qu'il peut commencer à entrer. Dommage que mon code simple est devenu un peu plus compliqué à cause de ce problème.