作業6-2: 模仿 iOS 的 Music App 製作情歌點唱機,可忽略進階功能
Published in
8 min readJul 27, 2020
主要功能
- 播放/暫停
- 上、下一首
- 更新image、歌手名稱、歌曲名稱
- Slider 調整播放進度
- Slider 播放進度時間、總時間
- 音量調整(非系統)
- 隨機播放、循環播放、單曲播放
- 背景&鎖定播放
- 背景播放時,系統可控制播放、上下一首並顯示歌曲資訊
音樂播放相關的程式碼就不額外放上來了,
只提一些我覺得比較重要的東西。
func updatePlayerUI() {
//更新總時間& Slider 的Value
guard let duration = playerItem?.asset.duration else {
return
}
//轉為歌曲的總時間
let seconds = CMTimeGetSeconds(duration)
//在Label顯示歌曲總時間
totalPlayLabel.text = formatConversion(time: seconds)
slider.minimumValue = 0
slider.maximumValue = Float(seconds)
slider.isContinuous = true
}
取歌曲的總時間(秒),並設定slider。
func CurrentTime() {
//監聽現在播放時間&換Slider的Value
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.slider.value = Float(currentTime)
self.nowPlayLabel.text = self.formatConversion(time: currentTime)
}
})
}
現在播放時間,並更新Slider Value and Label Text。
func checkMusicIsEnd(){
//偵測是否播放到最後
NotificationCenter.default.addObserver(forName: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil, queue: .main) { (_) in
if self.repeatOnePlay{
//回到0秒 繼續播放
let targetTime:CMTime = CMTimeMake(value: 0, timescale: 1)
self.player.seek(to: targetTime)
self.player.play()
}else{
self.playNextMusic()
}
}
}
播放完畢後的動作。
func createPlayAry(){
//創建playArray
for i in 0 ..< musicList.count{
playAry.append(i)
}
}
func sortPlayAry(){
//playArray 清單排序
playAry.sort()
}
func shufflePlayAry(){
//playArray 清單亂序排序
playAry.shuffle()
}
播放列表,亂序or排序。
設定背景&鎖定播放
// 設定背景&鎖定播放
func setupRemoteTransportControls() {
// Get the shared MPRemoteCommandCenter
let commandCenter = MPRemoteCommandCenter.shared()
// Add handler for Play Command
commandCenter.playCommand.addTarget { [unowned self] event in
if self.player.rate == 0.0 {
self.player.play()
return .success
}
return .commandFailed
}
// Add handler for Pause Command
commandCenter.pauseCommand.addTarget { [unowned self] event in
if self.player.rate == 1.0 {
self.player.pause()
return .success
}
return .commandFailed
}
commandCenter.nextTrackCommand.addTarget{ [unowned self] event in
self.playNextMusic()
return .success
}
commandCenter.previousTrackCommand.addTarget{ [unowned self] event in
self.playPreviousMusic()
return .success
}
}
playCommand :背景播放按鈕設定。
pauseCommand:背景暫停按鈕設定。
nextTrackCommand:背景下一首按鈕設定。
previousTrackCommand:背景上一首按鈕設定。
上下一首的.success不確定有沒有必要加入,可能需要在試試看才知道了。
另外,調整系統音量內建好像已經幫你用好了,不用在自己加入。
commandCenter還有其他的東西可以用,有興趣的可以在自己研究。
背景播放時的歌曲資訊
// 設定背景播放的歌曲資訊
func setupNowPlaying() {
// Define Now Playing Info
let songName:String = (self.musicList[playAry[playNum]].trackName)
let artistName:String = (self.musicList[playAry[playNum]].artistName)
let albumImage:String = (self.musicList[playAry[playNum]].previewName)
var nowPlayingInfo = [String : Any]()
nowPlayingInfo[MPMediaItemPropertyTitle] = songName
nowPlayingInfo[MPMediaItemPropertyAlbumTitle] = artistName
if let image = UIImage(named: albumImage) {
nowPlayingInfo[MPMediaItemPropertyArtwork] =
MPMediaItemArtwork(boundsSize: image.size) { size in
return image
}
}
nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = player.currentTime().seconds
nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = player.currentItem?.asset.duration.seconds
nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = player.rate
// Set the metadata
MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
}
圖片、歌手、歌曲名稱。
建議大家參考Apple 文檔會比較不被我誤導XD
參考連結
背景播放
背景控制播放
AVFile格式