即使有 toleranceBefore:kCMTimeZero,AVPlayer Seek 也不准确

AVPlayer Seek not accurate even with toleranceBefore: kCMTimeZero

我们有一个播放长 mp3 文件(1 小时长)的应用程序。我们希望能够从文件中的设定点开始播放。但是,当我们这样做时,最多有 10 秒不准确。

代码如下:

  let trackStart = arrTracks![MediaPlayer.shared.currentSongNo].samples

  let frameRate : Int32 = (MediaPlayer.shared.player?.currentItem?.asset.duration.timescale)!

  MediaPlayer.shared.player?.seek(to: CMTimeMakeWithSeconds(Double(trackStart), frameRate), 
    toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero)

非常感谢任何帮助!谢谢

[编辑:]

我做了类似的事情,但用一个滑块来改变播放的秒数并且效果很好。

 @objc func handleSliderChange(sender: UISlider?){
        if let duration = player?.currentItem?.duration{
            let totalSeconds = CMTimeGetSeconds(duration)
            let value = Float64(videoSlider.value) * totalSeconds
            let seekTime = CMTime(value: CMTimeValue(value), timescale: 1)
            player?.seek(to: seekTime , completionHandler: { (completedSeek) in
                //do smthg later
            })
        }
    }

在你的情况下是这样的:

let trackStart = arrTracks![MediaPlayer.shared.currentSongNo].samples
let value = Float64(trackStart)
let seekTime = CMTime(value: CMTimeValue(value), timescale: 1)
MediaPlayer.shared.player?.seek(to: seekTime , completionHandler: { (completedSeek) in
                //do smthg later
            })

试试这个,它对我来说效果很好

@IBAction func playbackSliderValueChanged(_ playbackSlider: UISlider) {
    let seconds : Int64 = Int64(playbackSlider.value)
    let targetTime: CMTime = CMTimeMake(value: seconds, timescale: 1)
    DispatchQueue.main.async {
        self.player!.seek(to: targetTime)
        if self.player!.rate == 0 { // if the player is not yet started playing
            self.player?.play()
        }
    }
}

这就是 AVURLAssetAVURLAssetPreferPreciseDurationAndTimingKey 的用途。

Apple's documentation.

请注意,这会增加加载时间。