mirror of
https://github.com/androidx/media.git
synced 2025-05-03 21:57:46 +08:00
Refactor ComponentListener of PlayerWrapper
PiperOrigin-RevId: 343432873
This commit is contained in:
parent
8c8176647c
commit
d67b70340e
@ -80,6 +80,9 @@
|
|||||||
that lie outside the length of the cue text.
|
that lie outside the length of the cue text.
|
||||||
* Metadata retriever:
|
* Metadata retriever:
|
||||||
* Parse Google Photos HEIC motion photos metadata.
|
* Parse Google Photos HEIC motion photos metadata.
|
||||||
|
* Media2 extention:
|
||||||
|
* Notify onBufferingEnded when the state of origin player becomes
|
||||||
|
STATE_IDLE or STATE_ENDED.
|
||||||
|
|
||||||
### 2.12.1 (2020-10-23) ###
|
### 2.12.1 (2020-10-23) ###
|
||||||
|
|
||||||
|
@ -826,7 +826,6 @@ public class SessionPlayerConnectorTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
sessionPlayerConnector.setPlaylist(playlistToSessionPlayer, /* metadata= */ null);
|
|
||||||
InstrumentationRegistry.getInstrumentation()
|
InstrumentationRegistry.getInstrumentation()
|
||||||
.runOnMainSync(() -> playerTestRule.getSimpleExoPlayer().setMediaItems(exoMediaItems));
|
.runOnMainSync(() -> playerTestRule.getSimpleExoPlayer().setMediaItems(exoMediaItems));
|
||||||
assertThat(onPlaylistChangedLatch.await(PLAYLIST_CHANGE_WAIT_TIME_MS, MILLISECONDS)).isTrue();
|
assertThat(onPlaylistChangedLatch.await(PLAYLIST_CHANGE_WAIT_TIME_MS, MILLISECONDS)).isTrue();
|
||||||
|
@ -65,10 +65,10 @@ import java.util.List;
|
|||||||
/** Called when a seek request has completed. */
|
/** Called when a seek request has completed. */
|
||||||
void onSeekCompleted();
|
void onSeekCompleted();
|
||||||
|
|
||||||
/** Called when the player rebuffers. */
|
/** Called when the player starts buffering. */
|
||||||
void onBufferingStarted(androidx.media2.common.MediaItem media2MediaItem);
|
void onBufferingStarted(androidx.media2.common.MediaItem media2MediaItem);
|
||||||
|
|
||||||
/** Called when the player becomes ready again after rebuffering. */
|
/** Called when the player becomes ready again after buffering started. */
|
||||||
void onBufferingEnded(
|
void onBufferingEnded(
|
||||||
androidx.media2.common.MediaItem media2MediaItem, int bufferingPercentage);
|
androidx.media2.common.MediaItem media2MediaItem, int bufferingPercentage);
|
||||||
|
|
||||||
@ -120,8 +120,9 @@ import java.util.List;
|
|||||||
private final List<MediaItem> exoPlayerPlaylist;
|
private final List<MediaItem> exoPlayerPlaylist;
|
||||||
|
|
||||||
private ControlDispatcher controlDispatcher;
|
private ControlDispatcher controlDispatcher;
|
||||||
|
private int sessionPlayerState;
|
||||||
private boolean prepared;
|
private boolean prepared;
|
||||||
private boolean rebuffering;
|
@Nullable private androidx.media2.common.MediaItem bufferingItem;
|
||||||
private int currentWindowIndex;
|
private int currentWindowIndex;
|
||||||
private boolean ignoreTimelineUpdates;
|
private boolean ignoreTimelineUpdates;
|
||||||
|
|
||||||
@ -154,11 +155,14 @@ import java.util.List;
|
|||||||
media2Playlist = new ArrayList<>();
|
media2Playlist = new ArrayList<>();
|
||||||
exoPlayerPlaylist = new ArrayList<>();
|
exoPlayerPlaylist = new ArrayList<>();
|
||||||
currentWindowIndex = C.INDEX_UNSET;
|
currentWindowIndex = C.INDEX_UNSET;
|
||||||
|
|
||||||
prepared = player.getPlaybackState() != Player.STATE_IDLE;
|
|
||||||
rebuffering = player.getPlaybackState() == Player.STATE_BUFFERING;
|
|
||||||
|
|
||||||
updatePlaylist(player.getCurrentTimeline());
|
updatePlaylist(player.getCurrentTimeline());
|
||||||
|
|
||||||
|
sessionPlayerState = evaluateSessionPlayerState();
|
||||||
|
@Player.State int playbackState = player.getPlaybackState();
|
||||||
|
prepared = playbackState != Player.STATE_IDLE;
|
||||||
|
if (playbackState == Player.STATE_BUFFERING) {
|
||||||
|
bufferingItem = getCurrentMediaItem();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setControlDispatcher(ControlDispatcher controlDispatcher) {
|
public void setControlDispatcher(ControlDispatcher controlDispatcher) {
|
||||||
@ -360,7 +364,7 @@ import java.util.List;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* @SessionPlayer.PlayerState */
|
/* @SessionPlayer.PlayerState */
|
||||||
private int getState() {
|
private int evaluateSessionPlayerState() {
|
||||||
if (hasError()) {
|
if (hasError()) {
|
||||||
return SessionPlayer.PLAYER_STATE_ERROR;
|
return SessionPlayer.PLAYER_STATE_ERROR;
|
||||||
}
|
}
|
||||||
@ -381,6 +385,63 @@ import java.util.List;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateSessionPlayerState() {
|
||||||
|
int newState = evaluateSessionPlayerState();
|
||||||
|
if (sessionPlayerState != newState) {
|
||||||
|
sessionPlayerState = newState;
|
||||||
|
listener.onPlayerStateChanged(newState);
|
||||||
|
if (newState == SessionPlayer.PLAYER_STATE_ERROR) {
|
||||||
|
listener.onError(getCurrentMediaItem());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateBufferingState(boolean isBuffering) {
|
||||||
|
if (isBuffering) {
|
||||||
|
androidx.media2.common.MediaItem curMediaItem = getCurrentMediaItem();
|
||||||
|
if (prepared && (bufferingItem == null || !bufferingItem.equals(curMediaItem))) {
|
||||||
|
bufferingItem = getCurrentMediaItem();
|
||||||
|
listener.onBufferingStarted(Assertions.checkNotNull(bufferingItem));
|
||||||
|
}
|
||||||
|
} else if (bufferingItem != null) {
|
||||||
|
listener.onBufferingEnded(bufferingItem, player.getBufferedPercentage());
|
||||||
|
bufferingItem = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handlePlayerStateChanged() {
|
||||||
|
updateSessionPlayerState();
|
||||||
|
|
||||||
|
int playbackState = player.getPlaybackState();
|
||||||
|
handler.removeCallbacks(pollBufferRunnable);
|
||||||
|
|
||||||
|
switch (playbackState) {
|
||||||
|
case Player.STATE_IDLE:
|
||||||
|
prepared = false;
|
||||||
|
updateBufferingState(/* isBuffering= */ false);
|
||||||
|
break;
|
||||||
|
case Player.STATE_BUFFERING:
|
||||||
|
updateBufferingState(/* isBuffering= */ true);
|
||||||
|
postOrRun(handler, pollBufferRunnable);
|
||||||
|
break;
|
||||||
|
case Player.STATE_READY:
|
||||||
|
if (!prepared) {
|
||||||
|
prepared = true;
|
||||||
|
handlePositionDiscontinuity(Player.DISCONTINUITY_REASON_PERIOD_TRANSITION);
|
||||||
|
listener.onPrepared(
|
||||||
|
Assertions.checkNotNull(getCurrentMediaItem()), player.getBufferedPercentage());
|
||||||
|
}
|
||||||
|
updateBufferingState(/* isBuffering= */ false);
|
||||||
|
postOrRun(handler, pollBufferRunnable);
|
||||||
|
break;
|
||||||
|
case Player.STATE_ENDED:
|
||||||
|
listener.onPlaybackEnded();
|
||||||
|
player.setPlayWhenReady(false);
|
||||||
|
updateBufferingState(/* isBuffering= */ false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void setAudioAttributes(AudioAttributesCompat audioAttributes) {
|
public void setAudioAttributes(AudioAttributesCompat audioAttributes) {
|
||||||
Player.AudioComponent audioComponent = Assertions.checkStateNotNull(player.getAudioComponent());
|
Player.AudioComponent audioComponent = Assertions.checkStateNotNull(player.getAudioComponent());
|
||||||
audioComponent.setAudioAttributes(
|
audioComponent.setAudioAttributes(
|
||||||
@ -407,7 +468,7 @@ import java.util.List;
|
|||||||
public void reset() {
|
public void reset() {
|
||||||
controlDispatcher.dispatchStop(player, /* reset= */ true);
|
controlDispatcher.dispatchStop(player, /* reset= */ true);
|
||||||
prepared = false;
|
prepared = false;
|
||||||
rebuffering = false;
|
bufferingItem = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
@ -446,35 +507,6 @@ import java.util.List;
|
|||||||
return player.getPlayerError() != null;
|
return player.getPlayerError() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handlePlayWhenReadyChanged() {
|
|
||||||
listener.onPlayerStateChanged(getState());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handlePlayerStateChanged(@Player.State int state) {
|
|
||||||
if (state == Player.STATE_READY || state == Player.STATE_BUFFERING) {
|
|
||||||
postOrRun(handler, pollBufferRunnable);
|
|
||||||
} else {
|
|
||||||
handler.removeCallbacks(pollBufferRunnable);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (state) {
|
|
||||||
case Player.STATE_BUFFERING:
|
|
||||||
maybeNotifyBufferingEvents();
|
|
||||||
break;
|
|
||||||
case Player.STATE_READY:
|
|
||||||
maybeNotifyReadyEvents();
|
|
||||||
break;
|
|
||||||
case Player.STATE_ENDED:
|
|
||||||
maybeNotifyEndedEvents();
|
|
||||||
break;
|
|
||||||
case Player.STATE_IDLE:
|
|
||||||
// Do nothing.
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new IllegalStateException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handlePositionDiscontinuity(@Player.DiscontinuityReason int reason) {
|
private void handlePositionDiscontinuity(@Player.DiscontinuityReason int reason) {
|
||||||
int currentWindowIndex = getCurrentMediaItemIndex();
|
int currentWindowIndex = getCurrentMediaItemIndex();
|
||||||
if (this.currentWindowIndex != currentWindowIndex) {
|
if (this.currentWindowIndex != currentWindowIndex) {
|
||||||
@ -487,34 +519,6 @@ import java.util.List;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handlePlayerError() {
|
|
||||||
listener.onPlayerStateChanged(SessionPlayer.PLAYER_STATE_ERROR);
|
|
||||||
listener.onError(getCurrentMediaItem());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleRepeatModeChanged(@Player.RepeatMode int repeatMode) {
|
|
||||||
listener.onRepeatModeChanged(Utils.getRepeatMode(repeatMode));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleShuffleMode(boolean shuffleModeEnabled) {
|
|
||||||
listener.onShuffleModeChanged(Utils.getShuffleMode(shuffleModeEnabled));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handlePlaybackParametersChanged(PlaybackParameters playbackParameters) {
|
|
||||||
listener.onPlaybackSpeedChanged(playbackParameters.speed);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleTimelineChanged(Timeline timeline) {
|
|
||||||
if (ignoreTimelineUpdates) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!isExoPlayerMediaItemsChanged(timeline)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
updatePlaylist(timeline);
|
|
||||||
listener.onPlaylistChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check whether Timeline is changed by media item changes or not
|
// Check whether Timeline is changed by media item changes or not
|
||||||
private boolean isExoPlayerMediaItemsChanged(Timeline timeline) {
|
private boolean isExoPlayerMediaItemsChanged(Timeline timeline) {
|
||||||
if (exoPlayerPlaylist.size() != timeline.getWindowCount()) {
|
if (exoPlayerPlaylist.size() != timeline.getWindowCount()) {
|
||||||
@ -554,10 +558,6 @@ import java.util.List;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleAudioAttributesChanged(AudioAttributes audioAttributes) {
|
|
||||||
listener.onAudioAttributesChanged(Utils.getAudioAttributesCompat(audioAttributes));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateBufferingAndScheduleNextPollBuffer() {
|
private void updateBufferingAndScheduleNextPollBuffer() {
|
||||||
androidx.media2.common.MediaItem media2MediaItem =
|
androidx.media2.common.MediaItem media2MediaItem =
|
||||||
Assertions.checkNotNull(getCurrentMediaItem());
|
Assertions.checkNotNull(getCurrentMediaItem());
|
||||||
@ -566,39 +566,6 @@ import java.util.List;
|
|||||||
handler.postDelayed(pollBufferRunnable, POLL_BUFFER_INTERVAL_MS);
|
handler.postDelayed(pollBufferRunnable, POLL_BUFFER_INTERVAL_MS);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void maybeNotifyBufferingEvents() {
|
|
||||||
androidx.media2.common.MediaItem media2MediaItem =
|
|
||||||
Assertions.checkNotNull(getCurrentMediaItem());
|
|
||||||
if (prepared && !rebuffering) {
|
|
||||||
rebuffering = true;
|
|
||||||
listener.onBufferingStarted(media2MediaItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void maybeNotifyReadyEvents() {
|
|
||||||
androidx.media2.common.MediaItem media2MediaItem =
|
|
||||||
Assertions.checkNotNull(getCurrentMediaItem());
|
|
||||||
boolean prepareComplete = !prepared;
|
|
||||||
if (prepareComplete) {
|
|
||||||
prepared = true;
|
|
||||||
handlePositionDiscontinuity(Player.DISCONTINUITY_REASON_PERIOD_TRANSITION);
|
|
||||||
listener.onPlayerStateChanged(SessionPlayer.PLAYER_STATE_PAUSED);
|
|
||||||
listener.onPrepared(media2MediaItem, player.getBufferedPercentage());
|
|
||||||
}
|
|
||||||
if (rebuffering) {
|
|
||||||
rebuffering = false;
|
|
||||||
listener.onBufferingEnded(media2MediaItem, player.getBufferedPercentage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void maybeNotifyEndedEvents() {
|
|
||||||
if (player.getPlayWhenReady()) {
|
|
||||||
listener.onPlayerStateChanged(SessionPlayer.PLAYER_STATE_PAUSED);
|
|
||||||
listener.onPlaybackEnded();
|
|
||||||
player.setPlayWhenReady(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void releaseMediaItem(androidx.media2.common.MediaItem media2MediaItem) {
|
private void releaseMediaItem(androidx.media2.common.MediaItem media2MediaItem) {
|
||||||
try {
|
try {
|
||||||
if (media2MediaItem instanceof CallbackMediaItem) {
|
if (media2MediaItem instanceof CallbackMediaItem) {
|
||||||
@ -615,12 +582,12 @@ import java.util.List;
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlayWhenReadyChanged(boolean playWhenReady, int reason) {
|
public void onPlayWhenReadyChanged(boolean playWhenReady, int reason) {
|
||||||
handlePlayWhenReadyChanged();
|
updateSessionPlayerState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlaybackStateChanged(@Player.State int state) {
|
public void onPlaybackStateChanged(@Player.State int state) {
|
||||||
handlePlayerStateChanged(state);
|
handlePlayerStateChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -630,34 +597,41 @@ import java.util.List;
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlayerError(ExoPlaybackException error) {
|
public void onPlayerError(ExoPlaybackException error) {
|
||||||
handlePlayerError();
|
updateSessionPlayerState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRepeatModeChanged(@Player.RepeatMode int repeatMode) {
|
public void onRepeatModeChanged(@Player.RepeatMode int repeatMode) {
|
||||||
handleRepeatModeChanged(repeatMode);
|
listener.onRepeatModeChanged(Utils.getRepeatMode(repeatMode));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
|
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
|
||||||
handleShuffleMode(shuffleModeEnabled);
|
listener.onShuffleModeChanged(Utils.getShuffleMode(shuffleModeEnabled));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
|
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
|
||||||
handlePlaybackParametersChanged(playbackParameters);
|
listener.onPlaybackSpeedChanged(playbackParameters.speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTimelineChanged(Timeline timeline, int reason) {
|
public void onTimelineChanged(Timeline timeline, int reason) {
|
||||||
handleTimelineChanged(timeline);
|
if (ignoreTimelineUpdates) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!isExoPlayerMediaItemsChanged(timeline)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
updatePlaylist(timeline);
|
||||||
|
listener.onPlaylistChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
// AudioListener implementation.
|
// AudioListener implementation.
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAudioAttributesChanged(AudioAttributes audioAttributes) {
|
public void onAudioAttributesChanged(AudioAttributes audioAttributes) {
|
||||||
handleAudioAttributesChanged(audioAttributes);
|
listener.onAudioAttributesChanged(Utils.getAudioAttributesCompat(audioAttributes));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user