[Android] ExoPlayer 간단하게 사용해보기

Happy Jiwon·2023년 1월 6일
0

Android

목록 보기
2/13
post-thumbnail

오늘은 안드로이드 스튜디오에서 ExoPlayer를 이용해 간단하게 mp3와 동영상을 재생하는 예제를 먼저 작성하고 커스텀 해 볼 예정이다.
나처럼 간단한 것도 오래 봐야지 아는 사람을 위해(사실은 까먹을 수 있는 나를 위해...) ExoPlyaer 기본 사용법부터 자세하게 작성해보겠다.


ExoPlayer에 대해

  • ExoPlayer는 구글에서 만든 미디어 재생 라이브러리로 다양한 종류의 미디어 파일을 쉽게 재생할 수 있도록 도와준다.

  • Android 프레임워크의 일부가 아니며 AndroidSDK와 별도로 배포되는 오픈 소스 프로젝트이다.

  • MediaPlayer API와 달리 ExoPlayer는 사용자 지정 및 확장이 쉽고 Play Store 애플리케이션 업데이트를 통해 업데이트할 수 있다.

  • 별다른 설정 없이도 네트워크로부터 미디어를 스트리밍 형태로 불러와 재생할 수도 있고, 다양한 포맷들을 지원하며 커스터마이징도 지원한다.

ExoPlayer를 사용한 대표적인 서비스에는 Youtube가 있다!! 자세한 내용은 개발자 가이드 참조

필요항목

  • Android 스튜디오의 최신 정식 버전
  • JellyBean(4.1) 이상을 사용하는 Android 기기
    가장 좋은 것은 멀티 윈도우를 지원하는 Nougat(7.1) 이상을 사용하는 기기

((코드 가져와서 사용하기)) ExoPlayer를 사용한 미디어 스트리밍 링크를 통해 코드를 가져와 실행할 수 있다.



ExoPlayer 사용하기

ExoPlayer dependency 추가하기

implementation 'com.google.android.exoplayer:exoplayer:X.X.X'

위와 같이 앱 모듈의 build.gradle 파일에 ExoPlayer module dependencies를 추가할 수 있다.

🖐🏻 ExoPlayer 라이브러리는 모듈로 분할되어 필요한 기능만 가져올 수 있기때문에 사용 목적에 따라 필요한 라이브러리만 추가해줘야 한다.
이를 구분하지 않으면 많은 확장함수들을 다운로드 받기 때문에 앱의 성능을 떨어뜨릴 수 있다.


github 문서에 있는 라이브러리에 대한 설명

.

아래와 같이 가져왔다.

dependencies {
   ...
   
implementation 'com.google.android.exoplayer:exoplayer-core:2.18.2'
implementation 'com.google.android.exoplayer:exoplayer-dash:2.18.2'
implementation 'com.google.android.exoplayer:exoplayer-ui:2.18.2'

}

자세한 내용은 모듈 추가 참고!!


XML에 PlayerView 추가하기

다음은 XML 파일에 PlayerView를 추가하고 id를 다음과 같이 player_view라고 지정

  <com.google.android.exoplayer2.ui.StyledPlayerView
      android:id="@+id/player_view"
      android:layout_width="match_parent"
      android:layout_height="match_parent" />

PlayerView deprecatedStyledPlayerView

Player 만들기

  1. ExoPlayer.Builder 클래스를 사용해 간단히 생성한다. (미디어 스트리밍을 재생하려면 ExoPlayer 객체 필요)
  2. 해당하는 뷰에 player를 바인딩한다.
private ExoPlayer player;
private StyledPlayerView videoView;
[...]
videoView = findViewById(R.id.video_view);
player = new ExoPlayer.Builder(this).build();
videoView.setPlayer(player);

SimpleExoPlayer deprecatedExoPlayer

미디어 항목 만들기

MediaItem 을 만들어 player에 재생할 콘텐츠를 생성할 예정으로 MP3 파일용 항목을 만들어보자.

MediaItem mediaItem = MediaItem.fromUri(getString(R.string.media_url_mp3));
player.setMediaItem(mediaItem);

R.string.media_url_mp3는 strings.xml에서 https://storage.googleapis.com/exoplayer-test-media-0/play.mp3로 정의함.

활동 수명 주기

4가지 메서드 onStart, onResume, onPause, onStop 을 재정의하여 사용하자.
자세한 내용은 앱의 수명 주기 참고!!

먼저 아래 사진과 같이 Code menu > Override methods를 클릭하여 onStart, onResume, onPause, onStop을 선택한다.

그 다음 API 수준에 따라 onStart 또는 onResume 콜백에서 플레이어를 초기화 해준다.

1. onStart()

    @Override
    protected void onStart() {
        super.onStart();
        if (Util.SDK_INT >= 24) {
            initializePlayer();
        }
    }

2. onResume()

    @Override
    protected void onResume() {
        super.onResume();
        hideSystemUi();
        if (Util.SDK_INT < 24 || player == null) {
            initializePlayer();
        }
    }
  • Android API 수준 24 이하에서는 리소스를 포착할 때까지 최대한 오래 대기해야 하므로 onResume까지 기다린 후에 플레이어를 초기화

  • Android API 수준 24 이상에서는자세한 내용은 멀티 윈도우를 지원한다.. 앱이 표시되지만 분할 윈도우 모드로 활성화되지는 않으므로 onStart에서 플레이어를 초기화

  • initializePlayer()는 아래에서 설명할 예정이다....

전체화면으로 표시할 때 사용할 수 있는 메서드 (onResume에서 호출할 수 있는 도우미 메서드)

