Add COMMAND_SET_MEDIA_ITEM to Player.Commands
Some Player implementations have no playlist capability but can still set a MediaItem for playback. Examples are a MediaController connected to a legacy MediaSession, ExoPlayer up to 2.12 or MediaPlayer. To indicate this capability, we need an allowed command in addition to COMMAND_CHANGE_MEDIA_ITEMS that just allows to set a single item that replaces everything that is currently played. #minor-release PiperOrigin-RevId: 453879626
This commit is contained in:
parent
d506c709c9
commit
5333c67d08
@ -26,6 +26,8 @@
|
||||
* Add `MediaItem.RequestMetadata` to represent metadata needed to play
|
||||
media when the exact `LocalConfiguration` is not known. Also remove
|
||||
`MediaMetadata.mediaUrl` as this is now included in `RequestMetadata`.
|
||||
* Add `Player.Command.COMMAND_SET_MEDIA_ITEM` to enable players to allow
|
||||
setting a single item.
|
||||
* Track selection:
|
||||
* Flatten `TrackSelectionOverrides` class into `TrackSelectionParameters`,
|
||||
and promote `TrackSelectionOverride` to a top level class.
|
||||
|
@ -102,7 +102,8 @@ public final class CastPlayer extends BasePlayer {
|
||||
COMMAND_GET_MEDIA_ITEMS_METADATA,
|
||||
COMMAND_SET_MEDIA_ITEMS_METADATA,
|
||||
COMMAND_CHANGE_MEDIA_ITEMS,
|
||||
COMMAND_GET_TRACKS)
|
||||
COMMAND_GET_TRACKS,
|
||||
COMMAND_SET_MEDIA_ITEM)
|
||||
.build();
|
||||
|
||||
public static final float MIN_SPEED_SUPPORTED = 0.5f;
|
||||
|
@ -36,6 +36,7 @@ import static androidx.media3.common.Player.COMMAND_SEEK_TO_NEXT_MEDIA_ITEM;
|
||||
import static androidx.media3.common.Player.COMMAND_SEEK_TO_PREVIOUS;
|
||||
import static androidx.media3.common.Player.COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_DEVICE_VOLUME;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_MEDIA_ITEM;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_MEDIA_ITEMS_METADATA;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_REPEAT_MODE;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_SHUFFLE_MODE;
|
||||
@ -1359,6 +1360,7 @@ public class CastPlayerTest {
|
||||
assertThat(castPlayer.isCommandAvailable(COMMAND_GET_MEDIA_ITEMS_METADATA)).isTrue();
|
||||
assertThat(castPlayer.isCommandAvailable(COMMAND_SET_MEDIA_ITEMS_METADATA)).isTrue();
|
||||
assertThat(castPlayer.isCommandAvailable(COMMAND_CHANGE_MEDIA_ITEMS)).isTrue();
|
||||
assertThat(castPlayer.isCommandAvailable(COMMAND_SET_MEDIA_ITEM)).isTrue();
|
||||
assertThat(castPlayer.isCommandAvailable(COMMAND_GET_AUDIO_ATTRIBUTES)).isFalse();
|
||||
assertThat(castPlayer.isCommandAvailable(COMMAND_GET_VOLUME)).isFalse();
|
||||
assertThat(castPlayer.isCommandAvailable(COMMAND_GET_DEVICE_VOLUME)).isFalse();
|
||||
|
@ -384,6 +384,7 @@ public interface Player {
|
||||
COMMAND_GET_TEXT,
|
||||
COMMAND_SET_TRACK_SELECTION_PARAMETERS,
|
||||
COMMAND_GET_TRACKS,
|
||||
COMMAND_SET_MEDIA_ITEM,
|
||||
};
|
||||
|
||||
private final FlagSet.Builder flagsBuilder;
|
||||
@ -1402,7 +1403,8 @@ public interface Player {
|
||||
* #COMMAND_GET_VOLUME}, {@link #COMMAND_GET_DEVICE_VOLUME}, {@link #COMMAND_SET_VOLUME}, {@link
|
||||
* #COMMAND_SET_DEVICE_VOLUME}, {@link #COMMAND_ADJUST_DEVICE_VOLUME}, {@link
|
||||
* #COMMAND_SET_VIDEO_SURFACE}, {@link #COMMAND_GET_TEXT}, {@link
|
||||
* #COMMAND_SET_TRACK_SELECTION_PARAMETERS} or {@link #COMMAND_GET_TRACKS}.
|
||||
* #COMMAND_SET_TRACK_SELECTION_PARAMETERS}, {@link #COMMAND_GET_TRACKS} or {@link
|
||||
* #COMMAND_SET_MEDIA_ITEM}.
|
||||
*/
|
||||
// @Target list includes both 'default' targets and TYPE_USE, to ensure backwards compatibility
|
||||
// with Kotlin usages from before TYPE_USE was added.
|
||||
@ -1441,6 +1443,7 @@ public interface Player {
|
||||
COMMAND_GET_TEXT,
|
||||
COMMAND_SET_TRACK_SELECTION_PARAMETERS,
|
||||
COMMAND_GET_TRACKS,
|
||||
COMMAND_SET_MEDIA_ITEM,
|
||||
})
|
||||
@interface Command {}
|
||||
/** Command to start, pause or resume playback. */
|
||||
@ -1520,6 +1523,8 @@ public interface Player {
|
||||
int COMMAND_SET_TRACK_SELECTION_PARAMETERS = 29;
|
||||
/** Command to get details of the current track selection. */
|
||||
int COMMAND_GET_TRACKS = 30;
|
||||
/** Command to set a {@link MediaItem MediaItem}. */
|
||||
int COMMAND_SET_MEDIA_ITEM = 31;
|
||||
|
||||
/** Represents an invalid {@link Command}. */
|
||||
int COMMAND_INVALID = -1;
|
||||
|
@ -303,7 +303,8 @@ import java.util.concurrent.TimeoutException;
|
||||
COMMAND_SET_DEVICE_VOLUME,
|
||||
COMMAND_ADJUST_DEVICE_VOLUME,
|
||||
COMMAND_SET_VIDEO_SURFACE,
|
||||
COMMAND_GET_TEXT)
|
||||
COMMAND_GET_TEXT,
|
||||
COMMAND_SET_MEDIA_ITEM)
|
||||
.addIf(
|
||||
COMMAND_SET_TRACK_SELECTION_PARAMETERS, trackSelector.isSetParametersSupported())
|
||||
.build();
|
||||
|
@ -37,6 +37,7 @@ import static androidx.media3.common.Player.COMMAND_SEEK_TO_NEXT_MEDIA_ITEM;
|
||||
import static androidx.media3.common.Player.COMMAND_SEEK_TO_PREVIOUS;
|
||||
import static androidx.media3.common.Player.COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_DEVICE_VOLUME;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_MEDIA_ITEM;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_MEDIA_ITEMS_METADATA;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_REPEAT_MODE;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_SHUFFLE_MODE;
|
||||
@ -8979,6 +8980,7 @@ public final class ExoPlayerTest {
|
||||
assertThat(player.isCommandAvailable(COMMAND_GET_MEDIA_ITEMS_METADATA)).isTrue();
|
||||
assertThat(player.isCommandAvailable(COMMAND_SET_MEDIA_ITEMS_METADATA)).isTrue();
|
||||
assertThat(player.isCommandAvailable(COMMAND_CHANGE_MEDIA_ITEMS)).isTrue();
|
||||
assertThat(player.isCommandAvailable(COMMAND_SET_MEDIA_ITEM)).isTrue();
|
||||
assertThat(player.isCommandAvailable(COMMAND_GET_AUDIO_ATTRIBUTES)).isTrue();
|
||||
assertThat(player.isCommandAvailable(COMMAND_GET_VOLUME)).isTrue();
|
||||
assertThat(player.isCommandAvailable(COMMAND_GET_DEVICE_VOLUME)).isTrue();
|
||||
@ -12128,6 +12130,7 @@ public final class ExoPlayerTest {
|
||||
COMMAND_GET_MEDIA_ITEMS_METADATA,
|
||||
COMMAND_SET_MEDIA_ITEMS_METADATA,
|
||||
COMMAND_CHANGE_MEDIA_ITEMS,
|
||||
COMMAND_SET_MEDIA_ITEM,
|
||||
COMMAND_GET_AUDIO_ATTRIBUTES,
|
||||
COMMAND_GET_VOLUME,
|
||||
COMMAND_GET_DEVICE_VOLUME,
|
||||
|
@ -29,6 +29,7 @@ import static androidx.media3.common.Player.COMMAND_SEEK_TO_NEXT_MEDIA_ITEM;
|
||||
import static androidx.media3.common.Player.COMMAND_SEEK_TO_PREVIOUS;
|
||||
import static androidx.media3.common.Player.COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_DEVICE_VOLUME;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_MEDIA_ITEM;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_MEDIA_ITEMS_METADATA;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_REPEAT_MODE;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_SHUFFLE_MODE;
|
||||
@ -817,12 +818,12 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
@Override
|
||||
public void setMediaItem(MediaItem mediaItem) {
|
||||
if (!isPlayerCommandAvailable(COMMAND_CHANGE_MEDIA_ITEMS)) {
|
||||
if (!isPlayerCommandAvailable(COMMAND_SET_MEDIA_ITEM)) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatchRemoteSessionTaskWithPlayerCommand(
|
||||
COMMAND_CHANGE_MEDIA_ITEMS,
|
||||
COMMAND_SET_MEDIA_ITEM,
|
||||
(iSession, seq) -> iSession.setMediaItem(controllerStub, seq, mediaItem.toBundle()));
|
||||
|
||||
setMediaItemsInternal(
|
||||
@ -834,12 +835,12 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
@Override
|
||||
public void setMediaItem(MediaItem mediaItem, long startPositionMs) {
|
||||
if (!isPlayerCommandAvailable(COMMAND_CHANGE_MEDIA_ITEMS)) {
|
||||
if (!isPlayerCommandAvailable(COMMAND_SET_MEDIA_ITEM)) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatchRemoteSessionTaskWithPlayerCommand(
|
||||
COMMAND_CHANGE_MEDIA_ITEMS,
|
||||
COMMAND_SET_MEDIA_ITEM,
|
||||
(iSession, seq) ->
|
||||
iSession.setMediaItemWithStartPosition(
|
||||
controllerStub, seq, mediaItem.toBundle(), startPositionMs));
|
||||
@ -853,12 +854,12 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
@Override
|
||||
public void setMediaItem(MediaItem mediaItem, boolean resetPosition) {
|
||||
if (!isPlayerCommandAvailable(COMMAND_CHANGE_MEDIA_ITEMS)) {
|
||||
if (!isPlayerCommandAvailable(COMMAND_SET_MEDIA_ITEM)) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatchRemoteSessionTaskWithPlayerCommand(
|
||||
COMMAND_CHANGE_MEDIA_ITEMS,
|
||||
COMMAND_SET_MEDIA_ITEM,
|
||||
(iSession, seq) ->
|
||||
iSession.setMediaItemWithResetPosition(
|
||||
controllerStub, seq, mediaItem.toBundle(), resetPosition));
|
||||
|
@ -889,32 +889,6 @@ public class MediaSession {
|
||||
* @param controller The controller information.
|
||||
* @param playerCommand A {@link Player.Command command}.
|
||||
* @return {@link SessionResult#RESULT_SUCCESS} to proceed, or another code to ignore.
|
||||
* @see Player.Command#COMMAND_PLAY_PAUSE
|
||||
* @see Player.Command#COMMAND_PREPARE
|
||||
* @see Player.Command#COMMAND_STOP
|
||||
* @see Player.Command#COMMAND_SEEK_TO_DEFAULT_POSITION
|
||||
* @see Player.Command#COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM
|
||||
* @see Player.Command#COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM
|
||||
* @see Player.Command#COMMAND_SEEK_TO_NEXT_MEDIA_ITEM
|
||||
* @see Player.Command#COMMAND_SEEK_TO_MEDIA_ITEM
|
||||
* @see Player.Command#COMMAND_SET_SPEED_AND_PITCH
|
||||
* @see Player.Command#COMMAND_SET_SHUFFLE_MODE
|
||||
* @see Player.Command#COMMAND_SET_REPEAT_MODE
|
||||
* @see Player.Command#COMMAND_GET_CURRENT_MEDIA_ITEM
|
||||
* @see Player.Command#COMMAND_GET_TIMELINE
|
||||
* @see Player.Command#COMMAND_GET_MEDIA_ITEMS_METADATA
|
||||
* @see Player.Command#COMMAND_SET_MEDIA_ITEMS_METADATA
|
||||
* @see Player.Command#COMMAND_CHANGE_MEDIA_ITEMS
|
||||
* @see Player.Command#COMMAND_GET_AUDIO_ATTRIBUTES
|
||||
* @see Player.Command#COMMAND_GET_VOLUME
|
||||
* @see Player.Command#COMMAND_GET_DEVICE_VOLUME
|
||||
* @see Player.Command#COMMAND_SET_VOLUME
|
||||
* @see Player.Command#COMMAND_SET_DEVICE_VOLUME
|
||||
* @see Player.Command#COMMAND_ADJUST_DEVICE_VOLUME
|
||||
* @see Player.Command#COMMAND_SET_VIDEO_SURFACE
|
||||
* @see Player.Command#COMMAND_GET_TEXT
|
||||
* @see Player.Command#COMMAND_SET_TRACK_SELECTION_PARAMETERS
|
||||
* @see Player.Command#COMMAND_GET_TRACKS
|
||||
*/
|
||||
default @SessionResult.Code int onPlayerCommandRequest(
|
||||
MediaSession session, ControllerInfo controller, @Player.Command int playerCommand) {
|
||||
|
@ -24,6 +24,7 @@ import static androidx.media3.common.Player.COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM;
|
||||
import static androidx.media3.common.Player.COMMAND_SEEK_TO_MEDIA_ITEM;
|
||||
import static androidx.media3.common.Player.COMMAND_SEEK_TO_NEXT;
|
||||
import static androidx.media3.common.Player.COMMAND_SEEK_TO_PREVIOUS;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_MEDIA_ITEM;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_REPEAT_MODE;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_SHUFFLE_MODE;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_SPEED_AND_PITCH;
|
||||
@ -679,7 +680,7 @@ import org.checkerframework.checker.initialization.qual.Initialized;
|
||||
|
||||
private void handleMediaRequest(MediaItem mediaItem, boolean play) {
|
||||
dispatchSessionTaskWithPlayerCommand(
|
||||
COMMAND_CHANGE_MEDIA_ITEMS,
|
||||
COMMAND_SET_MEDIA_ITEM,
|
||||
controller -> {
|
||||
ListenableFuture<List<MediaItem>> mediaItemsFuture =
|
||||
sessionImpl.onAddMediaItemsOnHandler(controller, ImmutableList.of(mediaItem));
|
||||
|
@ -29,6 +29,7 @@ import static androidx.media3.common.Player.COMMAND_SEEK_TO_NEXT_MEDIA_ITEM;
|
||||
import static androidx.media3.common.Player.COMMAND_SEEK_TO_PREVIOUS;
|
||||
import static androidx.media3.common.Player.COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_DEVICE_VOLUME;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_MEDIA_ITEM;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_MEDIA_ITEMS_METADATA;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_REPEAT_MODE;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_SHUFFLE_MODE;
|
||||
@ -846,7 +847,7 @@ import java.util.concurrent.ExecutionException;
|
||||
dispatchSessionTaskWithPlayerCommand(
|
||||
caller,
|
||||
seq,
|
||||
COMMAND_CHANGE_MEDIA_ITEMS,
|
||||
COMMAND_SET_MEDIA_ITEM,
|
||||
(sessionImpl, controller) ->
|
||||
sessionImpl.onAddMediaItemsOnHandler(controller, ImmutableList.of(mediaItem)),
|
||||
(sessionImpl, controller, sequence, future) ->
|
||||
@ -873,7 +874,7 @@ import java.util.concurrent.ExecutionException;
|
||||
dispatchSessionTaskWithPlayerCommand(
|
||||
caller,
|
||||
seq,
|
||||
COMMAND_CHANGE_MEDIA_ITEMS,
|
||||
COMMAND_SET_MEDIA_ITEM,
|
||||
(sessionImpl, controller) ->
|
||||
sessionImpl.onAddMediaItemsOnHandler(controller, ImmutableList.of(mediaItem)),
|
||||
(sessionImpl, controller, sequence, future) ->
|
||||
@ -905,7 +906,7 @@ import java.util.concurrent.ExecutionException;
|
||||
dispatchSessionTaskWithPlayerCommand(
|
||||
caller,
|
||||
seq,
|
||||
COMMAND_CHANGE_MEDIA_ITEMS,
|
||||
COMMAND_SET_MEDIA_ITEM,
|
||||
(sessionImpl, controller) ->
|
||||
sessionImpl.onAddMediaItemsOnHandler(controller, ImmutableList.of(mediaItem)),
|
||||
(sessionImpl, controller, sequence, future) ->
|
||||
|
@ -22,6 +22,7 @@ import static androidx.media3.common.Player.COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM;
|
||||
import static androidx.media3.common.Player.COMMAND_SEEK_TO_NEXT_MEDIA_ITEM;
|
||||
import static androidx.media3.common.Player.COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_DEVICE_VOLUME;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_MEDIA_ITEM;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_MEDIA_ITEMS_METADATA;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_TRACK_SELECTION_PARAMETERS;
|
||||
import static androidx.media3.session.MediaUtils.createPlayerCommandsWith;
|
||||
@ -135,6 +136,12 @@ public class MediaSessionPermissionTest {
|
||||
controller -> controller.setPlaylistMetadata(MediaMetadata.EMPTY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setMediaItem() throws Exception {
|
||||
testOnCommandRequest(
|
||||
COMMAND_SET_MEDIA_ITEM, controller -> controller.setMediaItem(MediaItem.EMPTY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setMediaItems() throws Exception {
|
||||
testOnCommandRequest(
|
||||
|
Loading…
x
Reference in New Issue
Block a user