#3 修煉程式的心酸~~

用Swift自製音樂播放器

--

這次做得作品是抄ㄒㄧ…呃!不對,模仿Apple Music的音樂播放器。聽起來就是個不是很難的題目的感覺呢!就來看看是怎麼完成的吧!

一、畫面

一樣先從畫面開始講起,相信大家都對music player不陌生。上面一個ImageView是用來放歌曲圖片的,下面有歌名和歌手名,然後是用Slider偽裝的進度條,然後是控制播放暫停、上下首歌的按鈕。最下面送左到右依序是歌詞(暫時未完成)、隨機播放、循環。

二、基礎功能

首先我們要先設定音樂的格式,一首歌裡面要顯示的東西就是曲名跟歌手名啦!這邊因為我原本想做做看動態歌詞,所以順便宣告了另一個Lyric的struct,而且為了兼容沒有歌詞的音樂所以有個沒有歌詞的init。

再來是設定一首歌的資訊到UI元件上,包括圖片、歌名歌手名、進度條的最大值、歌曲本身。

這邊我用了一個方法,我把圖片、音樂檔名設定成“曲名-歌手名“,這樣在抓歌的時候比較方便,不用在struct裡面寫很多東西。

把樂曲設定好後,就要來播音樂啦!我在這邊因為後面要解決其他的問題,音樂的播放跟按下播放鍵的時間是不同步的,所以是另外設一個isPlaying: Bool 的參數控制音樂的播放與暫停,而不是用player.rate來判斷。

這樣基本功能剩最後一個上下首歌啦,我們的清單是 [Song]所以要換下一首歌只需要把 index加 1或減 1,再呼叫 prepareSong就可以啦。剩下都是些其他細節的判斷了。

目前為止花費時間1.5小時…

三、進階功能

  1. 難搞的進度條(其實難搞的是PeriodicTimeObserver)

身為一個最基本的music player,雖然被列在進階功能,但是還是會想做出來的,不做出來感覺就是不對啊!!可是殊不知不做還好一做就是萬丈深淵啊~

首先要在AVPlayer上先增加PeriodicTimeObserver,讓他能每秒偵測AVPlayer的播放進度藉此設定Slider的value和顯示的時間,達到每秒更新時間的效果。

再來我們要讓Slider可以滑動來設定時間,因為在之前已經把Slider的max值設定好了。所以直接讀取value,利用player.seek()就可以完成。

※強迫症注意!

這邊得到了神力彼得潘帥的大力協助,利用UIEvent在碰到時把PeriodicTimeObserver關掉,手放開時再加回來。不然就會像圖裡這樣,超自然震動~

我的呼叫play時用的是自己處理過的play function,會延遲0.5秒後播放。用意是我發現在seek剛結束或是剛play時,PeriodicTimeObserver會很不穩定,一樣會出現超自然震動現象。

到此花費時間大約10小時……(坑啊 OAQ

2.重覆播放

透過設定playType,在做按鈕換歌(參看上面changeSong function)、歌曲結束時,做出相對應的動作。

到此花費時間10.5小時

3.隨機播放

這邊的隨機播放是參照apple music的模式,隨機開啟歌曲會重新排列行成新的排序,不會再改變。隨機關閉後會恢復原狀,再一次隨機會出現不同的結果。

這邊用的是shuffled,shuffled完後記得把index值做更新。不然播放時會播放出不同首歌。

到此花費11小時

4.背景播放

這部分的程式碼跟前面提到的大同小異,只是呼叫的function不一樣而已。所以就不特別介紹了。

四、終於算是做到一個段落了~~(感動

這次的練習雖然看似簡單不複雜,不過俗話說“魔鬼總是藏在細節裡”。想把細節做到好,也是得花不少功夫的!!用了不少連自己也還不是很了解的東西,要再多纏著神力彼得潘帥大神問問題了 XD。以下附上程式碼

--

--

小黑
彼得潘的 Swift iOS / Flutter App 開發教室

目前會把學習Swift的練習放上來,有空會也把Android Studio的東西也加進來~