2016-07-12 3 views
3

재생을 시작한 직후 오디오 파일에서 특정 시간으로 이동해야합니다. 그래서AVPlayer가 재생을 시작한 직후에 검색합니다.

avPlayer?.seekToTime(jumpTime, completionHandler: { isComplete in 
    if isComplete { 
     MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo![MPNowPlayingInfoPropertyElapsedPlaybackTime] = CMTimeGetSeconds((self.avPlayer!.currentItem?.currentTime())!) 
    } 
}) 

문제는 인터넷에서 파일을 재생을 시작하는 데 시간이 필요하다는 것입니다 ... 완료 핸들러

avPlayer.play() 

와 seekToTime 방법을 사용합니다. 어떤 이유로 avPlayer가 재생하기 전에 호출되기 때문에 완료 핸들러가있는 seekToTime 버전이 앱을 충돌시킵니다. 완료 처리기가없는 버전에서는 문제가 없습니다.

오류 :

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'AVPlayerItem cannot service a seek request with a completion handler until its status is AVPlayerItemStatusReadyToPlay.' 

avPlayer.play()와 콜백을 사용하는 방법이 있나요?

답변

2

예, 방법이 있습니다.

func handleCallback(time: CMTime) {  
    if avPlayer?.status == .ReadyToPlay { 
     // place your seek logic here 
    } 
} 
+0

정확하게 작동하지 않지만 작동하게 만들었습니다. 그것은 시작되지 않았다. 그래서 완성 처리기없이 seekToTime 버전을 사용하여 거기에서 handleCallback() 코드를 삽입했습니다. – ttrs

+0

오, 그래, 의미가 있습니다. 더 이상 필요하지 않을 때'avPlayer? .removeTimeObserver (observer)'를 호출하여 관찰자를 제거하는 것을 잊지 마십시오 :) – fiks

-1

이에 대한 애플의 답변을보고하십시오 : https://developer.apple.com/library/content/qa/qa1820/_index.html

당신은 플레이어의 변화를 관찰해야합니다

avPlayer?.addPeriodicTimeObserverForInterval(CMTime(value: 1, timescale: 3), queue: dispatch_get_main_queue()) { [weak self] time in 
    self?.handleCallback(time) 
} 

을 그리고 당신은 콜백 상태를 처리

class MyClass { 

    var isSeekInProgress = false 
    let player = <#A valid player object #> 
    var chaseTime = kCMTimeZero 
    // your player.currentItem.status 
    var playerCurrentItemStatus:AVPlayerItemStatus = .Unknown 

    ... 

    func stopPlayingAndSeekSmoothlyToTime(newChaseTime:CMTime) 
    { 
     player.pause() 

     if CMTimeCompare(newChaseTime, chaseTime) != 0 
     { 
      chaseTime = newChaseTime; 

      if !isSeekInProgress 
      { 
       trySeekToChaseTime() 
      } 
     } 
    } 

    func trySeekToChaseTime() 
    { 
     if playerCurrentItemStatus == .Unknown 
     { 
      // wait until item becomes ready (KVO player.currentItem.status) 
     } 
     else if playerCurrentItemStatus == .ReadyToPlay 
     { 
      actuallySeekToTime() 
     } 
    } 

    func actuallySeekToTime() 
    { 
     isSeekInProgress = true 
     let seekTimeInProgress = chaseTime 
     player.seekToTime(seekTimeInProgress, toleranceBefore: kCMTimeZero, 
       toleranceAfter: kCMTimeZero, completionHandler: 
     { (isFinished:Bool) -> Void in 

      if CMTimeCompare(seekTimeInProgress, chaseTime) == 0 
      { 
       isSeekInProgress = false 
      } 
      else 
      { 
       trySeekToChaseTime() 
      } 
     }) 
    } 

} 
+0

해결책에 대한 링크는 환영하지만, 응답이 없으면 유용하다는 것을 확인하십시오. 링크] (// meta.stackexchange.com/a/8259) 그래서 동료 사용자는 그것이 무엇인지, 왜 있는지, 그리고 대상이 링크 된 페이지의 가장 관련성이 높은 부분을 인용하십시오. 페이지를 사용할 수 없습니다. [링크 이상의 답변은 삭제 될 수 있습니다.] (// stackoverflow.com/help/deleted-answers) –

관련 문제