technically you don't need a timer for this one.
Just add property
private var isUserDragingSlider: Bool = false
Then you need to set up a slider target.
STEP 1
self.timeSlider.addTarget(self, action: #selector(handleSliderChangeValue(slider:event:)), for: .allEvents)
and in func handleSliderChangeValue you need to add this:
STEP 2
@objc
func handleSliderChangeValue(slider: UISlider, event: UIEvent) {
if let touchEvent = event.allTouches?.first {
switch touchEvent.phase {
case .began:
self.isUserDragingSlider = true
case .ended:
self.isUserDragingSlider = false
self.updateplayerWithSliderChangeValue()
default:
break
}
}
}
and in the end, you need to update your player with the selected time from a slider.
STEP 3
func updateplayerWithSliderChangeValue() {
if let duration = player?.currentItem?.duration {
let totalSeconds = CMTimeGetSeconds(duration)
if !(totalSeconds.isNaN || totalSeconds.isInfinite) {
let newCurrentTime: TimeInterval = Double(self.timeSlider.value) * CMTimeGetSeconds(duration)
let seekToTime: CMTime = CMTimeMakeWithSeconds(newCurrentTime, preferredTimescale: 600)
self.player?.seek(to: seekToTime)
self.isUserDragingSlider.toggle()
}
}
}
And last thing, You need to update your code. Video is updating your slider.
STEP 4
func setupSliderValue(_ seconds: Float64) {
guard !(seconds.isNaN || seconds.isInfinite) else {
return
}
if !isUserDragingSlider {
if let duration = self.player?.currentItem?.duration {
let durationInSeconds = CMTimeGetSeconds(duration)
self.timeSlider.value = Float(seconds / durationInSeconds)
}
}
}
So main problem here is that when we move the slider we have a conflict between updating the slider ( from video ) and updating the video with our slider change.
That is why the slider is not working well. When you block updates from video time to slider with isUserDragingSlider all is working fine.