#12 Music player實現播放暫停、上下首、音量調整與圓形進度條功能
Published in
6 min readSep 7, 2021
始終對音樂播放器的介面設計很有興趣,因為是結合資訊、互動與娛樂效果的互動。
這次特別嘗試將音樂播放進度以圓形進度條形式呈現,先忽略手動調整播放進度的操作,待之後與隨機和重複播放功能一起實踐。
介面佈局
將除了專輯封面與圓形進度條外的元件佈局在Storyboard上。
利用 AVPlayer 播放 App 裡的音樂
音樂檔案與歌名的陣列
將音樂檔案放入專案並以陣列方式儲存,以後面切換時調用
let songTitle = ["The Kids Are Coming","Dance Monkey","Colourblind","Johnny Run Away","Jimmy","Never Seen the Rain"]let songName = ["01.The Kids Are Coming","02.Dance Monkey","03.Colourblind","04.Johnny Run Away","05.Jimmy","06.Never Seen the Rain"]
AVPlayer
let player = AVPlayer()
var playerItem: AVPlayerItem?
var fileUrl = Bundle.main.url(forResource: nil, withExtension: "mp3")
播放音樂
func playSong(index: Int) {
fileUrl = Bundle.main.url(forResource: songName[index], withExtension: "mp3")!
playerItem = AVPlayerItem(url: fileUrl!)
player.replaceCurrentItem(with: playerItem)
player.play()
setImage(imageName: "pause.circle")
songLable.text = songTitle[songIndex]
}
Play / Pause Button
@IBAction func playMusic(_ sender: UIButton) {
if player.timeControlStatus == .paused {
setImage(imageName: "pause.circle")
player.play()
}else {
setImage(imageName: "play.circle")
player.pause()
}
}
Previous Button
@IBAction func previousSong(_ sender: UIButton) {
if songIndex == 0 {
songIndex = songName.count - 1
playSong(index: songIndex)
songTotalLength() }else {
songIndex -= 1
playSong(index: songIndex)
songTotalLength()
}
}
音樂播放時間
音樂長度
func songTotalLength() { //讀取歌曲的音樂長度
let duration = playerItem!.asset.duration
let seconds = CMTimeGetSeconds(duration) //將播放進度賦值給totalTimeLabel
totalTimeLabel.text = formateConversion(time: seconds)
//將時間長度賦值給totoalTime
totoalTime = seconds
}
播放進度條圖形的函式
總長度即為360度,不需定義。但須計算當前播放進度跟音樂長度的比例取得圓環角度。
func songProgressBar(time: CGFloat) -> UIView {
let startAngle = CGFloat.pi / 2 * 3
//當前進度除以音樂長度取得角度 let angle:CGFloat = 360 * time / totoalTime
let endAngle = startAngle + angle.degree
let songCurrenPath = UIBezierPath()
songCurrenPath.addArc(withCenter: CGPoint(x: 0, y: 0), radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: true)
songCurrentShape.path = songCurrenPath.cgPath
songCurrentShape.strokeColor = UIColor.orange.cgColor
songCurrentShape.lineWidth = 4
songCurrentShape.lineCap = .round
songCurrentShape.fillColor = UIColor.clear.cgColor
barView.layer.addSublayer(songCurrentShape)
return barView
}
觀察音樂播放進度
func songCurrentTime() {
let timeScale = CMTimeScale(NSEC_PER_SEC)
let time = CMTime(seconds: 0.5, preferredTimescale: timeScale)
player.addPeriodicTimeObserver(forInterval: time, queue: .main, using: { (time) in
if self.player.currentItem?.status == .readyToPlay {
let currentTime = CMTimeGetSeconds(self.player.currentTime())
//將播放進度賦值給currentTimeLabel
self.currentTimeLabel.text = self.formateConversion(time: currentTime)
//將播放進度賦值給圖形函式
self.songProgressBar(time: currentTime)
}
})
}