private void hideSystemUi() {
	videoView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE
	| View.SYSTEM_UI_FLAG_FULLSCREEN
	| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
	| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
	| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
	| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
    }

3. onPause(), onStop()

releasePlayer()를 사용해 리소스 해제하기

@Override
protected void onStop() {
	super.onStop();
    if (Util.SDK_INT >= 24) {
		releasePlayer();
	}
}

@Override
protected void onPause() {
	super.onPause();
	if (Util.SDK_INT < 24) {
		releasePlayer();
	}
}
  • API 수준 24 이하에서는 onStop의 호출이 보장되지 않으므로 onPause에서 해제
  • API 수준 24 이상(멀티 윈도우 및 분할 윈도우 모드 도입)에서는 onStop의 호출이 보장

releasePlayer()에 작성한 코드, releasePlayer 메서드에 필요한 변수 선언

private Boolean playWhenReady = true; // 재생,일시정지 정보
private int currentWindow = 0; // 현재 윈도우 지수
private Long playbackPosition = 0L; // 현재 재생 위치

플레이어를 해제하고 제거하기 전에 다음 정보를 저장한다.

private void releasePlayer() {
	playbackPosition = player.getCurrentPosition();
	currentWindow = player.getCurrentMediaItemIndex();
	playWhenReady = player.getPlayWhenReady();
	player.release();
	player = null;
}

이제 releasePlayer()에 저장한 상태 정보를 초기화 할 때 플레이어에게 제공하면 끝난다!!

그러기 위해 초기화 부분을 initializePlayer() 를 사용해 정리하였다.

private void initializePlayer() {
	if (player == null) {
		player = new ExoPlayer.Builder(this).build();
		videoView.setPlayer(player);
		MediaItem mediaItem = MediaItem.fromUri(getString(R.string.media_url_mp3));
		player.setMediaItem(mediaItem);
	}
	// releasePlayer에 저장한 상태 정보를 초기화 중에 플레이어에게 제공하는 부분
	player.setPlayWhenReady(playWhenReady);
	player.seekTo(currentWindow, playbackPosition);
	player.prepare();
    }
  • playWhenReady는 재생을 시작할지 여부를 플레이어에 알린다.
    처음에 true 이므로 앱이 처음 실행될 때 재생이 자동으로 시작된다.
  • seekTo가 플레이어에 특정 윈도우 내의 특정 위치를 찾도록 알린다.
    앱이 처음 실행될 때 맨 처음부터 재생이 시작되도록 currentWindowplaybackPosition이 모두 0으로 초기화된다.
  • prepare가 재생에 필요한 모든 리소스를 확보하도록 플레이어에 알린다.

MP3 예제 끝~~!

동영상으로 변경

mp3 재생하는 간단한 예제를 해보았는데 동영상도 간단하다!!
처음에 설정했던 미디어 항목 URI를 MP4 파일로 수정하면 끝난다...

private fun initializePlayer() {
  [...]
     val mediaItem = MediaItem.fromUri(getString(R.string.media_url_mp4));
  [...]
}

R.string.media_url_mp4는 strings.xml에서 https://storage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4로 정의함.

이렇게 바꾸면 된다.....


💡 무료 URI 찾아서 쓸 때.....

나만 에러 나는거야 ....
혼자 무료 URI를 통해 ExoPlayer를 구현할때 간혹 URI 주소가 https가 아닌 http로 되어있을 때가 있다. http를 사용하게 되면 CleartextNotPermittedException 에러가 발생하는데 ..

에러 메시지를 확인해보면.... 문제 원인은 안드로이드에서 기본적으로 Http 접근을 허용하지 않는다는 것이다.
물론 Https로 접근을 하면 문제가 없지만 해당 사이트가 Https로 지원하지 않는 등의 이유로 Http접근을 해야한다면 예외처리를 해야한다.

Android Developer의 Opt out of cleartext traffic을 보면 안드로이드 Pie(API28)부터 cleartext HTTP 를 비활성화한다고 한다. 따라서 API28 이후에서 Http에 접근하려면 cleartext HTTP 를 활성화 시켜야 한다.

1. 모든 Http URL에 대해서 접근 허용

AndroidManifest의 application 태그에서 android:usesCleartextTraffictrue 로 설정하시면 모든 Http 주소에 접근할 수 있다.

<application
        android:label="@string/app_name"
        ...
        android:usesCleartextTraffic="true">

2. 일부 Http URL에 대해서 접근 허용

android:usesCleartextTraffic 는 모든 Http 사이트에 대한 접근을 허용한다. 만약 몇몇 사이트에 대한 접근만 허용하려면 /res/xml/network_security_config.xml 파일을 생성하고 예외 항목들을 추가해야 한다.

다음과 같이 입력하면 secure.example.com에 대한 접근만 허용 된다.

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="false">
        <domain includeSubdomains="true">secure.example.com</domain>
    </domain-config>
</network-security-config>

리스트를 모두 작성했다면 AndroidManifest에 android:networkSecurityConfig 속성으로 예외 리스트 파일을 설정한다.

<application
    android:label="@string/app_name"
    ...
    android:networkSecurityConfig="@xml/network_security_config"

다음엔 커스텀 ExoPlayer로 돌아오겠다.....

profile
공부가 조은 안드로이드 개발자

1개의 댓글

comment-user-thumbnail
2023년 4월 10일

안녕하세요 글 잘봤습니다. 혹 google cloud api 키는 따로 발급을 해야하는건가요?>

답글 달기