Search in sources :

Example 6 with PlayerResult

use of androidx.media2.common.SessionPlayer.PlayerResult in project ExoPlayer by google.

the class PlayerCommandQueue method processPendingCommandOnHandler.

private void processPendingCommandOnHandler() {
    while (pendingAsyncPlayerCommandResult == null) {
        @Nullable PlayerCommand playerCommand;
        synchronized (lock) {
            playerCommand = pendingPlayerCommandQueue.poll();
        }
        if (playerCommand == null) {
            return;
        }
        int commandCode = playerCommand.commandCode;
        // Check if it's @AsyncCommandCode
        boolean asyncCommand = isAsyncCommand(playerCommand.commandCode);
        // Continuous COMMAND_CODE_PLAYER_SEEK_TO can be skipped.
        if (commandCode == COMMAND_CODE_PLAYER_SEEK_TO) {
            @Nullable List<PlayerCommand> skippingCommands = null;
            while (true) {
                synchronized (lock) {
                    @Nullable PlayerCommand pendingCommand = pendingPlayerCommandQueue.peek();
                    if (pendingCommand == null || pendingCommand.commandCode != commandCode) {
                        break;
                    }
                    pendingPlayerCommandQueue.poll();
                    if (skippingCommands == null) {
                        skippingCommands = new ArrayList<>();
                    }
                    skippingCommands.add(playerCommand);
                    playerCommand = pendingCommand;
                }
            }
            if (skippingCommands != null) {
                for (PlayerCommand skippingCommand : skippingCommands) {
                    skippingCommand.result.set(new PlayerResult(PlayerResult.RESULT_INFO_SKIPPED, player.getCurrentMediaItem()));
                    if (DEBUG) {
                        Log.d(TAG, "skipping pending command, " + skippingCommand);
                    }
                }
            }
        }
        if (asyncCommand) {
            // Result would come later, via #notifyCommandCompleted().
            // Set pending player result first because it may be notified while the command is running.
            pendingAsyncPlayerCommandResult = new AsyncPlayerCommandResult(commandCode, playerCommand.result);
        }
        if (DEBUG) {
            Log.d(TAG, "start processing command, " + playerCommand);
        }
        int resultCode;
        if (player.hasError()) {
            resultCode = PlayerResult.RESULT_ERROR_INVALID_STATE;
        } else {
            try {
                boolean handled = playerCommand.command.call();
                resultCode = handled ? PlayerResult.RESULT_SUCCESS : PlayerResult.RESULT_INFO_SKIPPED;
            } catch (IllegalStateException e) {
                resultCode = PlayerResult.RESULT_ERROR_INVALID_STATE;
            } catch (IllegalArgumentException | IndexOutOfBoundsException e) {
                resultCode = PlayerResult.RESULT_ERROR_BAD_VALUE;
            } catch (SecurityException e) {
                resultCode = PlayerResult.RESULT_ERROR_PERMISSION_DENIED;
            } catch (Exception e) {
                resultCode = PlayerResult.RESULT_ERROR_UNKNOWN;
            }
        }
        if (DEBUG) {
            Log.d(TAG, "command processed, " + playerCommand);
        }
        if (asyncCommand) {
            if (resultCode != PlayerResult.RESULT_SUCCESS && pendingAsyncPlayerCommandResult != null && playerCommand.result == pendingAsyncPlayerCommandResult.result) {
                pendingAsyncPlayerCommandResult = null;
                playerCommand.result.set(new PlayerResult(resultCode, player.getCurrentMediaItem()));
            }
        } else {
            playerCommand.result.set(new PlayerResult(resultCode, player.getCurrentMediaItem()));
        }
    }
}
Also used : PlayerResult(androidx.media2.common.SessionPlayer.PlayerResult) Nullable(androidx.annotation.Nullable)

Example 7 with PlayerResult

use of androidx.media2.common.SessionPlayer.PlayerResult in project ExoPlayer by google.

the class TestUtils method assertPlayerResult.

public static void assertPlayerResult(Future<PlayerResult> future, /* @PlayerResult.ResultCode */
int playerResult) throws Exception {
    assertThat(future).isNotNull();
    PlayerResult result = future.get(PLAYER_STATE_CHANGE_WAIT_TIME_MS, MILLISECONDS);
    assertThat(result).isNotNull();
    assertThat(result.getResultCode()).isEqualTo(playerResult);
}
Also used : PlayerResult(androidx.media2.common.SessionPlayer.PlayerResult)

Example 8 with PlayerResult

use of androidx.media2.common.SessionPlayer.PlayerResult in project ExoPlayer by google.

the class SessionPlayerConnectorTest method cancelReturnedFuture_withSeekTo_cancelsPendingCommand.

