作業37# 模仿 iOS 的 Music App 製作情歌點唱機-上

終於把卡關很久的 音樂播放器 Music App 生出來啦~

在眾多困難的作業當中,音樂播放器這個作業算是我認為滿有興趣的也覺得完成後應該很有成就感吧。最後還是參考了學長姐的文章才順利做出來。

基本功能有:

1. 使用AVPlayer播放音樂

2. 音樂播放/暫停

3. 上一首下一首

4. 隨機放音樂

先拉好元件的Outlet跟Action

用綠色代表是有Outlet跟Action的,紅色就是只有Outlet。

宣告類別,常數、變數

用struct將歌曲的相關資訊裝在一起,以便在程式中輕鬆地管理和傳遞歌曲資訊。

使用Func

播放音樂

let song = songs[index]
let url = Bundle.main.url(forResource: song.songName, withExtension: "mp3")!
let playerItem = AVPlayerItem(url: url)
player.replaceCurrentItem(with: playerItem)
player.play()

播放新歌曲

func playNewSong() {
player.replaceCurrentItem(with: nil)
playSong()
}

更新畫面

這邊就是一些之前學到的東西。

//更新歌曲、歌手、畫面圖片
func updateUI() {
let song = songs[index]
singerLabel.text = song.singer
songNameLabel.text = song.songName
songImageView.image = UIImage(named: song.cover )
songPageControl.currentPage = index
}

上\下一首歌

這邊也是比較簡單的部分!只要讓index +1就可以跳到下一首。

// 播放下一首歌曲的方法
@IBAction func next(_ sender: Any) {
index += 1
if index == songs.count {
index = 0
}
playNewSong()


}
// 播放上一首歌曲的方法
@IBAction func pre(_ sender: Any) {
index -= 1
if index < 0 {
index = songs.count - 1
}
playNewSong()
}

隨機播放

 @IBAction func shuffle(_ sender: Any) {
index = songs.indices.randomElement()!
playNewSong()
}

設定Symbols圖案大小以及圖片

Image 欄位要清掉,Background要設定為Symbols圖案

成果畫面
playButton.setBackgroundImage(UIImage(systemName: "pause.fill"), for: .normal)

完整程式碼

import UIKit
import AVFoundation

class ViewController: UIViewController {

var player = AVPlayer() // 創建一個 AVPlayer 實例,用於播放音樂
var index = 0 // 用於追蹤當前歌曲的索引

// IBOutlet 屬性,連接到介面建構中的各個元件
@IBOutlet weak var playButton: UIButton!
@IBOutlet weak var songNameLabel: UILabel!
@IBOutlet weak var singerLabel: UILabel!
@IBOutlet weak var songImageView: UIImageView!
@IBOutlet weak var songPageControl: UIPageControl!
@IBOutlet weak var shuffleButton: UIButton!

// 覆寫 viewDidLoad() 方法,在視圖載入完成時調用
override func viewDidLoad() {
super.viewDidLoad()
updateUI() // 更新介面
playSong() // 播放歌曲
playNewSong() // 播放新歌曲
replaceCurrentItem() // 替換當前播放項目
}

// 更新介面的方法
func updateUI() {
let song = songs[index] // 從歌曲數組中獲取當前歌曲
singerLabel.text = song.singer // 顯示歌手名稱
songNameLabel.text = song.songName // 顯示歌曲名稱
songImageView.image = UIImage(named: song.cover ) // 顯示封面圖片
songPageControl.currentPage = index // 更新分頁控制器的當前頁數
}

// 播放/暫停按鈕的動作方法
@IBAction func play(_ sender: UIButton) {
if player.timeControlStatus == .playing {
sender.setBackgroundImage(UIImage(systemName: "play.fill"), for: .normal) // 切換播放圖示為暫停圖示
player.pause() // 暫停音樂播放
} else {
playSong() // 播放音樂
}
}

// 播放歌曲的方法
func playSong() {
playButton.setBackgroundImage(UIImage(systemName: "pause.fill"), for: .normal) // 切換暫停圖示為播放圖示
if player.currentItem == nil {
replaceCurrentItem() // 如果當前播放項目為空,替換為新的播放項目
}
player.play() // 播放音樂
}

// 播放新歌曲的方法
func playNewSong() {
player.replaceCurrentItem(with: nil) // 替換當前播放項目為空
playSong() // 播放音樂
}

// 替換當前項目的方法,用於播放選定的歌曲
func replaceCurrentItem() {
let song = songs[index] // 獲取當前歌曲
let url = Bundle.main.url(forResource: song.songName, withExtension: "mp3")! // 獲取歌曲文件的 URL
let playerItem = AVPlayerItem(url: url) // 創建 AVPlayerItem
player.replaceCurrentItem(with: playerItem) // 替換當前播放項目
player.play() // 播放音樂
updateUI() // 更新介面
}

// 播放下一首歌曲的方法
@IBAction func next(_ sender: Any) {
index += 1 // 索引遞增
if index == songs.count {
index = 0 // 如果索引越界,則回到第一首歌曲
}
playNewSong() // 播放新歌曲
}

// 播放上一首歌曲的方法
@IBAction func pre(_ sender: Any) {
index -= 1 // 索引遞減
if index < 0 {
index = songs.count - 1 // 如果索引小於零,則跳轉到最後一首歌曲
}
playNewSong() // 播放新歌曲
}

// 隨機播放一首歌曲的方法
@IBAction func shuffle(_ sender: Any) {
index = songs.indices.randomElement()! // 隨機生成索引
playNewSong() // 播放新歌曲
}

// 分頁控制器值改變時的方法
@IBAction func changePageControl(_ sender: UIPageControl) {
index = songPageControl.currentPage // 更新當前索引
}

之後會再加入播放MV 及音量大小跟音樂播放長度的Slider。

成品:

參考作品:

--

--