模仿 iOS 的 Music App 音樂播放器
程式碼如下:
import UIKit
//使用 AVPlayer 播放指定音樂,必須先加入 AVFoundation
import AVFoundation
class ViewController: UIViewController {
var index = 0
let player = AVPlayer()
var musicItem:AVPlayerItem?
let gradientLayer = CAGradientLayer()
let time = CMTime(value: 0, timescale: 1)
@IBOutlet weak var songNameLabel: UILabel!
@IBOutlet weak var songSlider: UISlider!
@IBOutlet weak var currentTime: UILabel!
@IBOutlet weak var songLengthLabel: UILabel!
@IBOutlet weak var playandPause: UIButton!
@IBOutlet weak var musicImage: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let fileUrl = Bundle.main.url(forResource: “涼涼”, withExtension: “mp3”)!
musicItem = AVPlayerItem(url: fileUrl)
musicImage.image = UIImage(named: “涼涼.jpg”)
songNameLabel.text = “涼涼”
observeCurrentTime()
updatePlayerUI()
viewBackGround()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
@IBAction func volumeSlider(_ sender: UISlider) {
sender.setValue(sender.value, animated: true)
player.volume = sender.value
}
@IBAction func playButton(_ sender: UIButton) {
player.replaceCurrentItem(with: musicItem)
// 根據播放的rate(播放速率),來判斷他是否正在播放
if player.rate == 0 {
// 按下播放鍵將圖換成暫停鍵
playandPause.setImage(UIImage(systemName: “pause.fill”), for: UIControl.State.normal)
player.play()
}else{
// 按下暫停鍵將圖換成播放鍵
playandPause.setImage(UIImage(systemName: “play.fill”), for: UIControl.State.normal)
player.pause()
}
}
@IBAction func songActionSlider(_ sender: UISlider) {
let seconds = Int64(songSlider.value)
let targetTime:CMTime = CMTimeMake(value: seconds, timescale: 1)
player.seek(to: targetTime)
}
@IBAction func forwardButton(_ sender: UIButton) {
let fileUrl = Bundle.main.url(forResource: “I will always love you”, withExtension: “mp3”)!
musicItem = AVPlayerItem(url: fileUrl)
musicImage.image = UIImage(named: “I will always love you.jpg”)
songNameLabel.text = “I will always love you”
observeCurrentTime()
updatePlayerUI()
player.replaceCurrentItem(with: musicItem)
}
@IBAction func backwardButton(_ sender: UIButton) {
let fileUrl = Bundle.main.url(forResource: “涼涼”, withExtension: “mp3”)!
musicItem = AVPlayerItem(url: fileUrl)
musicImage.image = UIImage(named: “涼涼.jpg”)
songNameLabel.text = “涼涼”
observeCurrentTime()
updatePlayerUI()
player.replaceCurrentItem(with: musicItem)
}
func updatePlayerUI(){
guard let duration = musicItem?.asset.duration else {
return
}
//轉為歌曲的總時間
let seconds = CMTimeGetSeconds(duration)
//在Label顯示歌曲總時間
songLengthLabel.text = formatConversion(time:seconds)
songSlider.minimumValue = 0
songSlider.maximumValue = Float(seconds)
songSlider.isContinuous = true
}
func observeCurrentTime(){
//偵測播放的時間
player.addPeriodicTimeObserver(forInterval: CMTimeMake(value: 1, timescale: 1), queue: DispatchQueue.main, using: {(CMTime) in
if self.player.currentItem?.status == .readyToPlay {
let currentTime = CMTimeGetSeconds(self.player.currentTime())
self.songSlider.value = Float(currentTime)
self.currentTime.text = self.formatConversion(time:currentTime)
}
})
}
func formatConversion(time:Float64) -> String {
let songLength = Int(time)
let minutes = Int(songLength / 60) // 求songLength的商,為分鐘數
let seconds = Int(songLength % 60) // 求songLength的餘數,為秒數
var time = “”
if minutes < 10 {
time = “0\(minutes):”
}else {
time = “\(minutes):”
}
if seconds < 10 {
time = time + “0\(seconds)”
}else {
time = time + “\(seconds)”
}
return time
}
// 自行設計漸層
func viewBackGround(){
gradientLayer.frame = view.bounds
gradientLayer.colors = [UIColor.red.cgColor,UIColor.purple.cgColor,UIColor.orange.cgColor]
view.layer.insertSublayer(gradientLayer, at: 0)
//設定方向為斜的
gradientLayer.startPoint = CGPoint(x: 0, y: 0)
gradientLayer.endPoint = CGPoint(x: 1, y: 1)
gradientLayer.locations = [0,0.6,0.8,1]
}
}