iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 1
1
Mobile Development

Android 音樂播放器自己來系列 第 1

播放器架構介紹

  • 分享至 

  • xImage
  •  

大家對於音樂播放器會想到什麼呢,平常聽線上串流像是 Spotify, KKBOX, Youtube music, Tidal,或是播放自己手機內的音樂都會使用到,看似是一個很平常常用到的功能,但就單一個播放器元件就可以完成了嗎,其實故中是有很大的奧秘的,不然就寫不到 30 天了 XD。

音樂播放器除了有本身的功能外(播放、暫停、上下一首...),還會和系統有些互動,ex: 透過 Notification 來控制,或是透過手錶、透過耳機,不一定要透過 App 上的 UI 才能控制。在播放音樂時可以在背景使用其他 App 或是關螢幕都可以繼續播放,這些又是怎麼達成的呢?怎麼樣是一個完整且良好的音樂播放器體驗呢?那做好的播放器要怎麼測試呢? 播放器行為是否有依照預期的運作呢?

這系列文章會介紹官方所推薦的架構和觀念,並且以這個官方的 UAMP 當作範本,帶領大家一步一步來完成,在開始實作前先了解整體的觀念吧。

先從大範圍的架構來看,App 分成兩部分:UI 和 Player,UI 上可以控制 Player 和顯示 Player 的狀態,現在是在播哪首歌,是不是在播放中…等。Player 的實作可以用 Android 官方提供的 MediaPlayer, ExoPlayer 或是 ijkplayer,也可以用較底層的 AudioTrack 來自己實作。如果用比抽象的概念來稱呼就是 client / server,client 不一定是 UI 了,可能是藍芽耳機、Android wear、或是 Pixel 4 的揮手控制,想像成有一個遙控器可以來控制這個 Player 播放,因此將控制和播放邏輯拆開,而不要綁在一起,是一個有擴充性且方便使用的架構。

Ref: https://developer.android.com/guide/topics/media-apps/media-apps-overview

接著再看得仔細一點,官方提供了什麼元件供開發者使用呢?因為 UI 和 Player 都可以是任意的,因應自己的需求調整,但播放器是有共通的播放行為,官方就提供了 MediaController 和 MediaSession 元件,裡面有一些預設的 callback(play, pause, stop) 可供使用。

MediaSession 就像是 Player 的代理人,要控制 Player,都必須透過 MediaSession 來控制,MediaSession 也會有目前播放的狀態(歌曲資訊、是否在播放中),MediaSession 可由多個 MediaController 來控制,舉例來說,透過 App 播放音樂後,可以透過手錶上對應的 App 來獲取現在的播放狀態。

那 MediaController 就像是 client 端的代理人了,要透過 MediaController 來下指令,同時也會收從 MediaSession 來的 Callback,比如一首歌播放完了,會跳下一首,這時候 MediaController 收到 MediaSession 來的通知,播放狀態改變了,這時候就可以做相對應的處理(UI 改變)。

既然是類似 client 和 server 的關係,那可以多對一或是多對多之類的嗎?可以從使用情境可以推知,可能會有多個 client(App, 手錶) 對應到一個播放器,因此多個 MediaController 可以綁定同一個 MediaSession,但一個 MediaController 一次就只能綁定一個 MediaSession。

Ref: https://developer.android.com/guide/topics/media-apps/media-apps-overview

大部分使用者,在使用音樂 App 時,可能再找到要聽的音樂後,按下播放,接著可能就是切換到別的 App 使用,或是關掉螢幕純粹聽音樂。這時候音樂 App 就沒有再前景了,那會發生什麼事呢?如果自己簡單測試寫來玩玩看,好像也不會發生什麼事,聲音還是會繼續播啊,但隨著切換 App 多一點,或是時間放久一點,音樂可能就停了,因為 Android 系統對 App 的生命週期會依據 Process 的 priority 來做管控,前景的 priority 是最高的,最慢被系統回收。那要怎麼讓 App 在這個使用情境維持在前景呢?就是使用 Service 啦。

Android 在 5.0 時提供了 MediaBrowserService,可以專門用來播歌和瀏覽音樂資訊的 Service,就不用再用一般的 Service 了,還需要用 Bind 來 Service 來做一些操作,會變得有點繁瑣。要實作的時候會使用 MediaBrowserServiceCompat,提供了很好的向前支援,App 最低需求版本低於 Android 5.0 也可以使用。在 UI 端就是使用 MediaBrowser 來連接 MediaBrowserService,官方提供了一個內建溝通架構。

Ref: https://developer.android.com/guide/topics/media-apps/media-apps-overview

上面這張圖就是官方的所推薦的音樂播放器架構,可以先對這個有印象,之後的文章就會陸續來實作這些元件和概念。

Ref:

  1. Media app architecture overview
  2. Android 音樂播放器架構導讀 Part 1
  3. uamp github

下一篇
播放器實作概觀
系列文
Android 音樂播放器自己來30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言