Search in sources :

Example 1 with SessionPlayer

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);
}
Also used : SessionPlayer(androidx.media2.common.SessionPlayer) 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 2 with SessionPlayer

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);
}
Also used : UriMediaItem(androidx.media2.common.UriMediaItem) MediaItem(androidx.media2.common.MediaItem) SessionPlayer(androidx.media2.common.SessionPlayer) CountDownLatch(java.util.concurrent.CountDownLatch) Nullable(androidx.annotation.Nullable) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) 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 3 with SessionPlayer

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);
}
Also used : TestUtils.assertPlayerResult(com.google.android.exoplayer2.ext.media2.TestUtils.assertPlayerResult) PlayerResult(androidx.media2.common.SessionPlayer.PlayerResult) SessionPlayer(androidx.media2.common.SessionPlayer) AtomicLong(java.util.concurrent.atomic.AtomicLong) CountDownLatch(java.util.concurrent.CountDownLatch) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) 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 4 with SessionPlayer

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();
}
Also used : SessionPlayer(androidx.media2.common.SessionPlayer) 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 5 with SessionPlayer

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();
}
Also used : SessionCommandGroup(androidx.media2.session.SessionCommandGroup) MediaItem(androidx.media2.common.MediaItem) SessionCommand(androidx.media2.session.SessionCommand) Nullable(androidx.annotation.Nullable)

Aggregations

LargeTest (androidx.test.filters.LargeTest)26 Test (org.junit.Test)26 SessionPlayer (androidx.media2.common.SessionPlayer)25 MediumTest (androidx.test.filters.MediumTest)25 SmallTest (androidx.test.filters.SmallTest)25 CountDownLatch (java.util.concurrent.CountDownLatch)24 MediaItem (androidx.media2.common.MediaItem)16 UriMediaItem (androidx.media2.common.UriMediaItem)15 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)11 ArrayList (java.util.ArrayList)9 MediaMetadata (androidx.media2.common.MediaMetadata)8 ExoPlayer (com.google.android.exoplayer2.ExoPlayer)5 Nullable (androidx.annotation.Nullable)3 AudioAttributesCompat (androidx.media.AudioAttributesCompat)2 SessionCommand (androidx.media2.session.SessionCommand)2 SessionCommandGroup (androidx.media2.session.SessionCommandGroup)2 List (java.util.List)2 AtomicLong (java.util.concurrent.atomic.AtomicLong)2 Context (android.content.Context)1 Uri (android.net.Uri)1