플레이어는 미디어 항목의 재생을 용이하게 하는 앱의 구성요소입니다.
Media3 Player
인터페이스는 일반적으로 플레이어에서 처리하는 기능의 개요를 설정합니다. 여기에는 다음이 포함됩니다.
- 재생, 일시중지, 탐색과 같은 재생 컨트롤에 영향을 미칩니다.
- 현재 재생 중인 미디어의 속성(예: 재생 위치) 쿼리
- 미디어 항목의 재생목록/대기열 관리
- 재생 속성(예: 셔플, 반복, 속도, 볼륨) 구성
- 화면에 동영상 렌더링
Media3는 Player
인터페이스의 구현인 ExoPlayer
도 제공합니다.
구성요소 간의 공통 인터페이스
Media3의 여러 구성요소는 플레이어 인터페이스를 구현합니다. 예를 들면 다음과 같습니다.
구성요소 | 설명 및 동작 참고사항 |
---|---|
ExoPlayer |
미디어 플레이어 API 및 Player 인터페이스의 기본 구현입니다. |
MediaController |
MediaSession 와 상호작용하여 재생 명령을 전송합니다. Player 및 MediaSession 가 플레이어의 UI가 있는 Activity 또는 Fragment 와는 다른 Service 에 있다면 MediaController 를 PlayerView UI의 플레이어로 할당할 수 있습니다. 재생 및 재생목록 메서드 호출은 MediaSession 를 통해 Player 로 전송됩니다.
|
MediaBrowser |
MediaController 에서 제공하는 기능 외에도 MediaLibrarySession 와 상호작용하여 사용 가능한 미디어 콘텐츠를 탐색합니다.
|
ForwardingPlayer |
메서드 호출을 다른 Player 로 전달하는 Player 구현입니다. 이 클래스를 사용하여 각 메서드를 재정의하여 특정 작업을 억제하거나 수정합니다.
|
SimpleBasePlayer |
구현할 메서드 수를 최소로 줄이는 Player 구현입니다. MediaSession 에 연결하려는 맞춤 플레이어를 사용할 때 유용합니다.
|
CastPlayer |
Cast 수신기 앱과 통신하는 Player 구현입니다. 동작은 기본 Cast 세션에 따라 다릅니다.
|
MediaSession
는 Player
인터페이스를 구현하지 않지만 인터페이스를 만들 때 Player
가 필요합니다. 이 목적은 다른 프로세스 또는 스레드에서 Player
에 대한 액세스를 제공하는 것입니다.
Media3 재생 아키텍처
Player
에 액세스할 수 있는 경우 재생 명령어를 실행하려면 메서드를 직접 호출해야 합니다. MediaSession
를 구현하여 재생을 광고하고 외부 소스에 재생 제어 권한을 부여할 수 있습니다. 이러한 외부 소스는 미디어 세션에 연결하고 재생 명령 요청을 실행하는 데 도움이 되는 MediaController
를 구현합니다.
백그라운드에서 미디어를 재생할 때는 포그라운드 서비스로 실행되는 MediaSessionService
또는 MediaLibraryService
내에 미디어 세션과 플레이어를 배치해야 합니다. 이렇게 하면 재생 제어용 UI가 포함된 앱의 Activity에서 플레이어를 분리할 수 있습니다. 이 경우 미디어 컨트롤러를 사용해야 할 수도 있습니다.
플레이어 상태
Player
인터페이스를 구현하는 미디어 플레이어의 상태는 주로 다음 네 가지 카테고리의 정보로 구성됩니다.
- 재생 상태
getPlaybackState()
를 사용하여 가져옵니다.- 인터페이스에 의해 정의된 상태 값은
STATE_IDLE
,STATE_BUFFERING
,STATE_READY
,STATE_ENDED
입니다.
- 미디어 항목의 재생목록
- 재생할
MediaItem
인스턴스 시퀀스입니다. getCurrentTimeline()
를 사용하여 검색Player
인스턴스는MediaItem
를 추가하거나 삭제하는 것과 같은 재생목록 작업 메서드와getCurrentMediaItem()
와 같은 편의 메서드를 제공할 수 있습니다.
- 재생할
- 재생/일시중지 속성(예: 다음)
playWhenReady
: 사용자가 가능한 경우 미디어를 재생할지 아니면 일시중지된 상태로 둘지 나타내는 표시입니다.- 재생 억제 이유: 재생이 억제되는 이유를 나타냅니다(해당하는 경우,
playWhenReady
이true
인 경우에도 적용됨). isPlaying
: 플레이어가 현재 재생 중인지 여부를 나타냅니다. 재생 상태가STATE_READY
이고,playWhenReady
가true
이며, 재생이 억제되지 않은 경우에만true
입니다.
- 재생 위치(다음 포함)
- 현재 미디어 항목 색인: 재생목록의 현재
MediaItem
색인입니다. isPlayingAd
: 삽입된 광고가 재생 중인지 여부를 나타냅니다.- 현재 재생 위치:
현재
MediaItem
또는 삽입된 광고 내의 현재 재생 위치입니다.
- 현재 미디어 항목 색인: 재생목록의 현재
또한 Player
인터페이스를 통해 사용 가능한 트랙, 미디어 메타데이터, 재생 속도, 볼륨 및 기타 재생 보조 속성에 액세스할 수 있습니다.
변경사항 수신 대기
Player.Listener
를 사용하여 Player
의 변경사항을 수신 대기합니다. 리스너를 만들고 사용하는 방법에 관한 자세한 내용은 플레이어 이벤트에 관한 ExoPlayer 문서를 참고하세요.
리스너 인터페이스에는 정상적인 재생 진행을 추적하는 콜백이 포함되어 있지 않습니다. 진행률 표시줄 UI를 설정하는 등 재생 진행률을 지속적으로 모니터링하려면 적절한 간격으로 현재 위치를 쿼리해야 합니다.
Kotlin
val handler = Handler(Looper.getMainLooper()) fun checkPlaybackPosition(delayMs: Long): Boolean = handler.postDelayed( { val currentPosition = player.currentPosition // Update UI based on currentPosition checkPlaybackPosition(delayMs) }, delayMs)
자바
Handler handler = new Handler(Looper.getMainLooper()); boolean checkPlaybackPosition(long delayMs) { return handler.postDelayed(() -> { long currentPosition = player.getCurrentPosition(); // Update UI based on currentPosition checkPlaybackPosition(delayMs); }, delayMs); }
재생 제어
Player
인터페이스는 상태를 조작하고 재생을 제어하는 다양한 방법을 제공합니다.
play()
,pause()
,prepare()
,stop()
와 같은 기본 재생 컨트롤addMediaItem()
또는removeMediaItem()
와 같은 재생목록 작업- 시킹: 현재 항목 또는 위치를 변경합니다.
- 반복 모드와 셔플 모드를 설정합니다.
- 트랙 선택 환경설정을 업데이트합니다.
- 재생 속도를 설정합니다.
맞춤 Player
구현
맞춤 플레이어를 만들려면 Media3에 포함된 SimpleBasePlayer
를 확장하면 됩니다. 이 클래스는 구현해야 하는 메서드 수를 최소로 줄이기 위해 Player
인터페이스의 기본 구현을 제공합니다.
먼저 getState()
메서드를 재정의합니다. 이 메서드는 호출될 때 다음을 포함하여 현재 플레이어 상태를 채워야 합니다.
- 사용 가능한 명령어 집합
- 재생 속성이
STATE_READY
일 때 플레이어가 재생을 시작해야 하는지 여부, 현재 재생 중인 미디어 항목의 색인, 현재 항목 내 재생 위치와 같은 재생 속성
Kotlin
class CustomPlayer : SimpleBasePlayer(looper) { override fun getState(): State { return State.Builder() .setAvailableCommands(...) // Set which playback commands the player can handle // Configure additional playback properties .setPlayWhenReady(true, PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST) .setCurrentMediaItemIndex(0) .setContentPositionMs(0) .build() } }
자바
public class CustomPlayer extends SimpleBasePlayer { public CustomPlayer(Looper looper) { super(looper); } @Override protected State getState() { return new State.Builder() .setAvailableCommands(...) // Set which playback commands the player can handle // Configure additional playback properties .setPlayWhenReady(true, PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST) .setCurrentMediaItemIndex(0) .setContentPositionMs(0) .build(); } }
SimpleBasePlayer
는 State
가 유효한 상태 값 조합으로 생성되도록 합니다. 또한 리스너를 처리하고 리스너에게 상태 변경을 알립니다. 상태 업데이트를 수동으로 트리거해야 하는 경우 invalidateState()
를 호출합니다.
getState()
메서드 외에도 플레이어가 사용 가능하도록 선언한 명령어에 사용되는 메서드만 구현하면 됩니다. 구현하려는 기능에 해당하는 재정의 가능한 핸들러 메서드를 찾습니다. 예를 들어 handleSeek()
메서드를 재정의하여 COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM
및 COMMAND_SEEK_TO_NEXT_MEDIA_ITEM
와 같은 작업을 지원합니다.