Swift iOS -CMTimeMakeWithSeconds: предупреждение: ошибка -0,433 внесена из-за очень низкого масштаба времени
Я использую AVPlayer для воспроизведения видео. Я следовал этому видео-уроку Let's Build That App
Я использую UISlider/ скруббер, чтобы соответствовать текущему кадру / времени видео.
У меня есть видео продолжительностью 10,43 секунды, и я использую функцию ускоренной перемотки, которая выводит меня до самого конца.
@objc fileprivate func handleFastForward(){
guard let playerItem = playerItem else { return }
guard let player = player else { return }
let duration: Float64 = CMTimeGetSeconds(playerItem.duration)
let seekTime: CMTime = CMTimeMakeWithSeconds(duration, 1)
player.seek(to: seekTime)
}
Видео доходит до самого конца, но проблема в том, что слайдер движется только к 10-секундной точке, и я не могу заставить его идти до последних.43-секундных. Я получаю предупреждение:
Значение слайдера определяется в player?.addPeriodicTimeObserver()
И из-за этого, когда я нажимаю ускоренную перемотку вперед, а не ползунок, идущий до самого конца, он останавливается на пару пунктов дальше (обратите внимание на пробел):
Как я могу получить более точные значения, чтобы мой ползунок мог чистить до конца?
playerItem?.addObserver(self, forKeyPath: #keyPath(AVPlayerItem.status),
options: [.old, .new],
context: &playerItemContext)
let interval = CMTime(value: 1, timescale: 2)
timeObserverToken = player?.addPeriodicTimeObserver(forInterval: interval, queue: DispatchQueue.main, using: {
[weak self] (progressTime) in
let seconds = CMTimeGetSeconds(progressTime)
let secondsString = String(format: "%02d", Int(seconds) % 60)
let minutesString = String(format: "%02d", Int(seconds) / 60)
self?.currentTimeLabel.text = "\(minutesString):\(secondsString)"
if let duration = self?.playerItem!.duration{
let durationSeconds = CMTimeGetSeconds(duration)
self?.slider.value = Float(seconds / durationSeconds) // SLIDER IS UPDATED HERE
}
})
1 ответ
Я провел некоторое исследование и AVPlayer
имеет seek
метод на это:
seek(to: <CMTime>, toleranceBefore: <CMTime>, toleranceAfter: <CMTime>)
С помощью этого метода вы можете установить допуск на него, чтобы компенсировать усеченное переполнение, которое в моей ситуации составляло дополнительные -0,433 секунды.
В первом аргументе вы указываете время вашего поиска, а во втором и третьем аргументах - kCMTimeZero
,
Я последовал этому ответу, и хитрость была в том, что, когда я инициализировал время поиска второго аргумента, мне нужно было положить 1000, чтобы все работало.
let seekTime: CMTime = CMTimeMakeWithSeconds(duration, 1000)
Вот код для моей кнопки быстрой перемотки:
@objc fileprivate func handleFastForward(){
guard let playerItem = playerItem else { return }
guard let player = player else { return }
let duration: Float64 = CMTimeGetSeconds(playerItem.duration)
let seekTime: CMTime = CMTimeMakeWithSeconds(duration, 1000)
player.seek(to: seekTime, toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero)
}