Saturday, June 17, 2017

Achieve smooth video scrubbing with AVPlayer

Leave a Comment

I am trying to achieve smooth video scrubbing with AVPlayer through UISlider I have searched and it seems Apple has a Technical Q&A and explained how to achieve this, but my problem is how should I use this method and change player current time with a UISlider: stopPlayingAndSeekSmoothlyToTime(newChaseTime:CMTime)

Here is my code :

//Play Intro Movie let videoURL = Bundle.main.url(forResource: "intro", withExtension: "mp4") player = AVPlayer(url:videoURL!) let playerLayer = AVPlayerLayer(player: player) playerLayer.frame = self.view.frame view.layer.addSublayer(playerLayer) //videoPlayer.play()   view.addSubview(slider) slider.maximumValue = 0 slider.maximumValue = Float(CMTimeGetSeconds((player.currentItem?.asset.duration)!)) 

Here is Apple sample code :

func stopPlayingAndSeekSmoothlyToTime(newChaseTime:CMTime)     {         player.pause()          if CMTimeCompare(newChaseTime, chaseTime) != 0         {             chaseTime = newChaseTime;              if !isSeekInProgress             {                 trySeekToChaseTime()             }         }     }         func trySeekToChaseTime()     {         if playerCurrentItemStatus == .unknown         {             // wait until item becomes ready (KVO player.currentItem.status)         }         else if playerCurrentItemStatus == .readyToPlay         {             actuallySeekToTime()         }     }       func actuallySeekToTime()     {         isSeekInProgress = true         let seekTimeInProgress = chaseTime         player.seek(to: seekTimeInProgress, toleranceBefore: kCMTimeZero,                           toleranceAfter: kCMTimeZero, completionHandler:             { (isFinished:Bool) -> Void in                  if CMTimeCompare(seekTimeInProgress, self.chaseTime) == 0                 {                     self.isSeekInProgress = false                 }                 else                 {                     self.trySeekToChaseTime()                 }         })     } 

2 Answers

Answers 1

Although I'm not using the same method as you do which is stopPlayingAndSeekSmoothlyToTime, I thought I should help you with the seeking action of the player.

func sliderValueChanged() {     var timeToSeek = player.currentItem?.asset.duration.seconds     timeToSeek = timeToSeek * Double(slider.value)     player.seek(to: CMTimeMake(Int64(timeToSeek), 1)) } 

Also you should set the slider.maximumValue to 1. Hope this helps.

Note: Please don't forget to handle currentItem optional value. If it is nil you should set the value 0 for timeToSeek variable.

Answers 2

On slider value change event, just call the

stopPlayingAndSeekSmoothlyToTime(CMTime.init(seconds: (player.currentItem?.asset.duration.seconds)!* slider.value, preferredTimescale: 1000))

The Apples sample code will change the player current time. You can also adjust toleranceBefore and toleranceAfter if you scrub the slider really fast.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment