Jumpy UISlider when scrubbing - Using UISlider with AVPlayer

假装没事ソ 提交于 2019-12-06 13:03:17

you need to remove observers and invalidate timers as soon as user selects the thumb on slider and add them back again when dragging is done

to do add targets like this where you load your player:

    mySlider.addTarget(self, 
action: #selector(PlayerViewController.mySliderBeganTracking(_:)),
forControlEvents:.TouchDown)

    mySlider.addTarget(self,
action: #selector(PlayerViewController.mySliderEndedTracking(_:)),
forControlEvents: .TouchUpInside)

   mySlider.addTarget(self,
action: #selector(PlayerViewController.mySliderEndedTracking(_:)),
forControlEvents: .TouchUpOutside )

and remove observers and invalidate timers in mySliderBeganTracking then add observers in mySliderEndedTracking for better control on what happens in your player write 2 functions : addObservers and removeObservers and call them when needed

Try using the time slider value like below:

 @IBAction func timeSliderDidChange(_ sender: UISlider) {
            AVPlayerManager.sharedInstance.currentTime = Double(sender.value)
        }

var currentTime: Double {
        get {
            return CMTimeGetSeconds(player.currentTime())
        }

        set {
            if self.player.status == .readyToPlay {
                let newTime = CMTimeMakeWithSeconds(newValue, 1)
                player.seek(to: newTime, toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero) { ( _ ) in
                    self.updatePlayerInfo()
                }
            }
        }
    }

and pass the value of slider when user release the slider, also don't update the slider value of current playing while user interaction happening on the slider

Swift 5, Xcode 11

I faced the same issue, it was apparently periodicTimeObserver which was causing to return incorrect time which caused lag or jump in the slider. I solved it by removing periodic time observer when the slider was changing and adding it back when seeking completion handler was called.

@objc func sliderValueChanged(_ playbackSlider: UISlider, event: UIEvent){

    let seconds : Float = Float(playbackSlider.value)
    let targetTime:CMTime = CMTimeMake(value: Int64(seconds), timescale: 1)


    if let touchEvent = event.allTouches?.first {
        switch touchEvent.phase {
        case .began:
            // handle drag began
            //Remove observer when dragging is in progress
            self.removePeriodicTimeObserver()


            break
        case .moved:
            // handle drag moved

            break
        case .ended:
            // handle drag ended

            //Add Observer back when seeking got completed
            player.seek(to: targetTime, toleranceBefore: .zero, toleranceAfter: .zero) { [weak self] (value) in
                self?.addTimeObserver()
            }

            break
        default:
            break
        }
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!