Implementing the time scrubber

The user interface for the audio player app already contains a scrubber that is hooked up to the following three actions in the view controller:

  • sliderDragStart()
  • sliderDragEnd()
  • sliderChanged()

When an audio file is playing, the scrubber should automatically update to reflect the current position in the song. However, when a user starts dragging the scrubber, it should not update its position until the user has chosen the scrubber's new position. When the user is done dragging the scrubber, it should adjust itself based on the song's progress again. Any time the value for the slider changes, the audio player should adjust the playhead, so the song's progress matches that of the scrubber.

Unfortunately, the AVAudioPlayer object does not expose any delegate method to observe the progress of the current audio file. To update the scrubber regularly, you can implement a timer that updates the scrubber to the audio player's current position every second. Add the following property to the AudioViewController, so you can hold on to the timer after you have created it:

var timer: Timer?

Also, add the following two methods to AudioViewController as a convenient way to start the timer when the user starts dragging the scrubber, or when a file starts playing, and stop it when a user starts dragging the scrubber or to preserve resources when the playback is paused:

func startTimer() {
  timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [unowned self] timer in
    self.slider.value = Float(self.audioPlayer.currentTime / self.audioPlayer.duration)
  }
}

func stopTimer() {
  timer?.invalidate()
}

Add a call to startTimer() in the startPlayback() method and a call to stopTimer() in the stopPlayback() method. If you run the app after doing this, the scrubber will immediately begin updating its position when a song starts playing. However, scrubbing does not work yet. Add the following implementations for the scrubber actions to enable manual scrubbing:

@IBAction func sliderDragStart() {
  stopTimer()
}

@IBAction func sliderDragEnd() {
  startTimer()
}

@IBAction func sliderChanged() {
  audioPlayer.currentTime = Double(slider.value) * audioPlayer.duration
}

The preceding methods are relatively simple, but they provide a very powerful feature that immediately makes your homemade audio player feel like an audio player you might use every day. The final step for implementing the audio player's functionality is to display metadata about the current song.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset