Commit 9fad5f41 by krocard Committed by bachinger

Add Track selection to the Player API

This cl doesn't implement completely the API for
`ExoPlayerImpl` as
`onTrackSelectionParametersChanged` is not called.

The follow up cl adds `TrackSelectionParameters` in PlaybackInfo
to correctly propagate the change event and mask it.

Additionally `TrackSelectionParameters` is serialized as a Parcelable
for now. It is transitioned to bundleable in a follow up cl.

PiperOrigin-RevId: 392899918
parent 66c85245
...@@ -44,6 +44,7 @@ import com.google.android.exoplayer2.source.TrackGroupArray; ...@@ -44,6 +44,7 @@ import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.text.Cue; import com.google.android.exoplayer2.text.Cue;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray; import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.trackselection.TrackSelectionParameters;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Clock; import com.google.android.exoplayer2.util.Clock;
import com.google.android.exoplayer2.util.ListenerSet; import com.google.android.exoplayer2.util.ListenerSet;
...@@ -542,6 +543,14 @@ public final class CastPlayer extends BasePlayer { ...@@ -542,6 +543,14 @@ public final class CastPlayer extends BasePlayer {
return currentTrackGroups; return currentTrackGroups;
} }
@Override
public TrackSelectionParameters getTrackSelectionParameters() {
return TrackSelectionParameters.DEFAULT_WITHOUT_CONTEXT;
}
@Override
public void setTrackSelectionParameters(TrackSelectionParameters parameters) {}
@Deprecated @Deprecated
@Override @Override
public ImmutableList<Metadata> getCurrentStaticMetadata() { public ImmutableList<Metadata> getCurrentStaticMetadata() {
......
...@@ -21,6 +21,7 @@ import com.google.android.exoplayer2.Player; ...@@ -21,6 +21,7 @@ import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.testutil.StubExoPlayer; import com.google.android.exoplayer2.testutil.StubExoPlayer;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray; import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.trackselection.TrackSelectionParameters;
import com.google.android.exoplayer2.util.Clock; import com.google.android.exoplayer2.util.Clock;
import com.google.android.exoplayer2.util.ListenerSet; import com.google.android.exoplayer2.util.ListenerSet;
...@@ -232,6 +233,14 @@ import com.google.android.exoplayer2.util.ListenerSet; ...@@ -232,6 +233,14 @@ import com.google.android.exoplayer2.util.ListenerSet;
} }
@Override @Override
public TrackSelectionParameters getTrackSelectionParameters() {
return TrackSelectionParameters.DEFAULT_WITHOUT_CONTEXT;
}
@Override
public void setTrackSelectionParameters(TrackSelectionParameters parameters) {}
@Override
public Timeline getCurrentTimeline() { public Timeline getCurrentTimeline() {
return timeline; return timeline;
} }
......
...@@ -26,6 +26,7 @@ import com.google.android.exoplayer2.metadata.Metadata; ...@@ -26,6 +26,7 @@ import com.google.android.exoplayer2.metadata.Metadata;
import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.text.Cue; import com.google.android.exoplayer2.text.Cue;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray; import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.trackselection.TrackSelectionParameters;
import com.google.android.exoplayer2.video.VideoSize; import com.google.android.exoplayer2.video.VideoSize;
import java.util.List; import java.util.List;
...@@ -371,6 +372,16 @@ public class ForwardingPlayer implements Player { ...@@ -371,6 +372,16 @@ public class ForwardingPlayer implements Player {
return player.getCurrentTrackSelections(); return player.getCurrentTrackSelections();
} }
@Override
public TrackSelectionParameters getTrackSelectionParameters() {
return player.getTrackSelectionParameters();
}
@Override
public void setTrackSelectionParameters(TrackSelectionParameters parameters) {
player.setTrackSelectionParameters(parameters);
}
@Deprecated @Deprecated
@Override @Override
public List<Metadata> getCurrentStaticMetadata() { public List<Metadata> getCurrentStaticMetadata() {
...@@ -684,6 +695,11 @@ public class ForwardingPlayer implements Player { ...@@ -684,6 +695,11 @@ public class ForwardingPlayer implements Player {
} }
@Override @Override
public void onTrackSelectionParametersChanged(TrackSelectionParameters parameters) {
eventListener.onTrackSelectionParametersChanged(parameters);
}
@Override
public void onPlayerStateChanged(boolean playWhenReady, @State int playbackState) { public void onPlayerStateChanged(boolean playWhenReady, @State int playbackState) {
eventListener.onPlayerStateChanged(playWhenReady, playbackState); eventListener.onPlayerStateChanged(playWhenReady, playbackState);
} }
......
...@@ -31,6 +31,7 @@ import com.google.android.exoplayer2.source.TrackGroupArray; ...@@ -31,6 +31,7 @@ import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.text.Cue; import com.google.android.exoplayer2.text.Cue;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray; import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.trackselection.TrackSelectionParameters;
import com.google.android.exoplayer2.util.FlagSet; import com.google.android.exoplayer2.util.FlagSet;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.video.VideoSize; import com.google.android.exoplayer2.video.VideoSize;
...@@ -176,6 +177,16 @@ public interface Player { ...@@ -176,6 +177,16 @@ public interface Player {
default void onAvailableCommandsChanged(Commands availableCommands) {} default void onAvailableCommandsChanged(Commands availableCommands) {}
/** /**
* Called when the value returned from {@link #getTrackSelectionParameters()} changes.
*
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
* other events that happen in the same {@link Looper} message queue iteration.
*
* @param parameters The new {@link TrackSelectionParameters}.
*/
default void onTrackSelectionParametersChanged(TrackSelectionParameters parameters) {}
/**
* @deprecated Use {@link #onPlaybackStateChanged(int)} and {@link * @deprecated Use {@link #onPlaybackStateChanged(int)} and {@link
* #onPlayWhenReadyChanged(boolean, int)} instead. * #onPlayWhenReadyChanged(boolean, int)} instead.
*/ */
...@@ -648,7 +659,8 @@ public interface Player { ...@@ -648,7 +659,8 @@ public interface Player {
COMMAND_SET_DEVICE_VOLUME, COMMAND_SET_DEVICE_VOLUME,
COMMAND_ADJUST_DEVICE_VOLUME, COMMAND_ADJUST_DEVICE_VOLUME,
COMMAND_SET_VIDEO_SURFACE, COMMAND_SET_VIDEO_SURFACE,
COMMAND_GET_TEXT COMMAND_GET_TEXT,
COMMAND_SET_TRACK_SELECTION_PARAMETERS,
}; };
private final FlagSet.Builder flagsBuilder; private final FlagSet.Builder flagsBuilder;
...@@ -1226,7 +1238,8 @@ public interface Player { ...@@ -1226,7 +1238,8 @@ public interface Player {
EVENT_PLAYLIST_METADATA_CHANGED, EVENT_PLAYLIST_METADATA_CHANGED,
EVENT_SEEK_BACK_INCREMENT_CHANGED, EVENT_SEEK_BACK_INCREMENT_CHANGED,
EVENT_SEEK_FORWARD_INCREMENT_CHANGED, EVENT_SEEK_FORWARD_INCREMENT_CHANGED,
EVENT_MAX_SEEK_TO_PREVIOUS_POSITION_CHANGED EVENT_MAX_SEEK_TO_PREVIOUS_POSITION_CHANGED,
EVENT_TRACK_SELECTION_PARAMETERS_CHANGED,
}) })
@interface Event {} @interface Event {}
/** {@link #getCurrentTimeline()} changed. */ /** {@link #getCurrentTimeline()} changed. */
...@@ -1272,6 +1285,8 @@ public interface Player { ...@@ -1272,6 +1285,8 @@ public interface Player {
int EVENT_SEEK_FORWARD_INCREMENT_CHANGED = 18; int EVENT_SEEK_FORWARD_INCREMENT_CHANGED = 18;
/** {@link #getMaxSeekToPreviousPosition()} changed. */ /** {@link #getMaxSeekToPreviousPosition()} changed. */
int EVENT_MAX_SEEK_TO_PREVIOUS_POSITION_CHANGED = 19; int EVENT_MAX_SEEK_TO_PREVIOUS_POSITION_CHANGED = 19;
/** {@link #getTrackSelectionParameters()} changed. */
int EVENT_TRACK_SELECTION_PARAMETERS_CHANGED = 20;
/** /**
* Commands that can be executed on a {@code Player}. One of {@link #COMMAND_PLAY_PAUSE}, {@link * Commands that can be executed on a {@code Player}. One of {@link #COMMAND_PLAY_PAUSE}, {@link
...@@ -1286,7 +1301,8 @@ public interface Player { ...@@ -1286,7 +1301,8 @@ public interface Player {
* #COMMAND_CHANGE_MEDIA_ITEMS}, {@link #COMMAND_GET_AUDIO_ATTRIBUTES}, {@link * #COMMAND_CHANGE_MEDIA_ITEMS}, {@link #COMMAND_GET_AUDIO_ATTRIBUTES}, {@link
* #COMMAND_GET_VOLUME}, {@link #COMMAND_GET_DEVICE_VOLUME}, {@link #COMMAND_SET_VOLUME}, {@link * #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_DEVICE_VOLUME}, {@link #COMMAND_ADJUST_DEVICE_VOLUME}, {@link
* #COMMAND_SET_VIDEO_SURFACE} or {@link #COMMAND_GET_TEXT}. * #COMMAND_SET_VIDEO_SURFACE}, {@link #COMMAND_GET_TEXT} or {@link
* #COMMAND_SET_TRACK_SELECTION_PARAMETERS}.
*/ */
@Documented @Documented
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
...@@ -1318,7 +1334,8 @@ public interface Player { ...@@ -1318,7 +1334,8 @@ public interface Player {
COMMAND_SET_DEVICE_VOLUME, COMMAND_SET_DEVICE_VOLUME,
COMMAND_ADJUST_DEVICE_VOLUME, COMMAND_ADJUST_DEVICE_VOLUME,
COMMAND_SET_VIDEO_SURFACE, COMMAND_SET_VIDEO_SURFACE,
COMMAND_GET_TEXT COMMAND_GET_TEXT,
COMMAND_SET_TRACK_SELECTION_PARAMETERS,
}) })
@interface Command {} @interface Command {}
/** Command to start, pause or resume playback. */ /** Command to start, pause or resume playback. */
...@@ -1375,6 +1392,8 @@ public interface Player { ...@@ -1375,6 +1392,8 @@ public interface Player {
int COMMAND_SET_VIDEO_SURFACE = 26; int COMMAND_SET_VIDEO_SURFACE = 26;
/** Command to get the text that should currently be displayed by the player. */ /** Command to get the text that should currently be displayed by the player. */
int COMMAND_GET_TEXT = 27; int COMMAND_GET_TEXT = 27;
/** Command to set the player's track selection parameters. */
int COMMAND_SET_TRACK_SELECTION_PARAMETERS = 28;
/** Represents an invalid {@link Command}. */ /** Represents an invalid {@link Command}. */
int COMMAND_INVALID = -1; int COMMAND_INVALID = -1;
...@@ -1951,6 +1970,28 @@ public interface Player { ...@@ -1951,6 +1970,28 @@ public interface Player {
*/ */
TrackSelectionArray getCurrentTrackSelections(); TrackSelectionArray getCurrentTrackSelections();
/** Returns the parameters constraining the track selection. */
TrackSelectionParameters getTrackSelectionParameters();
/**
* Sets the parameters constraining the track selection.
*
* <p>Unsupported parameters will be silently ignored.
*
* <p>Use {@link #getTrackSelectionParameters()} to retrieve the current parameters. For example,
* the following snippet restricts video to SD whilst keep other track selection parameters
* unchanged:
*
* <pre>{@code
* player.setTrackSelectionParameters(
* player.getTrackSelectionParameters()
* .buildUpon()
* .setMaxVideoSizeSd()
* .build())
* }</pre>
*/
void setTrackSelectionParameters(TrackSelectionParameters parameters);
/** /**
* @deprecated Use {@link #getMediaMetadata()} and {@link * @deprecated Use {@link #getMediaMetadata()} and {@link
* Listener#onMediaMetadataChanged(MediaMetadata)} for access to structured metadata, or * Listener#onMediaMetadataChanged(MediaMetadata)} for access to structured metadata, or
......
...@@ -35,8 +35,28 @@ import java.lang.annotation.Documented; ...@@ -35,8 +35,28 @@ import java.lang.annotation.Documented;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.util.Locale; import java.util.Locale;
import org.checkerframework.checker.initialization.qual.UnknownInitialization;
import org.checkerframework.checker.nullness.qual.EnsuresNonNull;
/** Constraint parameters for track selection. */ /**
* Constraint parameters for track selection.
*
* <p>For example the following code modifies the parameters to restrict video track selections to
* SD, and to select a German audio track if there is one:
*
* <pre>{@code
* // Build on the current parameters.
* TrackSelectionParameters currentParameters = player.getTrackSelectionParameters()
* // Build the resulting parameters.
* TrackSelectionParameters newParameters = currentParameters
* .buildUpon()
* .setMaxVideoSizeSd()
* .setPreferredAudioLanguage("deu")
* .build();
* // Set the new parameters.
* player.setTrackSelectionParameters(newParameters);
* }</pre>
*/
public class TrackSelectionParameters implements Bundleable { public class TrackSelectionParameters implements Bundleable {
/** /**
...@@ -115,32 +135,7 @@ public class TrackSelectionParameters implements Bundleable { ...@@ -115,32 +135,7 @@ public class TrackSelectionParameters implements Bundleable {
/** Creates a builder with the initial values specified in {@code initialValues}. */ /** Creates a builder with the initial values specified in {@code initialValues}. */
protected Builder(TrackSelectionParameters initialValues) { protected Builder(TrackSelectionParameters initialValues) {
// Video init(initialValues);
maxVideoWidth = initialValues.maxVideoWidth;
maxVideoHeight = initialValues.maxVideoHeight;
maxVideoFrameRate = initialValues.maxVideoFrameRate;
maxVideoBitrate = initialValues.maxVideoBitrate;
minVideoWidth = initialValues.minVideoWidth;
minVideoHeight = initialValues.minVideoHeight;
minVideoFrameRate = initialValues.minVideoFrameRate;
minVideoBitrate = initialValues.minVideoBitrate;
viewportWidth = initialValues.viewportWidth;
viewportHeight = initialValues.viewportHeight;
viewportOrientationMayChange = initialValues.viewportOrientationMayChange;
preferredVideoMimeTypes = initialValues.preferredVideoMimeTypes;
// Audio
preferredAudioLanguages = initialValues.preferredAudioLanguages;
preferredAudioRoleFlags = initialValues.preferredAudioRoleFlags;
maxAudioChannelCount = initialValues.maxAudioChannelCount;
maxAudioBitrate = initialValues.maxAudioBitrate;
preferredAudioMimeTypes = initialValues.preferredAudioMimeTypes;
// Text
preferredTextLanguages = initialValues.preferredTextLanguages;
preferredTextRoleFlags = initialValues.preferredTextRoleFlags;
selectUndeterminedTextLanguage = initialValues.selectUndeterminedTextLanguage;
// General
forceLowestBitrate = initialValues.forceLowestBitrate;
forceHighestSupportedBitrate = initialValues.forceHighestSupportedBitrate;
} }
/** Creates a builder with the initial values specified in {@code bundle}. */ /** Creates a builder with the initial values specified in {@code bundle}. */
...@@ -226,6 +221,48 @@ public class TrackSelectionParameters implements Bundleable { ...@@ -226,6 +221,48 @@ public class TrackSelectionParameters implements Bundleable {
DEFAULT_WITHOUT_CONTEXT.forceHighestSupportedBitrate); DEFAULT_WITHOUT_CONTEXT.forceHighestSupportedBitrate);
} }
/** Overrides the value of the builder with the value of {@link TrackSelectionParameters}. */
@EnsuresNonNull({
"preferredVideoMimeTypes",
"preferredAudioLanguages",
"preferredAudioMimeTypes",
"preferredTextLanguages"
})
private void init(@UnknownInitialization Builder this, TrackSelectionParameters parameters) {
// Video
maxVideoWidth = parameters.maxVideoWidth;
maxVideoHeight = parameters.maxVideoHeight;
maxVideoFrameRate = parameters.maxVideoFrameRate;
maxVideoBitrate = parameters.maxVideoBitrate;
minVideoWidth = parameters.minVideoWidth;
minVideoHeight = parameters.minVideoHeight;
minVideoFrameRate = parameters.minVideoFrameRate;
minVideoBitrate = parameters.minVideoBitrate;
viewportWidth = parameters.viewportWidth;
viewportHeight = parameters.viewportHeight;
viewportOrientationMayChange = parameters.viewportOrientationMayChange;
preferredVideoMimeTypes = parameters.preferredVideoMimeTypes;
// Audio
preferredAudioLanguages = parameters.preferredAudioLanguages;
preferredAudioRoleFlags = parameters.preferredAudioRoleFlags;
maxAudioChannelCount = parameters.maxAudioChannelCount;
maxAudioBitrate = parameters.maxAudioBitrate;
preferredAudioMimeTypes = parameters.preferredAudioMimeTypes;
// Text
preferredTextLanguages = parameters.preferredTextLanguages;
preferredTextRoleFlags = parameters.preferredTextRoleFlags;
selectUndeterminedTextLanguage = parameters.selectUndeterminedTextLanguage;
// General
forceLowestBitrate = parameters.forceLowestBitrate;
forceHighestSupportedBitrate = parameters.forceHighestSupportedBitrate;
}
/** Overrides the value of the builder with the value of {@link TrackSelectionParameters}. */
protected Builder set(TrackSelectionParameters parameters) {
init(parameters);
return this;
}
// Video // Video
/** /**
......
...@@ -43,6 +43,7 @@ import com.google.android.exoplayer2.source.TrackGroupArray; ...@@ -43,6 +43,7 @@ import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.text.Cue; import com.google.android.exoplayer2.text.Cue;
import com.google.android.exoplayer2.trackselection.ExoTrackSelection; import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray; import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.trackselection.TrackSelectionParameters;
import com.google.android.exoplayer2.trackselection.TrackSelector; import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelectorResult; import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
import com.google.android.exoplayer2.upstream.BandwidthMeter; import com.google.android.exoplayer2.upstream.BandwidthMeter;
...@@ -210,6 +211,7 @@ import java.util.concurrent.CopyOnWriteArraySet; ...@@ -210,6 +211,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
COMMAND_GET_MEDIA_ITEMS_METADATA, COMMAND_GET_MEDIA_ITEMS_METADATA,
COMMAND_SET_MEDIA_ITEMS_METADATA, COMMAND_SET_MEDIA_ITEMS_METADATA,
COMMAND_CHANGE_MEDIA_ITEMS) COMMAND_CHANGE_MEDIA_ITEMS)
.addIf(COMMAND_SET_TRACK_SELECTION_PARAMETERS, trackSelector.isSetParametersSupported())
.addAll(additionalPermanentAvailableCommands) .addAll(additionalPermanentAvailableCommands)
.build(); .build();
availableCommands = availableCommands =
...@@ -952,6 +954,23 @@ import java.util.concurrent.CopyOnWriteArraySet; ...@@ -952,6 +954,23 @@ import java.util.concurrent.CopyOnWriteArraySet;
} }
@Override @Override
public TrackSelectionParameters getTrackSelectionParameters() {
return trackSelector.getParameters();
}
@Override
public void setTrackSelectionParameters(TrackSelectionParameters parameters) {
if (!trackSelector.isSetParametersSupported()
|| parameters.equals(trackSelector.getParameters())) {
return;
}
trackSelector.setParameters(parameters);
listeners.queueEvent(
EVENT_TRACK_SELECTION_PARAMETERS_CHANGED,
listener -> listener.onTrackSelectionParametersChanged(parameters));
}
@Override
public MediaMetadata getMediaMetadata() { public MediaMetadata getMediaMetadata() {
return mediaMetadata; return mediaMetadata;
} }
......
...@@ -65,6 +65,7 @@ import com.google.android.exoplayer2.text.Cue; ...@@ -65,6 +65,7 @@ import com.google.android.exoplayer2.text.Cue;
import com.google.android.exoplayer2.text.TextOutput; import com.google.android.exoplayer2.text.TextOutput;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray; import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.trackselection.TrackSelectionParameters;
import com.google.android.exoplayer2.trackselection.TrackSelector; import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.upstream.BandwidthMeter; import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter; import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
...@@ -1449,6 +1450,18 @@ public class SimpleExoPlayer extends BasePlayer ...@@ -1449,6 +1450,18 @@ public class SimpleExoPlayer extends BasePlayer
return player.getCurrentTrackSelections(); return player.getCurrentTrackSelections();
} }
@Override
public TrackSelectionParameters getTrackSelectionParameters() {
verifyApplicationThread();
return player.getTrackSelectionParameters();
}
@Override
public void setTrackSelectionParameters(TrackSelectionParameters parameters) {
verifyApplicationThread();
player.setTrackSelectionParameters(parameters);
}
@Deprecated @Deprecated
@Override @Override
public List<Metadata> getCurrentStaticMetadata() { public List<Metadata> getCurrentStaticMetadata() {
......
...@@ -61,7 +61,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; ...@@ -61,7 +61,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
/** /**
* A default {@link TrackSelector} suitable for most use cases. Track selections are made according * A default {@link TrackSelector} suitable for most use cases. Track selections are made according
* to configurable {@link Parameters}, which can be set by calling {@link * to configurable {@link Parameters}, which can be set by calling {@link
* #setParameters(Parameters)}. * Player#setTrackSelectionParameters}.
* *
* <h2>Modifying parameters</h2> * <h2>Modifying parameters</h2>
* *
...@@ -73,25 +73,26 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; ...@@ -73,25 +73,26 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
* *
* <pre>{@code * <pre>{@code
* // Build on the current parameters. * // Build on the current parameters.
* Parameters currentParameters = trackSelector.getParameters(); * TrackSelectionParameters currentParameters = player.getTrackSelectionParameters();
* // Build the resulting parameters. * // Build the resulting parameters.
* Parameters newParameters = currentParameters * TrackSelectionParameters newParameters = currentParameters
* .buildUpon() * .buildUpon()
* .setMaxVideoSizeSd() * .setMaxVideoSizeSd()
* .setPreferredAudioLanguage("deu") * .setPreferredAudioLanguage("deu")
* .build(); * .build();
* // Set the new parameters. * // Set the new parameters.
* trackSelector.setParameters(newParameters); * player.setTrackSelectionParameters(newParameters);
* }</pre> * }</pre>
* *
* Convenience methods and chaining allow this to be written more concisely as: * Convenience methods and chaining allow this to be written more concisely as:
* *
* <pre>{@code * <pre>{@code
* trackSelector.setParameters( * player.setTrackSelectionParameters(
* trackSelector * player.getTrackSelectionParameters()
* .buildUponParameters() * .buildUpon()
* .setMaxVideoSizeSd() * .setMaxVideoSizeSd()
* .setPreferredAudioLanguage("deu")); * .setPreferredAudioLanguage("deu")
* .build());
* }</pre> * }</pre>
* *
* Selection {@link Parameters} support many different options, some of which are described below. * Selection {@link Parameters} support many different options, some of which are described below.
...@@ -117,10 +118,11 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; ...@@ -117,10 +118,11 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
* *
* <pre>{@code * <pre>{@code
* SelectionOverride selectionOverride = new SelectionOverride(groupIndex, trackIndices); * SelectionOverride selectionOverride = new SelectionOverride(groupIndex, trackIndices);
* trackSelector.setParameters( * player.setTrackSelectionParameters(
* trackSelector * ((Parameters)player.getTrackSelectionParameters())
* .buildUponParameters() * .buildUpon()
* .setSelectionOverride(rendererIndex, rendererTrackGroups, selectionOverride)); * .setSelectionOverride(rendererIndex, rendererTrackGroups, selectionOverride)
* .build());
* }</pre> * }</pre>
* *
* <h2>Constraint based track selection</h2> * <h2>Constraint based track selection</h2>
...@@ -132,11 +134,12 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; ...@@ -132,11 +134,12 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
* a simpler and more flexible approach is to specify these constraints directly: * a simpler and more flexible approach is to specify these constraints directly:
* *
* <pre>{@code * <pre>{@code
* trackSelector.setParameters( * player.setTrackSelectionParameters(
* trackSelector * player.getTrackSelectionParameters()
* .buildUponParameters() * .buildUpon()
* .setMaxVideoSizeSd() * .setMaxVideoSizeSd()
* .setPreferredAudioLanguage("deu")); * .setPreferredAudioLanguage("deu")
* .build());
* }</pre> * }</pre>
* *
* There are several benefits to using constraint based track selection instead of specific track * There are several benefits to using constraint based track selection instead of specific track
...@@ -301,7 +304,13 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -301,7 +304,13 @@ public class DefaultTrackSelector extends MappingTrackSelector {
setSelectionOverridesFromBundle(bundle); setSelectionOverridesFromBundle(bundle);
rendererDisabledFlags = new SparseBooleanArray(); rendererDisabledFlags = new SparseBooleanArray();
setRendererDisableFlagsFromBundle(bundle); setRendererDisabledFlagsFromBundle(bundle);
}
@Override
protected ParametersBuilder set(TrackSelectionParameters parameters) {
super.set(parameters);
return this;
} }
// Video // Video
...@@ -819,7 +828,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -819,7 +828,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
} }
} }
private void setRendererDisableFlagsFromBundle(Bundle bundle) { private void setRendererDisabledFlagsFromBundle(Bundle bundle) {
int[] rendererIndexes = int[] rendererIndexes =
bundle.getIntArray(Parameters.keyForField(Parameters.FIELD_RENDERER_DISABLED_INDEXES)); bundle.getIntArray(Parameters.keyForField(Parameters.FIELD_RENDERER_DISABLED_INDEXES));
if (rendererIndexes == null) { if (rendererIndexes == null) {
...@@ -1151,9 +1160,9 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1151,9 +1160,9 @@ public class DefaultTrackSelector extends MappingTrackSelector {
} }
/** /**
* Bundles selection overrides in 3 arrays of equal length. Each triplet of matching index is - * Bundles selection overrides in 3 arrays of equal length. Each triplet of matching indices is:
* the selection override (stored in a sparse array as they can be null) - the trackGroupArray * the selection override (stored in a sparse array as they can be null), the trackGroupArray of
* of that override - the rendererIndex of that override * that override, the rendererIndex of that override.
*/ */
private static void putSelectionOverridesToBundle( private static void putSelectionOverridesToBundle(
Bundle bundle, Bundle bundle,
...@@ -1403,16 +1412,25 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1403,16 +1412,25 @@ public class DefaultTrackSelector extends MappingTrackSelector {
parametersReference = new AtomicReference<>(parameters); parametersReference = new AtomicReference<>(parameters);
} }
/** @Override
* Atomically sets the provided parameters for track selection. public Parameters getParameters() {
* return parametersReference.get();
* @param parameters The parameters for track selection. }
*/
public void setParameters(Parameters parameters) { @Override
Assertions.checkNotNull(parameters); public boolean isSetParametersSupported() {
if (!parametersReference.getAndSet(parameters).equals(parameters)) { return true;
invalidate(); }
}
@Override
public void setParameters(TrackSelectionParameters parameters) {
if (parameters instanceof Parameters) {
setParametersInternal((Parameters) parameters);
}
// Only add the fields of `TrackSelectionParameters` to `parameters`.
Parameters mergedParameters =
new ParametersBuilder(parametersReference.get()).set(parameters).build();
setParametersInternal(mergedParameters);
} }
/** /**
...@@ -1421,16 +1439,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1421,16 +1439,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* @param parametersBuilder A builder from which to obtain the parameters for track selection. * @param parametersBuilder A builder from which to obtain the parameters for track selection.
*/ */
public void setParameters(ParametersBuilder parametersBuilder) { public void setParameters(ParametersBuilder parametersBuilder) {
setParameters(parametersBuilder.build()); setParametersInternal(parametersBuilder.build());
}
/**
* Gets the current selection parameters.
*
* @return The current selection parameters.
*/
public Parameters getParameters() {
return parametersReference.get();
} }
/** Returns a new {@link ParametersBuilder} initialized with the current selection parameters. */ /** Returns a new {@link ParametersBuilder} initialized with the current selection parameters. */
...@@ -1438,6 +1447,18 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1438,6 +1447,18 @@ public class DefaultTrackSelector extends MappingTrackSelector {
return getParameters().buildUpon(); return getParameters().buildUpon();
} }
/**
* Atomically sets the provided {@link Parameters} for track selection.
*
* @param parameters The parameters for track selection.
*/
private void setParametersInternal(Parameters parameters) {
Assertions.checkNotNull(parameters);
if (!parametersReference.getAndSet(parameters).equals(parameters)) {
invalidate();
}
}
// MappingTrackSelector implementation. // MappingTrackSelector implementation.
@Override @Override
......
...@@ -136,6 +136,32 @@ public abstract class TrackSelector { ...@@ -136,6 +136,32 @@ public abstract class TrackSelector {
*/ */
public abstract void onSelectionActivated(@Nullable Object info); public abstract void onSelectionActivated(@Nullable Object info);
/** Returns the current parameters for track selection. */
public TrackSelectionParameters getParameters() {
return TrackSelectionParameters.DEFAULT_WITHOUT_CONTEXT;
}
/**
* Called by the player to provide parameters for track selection.
*
* <p>Only supported if {@link #isSetParametersSupported()} returns true.
*
* @param parameters The parameters for track selection.
*/
public void setParameters(TrackSelectionParameters parameters) {
// Default implementation doesn't support this method.
}
/**
* Returns if this {@code TrackSelector} supports {@link
* #setParameters(TrackSelectionParameters)}.
*
* <p>The same value is always returned for a given {@code TrackSelector} instance.
*/
public boolean isSetParametersSupported() {
return false;
}
/** /**
* Calls {@link InvalidationListener#onTrackSelectionsInvalidated()} to invalidate all previously * Calls {@link InvalidationListener#onTrackSelectionsInvalidated()} to invalidate all previously
* generated track selections. * generated track selections.
......
...@@ -40,6 +40,7 @@ import static com.google.android.exoplayer2.Player.COMMAND_SET_MEDIA_ITEMS_METAD ...@@ -40,6 +40,7 @@ import static com.google.android.exoplayer2.Player.COMMAND_SET_MEDIA_ITEMS_METAD
import static com.google.android.exoplayer2.Player.COMMAND_SET_REPEAT_MODE; import static com.google.android.exoplayer2.Player.COMMAND_SET_REPEAT_MODE;
import static com.google.android.exoplayer2.Player.COMMAND_SET_SHUFFLE_MODE; import static com.google.android.exoplayer2.Player.COMMAND_SET_SHUFFLE_MODE;
import static com.google.android.exoplayer2.Player.COMMAND_SET_SPEED_AND_PITCH; import static com.google.android.exoplayer2.Player.COMMAND_SET_SPEED_AND_PITCH;
import static com.google.android.exoplayer2.Player.COMMAND_SET_TRACK_SELECTION_PARAMETERS;
import static com.google.android.exoplayer2.Player.COMMAND_SET_VIDEO_SURFACE; import static com.google.android.exoplayer2.Player.COMMAND_SET_VIDEO_SURFACE;
import static com.google.android.exoplayer2.Player.COMMAND_SET_VOLUME; import static com.google.android.exoplayer2.Player.COMMAND_SET_VOLUME;
import static com.google.android.exoplayer2.Player.STATE_ENDED; import static com.google.android.exoplayer2.Player.STATE_ENDED;
...@@ -8203,6 +8204,7 @@ public final class ExoPlayerTest { ...@@ -8203,6 +8204,7 @@ public final class ExoPlayerTest {
assertThat(player.isCommandAvailable(COMMAND_ADJUST_DEVICE_VOLUME)).isTrue(); assertThat(player.isCommandAvailable(COMMAND_ADJUST_DEVICE_VOLUME)).isTrue();
assertThat(player.isCommandAvailable(COMMAND_SET_VIDEO_SURFACE)).isTrue(); assertThat(player.isCommandAvailable(COMMAND_SET_VIDEO_SURFACE)).isTrue();
assertThat(player.isCommandAvailable(COMMAND_GET_TEXT)).isTrue(); assertThat(player.isCommandAvailable(COMMAND_GET_TEXT)).isTrue();
assertThat(player.isCommandAvailable(COMMAND_SET_TRACK_SELECTION_PARAMETERS)).isTrue();
} }
@Test @Test
...@@ -10886,7 +10888,8 @@ public final class ExoPlayerTest { ...@@ -10886,7 +10888,8 @@ public final class ExoPlayerTest {
COMMAND_SET_DEVICE_VOLUME, COMMAND_SET_DEVICE_VOLUME,
COMMAND_ADJUST_DEVICE_VOLUME, COMMAND_ADJUST_DEVICE_VOLUME,
COMMAND_SET_VIDEO_SURFACE, COMMAND_SET_VIDEO_SURFACE,
COMMAND_GET_TEXT); COMMAND_GET_TEXT,
COMMAND_SET_TRACK_SELECTION_PARAMETERS);
if (!isTimelineEmpty) { if (!isTimelineEmpty) {
builder.add(COMMAND_SEEK_TO_PREVIOUS); builder.add(COMMAND_SEEK_TO_PREVIOUS);
} }
......
...@@ -40,6 +40,7 @@ import com.google.android.exoplayer2.source.ShuffleOrder; ...@@ -40,6 +40,7 @@ import com.google.android.exoplayer2.source.ShuffleOrder;
import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.text.Cue; import com.google.android.exoplayer2.text.Cue;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray; import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.trackselection.TrackSelectionParameters;
import com.google.android.exoplayer2.trackselection.TrackSelector; import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.util.Clock; import com.google.android.exoplayer2.util.Clock;
import com.google.android.exoplayer2.video.VideoFrameMetadataListener; import com.google.android.exoplayer2.video.VideoFrameMetadataListener;
...@@ -452,6 +453,16 @@ public class StubExoPlayer extends BasePlayer implements ExoPlayer { ...@@ -452,6 +453,16 @@ public class StubExoPlayer extends BasePlayer implements ExoPlayer {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override
public TrackSelectionParameters getTrackSelectionParameters() {
throw new UnsupportedOperationException();
}
@Override
public void setTrackSelectionParameters(TrackSelectionParameters parameters) {
throw new UnsupportedOperationException();
}
@Deprecated @Deprecated
@Override @Override
public List<Metadata> getCurrentStaticMetadata() { public List<Metadata> getCurrentStaticMetadata() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment