即使有 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)
- 我们必须使用 AVPlayer,因为我们需要更好的质量 "spectral:" AVAudioTimePitchAlgorithm。
我们没有使用 AVAudioPlayer 的问题,但是(AFAIK)我们必须使用 AVPlayer,因为我们需要更好的质量 "spectral:" AVAudioTimePitchAlgorithm。
[编辑:] - 错误是一致的 - 对于给定的请求位置,它总是从相同(错误)的位置播放。重启后也是如此
非常感谢任何帮助!谢谢
[编辑:]
- 我们已经试过了
preferredTimescale: playerTimescale
- 还尝试了
kCMTimeIndefinite
而不是 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()
}
}
}
这就是 AVURLAsset
的 AVURLAssetPreferPreciseDurationAndTimingKey
的用途。
请注意,这会增加加载时间。
我们有一个播放长 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)
- 我们必须使用 AVPlayer,因为我们需要更好的质量 "spectral:" AVAudioTimePitchAlgorithm。
我们没有使用 AVAudioPlayer 的问题,但是(AFAIK)我们必须使用 AVPlayer,因为我们需要更好的质量 "spectral:" AVAudioTimePitchAlgorithm。
[编辑:] - 错误是一致的 - 对于给定的请求位置,它总是从相同(错误)的位置播放。重启后也是如此
非常感谢任何帮助!谢谢
[编辑:]
- 我们已经试过了
preferredTimescale: playerTimescale
- 还尝试了
kCMTimeIndefinite
而不是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()
}
}
}
这就是 AVURLAsset
的 AVURLAssetPreferPreciseDurationAndTimingKey
的用途。
请注意,这会增加加载时间。