use of androidx.media2.common.SessionPlayer.PlayerResult 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.PlayerResult in project ExoPlayer by google.
the class SessionPlayerConnectorTest method seekTo_whenUnderlyingPlayerAlsoSeeks_throwsNoException.
@Test
@LargeTest
public void seekTo_whenUnderlyingPlayerAlsoSeeks_throwsNoException() throws Exception {
TestUtils.loadResource(R.raw.video_big_buck_bunny, sessionPlayerConnector);
assertPlayerResultSuccess(sessionPlayerConnector.prepare());
ExoPlayer exoPlayer = playerTestRule.getExoPlayer();
List<ListenableFuture<PlayerResult>> futures = new ArrayList<>();
for (int i = 0; i < 10; i++) {
futures.add(sessionPlayerConnector.seekTo(4123));
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> exoPlayer.seekTo(1243));
}
for (ListenableFuture<PlayerResult> future : futures) {
assertThat(future.get().getResultCode()).isAnyOf(PlayerResult.RESULT_INFO_SKIPPED, PlayerResult.RESULT_SUCCESS);
}
}
use of androidx.media2.common.SessionPlayer.PlayerResult in project ExoPlayer by google.
the class PlayerCommandQueue method addCommand.
public ListenableFuture<PlayerResult> addCommand(@CommandCode int commandCode, Callable<Boolean> command, @Nullable Object tag) {
SettableFuture<PlayerResult> result = SettableFuture.create();
synchronized (lock) {
PlayerCommand playerCommand = new PlayerCommand(commandCode, command, result, tag);
result.addListener(() -> {
if (result.isCancelled()) {
boolean isCommandPending;
synchronized (lock) {
isCommandPending = pendingPlayerCommandQueue.remove(playerCommand);
}
if (isCommandPending) {
result.set(new PlayerResult(PlayerResult.RESULT_INFO_SKIPPED, player.getCurrentMediaItem()));
if (DEBUG) {
Log.d(TAG, "canceled " + playerCommand);
}
}
if (pendingAsyncPlayerCommandResult != null && pendingAsyncPlayerCommandResult.result == result) {
pendingAsyncPlayerCommandResult = null;
}
}
processPendingCommandOnHandler();
}, (runnable) -> postOrRun(handler, runnable));
if (DEBUG) {
Log.d(TAG, "adding " + playerCommand);
}
pendingPlayerCommandQueue.add(playerCommand);
}
processPendingCommand();
return result;
}
use of androidx.media2.common.SessionPlayer.PlayerResult in project ExoPlayer by google.
the class PlayerCommandQueue method notifyCommandCompleted.
public void notifyCommandCompleted(@AsyncCommandCode int completedCommandCode) {
if (DEBUG) {
Log.d(TAG, "notifyCommandCompleted, completedCommandCode=" + completedCommandCode);
}
postOrRun(handler, () -> {
@Nullable AsyncPlayerCommandResult pendingResult = pendingAsyncPlayerCommandResult;
if (pendingResult == null || pendingResult.commandCode != completedCommandCode) {
if (DEBUG) {
Log.d(TAG, "Unexpected Listener is notified from the Player. Player may be used" + " directly rather than " + toLogFriendlyString(completedCommandCode));
}
return;
}
pendingResult.result.set(new PlayerResult(PlayerResult.RESULT_SUCCESS, player.getCurrentMediaItem()));
pendingAsyncPlayerCommandResult = null;
if (DEBUG) {
Log.d(TAG, "completed " + pendingResult);
}
processPendingCommandOnHandler();
});
}
use of androidx.media2.common.SessionPlayer.PlayerResult in project ExoPlayer by google.
the class PlayerCommandQueue method reset.
public void reset() {
handler.removeCallbacksAndMessages(/* token= */
null);
List<PlayerCommand> queue;
synchronized (lock) {
queue = new ArrayList<>(pendingPlayerCommandQueue);
pendingPlayerCommandQueue.clear();
}
for (PlayerCommand playerCommand : queue) {
playerCommand.result.set(new PlayerResult(PlayerResult.RESULT_INFO_SKIPPED, /* item= */
null));
}
}
Aggregations