use of androidx.media2.common.SessionPlayer in project ExoPlayer by google.
the class SessionPlayerConnectorTest method setMediaItem_withAudioResource_notifiesOnPlaybackCompleted.
@Test
@LargeTest
public void setMediaItem_withAudioResource_notifiesOnPlaybackCompleted() throws Exception {
TestUtils.loadResource(R.raw.audio, sessionPlayerConnector);
CountDownLatch onPlaybackCompletedLatch = new CountDownLatch(1);
sessionPlayerConnector.registerPlayerCallback(executor, new SessionPlayer.PlayerCallback() {
@Override
public void onPlaybackCompleted(SessionPlayer player) {
onPlaybackCompletedLatch.countDown();
}
});
sessionPlayerConnector.prepare();
sessionPlayerConnector.play();
// waiting to complete
assertThat(onPlaybackCompletedLatch.await(PLAYBACK_COMPLETED_WAIT_TIME_MS, MILLISECONDS)).isTrue();
assertThat(sessionPlayerConnector.getPlayerState()).isEqualTo(SessionPlayer.PLAYER_STATE_PAUSED);
}
use of androidx.media2.common.SessionPlayer in project ExoPlayer by google.
the class SessionPlayerConnectorTest method prepare_notifiesBufferingCompletedOnce.
@Test
@LargeTest
public void prepare_notifiesBufferingCompletedOnce() throws Throwable {
TestUtils.loadResource(R.raw.video_big_buck_bunny, sessionPlayerConnector);
CountDownLatch onBufferingCompletedLatch = new CountDownLatch(2);
CopyOnWriteArrayList<Integer> bufferingStateChanges = new CopyOnWriteArrayList<>();
SessionPlayer.PlayerCallback callback = new SessionPlayer.PlayerCallback() {
@Override
public void onBufferingStateChanged(SessionPlayer player, @Nullable MediaItem item, int buffState) {
bufferingStateChanges.add(buffState);
if (buffState == SessionPlayer.BUFFERING_STATE_COMPLETE) {
onBufferingCompletedLatch.countDown();
}
}
};
sessionPlayerConnector.registerPlayerCallback(executor, callback);
assertPlayerResultSuccess(sessionPlayerConnector.prepare());
assertWithMessage("Expected BUFFERING_STATE_COMPLETE only once. Full changes are %s", bufferingStateChanges).that(onBufferingCompletedLatch.await(PLAYER_STATE_CHANGE_WAIT_TIME_MS, MILLISECONDS)).isFalse();
assertThat(bufferingStateChanges).isNotEmpty();
int lastIndex = bufferingStateChanges.size() - 1;
assertWithMessage("Didn't end with BUFFERING_STATE_COMPLETE. Full changes are %s", bufferingStateChanges).that(bufferingStateChanges.get(lastIndex)).isEqualTo(SessionPlayer.BUFFERING_STATE_COMPLETE);
}
use of androidx.media2.common.SessionPlayer in project ExoPlayer by google.
the class SessionPlayerConnectorTest method seekTo_skipsUnnecessarySeek.
@Test
@LargeTest
public void seekTo_skipsUnnecessarySeek() throws Exception {
CountDownLatch readAllowedLatch = new CountDownLatch(1);
playerTestRule.setDataSourceInstrumentation(dataSpec -> {
try {
assertThat(readAllowedLatch.await(PLAYBACK_COMPLETED_WAIT_TIME_MS, MILLISECONDS)).isTrue();
} catch (Exception e) {
assertWithMessage("Unexpected exception %s", e).fail();
}
});
sessionPlayerConnector.setMediaItem(TestUtils.createMediaItem(R.raw.video_big_buck_bunny));
// prepare() will be pending until readAllowed is countDowned.
sessionPlayerConnector.prepare();
CopyOnWriteArrayList<Long> positionChanges = new CopyOnWriteArrayList<>();
long testIntermediateSeekToPosition1 = 3000;
long testIntermediateSeekToPosition2 = 2000;
long testFinalSeekToPosition = 1000;
CountDownLatch onSeekCompletedLatch = new CountDownLatch(1);
sessionPlayerConnector.registerPlayerCallback(executor, new SessionPlayer.PlayerCallback() {
@Override
public void onSeekCompleted(SessionPlayer player, long position) {
// Do not assert here, because onSeekCompleted() can be called after the player is
// closed.
positionChanges.add(position);
if (position == testFinalSeekToPosition) {
onSeekCompletedLatch.countDown();
}
}
});
ListenableFuture<PlayerResult> seekFuture1 = sessionPlayerConnector.seekTo(testIntermediateSeekToPosition1);
ListenableFuture<PlayerResult> seekFuture2 = sessionPlayerConnector.seekTo(testIntermediateSeekToPosition2);
ListenableFuture<PlayerResult> seekFuture3 = sessionPlayerConnector.seekTo(testFinalSeekToPosition);
readAllowedLatch.countDown();
assertThat(seekFuture1.get().getResultCode()).isEqualTo(RESULT_INFO_SKIPPED);
assertThat(seekFuture2.get().getResultCode()).isEqualTo(RESULT_INFO_SKIPPED);
assertThat(seekFuture3.get().getResultCode()).isEqualTo(RESULT_SUCCESS);
assertThat(onSeekCompletedLatch.await(PLAYBACK_COMPLETED_WAIT_TIME_MS, MILLISECONDS)).isTrue();
assertThat(positionChanges).containsNoneOf(testIntermediateSeekToPosition1, testIntermediateSeekToPosition2);
assertThat(positionChanges).contains(testFinalSeekToPosition);
}
use of androidx.media2.common.SessionPlayer in project ExoPlayer by google.
the class SessionPlayerConnectorTest method setPlaybackSpeed_whenPrepared_notifiesOnPlaybackSpeedChanged.
@Test
@LargeTest
public void setPlaybackSpeed_whenPrepared_notifiesOnPlaybackSpeedChanged() throws Throwable {
TestUtils.loadResource(R.raw.video_big_buck_bunny, sessionPlayerConnector);
assertPlayerResultSuccess(sessionPlayerConnector.prepare());
CountDownLatch onPlaybackSpeedChangedLatch = new CountDownLatch(1);
SessionPlayer.PlayerCallback callback = new SessionPlayer.PlayerCallback() {
@Override
public void onPlaybackSpeedChanged(SessionPlayer player, float speed) {
assertThat(speed).isWithin(FLOAT_TOLERANCE).of(0.5f);
onPlaybackSpeedChangedLatch.countDown();
}
};
sessionPlayerConnector.registerPlayerCallback(executor, callback);
sessionPlayerConnector.setPlaybackSpeed(0.5f);
assertThat(onPlaybackSpeedChangedLatch.await(PLAYER_STATE_CHANGE_WAIT_TIME_MS, MILLISECONDS)).isTrue();
}
use of androidx.media2.common.SessionPlayer in project ExoPlayer by google.
the class SessionCallback method buildAllowedCommands.
private SessionCommandGroup buildAllowedCommands(MediaSession session, MediaSession.ControllerInfo controllerInfo) {
SessionCommandGroup.Builder build;
@Nullable SessionCommandGroup commands = (customCommandProvider != null) ? customCommandProvider.getCustomCommands(session, controllerInfo) : null;
if (commands != null) {
build = new SessionCommandGroup.Builder(commands);
} else {
build = new SessionCommandGroup.Builder();
}
build.addAllPredefinedCommands(SessionCommand.COMMAND_VERSION_1);
build.addCommand(new SessionCommand(SessionCommand.COMMAND_CODE_PLAYER_MOVE_PLAYLIST_ITEM));
// TODO(internal b/142848015): Use removeCommand(int) when it's added.
if (mediaItemProvider == null) {
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_PLAYER_SET_MEDIA_ITEM));
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_PLAYER_SET_PLAYLIST));
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_PLAYER_ADD_PLAYLIST_ITEM));
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_PLAYER_REPLACE_PLAYLIST_ITEM));
}
if (ratingCallback == null) {
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_SESSION_SET_RATING));
}
if (skipCallback == null) {
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_SESSION_SKIP_BACKWARD));
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_SESSION_SKIP_FORWARD));
}
// Check whether the session has unexpectedly changed the player.
if (session.getPlayer() instanceof SessionPlayerConnector) {
SessionPlayerConnector sessionPlayerConnector = (SessionPlayerConnector) session.getPlayer();
// Check whether skipTo* works.
if (!sessionPlayerConnector.canSkipToPlaylistItem()) {
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_PLAYER_SKIP_TO_PLAYLIST_ITEM));
}
if (!sessionPlayerConnector.canSkipToPreviousPlaylistItem()) {
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_PLAYER_SKIP_TO_PREVIOUS_PLAYLIST_ITEM));
}
if (!sessionPlayerConnector.canSkipToNextPlaylistItem()) {
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_PLAYER_SKIP_TO_NEXT_PLAYLIST_ITEM));
}
// Check whether seekTo/rewind/fastForward works.
if (!sessionPlayerConnector.isCurrentMediaItemSeekable()) {
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_PLAYER_SEEK_TO));
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_SESSION_FAST_FORWARD));
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_SESSION_REWIND));
} else {
if (fastForwardMs <= 0) {
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_SESSION_FAST_FORWARD));
}
if (rewindMs <= 0) {
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_SESSION_REWIND));
}
}
} else {
if (!loggedUnexpectedSessionPlayerWarning) {
// This can happen if MediaSession#updatePlayer() is called.
Log.e(TAG, "SessionPlayer isn't a SessionPlayerConnector. Guess the allowed command.");
loggedUnexpectedSessionPlayerWarning = true;
}
if (fastForwardMs <= 0) {
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_SESSION_FAST_FORWARD));
}
if (rewindMs <= 0) {
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_SESSION_REWIND));
}
@Nullable List<MediaItem> playlist = sessionPlayer.getPlaylist();
if (playlist == null) {
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_PLAYER_SKIP_TO_PREVIOUS_PLAYLIST_ITEM));
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_PLAYER_SKIP_TO_NEXT_PLAYLIST_ITEM));
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_PLAYER_SKIP_TO_PLAYLIST_ITEM));
} else {
if (playlist.isEmpty() && (sessionPlayer.getRepeatMode() == SessionPlayer.REPEAT_MODE_NONE || sessionPlayer.getRepeatMode() == SessionPlayer.REPEAT_MODE_ONE)) {
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_PLAYER_SKIP_TO_PREVIOUS_PLAYLIST_ITEM));
}
if (playlist.size() == sessionPlayer.getCurrentMediaItemIndex() + 1 && (sessionPlayer.getRepeatMode() == SessionPlayer.REPEAT_MODE_NONE || sessionPlayer.getRepeatMode() == SessionPlayer.REPEAT_MODE_ONE)) {
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_PLAYER_SKIP_TO_NEXT_PLAYLIST_ITEM));
}
if (playlist.size() <= 1) {
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_PLAYER_SKIP_TO_PLAYLIST_ITEM));
}
}
}
return build.build();
}
Aggregations