재생 이벤트 수신 대기
상태 변경 및 재생 오류와 같은 이벤트는 등록된
Player.Listener
인스턴스. 리스너를 등록하여
이벤트:
Kotlin
// Add a listener to receive events from the player. player.addListener(listener)
자바
// Add a listener to receive events from the player. player.addListener(listener);
Player.Listener
에는 빈 기본 메서드가 있으므로 구현만 하면 됩니다.
관심 있는 방법을 찾을 수 있습니다. 다음에 대한 자세한 설명은 Javadoc을 참조하세요.
메서드와 메서드가 호출되는 시점에 따라 달라집니다. 가장 중요한 메서드로는
아래에 자세히 설명되어 있습니다.
리스너는 개별 이벤트 콜백을 구현하거나
하나 이상의 이벤트가 발생한 후에 호출되는 일반 onEvents
콜백
있습니다. 다음에 대한 설명은 Individual callbacks vs onEvents
를 참조하세요.
여러 사용 사례에 적합해야 합니다
재생 상태 변경
플레이어 상태 변경사항은
onPlaybackStateChanged(@State int state)
Player.Listener
입니다. 플레이어는 다음 네 가지 재생 상태 중 하나일 수 있습니다.
Player.STATE_IDLE
: 초기 상태이며 플레이어가 재생 실패 시 표시됩니다. 플레이어는 제한된 자원만을 보유하게 됩니다. 표시됩니다.Player.STATE_BUFFERING
: 플레이어가 다음 위치에서 즉시 재생할 수 없습니다. 현재 위치입니다. 이 문제는 더 많은 데이터를 로드해야 하기 때문에 발생합니다.Player.STATE_READY
: 플레이어가 현재 재생 중인 동영상에서 즉시 재생할 수 있습니다. 있습니다.Player.STATE_ENDED
: 플레이어에서 모든 미디어 재생을 완료했습니다.
이러한 상태 외에도 플레이어에는 playWhenReady
플래그를 사용하여
사용자의 플레이 의도를
파악할 수 있습니다 이 플래그의 변경사항은
onPlayWhenReadyChanged(playWhenReady, @PlayWhenReadyChangeReason int reason)
플레이어가 재생 중입니다. 즉, 플레이어의 위치가 올라가고 미디어가 재생되고 있습니다. 표시됩니다.
- 플레이어가
Player.STATE_READY
상태입니다. playWhenReady
은true
입니다.- 다음에서 반환된 이유로 재생이 중지되지 않습니다.
Player.getPlaybackSuppressionReason
이러한 속성을 개별적으로 확인하는 대신 Player.isPlaying
있습니다. 이 상태의 변경사항은 다음을 구현하여 수신할 수 있습니다.
onIsPlayingChanged(boolean isPlaying)
:
Kotlin
player.addListener( object : Player.Listener { override fun onIsPlayingChanged(isPlaying: Boolean) { if (isPlaying) { // Active playback. } else { // Not playing because playback is paused, ended, suppressed, or the player // is buffering, stopped or failed. Check player.playWhenReady, // player.playbackState, player.playbackSuppressionReason and // player.playerError for details. } } } )
자바
player.addListener( new Player.Listener() { @Override public void onIsPlayingChanged(boolean isPlaying) { if (isPlaying) { // Active playback. } else { // Not playing because playback is paused, ended, suppressed, or the player // is buffering, stopped or failed. Check player.getPlayWhenReady, // player.getPlaybackState, player.getPlaybackSuppressionReason and // player.getPlaybackError for details. } } });
재생 오류
재생 실패를 야기하는 오류는 다음을 구현하여 수신할 수 있습니다.
onPlayerError(PlaybackException error)
Player.Listener
입니다. 실패가 발생하면 이 메서드가 호출됩니다.
재생 상태가 Player.STATE_IDLE
로 전환되기 직전에 이 이벤트를 처리합니다.
실패하거나 중지된 재생은 ExoPlayer.prepare
를 호출하여 다시 시도할 수 있습니다.
일부 Player
구현은
PlaybackException
: 실패에 대한 추가 정보를 제공합니다. 대상
예를 들어 ExoPlayer
는 type
가 있는 ExoPlaybackException
를 전달합니다.
rendererIndex
, 기타 ExoPlayer 관련 필드
다음 예는 잘못된 연결로 인해 재생이 실패했는지 여부를 HTTP 네트워킹 문제:
Kotlin
player.addListener( object : Player.Listener { override fun onPlayerError(error: PlaybackException) { val cause = error.cause if (cause is HttpDataSourceException) { // An HTTP error occurred. val httpError = cause // It's possible to find out more about the error both by casting and by querying // the cause. if (httpError is InvalidResponseCodeException) { // Cast to InvalidResponseCodeException and retrieve the response code, message // and headers. } else { // Try calling httpError.getCause() to retrieve the underlying cause, although // note that it may be null. } } } } )
자바
player.addListener( new Player.Listener() { @Override public void onPlayerError(PlaybackException error) { @Nullable Throwable cause = error.getCause(); if (cause instanceof HttpDataSourceException) { // An HTTP error occurred. HttpDataSourceException httpError = (HttpDataSourceException) cause; // It's possible to find out more about the error both by casting and by querying // the cause. if (httpError instanceof HttpDataSource.InvalidResponseCodeException) { // Cast to InvalidResponseCodeException and retrieve the response code, message // and headers. } else { // Try calling httpError.getCause() to retrieve the underlying cause, although // note that it may be null. } } } });
재생목록 전환
플레이어가 재생목록의 새 미디어 항목으로 변경될 때마다
등록 시 onMediaItemTransition(MediaItem mediaItem,
@MediaItemTransitionReason int reason)
가 호출됩니다.
Player.Listener
객체. 이유는 자동 결제인지 여부를 나타냅니다.
전환, 탐색 (예: player.next()
호출 후), 반복
재생목록 변경으로 인해 발생한 오류 (예: 현재
삭제됩니다.
Metadata
player.getCurrentMediaMetadata()
에서 반환된 메타데이터는 여러 이유로 인해 변경될 수 있습니다.
재생목록 전환, 인스트림 메타데이터 업데이트,
현재 재생 중에 MediaItem
입니다.
메타데이터 변경에 관심이 있는 경우(예: UI를 표시하는 UI를 업데이트하려는 경우)
onMediaMetadataChanged
을 들을 수 있습니다.
탐색 중입니다.
Player.seekTo
메서드를 호출하면 등록된 콜백이 연속으로 발생합니다.
인스턴스 Player.Listener
개:
reason=DISCONTINUITY_REASON_SEEK
로onPositionDiscontinuity
호출 이것은Player.seekTo
호출의 직접적인 결과입니다. 콜백에는PositionInfo
가 있습니다. 탐색 전후 위치의 필드입니다.- 탐색과 관련된 즉각적인 상태 변경을 포함하는
onPlaybackStateChanged
입니다. 이러한 변경은 없을 수도 있습니다.
개별 콜백과 onEvents
비교
리스너는 다음과 같은 개별 콜백을 구현할지 선택할 수 있습니다.
onIsPlayingChanged(boolean isPlaying)
및 일반
onEvents(Player player, Events events)
콜백. 일반 콜백은
Player
객체에 대한 액세스 권한이며 발생한 events
의 집합을 지정합니다.
있습니다. 이 콜백은 항상
확인할 수 있습니다.
Kotlin
override fun onEvents(player: Player, events: Player.Events) { if ( events.contains(Player.EVENT_PLAYBACK_STATE_CHANGED) || events.contains(Player.EVENT_PLAY_WHEN_READY_CHANGED) ) { uiModule.updateUi(player) } }
자바
@Override public void onEvents(Player player, Events events) { if (events.contains(Player.EVENT_PLAYBACK_STATE_CHANGED) || events.contains(Player.EVENT_PLAY_WHEN_READY_CHANGED)) { uiModule.updateUi(player); } }
다음과 같은 경우 개별 이벤트가 선호되어야 합니다.
- 리스너는 변경 이유에 관심이 있습니다. 예를 들어
onPlayWhenReadyChanged
또는onMediaItemTransition
에 대해 제공된 이유입니다. - 리스너는 콜백 매개변수를 통해 제공된 새 값에만 작동합니다. 콜백 매개변수에 종속되지 않는 다른 무언가를 트리거합니다.
- 리스너 구현에서는 메서드 이름에서 이벤트를 트리거했습니다.
- 리스너는 모든 데이터에 대해 알아야 하는 분석 시스템에 보고 개별 이벤트 및 상태 변경을 수행할 수 있습니다
다음에서는 일반 onEvents(Player player, Events events)
가 선호되어야 합니다.
다음과 같습니다.
- 리스너는 여러 이벤트에 대해 동일한 로직을 트리거하려고 합니다. 대상
예를 들어
onPlaybackStateChanged
및onPlayWhenReadyChanged
입니다. - 추가 이벤트를 트리거하려면 리스너에서
Player
객체에 액세스해야 합니다. 예를 들어 미디어 항목 전환 후에 찾을 수 있습니다. - 리스너는 보고되는 여러 상태 값을 사용하려고 합니다.
별도의 콜백을 함께 사용하거나
Player
getter와 함께 사용 메서드를 참조하세요. 예를 들어Player.getCurrentWindowIndex()
를onTimelineChanged
에 제공된Timeline
는onEvents
콜백에 전달합니다. - 리스너는 이벤트가 논리적으로 함께 발생했는지 여부를 확인합니다. 대상
예: 미디어 항목으로 인해
onPlaybackStateChanged
에서STATE_BUFFERING
로 변경 있습니다.
경우에 따라 리스너가 개별 콜백을
일반 onEvents
콜백(예: 미디어 항목 변경 이유를 기록)
onMediaItemTransition
를 사용하지만 모든 상태 변경을 사용할 수 있는 경우에만 작동
onEvents
에 함께 표시됩니다.
AnalyticsListener
사용
ExoPlayer
를 사용하면 AnalyticsListener
를 플레이어에 등록할 수 있습니다.
addAnalyticsListener
를 호출하여
됩니다. AnalyticsListener
구현은 다음을 수행할 수 있습니다.
분석 및 로깅에 유용할 수 있는 자세한 이벤트를 수신 대기
있습니다. 자세한 내용은 분석 페이지를 참조하세요.
EventLogger
사용
EventLogger
는 다음 API의 라이브러리에서 직접 제공하는 AnalyticsListener
입니다.
로깅 목적으로 사용합니다 ExoPlayer
에 EventLogger
를 추가하여 유용한 사용 설정
한 줄로 추가 로깅을 제공합니다.
Kotlin
player.addAnalyticsListener(EventLogger())
자바
player.addAnalyticsListener(new EventLogger());
자세한 내용은 디버그 로깅 페이지를 참고하세요.
지정된 재생 위치에서 이벤트 실행
일부 사용 사례에서는 지정된 재생 위치에서 이벤트를 실행해야 합니다. 이것은
PlayerMessage
를 사용하여 지원됩니다. PlayerMessage
는 다음을 사용하여 만들 수 있습니다.
ExoPlayer.createMessage
입니다. 실행되어야 하는 재생 위치
PlayerMessage.setPosition
를 사용하여 설정할 수 있습니다. 메시지는
기본적으로 재생 스레드를 감안하여 설정하지만,
PlayerMessage.setLooper
PlayerMessage.setDeleteAfterDelivery
사용 가능
를 사용하면 지정된 요청이 실행될 때마다 메시지를 실행할지 여부를 제어할 수 있습니다.
재생 위치가 발생했습니다 (탐색으로 인해 여러 번 발생할 수 있음).
반복 모드)에서 실행할 수 있습니다. PlayerMessage
가
PlayerMessage.send
를 사용하여 예약할 수 있습니다.
Kotlin
player .createMessage { messageType: Int, payload: Any? -> } .setLooper(Looper.getMainLooper()) .setPosition(/* mediaItemIndex= */ 0, /* positionMs= */ 120000) .setPayload(customPayloadData) .setDeleteAfterDelivery(false) .send()
Java
player .createMessage( (messageType, payload) -> { // Do something at the specified playback position. }) .setLooper(Looper.getMainLooper()) .setPosition(/* mediaItemIndex= */ 0, /* positionMs= */ 120_000) .setPayload(customPayloadData) .setDeleteAfterDelivery(false) .send();