AVPlayer Поиск не точен даже с допуском. Перед: 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, потому что нам нужен спектраль лучшего качества: AVAudioTimePitchAlgorithm.
У нас не было проблемы с AVAudioPlayer, но (AFAIK) мы должны использовать AVPlayer, потому что нам нужен спектраль лучшего качества: "AVAudioTimePitchAlgorithm.
[Правка:] - ошибка постоянна - она всегда воспроизводится из одного и того же (неправильного) места для заданной запрошенной позиции. Это также верно после перезапуска.
Любая помощь очень ценится! Спасибо
[Редактировать:]
- Мы уже пробовали
preferredTimescale: playerTimescale
- Также попробовал
kCMTimeIndefinite
вместоkCMTimeZero
3 ответа
Это то, что AVURLAsset
"s AVURLAssetPreferPreciseDurationAndTimingKey
для.
Помните, что это должно увеличить время загрузки.
Я сделал что-то подобное, но с ползунком, чтобы изменить секунды игры и работал отлично.
@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()
}
}
}