2012-08-01 6 views
1

스트림 콘텐츠를 재생하는 오디오 앱이 있습니다. 때때로 신호가 약할 때 문제가 발생하여 재생이 중지됩니다. 네트워크에 계속 도달 할 수 있지만 버퍼가 비어있는 것처럼 보입니다.AVPlayer observeValueForKeyPath

플레이어의 상태 변화를 모니터하기 위해 옵저버를 구현했지만 작동하지 않으며 메소드가 호출되지 않습니다.

특히 AVPlayer 인스턴스는 AppDelegate에 여러보기가 있으며 플레이어는 표시되는 모든보기를 계속 재생해야하므로 특히 그렇습니다. 여기 샘플 코드가 있습니다 :

- (void)viewDidLoad 
    { 
     [super viewDidLoad]; 
     isPlaying = false; 
     playButton.enabled = NO; 

     //Add en observer for reachability change 
     [[NSNotificationCenter defaultCenter] addObserver:self 
               selector:@selector(reachabilityChanged:) 
                name:kReachabilityChangedNotification 
                object:nil]; 

     //Adding the observer for player's status change 
     AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; 
     [delegate.player addObserver:self forKeyPath:@"status" options:0 context:playerStatusContext]; 

     [self initPlayer]; 
    } 


    //Event raised whenever the current status of the player change 
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 

     UIAlertView *alert = [UIAlertView alloc]; 
     NSString *chaineConcat = @"Entering observer method..."]; 
     [alert initWithTitle:@"Test" message:chaineConcat delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil]; 
     [alert show]; 

     if (context == playerStatusContext) { 
      AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; 
      NSString *statusPlayer = nil; 
      if (object == delegate.player && [keyPath isEqualToString:@"status"]) { 
       if (delegate.player.status == AVPlayerStatusReadyToPlay) { 
        statusPlayer = @"Everything's OK"; 
       } else if (delegate.player.status == AVPlayerStatusFailed) { 
        statusPlayer = @"Houston, we have a problem"; 
       } 
      } 
      [self syncUI]; 

      UIAlertView *alert = [UIAlertView alloc]; 
      NSString *chaineConcat = [NSString stringWithFormat:@"%@/%@/", @"Player status' is ", statusPlayer]; 
      [alert initWithTitle:@"Test" message:chaineConcat delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil]; 
      [alert show]; 

     }else { 
      [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; 
     } 

     return; 
    } 

- (void) initPlayer { 

    // Load the array with the sample file 
    NSString *urlAddress = @"http://MYSTREAMURL"; 

    AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; 

    //Create a URL object. 
    delegate.urlStream = [NSURL URLWithString:urlAddress]; 

    //Reinit AVPlayer 
    delegate.player = [AVPlayer playerWithURL:delegate.urlStream]; 

} 

이벤트가 발생하지 않은 이유에 대해 누구도 알고 있습니까? 메서드에 2 개의 경고가 있지만 아무도 해고되지 않습니다. 즉 메서드에 들어 가지 않습니다. 이 모든 경우의 목표는 플레이어가 다시 시작될 수있는 방법을 구현하려고하는 것입니다.

감사합니다.

답변

1

관찰하려는 개체를 만들기 전에 관찰자를 추가하려고합니다. nil 개체로 메시지를 보내는 것입니다.
-addObserver:forKeyPath:options:context:으로 전화하기 전에 -initPlayer으로 전화하십시오.

0

다음은 작동하는 코드입니다. 관찰자를 처리하기 위해

- (void)viewWillAppear:(BOOL)animated 
{ 
    [self addObserver:self forKeyPath:@"player.currentItem.status" options:NSKeyValueObservingOptionNew context:AVPlayerItemStatusContext]; 
    [self addTimeObserverToPlayer]; 

    [super viewWillAppear:animated]; 
} 

:

- (void)viewDidLoad 
{ 
[super viewDidLoad]; 

_player = [[AVPlayer alloc] init]; 
} 

관찰자를 추가하려면 :

는 관찰 AVPlayer를 개체를 선언하려면 :

@interface APLViewController() 
{ 
    AVPlayer *_player; 
} 

가 할당을하고 AVPlayer를 초기화

은 관찰자 제거하려면 다음

- (void)viewWillDisappear:(BOOL)animated 
{ 
    [self removeObserver:self forKeyPath:@"player.currentItem.status" context:AVPlayerItemStatusContext]; 
    [self removeTimeObserverFromPlayer]; 

    [super viewWillDisappear:animated]; 
} 

내가했던 모든 것을 넣어 확인을하거나 작동하지 않을 수 있습니다.