2016-07-12 4 views
3

再生を開始した直後にオーディオファイルで特定の時間にジャンプする必要があります。だから私はAVPlayerが再生を開始した直後に再生する

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

...完了ハンドラ

avPlayer.play() 

でseekToTimeメソッドを使用して問題は、それは、インターネットからファイルの再生を開始する時間を必要としていることです。何らかの理由で、完了ハンドラを持つseekToTimeのバージョンでは、avPlayerが再生を開始する前に呼び出されるため、アプリケーションがクラッシュします。補完ハンドラのないバージョンで正常に動作します。

エラー:

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

はい、方法があります。

あなたはプレイヤーの変化を観察する必要があります。

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

をそしてあなたは、コールバックの状態を取り扱う:

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

それはまったく同じように動作しませんでしたが、私はそれを動作させました。それは演奏を開始しませんでした。だから私は完了ハンドラなしでseekToTimeバージョンを使用し、handleCallback()にそこからコードを入れた – ttrs

+0

ああ、ええ、意味があります。不要になったときに 'avPlayer?.removeTimeObserver(observer)'を呼んでオブザーバーを削除することを忘れないでください:) – fiks

-1

それのためのAppleの答えを見てください: https://developer.apple.com/library/content/qa/qa1820/_index.html

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) –

関連する問題