AVPlayer在开始播放后立即寻找

时间:2016-07-12 14:47:04

标签: ios swift avplayer

我需要在它开始播放后立即跳到audiofile的特定时间。所以我使用seekToTime方法和完成处理程序

avPlayer.play()

...

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

问题是需要时间从互联网上开始播放文件。由于某种原因,带有完成处理程序的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 个答案:

答案 0 :(得分:3)

是的,有办法。

你需要观察玩家的变化:

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
   }
}

答案 1 :(得分: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()
            }
        })
    }

}
相关问题