昨天設定好了 MediaSession,今天來加入 Player 了,會參考 uamp 專案內所使用的方式,就直接使用 ExoPlayer,使用 Kotin lazy 語法,在使用時在初始化,並使用 builder 設定參數。
private val exoPlayer: ExoPlayer by lazy {
SimpleExoPlayer.Builder(this).build().apply {
setAudioAttributes(musicAudioAttributes, true)
setHandleAudioBecomingNoisy(true)
addListener(playerListener)
}
}
private val musicAudioAttributes = AudioAttributes.Builder()
.setContentType(C.CONTENT_TYPE_MUSIC)
.setUsage(C.USAGE_MEDIA)
.build()
AudioAttributes 設定播放的類型(ContentType),設定會後會連動一些相對應的設定,比方說打開音量的設定介面,會看到有好幾個音量設定可以設定,透過這邊的設定,讓 Android 系統知道現在播放的類型,使用者調整音量時,才會對的起來。
AudioAttributes 第二個參數(handleAudioFocus) 是設定要不要處理 AudioFocus,AudioFocus 是什麼呢?
在電腦上播音樂,可能用 KKBOX 播了音樂,這時候再去看 Youtube 看影片,兩個聲音就會疊在一起,同時一起播出來,必須手動去停止一邊的播放。但在手機上就不是這個情況,後面的音樂軟體在播時,前面的音樂就會暫停播放,這在音樂播放 App 上是個良好的設計,想像如果有電話或是 Line 鈴響時,但音樂還是繼續播,這時候還需需要手動就暫停,就稍嫌麻煩了。
音樂 App 在播放時會須要向系統註冊 AudioFocus(執行 requestAudioFocus),通知系統要播放音樂了並觀察 AudioFocus 是否有改變(聽 onAudioFocusChange),一個目的是跟別的正在使用聲音的 App 通知,有其播音樂要播放囉,這時候就會看其他 App 是怎麼處理這個行為,通常的方式是暫停。觀察 AudioFocus 的功能就是有其他 App 需要播放向系統取得 AudioFocus,音樂 App 就會做對應的處理可能是暫停或是變小聲。
官網有介紹要怎麼處理這塊行為,Android 8 以前還有不同的寫法,程式碼比較多,可以參考這邊的介紹:Managing audio focus,ExoPlayer 幫開發者處理好了上述的行為,就不用另外在寫 code,收到什麼事件來控制 Player 播放或是暫停了。
setHandleAudioBecomingNoisy(true) 這個設定的用途是,在播放音樂時,如果拔掉耳機,這是音樂就會自動暫停了,這也是一個貼心的設計。背後的原理是註冊 BroadcastReceiver 去聽 ACTION_AUDIO_BECOMING_NOISY 事件,收到後就要暫停音樂播放,官網的介紹在這邊:Don't be noisy。這在 ExoPlayer 也幫開發者處理好了,就設定這行就可以了。
再來設定 listener,去監聽播放器的狀態,裡面其實有蠻多 callback 的,參考 uamp 專案,先處理 onPlayerStateChanged 和 onPlayerError,onPlayerStateChanged 會處理顯示或隱藏 notification 的邏輯,onPlayerError 就顯示 Toast,通知使用者
private inner class PlayerEventListener : Player.EventListener {
override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
when (playbackState) {
Player.STATE_BUFFERING,
Player.STATE_READY -> {
//TODO: show notification
}
else -> {
//TODO: hide notification
}
}
}
override fun onPlayerError(error: ExoPlaybackException) {
var message = R.string.generic_error
Toast.makeText(applicationContext, message, Toast.LENGTH_LONG).show()
}
}
明天會繼續介紹,關於 ExoPlayer 播歌的內容,就再一起提供程式碼。