Search in sources :

Example 1 with MediaItem

use of androidx.media2.common.MediaItem 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 2 with MediaItem

use of androidx.media2.common.MediaItem in project ExoPlayer by google.

the class DefaultMediaItemConverter method convertToExoPlayerMediaItem.

@Override
public MediaItem convertToExoPlayerMediaItem(androidx.media2.common.MediaItem media2MediaItem) {
    if (media2MediaItem instanceof FileMediaItem) {
        throw new IllegalStateException("FileMediaItem isn't supported");
    }
    if (media2MediaItem instanceof CallbackMediaItem) {
        throw new IllegalStateException("CallbackMediaItem isn't supported");
    }
    @Nullable Uri uri = null;
    @Nullable String mediaId = null;
    @Nullable String title = null;
    if (media2MediaItem instanceof UriMediaItem) {
        UriMediaItem uriMediaItem = (UriMediaItem) media2MediaItem;
        uri = uriMediaItem.getUri();
    }
    @Nullable androidx.media2.common.MediaMetadata metadata = media2MediaItem.getMetadata();
    if (metadata != null) {
        @Nullable String uriString = metadata.getString(METADATA_KEY_MEDIA_URI);
        mediaId = metadata.getString(METADATA_KEY_MEDIA_ID);
        if (uri == null) {
            if (uriString != null) {
                uri = Uri.parse(uriString);
            } else if (mediaId != null) {
                uri = Uri.parse("media2:///" + mediaId);
            }
        }
        title = metadata.getString(METADATA_KEY_DISPLAY_TITLE);
        if (title == null) {
            title = metadata.getString(METADATA_KEY_TITLE);
        }
    }
    if (uri == null) {
        // Generate a URI to make it non-null. If not, then the tag passed to setTag will be ignored.
        uri = Uri.parse("media2:///");
    }
    long startPositionMs = media2MediaItem.getStartPosition();
    if (startPositionMs == androidx.media2.common.MediaItem.POSITION_UNKNOWN) {
        startPositionMs = 0;
    }
    long endPositionMs = media2MediaItem.getEndPosition();
    if (endPositionMs == androidx.media2.common.MediaItem.POSITION_UNKNOWN) {
        endPositionMs = C.TIME_END_OF_SOURCE;
    }
    return new MediaItem.Builder().setUri(uri).setMediaId(mediaId != null ? mediaId : MediaItem.DEFAULT_MEDIA_ID).setMediaMetadata(new MediaMetadata.Builder().setTitle(title).build()).setTag(media2MediaItem).setClippingConfiguration(new MediaItem.ClippingConfiguration.Builder().setStartPositionMs(startPositionMs).setEndPositionMs(endPositionMs).build()).build();
}
Also used : CallbackMediaItem(androidx.media2.common.CallbackMediaItem) Uri(android.net.Uri) FileMediaItem(androidx.media2.common.FileMediaItem) Nullable(androidx.annotation.Nullable) UriMediaItem(androidx.media2.common.UriMediaItem)

Example 3 with MediaItem

use of androidx.media2.common.MediaItem 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)

Example 4 with MediaItem

use of androidx.media2.common.MediaItem in project ExoPlayer by google.

the class SessionPlayerConnector method notifySkipToCompletedOnHandler.

private void notifySkipToCompletedOnHandler() {
    MediaItem currentMediaItem = Assertions.checkNotNull(player.getCurrentMediaItem());
    if (Util.areEqual(this.currentMediaItem, currentMediaItem)) {
        return;
    }
    this.currentMediaItem = currentMediaItem;
    long currentPosition = getCurrentPosition();
    notifySessionPlayerCallback(callback -> {
        callback.onCurrentMediaItemChanged(SessionPlayerConnector.this, currentMediaItem);
    });
}
Also used : CallbackMediaItem(androidx.media2.common.CallbackMediaItem) MediaItem(androidx.media2.common.MediaItem) FileMediaItem(androidx.media2.common.FileMediaItem)

Example 5 with MediaItem

use of androidx.media2.common.MediaItem in project ExoPlayer by google.

the class SessionPlayerConnectorTest method setPlaylist_byUnderlyingPlayerAfterPrepare_notifiesOnPlaylistChanged.

@Test
@LargeTest
public void setPlaylist_byUnderlyingPlayerAfterPrepare_notifiesOnPlaylistChanged() throws Exception {
    List<MediaItem> playlistToSessionPlayer = TestUtils.createPlaylist(2);
    List<MediaItem> playlistToExoPlayer = TestUtils.createPlaylist(4);
    DefaultMediaItemConverter converter = new DefaultMediaItemConverter();
    List<com.google.android.exoplayer2.MediaItem> exoMediaItems = new ArrayList<>();
    for (MediaItem mediaItem : playlistToExoPlayer) {
        exoMediaItems.add(converter.convertToExoPlayerMediaItem(mediaItem));
    }
    CountDownLatch onPlaylistChangedLatch = new CountDownLatch(1);
    sessionPlayerConnector.registerPlayerCallback(executor, new SessionPlayer.PlayerCallback() {

        @Override
        public void onPlaylistChanged(SessionPlayer player, @Nullable List<MediaItem> list, @Nullable MediaMetadata metadata) {
            if (Util.areEqual(list, playlistToExoPlayer)) {
                onPlaylistChangedLatch.countDown();
            }
        }
    });
    sessionPlayerConnector.prepare();
    sessionPlayerConnector.setPlaylist(playlistToSessionPlayer, /* metadata= */
    null);
    InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> playerTestRule.getExoPlayer().setMediaItems(exoMediaItems));
    assertThat(onPlaylistChangedLatch.await(PLAYLIST_CHANGE_WAIT_TIME_MS, MILLISECONDS)).isTrue();
}
Also used : UriMediaItem(androidx.media2.common.UriMediaItem) MediaItem(androidx.media2.common.MediaItem) SessionPlayer(androidx.media2.common.SessionPlayer) ArrayList(java.util.ArrayList) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) MediaMetadata(androidx.media2.common.MediaMetadata) 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)

Aggregations

MediaItem (androidx.media2.common.MediaItem)22 UriMediaItem (androidx.media2.common.UriMediaItem)18 LargeTest (androidx.test.filters.LargeTest)16 Test (org.junit.Test)16 SessionPlayer (androidx.media2.common.SessionPlayer)15 CountDownLatch (java.util.concurrent.CountDownLatch)14 MediumTest (androidx.test.filters.MediumTest)13 SmallTest (androidx.test.filters.SmallTest)13 ArrayList (java.util.ArrayList)13 MediaMetadata (androidx.media2.common.MediaMetadata)11 CallbackMediaItem (androidx.media2.common.CallbackMediaItem)9 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)9 Nullable (androidx.annotation.Nullable)7 FileMediaItem (androidx.media2.common.FileMediaItem)5 Uri (android.net.Uri)4 SessionCommand (androidx.media2.session.SessionCommand)4 SessionCommandGroup (androidx.media2.session.SessionCommandGroup)4 List (java.util.List)4 Context (android.content.Context)3 Bundle (android.os.Bundle)3