In this tutorial, you will learn how to add a playback slider to AVPlayer in Swift to control audio playback.
By the end of this tutorial, you will have a working Swift code example that you can use in your mobile application.
Step 1: Create AVPlayer and AVPlayerItem
First, you need to import the necessary frameworks UIKit
and AVFoundation
, which provides the classes and methods necessary to work with audio and video content.
import UIKit import AVFoundation
Next, define two member variables: AVPlayer
and AVPlayerItem
. AVPlayer
is the class that you use to control the playback of audio and video content while AVPlayerItem
represents the audio or video data that you want to play.
var player: AVPlayer? var playerItem: AVPlayerItem?
You can initialize the AVPlayer
and AVPlayerItem
in the viewWillAppear
method of your view controller. This is where you set the URL of the audio file you want to play and create the AVPlayer
instance.
If you are looking for SwiftUI code, then you can learn how to use AVPlayer and AVPlayeItem classes using both UIKit and SwiftUI in this tutorial: Play Music MP3 File From a Remote URL In Swift.
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) let url = URL(string: "https://s3.amazonaws.com/kargopolov/kukushka.mp3") let playerItem: AVPlayerItem = AVPlayerItem(url: url!) player = AVPlayer(playerItem: playerItem) }
Step 2: Create UIButton Programmatically
To create a play button programmatically, you first need to create an instance of UIButton
and then configure its properties. You can set the button’s frame, background color, title, and add a target-action method that will be called when the button is tapped.
playButton = UIButton(type: UIButton.ButtonType.system) as UIButton let buttonWidth: CGFloat = 150 let buttonHeight: CGFloat = 45 playButton!.frame = CGRect(x: 50, y: 100, width: buttonWidth, height: buttonHeight) playButton!.backgroundColor = UIColor.lightGray playButton!.setTitle("Play", for: UIControl.State.normal) playButton!.tintColor = UIColor.black playButton!.addTarget(self, action: #selector(self.playButtonTapped(_:)), for: .touchUpInside) self.view.addSubview(playButton!)
Step 3: Create AVPlayerLayer and Add it as a Subview
The AVPlayerLayer
is a layer that you add to your view hierarchy to display the video content of an AVPlayer
instance. You create an instance of AVPlayerLayer
, set its frame, and add it as a sublayer of your view’s layer.
let playerLayer = AVPlayerLayer(player: player!) playerLayer.frame = CGRect(x: 0, y: 0, width: 10, height: 50) self.view.layer.addSublayer(playerLayer)
Step 4: Handle Play Button Action to Pause and Play Music
You’ve already added a target-action method to the play button in the previous step. Now, you need to implement this method to handle the button tap. When the button is tapped, you check if the player is currently playing. If it is, you pause the player; otherwise, you play the player.
@objc func playButtonTapped(_ sender: UIButton) { if player?.rate == 0 { player!.play() playButton!.setTitle("Pause", for: UIControl.State.normal) } else { player!.pause() playButton!.setTitle("Play", for: UIControl.State.normal) } }
Step 5: Playback Slider. Add UISlider as a Subview
As a playback slider, you can use the UISlider component.
To create a UISlider programmatically, set its frame and properties, and add it to your view’s subviews. The UISlider
is used to display the progress of the audio playback and to allow the user to seek to a different position in the audio.
let playbackSlider = UISlider(frame: CGRect(x: 10, y: 300, width: 300, height: 20)) playbackSlider.minimumValue = 0 self.view.addSubview(playbackSlider)
Step 6: Handle UISlider Value Changed Event
To handle the slider’s value change, you add a target-action method to the slider. This method will be called when the slider’s value changes, and you can use it to seek to the new position in the audio.
playbackSlider.addTarget(self, action: #selector(self.playbackSliderValueChanged(_:)), for: .valueChanged) @objc func playbackSliderValueChanged(_ playbackSlider: UISlider) { let seconds: Int64 = Int64(playbackSlider.value) let targetTime: CMTime = CMTimeMake(value: seconds, timescale: 1) player!.seek(to: targetTime) if player!.rate == 0 { player?.play() } }
Step 7: Determine Music File Duration in Seconds
To set the maximum value of the slider, you need to determine the duration of the audio file in seconds. You can get the duration from the asset
property of the AVPlayerItem
.
let duration: CMTime = playerItem.asset.duration let seconds: Float64 = CMTimeGetSeconds(duration) playbackSlider.maximumValue = Float(seconds)
Step 8: Update UISlider When mp3 is Playing
To keep the slider’s value in sync with the playback progress, you add a periodic time observer to the player. This observer will be called at regular intervals, and you can use it to update the slider’s value.
var timer: Any? timer = player?.addPeriodicTimeObserver(forInterval: CMTimeMake(value: 1, timescale: 600), queue: DispatchQueue.main) { [weak self] time in guard self != nil else { return } let currentTime = CMTimeGetSeconds(time) playbackSlider.value = Float(currentTime) }
Playback Slider: Complete Code Example
Below is a complete code example in Swift that demonstrates how to add a playback slider to AVPlayer. You can try it and use it in your app to play music or video.
import UIKit import AVFoundation class ViewController: UIViewController { var player: AVPlayer? var playerItem: AVPlayerItem? var playButton: UIButton? var duration: CMTime? var timer: Any? override func viewDidLoad() { super.viewDidLoad() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) let url = URL(string: "https://s3.amazonaws.com/kargopolov/kukushka.mp3") let playerItem:AVPlayerItem = AVPlayerItem(url: url!) player = AVPlayer(playerItem: playerItem) let playerLayer=AVPlayerLayer(player: player!) playerLayer.frame=CGRect(x:0, y:0, width:10, height:50) self.view.layer.addSublayer(playerLayer) playButton = UIButton(type: UIButton.ButtonType.system) as UIButton let xPostion:CGFloat = 50 let yPostion:CGFloat = 100 let buttonWidth:CGFloat = 150 let buttonHeight:CGFloat = 45 playButton!.frame = CGRect(x:xPostion, y:yPostion, width:buttonWidth, height:buttonHeight) playButton!.center = CGPoint(x: self.view.bounds.midX, y: self.view.bounds.midY) playButton!.backgroundColor = UIColor.lightGray playButton!.setTitle("Play", for: UIControl.State.normal) playButton!.tintColor = UIColor.black playButton!.addTarget(self, action: #selector(self.playButtonTapped(_:)), for: .touchUpInside) self.view.addSubview(playButton!) // Add playback slider let playbackSlider = UISlider(frame:CGRect(x:10, y:300, width:300, height:20)) playbackSlider.center = CGPoint(x: self.view.bounds.midX, y: self.view.bounds.midY + 50) playbackSlider.minimumValue = 0 let duration : CMTime = playerItem.asset.duration let seconds : Float64 = CMTimeGetSeconds(duration) playbackSlider.maximumValue = Float(seconds) playbackSlider.isContinuous = true playbackSlider.tintColor = UIColor.green playbackSlider.addTarget(self, action: #selector(self.playbackSliderValueChanged(_:)), for: .valueChanged) // Set up the periodic time observer timer = player?.addPeriodicTimeObserver(forInterval: CMTimeMake(value: 1, timescale: 600), queue: DispatchQueue.main) { [weak self] time in guard self != nil else { return } let currentTime = CMTimeGetSeconds(time) playbackSlider.value = Float(currentTime) } self.view.addSubview(playbackSlider) } @objc func playbackSliderValueChanged(_ playbackSlider:UISlider) { let seconds : Int64 = Int64(playbackSlider.value) let targetTime:CMTime = CMTimeMake(value: seconds, timescale: 1) player!.seek(to: targetTime) if player!.rate == 0 { player?.play() } } @objc func playButtonTapped(_ sender:UIButton) { if player?.rate == 0 { player!.play() playButton!.setTitle("Pause", for: UIControl.State.normal) } else { player!.pause() playButton!.setTitle("Play", for: UIControl.State.normal) } } // Remember to remove the observer when the view disappears override func viewDidDisappear(_ animated: Bool) { super.viewDidDisappear(animated) if let timer = timer { player?.removeTimeObserver(timer) } } }
Conclusion
I hope this tutorial was helpful to you and you were able to successfully add a playback slider to AVPlayer
in your mobile application.
For more Swift code examples and tutorials, please check the Swift Code Examples page on this website.
Happy learning!