2013-12-22 2 views
12

플레이어가 AVPlayer을 사용하여 외부 비디오를 (인터넷을 통해) 재생하기 시작할 때 약간의 문제가 있습니다. 해결책을 제안하기 전에 질문을 읽어보십시오. 이 같은 플레이어를 초기화 :AVPlayer가 실제로 재생을 시작할 때 (외부 소스에서)

player = [[AVPlayer alloc] initWithURL:[[NSURL alloc] initWithString:@"http://example.com/video.mp4"]]; 
playerLayer = [AVPlayerLayer playerLayerWithPlayer:player]; 
[playerLayer setFrame:[videoView bounds]]; 
[videoView.layer addSublayer:playerLayer]; 

이 올바르게보기로 플레이어를 추가합니다. 플레이어가 언제 준비되는지, 그리고 상태/속도가 무엇인지를 추적하기 위해 다음 두 줄의 코드를 추가했습니다. 뭔가 상태 또는 AVPlayer의 속도가 변경 될 때

[player addObserver:self forKeyPath:@"rate" options:0 context:nil]; 
[player addObserver:self forKeyPath:@"status" options:0 context:nil]; 

이 두 라인은 방법 - (void)observeValueForKeyPath:....를 호출합니다.

는 지금까지는 다음과 같습니다

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
{ 
    //To print out if it is 'rate' or 'status' that has changed: 
    NSLog(@"Changed: %@", keyPath); 

    if ([keyPath isEqualToString:@"rate"]) //If rate has changed: 
    { 
     if ([player rate] != 0) //If it started playing 
     { 
      NSLog(@"Total time: %f", CMTimeGetSeconds([[player currentItem] duration])); 
      // This NSLog is supposed to print out the duration of the video. 

      [self setControls]; 
      // This method (setControls) is supposed to set play/pause-buttons 
      // as well as labels for the current and total time of the current video. 
     } 
    } 
    else if ([keyPath isEqualToString:@"status"]) // If the status changed 
    { 
     if(player.status == AVPlayerStatusReadyToPlay) //If "ReadyToPlay" 
     { 
      NSLog(@"ReadyToPlay"); 
      [player play]; //Start the video 
     } 
    } 
} 

거의 즉시 초기화 후 readyToPlayAVPlayer 변화의 state, 나는 다음 [player play]를 호출합니다. 이러한 상황이 발생하면, rate는 실제로 그 속도로 재생됩니다 의미 1.00000로 변경되지만 비디오는 이제 단지 재생 버퍼하지 시작합니다. 화면이 검은 색이며 몇 초가 걸리며 , 그 다음에이 재생을 시작합니다. 그러나 속도는 재생되기 전에 재생이 시작됨을 나타냅니다. 1.00000 속도의 숙박은 0에 추락하지 않을 경우 플레이어가 컨트롤 (즉 타임 스탬프 등) 설정을 시작하기에 충분한 정보가있을 때 알려하는 것이 매우 어렵게 시작 버퍼링. 비디오의 지속 시간

NSLog() 인쇄 출력 위 출력합니다 nan는 항목이 연주 할 준비가 아니라고 생각하는 날 리드 (숫자), 그러나 1.0000에서 속도의 숙박은 버퍼링 될 때까지 잠시 후 실제로는 재생되며 요금은 1.0000입니다.

그것은 그러나, 두 번 전화를받을 않습니다. 그 사이에 아무 것도하지 않고 1.0000두 번rate "변화". 어느 호출에서도 비디오의 지속 시간은 사용 가능한 변수입니다.

내 목표는 최대한 빨리 비디오의 현재 및 총 타임 스탬프를 가져 오는 것입니다 (I.E 0:00/3:52). 이 기능은 슬라이더의 스크럽 (빨리 감기 등)을 등록하는데도 사용됩니다.

플레이어가 1.0000의 속도로 두 번째로 재생 중임을 플레이어가 알리면이 값은 준비되지 않습니다. 잠시 후 수동으로 "재생"을 클릭하면 (그리고 [player play]로 전화 걸기) 작동합니다. '준비를 마친 것'이 아닌 인 경우를 어떻게 알 수 있습니까?

+0

이 문제를 해결할만한 것을 찾았습니까? 나는 같은 문제를 겪고있다 ... –

+1

@RubenMartinezJr. 아니,이 응용 프로그램을 끝내지는 못했지만 몇 주 후에 다시 시작합니다!내가 다시 비틀 거리면 고칠 수 있다는 것을 기억하도록 노력할 것입니다. – Sti

+0

많은 감사를드립니다. –

답변

1

나는 당신이 얻을 것이다 가장 가까운이 player.currentItem.playbackLikelyToKeepUp

7

애플에서 AVPlayer를에 addBoundaryTimeObserverForTimes:queue:usingBlock:this example를 참조 관찰하는 것입니다 생각합니다.

AVPlayer *player = [AVPlayer playerWithURL:[NSURL URLWithString:@"http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8"]]; 

[player play]; 

// Assumes a property: @property (strong) id playerObserver; 
// Cannot use kCMTimeZero so instead use a very small period of time 
self.playerObserver = [player addBoundaryTimeObserverForTimes:@[[NSValue valueWithCMTime:CMTimeMake(1, 1000)]] queue:NULL usingBlock:^{ 

     //Playback started 

     [player removeTimeObserver:self.playerObserver]; 
}]; 
관련 문제