I have ViewController
with AVAudioPlayer
. Now I have this code
import UIKit
import AVFoundation
var audioPlayer = AVAudioPlayer()
class ViewController: UIViewController {
@IBOutlet weak var slider: UISlider!
@IBOutlet weak var playButton: UIButton!
var index = 0
var timer: Timer?
override func viewDidLoad() {
super.viewDidLoad()
if index == 0{
let url = Bundle.main.url(forResource: "1", withExtension: "mp3")!
do {
audioPlayer = try AVAudioPlayer(contentsOf: url)
audioPlayer.prepareToPlay()
//audioPlayer.play()
//play(sender:AnyObject.self as AnyObject)
} catch let error {
print(error.localizedDescription)
}
}
}
@IBAction func slide(_ slider: UISlider) {
audioPlayer.currentTime = TimeInterval(slider.value)
}
@IBAction func play(sender: AnyObject) {
if !audioPlayer.isPlaying{
audioPlayer.play()
// **** The line below is the new line ****
timer = Timer(timeInterval: 1.0, target: self, selector: #selector(self.updateSlider), userInfo: nil, repeats: true)
RunLoop.main.add(timer!, forMode: .commonModes)
} else {
audioPlayer.pause()
playButton.setImage(UIImage(named: "pause.png"), for: UIControlState.normal)
timer?.invalidate()
}
}
func updateSlider(_ timer: Timer) {
slider.value = Float(audioPlayer.currentTime)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
I want to add UISlider that change scrub through the audio file. How to do it?
First, you have to add a new IBAction from the slider to make sure your class gets notified when the sliders value changes (Look for "Responding to User Interaction" here: https://developer.apple.com/reference/uikit/uislider#2557863)
In this event handler you have to set the audios current time
@IBAction func slide(_ slider: UISlider) {
audioPlayer.currentTime = TimeInterval(slider.value)
}
To make sure the slider updates its value according to the current time, you have to add a timer when you start the player that calls a custom method which updates the sliders value.
@IBAction func play(sender: AnyObject) {
if !audioPlayer.isPlaying{
audioPlayer.play()
// **** The line below is the new line ****
timer = Timer(timeInterval: 1.0, target: self, selector: #selector(self.updateSlider), userInfo: nil, repeats: true)
RunLoop.main.add(timer, forMode: .commonModes)
} else {
audioPlayer.pause()
playButton.setImage(UIImage(named: "pause.png"), for: UIControlState.normal)
timer.invalidate()
}
}
Afterwards you have to create the method which updates the sliders value
func updateSlider(_ timer: Timer) {
slider.value = Float(audioPlayer.currentTime)
}
Then you have to set the sliders maximum value
override func viewDidLoad() {
super.viewDidLoad()
if index == 0{
let url = Bundle.main.url(forResource: "1", withExtension: "mp3")!
do {
audioPlayer = try AVAudioPlayer(contentsOf: url)
audioPlayer.prepareToPlay()
// **** These two lines below are new ****
slider.maximumValue = Float(audioPlayer.duration)
slider.value = 0.0
} catch let error {
print(error.localizedDescription)
}
}
}
And finally you have to create a property below your IBOutlets which holds the timer
var timer: Timer?