AVPlayer Поиск не точен даже с допуском. Перед: kCMTimeZero - PullRequest
0 голосов
/ 08 февраля 2019

У нас есть приложение, которое воспроизводит длинный 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.

  • [Edit:] - ошибка непротиворечивая- он всегда играет с одного и того же (неправильного) места для данной запрошенной позиции.Это также верно после перезапуска.

Любая помощь очень ценится!Спасибо

[Редактировать:]

  • Мы уже попробовали preferredTimescale: playerTimescale
  • Также попробовали kCMTimeIndefinite вместо kCMTimeZero

Ответы [ 3 ]

0 голосов
/ 08 февраля 2019

Попробуйте, у меня отлично работает

@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()
        }
    }
}
0 голосов
/ 11 февраля 2019

Это то, для чего AVURLAsset AVURLAssetPreferPreciseDurationAndTimingKey.

Документация Apple .

Помните, что это должно увеличить время загрузки.

0 голосов
/ 08 февраля 2019

Я сделал что-то подобное, но с ползунком, чтобы изменить секунды игры и работал отлично.

 @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
            })
...