ExoPlayer는 플레이어의 상태 이벤트 콜백을 제공하는 리스너 인터페이스를 제공한다!!
플레이어 리스너 인터페이스를 생성하는 익명함수 playbackStateListener를 만든다. 리스너 인터페이스는 상태변화 이벤트를 제공하는 onPlaybackStateChanged 함수를 오버라이드 한다.
private val playbackStateListener: Player.Listener = playbackStateListener()
private fun playbackStateListener() = object : Player.Listener {
override fun onPlaybackStateChanged(playbackState: Int) {
val stateString: String = when (playbackState) {
ExoPlayer.STATE_IDLE -> "ExoPlayer.STATE_IDLE -"
ExoPlayer.STATE_BUFFERING -> "ExoPlayer.STATE_BUFFERING -"
ExoPlayer.STATE_READY -> "ExoPlayer.STATE_READY -"
ExoPlayer.STATE_ENDED -> "ExoPlayer.STATE_ENDED -"
else -> "UNKNOWN_STATE -"
}
Log.d(TAG, "changed state to $stateString")
}
}
상태는 총 4가지로 각각
1. STATE_IDLE
: 플레이어가 인스턴스화되었지만 아직 준비되지는 않았습니다.
2. STATE_BUFFERING
: 버퍼링된 데이터가 충분하지 않아 플레이어가 현재 위치에서 재생할 수 없습니다.
3. STATE_READY
: 플레이어가 현재 위치에서 즉시 재생할 수 없습니다. 즉, 플레이어의 playWhenReady 속성이 true이면 플레이어가 미디어 재생을 시작합니다. 이 속성이 false이면 플레이어가 일시중지됩니다.
4. STATE_ENDED
: 플레이어가 미디어 재생을 완료했습니다.
💡 조건 (playWhenReady = true && STATE_READY) 을 만족 할 때 재생 중이라고 할 수 있다.
💡 현재 재생중인지 또한 리스너를 받을 수 있다.
override fun onIsPlayingChanged(isPlaying: Boolean) { super.onIsPlayingChanged(isPlaying) Log.d(TAG, "onIsPlayingChanged $isPlaying") }
리스너를 초기화 함수에서 등록해준다.
private void initializePlayer() {
[...]
exoPlayer.seekTo(currentWindow, playbackPosition)
exoPlayer.addListener(playbackStateListener)
[...]
}
플레이어를 해제하는 것과 마찬가지로 리스너 또한 메모리릭의 문제를 발생할 수 있으므로 같이 해제해준다.
private fun releasePlayer() {
player?.let { exoPlayer ->
playbackPosition = exoPlayer.currentPosition
currentItem = exoPlayer.currentMediaItemIndex
playWhenReady = exoPlayer.playWhenReady
exoPlayer.removeListener(playbackStateListener)
exoPlayer.release()
}
player = null
}