ExoPlayer는 Android용 애플리케이션 레벨 미디어 플레이어로, Media Player를 대체할 수 있으며 로컬 및 인터넷을 통해 오디오나 비디오를 재생할 수 있다.
ExoPlayer는 MediaPlayer에서 지원되지 않는 HTTP(DASH) 및 SmoothStreaming과 같은 많은 기능을 지원하고 커스터마이징이 매우 용이하다.
build.gradle 파일에서 의존성을 추가해준다.
implementation 'com.google.android.exoplayer:exoplayer:2.15.1'
ExoPlayerView는 미디어 재생에 사용되는 'View'이기 때문에 레이아웃 파일에서 ExoPlayerView를 추가해야한다.
<com.google.android.exoplayer2.ui.PlayerView
android:id="@+id/player_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:use_controller="false"
/>
여기서 use_controller
속성은 기본 컨트롤러를 사용하지 않도록 설정하는 속성이다. 이 속성을 true로 설정한다면 사용자 지정 컨트롤러를 구현하여 미디어 재생을 제어해야한다.
미디어를 재생하기 위한 ExoPlayer 객체를 생성하고 초기화한다.
private lateinit var player: SimpleExoPlayer
private lateinit var playerView: PlayerView
private fun initializePlayer() {
player = SimpleExoPlayer.Builder(context).build()
playerView.player = player
}
ExoPlayer는 다양한 미디어 소스를 지원한다. 각각의 미디어 소스에는 그에 맞는 생성 방법과 설정이 필요한데 예를 들어 ProgressiveMediaSource는 로컬에 저장된 mp4 파일과 같이 진행형 미디어를 지원하며, HlsMediaSource는 HTTP Live Streaming(HLS) 방식의 미디어를 지원합니다.
다음은 HlsMediaSource를 사용하여 미디어 소스를 생성하는 코드이다.
private fun buildMediaSource(uri: Uri): MediaSource {
val userAgent = "exoplayer-codelab"
return HlsMediaSource.Factory(DefaultDataSourceFactory(context, userAgent))
.createMediaSource(MediaItem.fromUri(uri))
}
DefaultDataSourceFactory
는 ExoPlayer에서 사용할 데이터 소스를 생성한다.HlsMediaSource.Factory
는 HLS 미디어 소스를 생성하기 위한 팩토리이다. * createMediaSource
메서드는 지정된 URI에서 미디어 소스를 생성한다.또한, ProgressiveMediaSource
를 사용하여 로컬에 저장된 mp4 파일과 같은 미디어를 재생할 수 있다. 다음은 ProgressiveMediaSource
를 사용하여 미디어 소스를 생성하는 코드이다.
private fun buildMediaSource(uri: Uri): MediaSource {
val userAgent = "exoplayer-codelab"
return ProgressiveMediaSource.Factory(DefaultDataSourceFactory(context, userAgent))
.createMediaSource(MediaItem.fromUri(uri))
}
위 코드에서 ProgressiveMediaSource.Factory
는 프로그레시브 다운로드 미디어 소스를 생성하기 위한 팩토리입니다.
미디어 소스를 생성하고 나면, ExoPlayer를 준비해야한다.
private fun preparePlayer() {
val uri = Uri.parse(getString(R.string.media_url_mp3))
val mediaSource = buildMediaSource(uri)
player.prepare(mediaSource)
player.playWhenReady = true
}
위 코드에서 Uri.parse 메서드는 재생할 미디어 파일의 URI를 파싱합니다. buildMediaSource 메서드에서는 해당 URI에서 미디어 소스를 생성하며, player.prepare 메서드를 사용하여 ExoPlayer를 준비합니다. player.playWhenReady 속성을 true로 설정하여 ExoPlayer를 자동 재생할 수 있습니다.
미디어 소스와 ExoPlayer가 준비되면 player.play 메서드를 호출해 미디어를 재생할 수 있다.
private fun playMedia() {
player.play()
}
ExoPlayer는 미디어를 재생하면서 EventListener 인터페이스를 통해 다양한 이벤트를 제공한다. 예를 들어 override된 Player.EventListener
를 구현하여 ExoPlayer에서 발생하는 이벤트를 캐치할 수 있다.
private val eventListener = object : Player.EventListener {
override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
super.onPlayerStateChanged(playWhenReady, playbackState)
when (playbackState) {
Player.STATE_IDLE -> {
// Player is idle
}
Player.STATE_BUFFERING -> {
// Player is buffering
}
Player.STATE_READY -> {
// Player is ready to play
}
Player.STATE_ENDED -> {
// Player has ended playing
}
else -> {
// Other player states
}
}
}
}
위 코드에서 onPlayerStateChanged
메서드는 ExoPlayer의 상태 변화를 감지한다.
playWhenReady
는 자동 재생 여부를 나타내며, playbackState
는 재생 상태를 나타낸다.
ExoPlayer의 재생 상태는 다음과 같다.
ExoPlayer를 사용한 후에는 항상 release 메서드를 호출하여 ExoPlayer를 해제해야한다.
private fun releasePlayer() {
player.release()
}