[ExoPlayer2] ExoPlayer의 기본 구성요소 ⚙️

Jay·2021년 1월 25일
1

ExoPlayer2

목록 보기
2/2
post-thumbnail

ExoPlayer's basic components


ExoPlayer

  • ExoPlayer 라이브러리의 핵심은 ExoPlayer interface이다.
  • 인스턴스는 ExoPlayerFactory를 통해 생성이 된다.
lateinit var player: SimpleExoPlayer

player = SimpleExoPlayer.Builder(context)
            .setTrackSelector(trackSelector)
            .build()

위의 player instance는 SimpleExoPlayer를 리턴받는다.

  • ExoPlayer는 getAudioFormat, getCurrentPosition, getDuration, setVolume, seekTo, setPlayWhenReady, stop등 기존의 고급 미디어 플레이어 기능을 제공한다.
  • ExoPlayer는 모듈성과 커스텀 가능성을 달성하기 위해 많은 컴포넌트를 사용한다.
  • ExoPlayer 인스턴스를 생성하고 준비 할 때, 주입해야하는 컴포넌트에게 작업을 위임하게 된다.
  • 💣 가장 중요한 건 ExoPlayer를 쓰지 않을 때, ExoPlayer.release를 사용해서 해제하는 것이 중요하다.

TrackSelector

위에서 ExoPlayer instance를 생성할 때,

SimpleExoPlayer.Builder(context)
            .setTrackSelector(trackSelector)
            .build()

아래와 같이 TrackSelector 인스턴스를 넣은 걸 기억해보자.

  • TrackSelector는 사용 가능한 각 Renderer에서 사용할 MediaSource에서 제공하는 트랙을 선택하는 역할을 한다.
    (Renderer와 MediaSource가 뭐지 싶어도 된다. 밑에서 설명할것이다.)

아래와 같은 방법으로 TrackSelector의 인스턴스를 구할 수 있다.

val trackSelector = DefaultTrackSelector(context)

MediaSource

  • ExoPlayer에서 재생될 미디어를 결정하여 제공하는 역할을 한다.
  • MediaSource의 인스턴스는 아래와 같이 생성된다.
 ExoPlayer.prepare(MediaSource mediaSource)
  • 📌 명심해야 할 점은, MediaSource 인스턴스는 재사용되지 않는다.
    (한번만 사용된다는 것이다.)
  • MediaSource의 인스턴스를 얻기 위해선 어떤 종류의 데이터를 플레이할지에 따라 결정될 수 있다.
  • 일반 미디어 파일의 경우, ExtractorMediaSource, DASH(DashMediaSource), SmoothStreaming(SsMediaSource), HLS(HlsMediaSource)를 사용한다.
private fun buildMediaSource(track: TrackData): MediaSource {
        val dataSourceFactory: DataSource.Factory = DefaultDataSourceFactory(context, userAgent) //userAgent = applicationName
        val mediaSourceFactory = ProgressiveMediaSource.Factory(dataSourceFactory)
        return mediaSourceFactory.createMediaSource(Uri.parse(track.url))
}
  • 위의 예제를 보면, 일반 MP3 file을 사용할 때, 이런 식으로 생성할 수 있다.

DataSource

  • 위에서 MP3 MediaSource를 생성할 때, 우리가 DataSource를 주입하는 걸 봤을 것이다.
  • MP3와 같은 파일을 사용할 때, DefaultDataSourceFactory를 사용하여 인스턴스를 생성할 수 있다.
val dataSourceFactory: DataSource.Factory = DefaultDataSourceFactory(context, userAgent) //userAgent = applicationName

Renderer

  • Renderer의 작업은 미디어의 개별 컴포넌트를 렌더링 하는 것이다.
    (렌더링? 완성본을 만들기 전에 완성에 가까운 작업물을 만드는 작업 정도로 생각하자.)
  • 라이브러리에선 일반 미디어 유형 (MediaCodecVideoRenderer, MediaCodecAudioRenderer, TextRenderer & MetaDataRenderer)에 대한 구현을 제공해준다.
  • 재생중인 MediaSource에서 미디어를 사용하게 된다.
  • Renderer는 ExoPlayer가 생성될 때, 주입된다.

LoadControl

  • LoadControl은 MediaSource가 더 많은 미디어를 버퍼링해야 하는 시기와 버퍼링을 해야하는 양을 제어한다.
  • 기본 제공되는 DefaultLoadControl은 대부분의 경우에 잘 동작한다.
  • ExoPlayer가 생성될 때 주입된다.
player = SimpleExoPlayer.Builder(this)
                .setTrackSelector(trackSelector)
                .setLoadControl(defaultLoadControl) //이렇게
                .build()

PlayerView

  • 비디오나 음악을 컨트롤 하고 싶은 경우, 사용 된다.

영상 재생을 하고 싶은 경우 & 음악 재생 화면을 보이고 싶은 경우

<com.google.android.exoplayer2.ui.PlayerView
    android:id="@+id/audio_player_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

음악 재생 컨트롤을 하는 컨트롤러가 필요한 경우

  <com.google.android.exoplayer2.ui.PlayerControlView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/playerControlView"
        app:layout_constraintBottom_toBottomOf="parent"
   	app:controller_layout_id="@layout/custom_audio_player" 
        android:layout_marginTop="10dp"
        />

위와 같은 코드는 xml에서 작성하게 되고
java or kt 코드에서는

playerControlView.player = player //player는 아까 만들어둔 SimpleExoPlayer instance

이렇게 작성하여 뷰에 나타낼 수 있다.


순서를 정리해보자.

1️⃣ SimpleExoPlayer를 필드에 선언하자.

lateinit var player : SimpleExoPlayer

2️⃣ onCreate()시점에 TrackSelector를 생성하자.

val trackSelector = DefaultTrackSelector()

3️⃣ SimpleExoPlayer 인스턴스를 생성하자.

player = SimpleExoPlayer.Builder(this)
                .setTrackSelector(trackSelector)
                .build()

4️⃣ XML 레이아웃에 PlayerView를 넣어주자.

   <com.google.android.exoplayer2.ui.PlayerView
        android:id="@+id/playerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:ignore="Overdraw" />

5️⃣ Activity 기준, onCreate()에서 MediaSource를 넣어주자.

// SimpleExoPlayer instance를 xml에 선언한 player에 넣어주자.
playerView.player = player 

// 미디어 데이터가 로드되는 DataSource.Factory 인스턴스 생성
val dataSourceFactory: DataSource.Factory = DefaultDataSourceFactory(this, userAgent)

// Media를 플레이 할 미디어 소스를 생성.
val mediaSourceFactory = ProgressiveMediaSource.Factory(dataSourceFactory)
val mediaSource = mediaSourceFactory.createMediaSource(Uri.parse(track.url))

// MediaSource로 플레이 할 미디어를 준비했으면 player에 넣어주자
player.prepare(mediaSource)

// media를 재생 시키자!
player.playWhenReady = true

🆘 반드시 onDestory()에서 release 시켜주자.

    override fun onDestroy() {
        super.onDestroy()
        player.release()
    }

물론, 위와 같은 모든 기능을 사용하기 위해선
build.gradle에 추가해주자.

implementation "com.google.android.exoplayer:exoplayer-core:2.11.3" //exoPlayer를 쓰기 위해 무조건 추가해줘야 하는 핵심 기능.
implementation "com.google.android.exoplayer:exoplayer-ui:2.11.3" // PlayerView와 같은 뷰를 추가하기 위해 추가.
profile
developer

0개의 댓글