@Test
@LargeTest
public void cancelReturnedFuture_withSeekTo_cancelsPendingCommand() throws Exception {
    CountDownLatch readRequestedLatch = new CountDownLatch(1);
    CountDownLatch readAllowedLatch = new CountDownLatch(1);
    // Need to wait from prepare() to counting down readAllowedLatch.
    playerTestRule.setDataSourceInstrumentation(dataSpec -> {
        readRequestedLatch.countDown();
        try {
            assertThat(readAllowedLatch.await(PLAYER_STATE_CHANGE_WAIT_TIME_MS, MILLISECONDS)).isTrue();
        } catch (Exception e) {
            assertWithMessage("Unexpected exception %s", e).fail();
        }
    });
    assertPlayerResultSuccess(sessionPlayerConnector.setMediaItem(TestUtils.createMediaItem(R.raw.audio)));
    // prepare() will be pending until readAllowed is countDowned.
    ListenableFuture<PlayerResult> prepareFuture = sessionPlayerConnector.prepare();
    ListenableFuture<PlayerResult> seekFuture = sessionPlayerConnector.seekTo(1000);
    assertThat(readRequestedLatch.await(PLAYER_STATE_CHANGE_WAIT_TIME_MS, MILLISECONDS)).isTrue();
    // Cancel the pending commands while preparation is on hold.
    seekFuture.cancel(false);
    // Make the on-going prepare operation resumed and finished.
    readAllowedLatch.countDown();
    assertPlayerResultSuccess(prepareFuture);
    // Check whether the canceled seek() didn't happened.
    // Checking seekFuture.get() will be useless because it always throws CancellationException due
    // to the CallbackToFuture implementation.
    Thread.sleep(PLAYER_STATE_CHANGE_WAIT_TIME_MS);
    assertThat(sessionPlayerConnector.getCurrentPosition()).isEqualTo(0);
}
Also used : TestUtils.assertPlayerResult(com.google.android.exoplayer2.ext.media2.TestUtils.assertPlayerResult) PlayerResult(androidx.media2.common.SessionPlayer.PlayerResult) CountDownLatch(java.util.concurrent.CountDownLatch) MediumTest(androidx.test.filters.MediumTest) LargeTest(androidx.test.filters.LargeTest) SmallTest(androidx.test.filters.SmallTest) Test(org.junit.Test) LargeTest(androidx.test.filters.LargeTest)

Example 9 with PlayerResult

use of androidx.media2.common.SessionPlayer.PlayerResult in project ExoPlayer by google.

the class PlayerCommandQueue method notifyCommandError.

public void notifyCommandError() {
    postOrRun(handler, () -> {
        @Nullable AsyncPlayerCommandResult pendingResult = pendingAsyncPlayerCommandResult;
        if (pendingResult == null) {
            if (DEBUG) {
                Log.d(TAG, "Ignoring notifyCommandError(). No pending async command.");
            }
            return;
        }
        pendingResult.result.set(new PlayerResult(PlayerResult.RESULT_ERROR_UNKNOWN, player.getCurrentMediaItem()));
        pendingAsyncPlayerCommandResult = null;
        if (DEBUG) {
            Log.d(TAG, "error on " + pendingResult);
        }
        processPendingCommandOnHandler();
    });
}
Also used : PlayerResult(androidx.media2.common.SessionPlayer.PlayerResult) Nullable(androidx.annotation.Nullable)

Example 10 with PlayerResult

use of androidx.media2.common.SessionPlayer.PlayerResult in project ExoPlayer by google.

the class SessionPlayerConnector method setPlaylist.

/**
 * {@inheritDoc}
 *
 * <p>{@link FileMediaItem} and {@link CallbackMediaItem} are not supported.
 */
@Override
public ListenableFuture<PlayerResult> setPlaylist(final List<MediaItem> playlist, @Nullable MediaMetadata metadata) {
    Assertions.checkNotNull(playlist);
    Assertions.checkArgument(!playlist.isEmpty());
    for (int i = 0; i < playlist.size(); i++) {
        MediaItem item = playlist.get(i);
        Assertions.checkNotNull(item);
        Assertions.checkArgument(!(item instanceof FileMediaItem));
        Assertions.checkArgument(!(item instanceof CallbackMediaItem));
        for (int j = 0; j < i; j++) {
            Assertions.checkArgument(item != playlist.get(j), "playlist shouldn't contain duplicated item, index=" + i + " vs index=" + j);
        }
    }
    ListenableFuture<PlayerResult> result = playerCommandQueue.addCommand(PlayerCommandQueue.COMMAND_CODE_PLAYER_SET_PLAYLIST, /* command= */
    () -> player.setPlaylist(playlist, metadata));
    return result;
}
Also used : CallbackMediaItem(androidx.media2.common.CallbackMediaItem) MediaItem(androidx.media2.common.MediaItem) FileMediaItem(androidx.media2.common.FileMediaItem) CallbackMediaItem(androidx.media2.common.CallbackMediaItem) FileMediaItem(androidx.media2.common.FileMediaItem)

Aggregations

PlayerResult (androidx.media2.common.SessionPlayer.PlayerResult)9 Nullable (androidx.annotation.Nullable)3 LargeTest (androidx.test.filters.LargeTest)3 MediumTest (androidx.test.filters.MediumTest)3 SmallTest (androidx.test.filters.SmallTest)3 TestUtils.assertPlayerResult (com.google.android.exoplayer2.ext.media2.TestUtils.assertPlayerResult)3 Test (org.junit.Test)3 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)2 CountDownLatch (java.util.concurrent.CountDownLatch)2 CallbackMediaItem (androidx.media2.common.CallbackMediaItem)1 FileMediaItem (androidx.media2.common.FileMediaItem)1 MediaItem (androidx.media2.common.MediaItem)1 SessionPlayer (androidx.media2.common.SessionPlayer)1 ExoPlayer (com.google.android.exoplayer2.ExoPlayer)1 ListenableFuture (com.google.common.util.concurrent.ListenableFuture)1 ArrayList (java.util.ArrayList)1 AtomicLong (java.util.concurrent.atomic.AtomicLong)1