diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index f3f76c73d6..fd9ccdd063 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -56,6 +56,9 @@
values in `Player.EventFlags`.
* Split `AnalyticsCollector` into an interface and default implementation
to allow it to be stripped by R8 if an app doesn't need it.
+* Track selection
+ * Flatten `TrackSelectionOverrides` class into `TrackSelectionParameters`,
+ and promote `TrackSelectionOverride` to a top level class.
* Android 12 compatibility:
* Upgrade the Cast extension to depend on
`com.google.android.gms:play-services-cast-framework:20.1.0`. Earlier
diff --git a/docs/track-selection.md b/docs/track-selection.md
index 90f1be5f7f..bb9bc8d4fe 100644
--- a/docs/track-selection.md
+++ b/docs/track-selection.md
@@ -124,13 +124,11 @@ track group to select this audio group and prevent any other audio track groups
from being selected:
~~~
-TrackSelectionOverrides overrides =
- new TrackSelectionOverrides.Builder()
- .setOverrideForType(new TrackSelectionOverride(audioTrackGroup))
- .build();
player.setTrackSelectionParameters(
player.getTrackSelectionParameters()
- .buildUpon().setTrackSelectionOverrides(overrides).build());
+ .buildUpon()
+ .setOverrideForType(new TrackSelectionOverride(audioTrackGroup))
+ .build());
~~~
{: .language-java}
@@ -149,20 +147,17 @@ player.setTrackSelectionParameters(
~~~
{: .language-java}
-Alternatively, it's possible to prevent the selection of track groups for the
-current playlist item only by specifying empty overrides for these groups:
+Alternatively, it's possible to prevent the selection of tracks from a specific
+`TrackGroup` only by specifying an empty override for that group:
~~~
-TrackSelectionOverrides overrides =
- new TrackSelectionOverrides.Builder()
- .addOverride(
- new TrackSelectionOverride(
- disabledTrackGroup,
- /* select no tracks for this group */ ImmutableList.of()))
- .build();
player.setTrackSelectionParameters(
player.getTrackSelectionParameters()
- .buildUpon().setTrackSelectionOverrides(overrides).build());
+ .buildUpon()
+ .addOverride(
+ new TrackSelectionOverride(
+ disabledTrackGroup, ImmutableList.of()))
+ .build());
~~~
{: .language-java}
diff --git a/library/common/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionOverride.java b/library/common/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionOverride.java
new file mode 100644
index 0000000000..8f8ce7a4f6
--- /dev/null
+++ b/library/common/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionOverride.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.android.exoplayer2.trackselection;
+
+import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
+import static java.util.Collections.max;
+import static java.util.Collections.min;
+
+import android.os.Bundle;
+import androidx.annotation.IntDef;
+import androidx.annotation.Nullable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.primitives.Ints;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.List;
+
+/**
+ * Forces the selection of {@link #trackIndices} for a {@link TrackGroup}.
+ *
+ *
If multiple tracks in {@link #trackGroup} are overridden, as many as possible will be selected
+ * depending on the player capabilities.
+ *
+ *
If {@link #trackIndices} is empty, no tracks from {@link #trackGroup} will be played. This is
+ * similar to {@link TrackSelectionParameters#disabledTrackTypes}, except it will only affect the
+ * playback of the associated {@link TrackGroup}. For example, if the only {@link
+ * C#TRACK_TYPE_VIDEO} {@link TrackGroup} is associated with no tracks, no video will play until the
+ * next video starts.
+ */
+public final class TrackSelectionOverride implements Bundleable {
+
+ /** The {@link TrackGroup} whose {@link #trackIndices} are forced to be selected. */
+ public final TrackGroup trackGroup;
+ /** The indices of tracks in a {@link TrackGroup} to be selected. */
+ public final ImmutableList trackIndices;
+
+ @Documented
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({
+ FIELD_TRACK_GROUP,
+ FIELD_TRACKS,
+ })
+ private @interface FieldNumber {}
+
+ private static final int FIELD_TRACK_GROUP = 0;
+ private static final int FIELD_TRACKS = 1;
+
+ /** Constructs an instance to force all tracks in {@code trackGroup} to be selected. */
+ public TrackSelectionOverride(TrackGroup trackGroup) {
+ this.trackGroup = trackGroup;
+ ImmutableList.Builder builder = new ImmutableList.Builder<>();
+ for (int i = 0; i < trackGroup.length; i++) {
+ builder.add(i);
+ }
+ this.trackIndices = builder.build();
+ }
+
+ /**
+ * Constructs an instance to force {@code trackIndices} in {@code trackGroup} to be selected.
+ *
+ * @param trackGroup The {@link TrackGroup} for which to override the track selection.
+ * @param trackIndices The indices of the tracks in the {@link TrackGroup} to select.
+ */
+ public TrackSelectionOverride(TrackGroup trackGroup, List trackIndices) {
+ if (!trackIndices.isEmpty()) {
+ if (min(trackIndices) < 0 || max(trackIndices) >= trackGroup.length) {
+ throw new IndexOutOfBoundsException();
+ }
+ }
+ this.trackGroup = trackGroup;
+ this.trackIndices = ImmutableList.copyOf(trackIndices);
+ }
+
+ /** Returns the {@link C.TrackType} of the overridden track group. */
+ public @C.TrackType int getTrackType() {
+ return MimeTypes.getTrackType(trackGroup.getFormat(0).sampleMimeType);
+ }
+
+ @Override
+ public boolean equals(@Nullable Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ TrackSelectionOverride that = (TrackSelectionOverride) obj;
+ return trackGroup.equals(that.trackGroup) && trackIndices.equals(that.trackIndices);
+ }
+
+ @Override
+ public int hashCode() {
+ return trackGroup.hashCode() + 31 * trackIndices.hashCode();
+ }
+
+ // Bundleable implementation
+
+ @Override
+ public Bundle toBundle() {
+ Bundle bundle = new Bundle();
+ bundle.putBundle(keyForField(FIELD_TRACK_GROUP), trackGroup.toBundle());
+ bundle.putIntArray(keyForField(FIELD_TRACKS), Ints.toArray(trackIndices));
+ return bundle;
+ }
+
+ /** Object that can restore {@code TrackSelectionOverride} from a {@link Bundle}. */
+ public static final Creator CREATOR =
+ bundle -> {
+ @Nullable Bundle trackGroupBundle = bundle.getBundle(keyForField(FIELD_TRACK_GROUP));
+ checkNotNull(trackGroupBundle); // Mandatory as there are no reasonable defaults.
+ TrackGroup trackGroup = TrackGroup.CREATOR.fromBundle(trackGroupBundle);
+ @Nullable int[] tracks = bundle.getIntArray(keyForField(FIELD_TRACKS));
+ if (tracks == null) {
+ return new TrackSelectionOverride(trackGroup);
+ }
+ return new TrackSelectionOverride(trackGroup, Ints.asList(tracks));
+ };
+
+ private static String keyForField(@FieldNumber int field) {
+ return Integer.toString(field, Character.MAX_RADIX);
+ }
+}
diff --git a/library/common/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionOverrides.java b/library/common/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionOverrides.java
deleted file mode 100644
index 20baeb466e..0000000000
--- a/library/common/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionOverrides.java
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.android.exoplayer2.trackselection;
-
-import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
-import static com.google.android.exoplayer2.util.BundleableUtil.fromBundleNullableList;
-import static com.google.android.exoplayer2.util.BundleableUtil.toBundleArrayList;
-import static java.lang.annotation.ElementType.TYPE_USE;
-import static java.util.Collections.max;
-import static java.util.Collections.min;
-
-import android.os.Bundle;
-import androidx.annotation.IntDef;
-import androidx.annotation.Nullable;
-import com.google.android.exoplayer2.Bundleable;
-import com.google.android.exoplayer2.C;
-import com.google.android.exoplayer2.MediaItem;
-import com.google.android.exoplayer2.source.TrackGroup;
-import com.google.android.exoplayer2.util.MimeTypes;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.primitives.Ints;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Forces the selection of the specified tracks in {@link TrackGroup TrackGroups}.
- *
- * Each {@link TrackSelectionOverride override} only affects the selection of tracks of that
- * {@link C.TrackType type}. For example overriding the selection of an {@link C#TRACK_TYPE_AUDIO
- * audio} {@link TrackGroup} will not affect the selection of {@link C#TRACK_TYPE_VIDEO video} or
- * {@link C#TRACK_TYPE_TEXT text} tracks.
- *
- *
If multiple {@link TrackGroup TrackGroups} of the same {@link C.TrackType} are overridden,
- * which tracks will be selected depend on the player capabilities. For example, by default {@code
- * ExoPlayer} doesn't support selecting more than one {@link TrackGroup} per {@link C.TrackType}.
- *
- *
Overrides of {@link TrackGroup} that are not currently available are ignored. For example,
- * when the player transitions to the next {@link MediaItem} in a playlist, any overrides of the
- * previous {@link MediaItem} are ignored.
- *
- * @see TrackSelectionParameters#trackSelectionOverrides
- */
-public final class TrackSelectionOverrides implements Bundleable {
-
- /** Builder for {@link TrackSelectionOverrides}. */
- public static final class Builder {
- // Cannot use ImmutableMap.Builder as it doesn't support removing entries.
- private final HashMap overrides;
-
- /** Creates an builder with no {@link TrackSelectionOverride}. */
- public Builder() {
- overrides = new HashMap<>();
- }
-
- private Builder(Map overrides) {
- this.overrides = new HashMap<>(overrides);
- }
-
- /** Adds an override for the provided {@link TrackGroup}. */
- public Builder addOverride(TrackSelectionOverride override) {
- overrides.put(override.trackGroup, override);
- return this;
- }
-
- /** Removes the override associated with the provided {@link TrackGroup} if present. */
- public Builder clearOverride(TrackGroup trackGroup) {
- overrides.remove(trackGroup);
- return this;
- }
-
- /** Set the override for the type of the provided {@link TrackGroup}. */
- public Builder setOverrideForType(TrackSelectionOverride override) {
- clearOverridesOfType(override.getTrackType());
- overrides.put(override.trackGroup, override);
- return this;
- }
-
- /**
- * Remove any override associated with {@link TrackGroup TrackGroups} of type {@code trackType}.
- */
- public Builder clearOverridesOfType(@C.TrackType int trackType) {
- for (Iterator it = overrides.values().iterator(); it.hasNext(); ) {
- TrackSelectionOverride trackSelectionOverride = it.next();
- if (trackSelectionOverride.getTrackType() == trackType) {
- it.remove();
- }
- }
- return this;
- }
-
- /** Returns a new {@link TrackSelectionOverrides} instance with the current builder values. */
- public TrackSelectionOverrides build() {
- return new TrackSelectionOverrides(overrides);
- }
- }
-
- /**
- * Forces the selection of {@link #trackIndices} for a {@link TrackGroup}.
- *
- * If multiple tracks in {@link #trackGroup} are overridden, as many as possible will be
- * selected depending on the player capabilities.
- *
- *
If {@link #trackIndices} is empty, no tracks from {@link #trackGroup} will be played. This
- * is similar to {@link TrackSelectionParameters#disabledTrackTypes}, except it will only affect
- * the playback of the associated {@link TrackGroup}. For example, if the only {@link
- * C#TRACK_TYPE_VIDEO} {@link TrackGroup} is associated with no tracks, no video will play until
- * the next video starts.
- */
- public static final class TrackSelectionOverride implements Bundleable {
-
- /** The {@link TrackGroup} whose {@link #trackIndices} are forced to be selected. */
- public final TrackGroup trackGroup;
- /** The indices of tracks in a {@link TrackGroup} to be selected. */
- public final ImmutableList trackIndices;
-
- /** Constructs an instance to force all tracks in {@code trackGroup} to be selected. */
- public TrackSelectionOverride(TrackGroup trackGroup) {
- this.trackGroup = trackGroup;
- ImmutableList.Builder builder = new ImmutableList.Builder<>();
- for (int i = 0; i < trackGroup.length; i++) {
- builder.add(i);
- }
- this.trackIndices = builder.build();
- }
-
- /**
- * Constructs an instance to force {@code trackIndices} in {@code trackGroup} to be selected.
- *
- * @param trackGroup The {@link TrackGroup} for which to override the track selection.
- * @param trackIndices The indices of the tracks in the {@link TrackGroup} to select.
- */
- public TrackSelectionOverride(TrackGroup trackGroup, List trackIndices) {
- if (!trackIndices.isEmpty()) {
- if (min(trackIndices) < 0 || max(trackIndices) >= trackGroup.length) {
- throw new IndexOutOfBoundsException();
- }
- }
- this.trackGroup = trackGroup;
- this.trackIndices = ImmutableList.copyOf(trackIndices);
- }
-
- @Override
- public boolean equals(@Nullable Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null || getClass() != obj.getClass()) {
- return false;
- }
- TrackSelectionOverride that = (TrackSelectionOverride) obj;
- return trackGroup.equals(that.trackGroup) && trackIndices.equals(that.trackIndices);
- }
-
- @Override
- public int hashCode() {
- return trackGroup.hashCode() + 31 * trackIndices.hashCode();
- }
-
- /** Returns the {@link C.TrackType} of the overriden track group. */
- public @C.TrackType int getTrackType() {
- return MimeTypes.getTrackType(trackGroup.getFormat(0).sampleMimeType);
- }
-
- // Bundleable implementation
-
- @Documented
- @Retention(RetentionPolicy.SOURCE)
- @Target(TYPE_USE)
- @IntDef({
- FIELD_TRACK_GROUP,
- FIELD_TRACKS,
- })
- private @interface FieldNumber {}
-
- private static final int FIELD_TRACK_GROUP = 0;
- private static final int FIELD_TRACKS = 1;
-
- @Override
- public Bundle toBundle() {
- Bundle bundle = new Bundle();
- bundle.putBundle(keyForField(FIELD_TRACK_GROUP), trackGroup.toBundle());
- bundle.putIntArray(keyForField(FIELD_TRACKS), Ints.toArray(trackIndices));
- return bundle;
- }
-
- /** Object that can restore {@code TrackSelectionOverride} from a {@link Bundle}. */
- public static final Creator CREATOR =
- bundle -> {
- @Nullable Bundle trackGroupBundle = bundle.getBundle(keyForField(FIELD_TRACK_GROUP));
- checkNotNull(trackGroupBundle); // Mandatory as there are no reasonable defaults.
- TrackGroup trackGroup = TrackGroup.CREATOR.fromBundle(trackGroupBundle);
- @Nullable int[] tracks = bundle.getIntArray(keyForField(FIELD_TRACKS));
- if (tracks == null) {
- return new TrackSelectionOverride(trackGroup);
- }
- return new TrackSelectionOverride(trackGroup, Ints.asList(tracks));
- };
-
- private static String keyForField(@FieldNumber int field) {
- return Integer.toString(field, Character.MAX_RADIX);
- }
- }
-
- /** Empty {@code TrackSelectionOverrides}, where no track selection is overridden. */
- public static final TrackSelectionOverrides EMPTY =
- new TrackSelectionOverrides(ImmutableMap.of());
-
- private final ImmutableMap overrides;
-
- private TrackSelectionOverrides(Map overrides) {
- this.overrides = ImmutableMap.copyOf(overrides);
- }
-
- /** Returns a {@link Builder} initialized with the values of this instance. */
- public Builder buildUpon() {
- return new Builder(overrides);
- }
-
- /** Returns a list of the {@link TrackSelectionOverride overrides}. */
- public ImmutableList asList() {
- return ImmutableList.copyOf(overrides.values());
- }
-
- /**
- * Returns the {@link TrackSelectionOverride} of the provided {@link TrackGroup} or {@code null}
- * if there is none.
- */
- @Nullable
- public TrackSelectionOverride getOverride(TrackGroup trackGroup) {
- return overrides.get(trackGroup);
- }
-
- @Override
- public boolean equals(@Nullable Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null || getClass() != obj.getClass()) {
- return false;
- }
- TrackSelectionOverrides that = (TrackSelectionOverrides) obj;
- return overrides.equals(that.overrides);
- }
-
- @Override
- public int hashCode() {
- return overrides.hashCode();
- }
-
- // Bundleable implementation
-
- @Documented
- @Retention(RetentionPolicy.SOURCE)
- @Target(TYPE_USE)
- @IntDef({
- FIELD_OVERRIDES,
- })
- private @interface FieldNumber {}
-
- private static final int FIELD_OVERRIDES = 0;
-
- @Override
- public Bundle toBundle() {
- Bundle bundle = new Bundle();
- bundle.putParcelableArrayList(
- keyForField(FIELD_OVERRIDES), toBundleArrayList(overrides.values()));
- return bundle;
- }
-
- /** Object that can restore {@code TrackSelectionOverrides} from a {@link Bundle}. */
- public static final Creator CREATOR =
- bundle -> {
- List trackSelectionOverrides =
- fromBundleNullableList(
- TrackSelectionOverride.CREATOR,
- bundle.getParcelableArrayList(keyForField(FIELD_OVERRIDES)),
- ImmutableList.of());
- ImmutableMap.Builder builder =
- new ImmutableMap.Builder<>();
- for (int i = 0; i < trackSelectionOverrides.size(); i++) {
- TrackSelectionOverride trackSelectionOverride = trackSelectionOverrides.get(i);
- builder.put(trackSelectionOverride.trackGroup, trackSelectionOverride);
- }
- return new TrackSelectionOverrides(builder.buildOrThrow());
- };
-
- private static String keyForField(@FieldNumber int field) {
- return Integer.toString(field, Character.MAX_RADIX);
- }
-}
diff --git a/library/common/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionParameters.java b/library/common/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionParameters.java
index a3b22b4a3b..ad83f1a6fe 100644
--- a/library/common/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionParameters.java
+++ b/library/common/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionParameters.java
@@ -16,9 +16,9 @@
package com.google.android.exoplayer2.trackselection;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
-import static com.google.android.exoplayer2.util.BundleableUtil.fromNullableBundle;
+import static com.google.android.exoplayer2.util.BundleableUtil.fromBundleNullableList;
+import static com.google.android.exoplayer2.util.BundleableUtil.toBundleArrayList;
import static com.google.common.base.MoreObjects.firstNonNull;
-import static java.lang.annotation.ElementType.TYPE_USE;
import android.content.Context;
import android.graphics.Point;
@@ -30,14 +30,18 @@ import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import com.google.android.exoplayer2.Bundleable;
import com.google.android.exoplayer2.C;
+import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.util.Util;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.primitives.Ints;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
import java.util.Locale;
import java.util.Set;
import org.checkerframework.checker.initialization.qual.UnknownInitialization;
@@ -96,7 +100,7 @@ public class TrackSelectionParameters implements Bundleable {
// General
private boolean forceLowestBitrate;
private boolean forceHighestSupportedBitrate;
- private TrackSelectionOverrides trackSelectionOverrides;
+ private HashMap overrides;
private ImmutableSet<@C.TrackType Integer> disabledTrackTypes;
/**
@@ -128,7 +132,7 @@ public class TrackSelectionParameters implements Bundleable {
// General
forceLowestBitrate = false;
forceHighestSupportedBitrate = false;
- trackSelectionOverrides = TrackSelectionOverrides.EMPTY;
+ overrides = new HashMap<>();
disabledTrackTypes = ImmutableSet.of();
}
@@ -234,11 +238,16 @@ public class TrackSelectionParameters implements Bundleable {
bundle.getBoolean(
keyForField(FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE),
DEFAULT_WITHOUT_CONTEXT.forceHighestSupportedBitrate);
- trackSelectionOverrides =
- fromNullableBundle(
- TrackSelectionOverrides.CREATOR,
- bundle.getBundle(keyForField(FIELD_SELECTION_OVERRIDE_KEYS)),
- TrackSelectionOverrides.EMPTY);
+ overrides = new HashMap<>();
+ List overrideList =
+ fromBundleNullableList(
+ TrackSelectionOverride.CREATOR,
+ bundle.getParcelableArrayList(keyForField(FIELD_SELECTION_OVERRIDES)),
+ ImmutableList.of());
+ for (int i = 0; i < overrideList.size(); i++) {
+ TrackSelectionOverride override = overrideList.get(i);
+ overrides.put(override.trackGroup, override);
+ }
disabledTrackTypes =
ImmutableSet.copyOf(
Ints.asList(
@@ -252,7 +261,7 @@ public class TrackSelectionParameters implements Bundleable {
"preferredAudioLanguages",
"preferredAudioMimeTypes",
"preferredTextLanguages",
- "trackSelectionOverrides",
+ "overrides",
"disabledTrackTypes",
})
private void init(@UnknownInitialization Builder this, TrackSelectionParameters parameters) {
@@ -283,8 +292,8 @@ public class TrackSelectionParameters implements Bundleable {
// General
forceLowestBitrate = parameters.forceLowestBitrate;
forceHighestSupportedBitrate = parameters.forceHighestSupportedBitrate;
- trackSelectionOverrides = parameters.trackSelectionOverrides;
disabledTrackTypes = parameters.disabledTrackTypes;
+ overrides = new HashMap<>(parameters.overrides);
}
/** Overrides the value of the builder with the value of {@link TrackSelectionParameters}. */
@@ -643,14 +652,42 @@ public class TrackSelectionParameters implements Bundleable {
return this;
}
+ /** Adds an override for the provided {@link TrackGroup}. */
+ public Builder addOverride(TrackSelectionOverride override) {
+ overrides.put(override.trackGroup, override);
+ return this;
+ }
+
+ /** Removes the override associated with the provided {@link TrackGroup} if present. */
+ public Builder clearOverride(TrackGroup trackGroup) {
+ overrides.remove(trackGroup);
+ return this;
+ }
+
+ /** Set the override for the type of the provided {@link TrackGroup}. */
+ public Builder setOverrideForType(TrackSelectionOverride override) {
+ clearOverridesOfType(override.getTrackType());
+ overrides.put(override.trackGroup, override);
+ return this;
+ }
+
/**
- * Sets the selection overrides.
- *
- * @param trackSelectionOverrides The track selection overrides.
- * @return This builder.
+ * Remove any override associated with {@link TrackGroup TrackGroups} of type {@code trackType}.
*/
- public Builder setTrackSelectionOverrides(TrackSelectionOverrides trackSelectionOverrides) {
- this.trackSelectionOverrides = trackSelectionOverrides;
+ public Builder clearOverridesOfType(@C.TrackType int trackType) {
+ Iterator it = overrides.values().iterator();
+ while (it.hasNext()) {
+ TrackSelectionOverride override = it.next();
+ if (override.getTrackType() == trackType) {
+ it.remove();
+ }
+ }
+ return this;
+ }
+
+ /** Removes all track overrides. */
+ public Builder clearOverrides() {
+ overrides.clear();
return this;
}
@@ -855,8 +892,9 @@ public class TrackSelectionParameters implements Bundleable {
*/
public final boolean forceHighestSupportedBitrate;
- /** Overrides to force tracks to be selected. */
- public final TrackSelectionOverrides trackSelectionOverrides;
+ /** Overrides to force selection of specific tracks. */
+ public final ImmutableMap overrides;
+
/**
* The track types that are disabled. No track of a disabled type will be selected, thus no track
* type contained in the set will be played. The default value is that no track type is disabled
@@ -892,7 +930,7 @@ public class TrackSelectionParameters implements Bundleable {
// General
this.forceLowestBitrate = builder.forceLowestBitrate;
this.forceHighestSupportedBitrate = builder.forceHighestSupportedBitrate;
- this.trackSelectionOverrides = builder.trackSelectionOverrides;
+ this.overrides = ImmutableMap.copyOf(builder.overrides);
this.disabledTrackTypes = builder.disabledTrackTypes;
}
@@ -937,7 +975,7 @@ public class TrackSelectionParameters implements Bundleable {
// General
&& forceLowestBitrate == other.forceLowestBitrate
&& forceHighestSupportedBitrate == other.forceHighestSupportedBitrate
- && trackSelectionOverrides.equals(other.trackSelectionOverrides)
+ && overrides.equals(other.overrides)
&& disabledTrackTypes.equals(other.disabledTrackTypes);
}
@@ -971,7 +1009,7 @@ public class TrackSelectionParameters implements Bundleable {
// General
result = 31 * result + (forceLowestBitrate ? 1 : 0);
result = 31 * result + (forceHighestSupportedBitrate ? 1 : 0);
- result = 31 * result + trackSelectionOverrides.hashCode();
+ result = 31 * result + overrides.hashCode();
result = 31 * result + disabledTrackTypes.hashCode();
return result;
}
@@ -980,7 +1018,6 @@ public class TrackSelectionParameters implements Bundleable {
@Documented
@Retention(RetentionPolicy.SOURCE)
- @Target(TYPE_USE)
@IntDef({
FIELD_PREFERRED_AUDIO_LANGUAGES,
FIELD_PREFERRED_AUDIO_ROLE_FLAGS,
@@ -1004,8 +1041,7 @@ public class TrackSelectionParameters implements Bundleable {
FIELD_PREFERRED_AUDIO_MIME_TYPES,
FIELD_FORCE_LOWEST_BITRATE,
FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE,
- FIELD_SELECTION_OVERRIDE_KEYS,
- FIELD_SELECTION_OVERRIDE_VALUES,
+ FIELD_SELECTION_OVERRIDES,
FIELD_DISABLED_TRACK_TYPE,
FIELD_PREFERRED_VIDEO_ROLE_FLAGS
})
@@ -1033,10 +1069,9 @@ public class TrackSelectionParameters implements Bundleable {
private static final int FIELD_PREFERRED_AUDIO_MIME_TYPES = 20;
private static final int FIELD_FORCE_LOWEST_BITRATE = 21;
private static final int FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE = 22;
- private static final int FIELD_SELECTION_OVERRIDE_KEYS = 23;
- private static final int FIELD_SELECTION_OVERRIDE_VALUES = 24;
- private static final int FIELD_DISABLED_TRACK_TYPE = 25;
- private static final int FIELD_PREFERRED_VIDEO_ROLE_FLAGS = 26;
+ private static final int FIELD_SELECTION_OVERRIDES = 23;
+ private static final int FIELD_DISABLED_TRACK_TYPE = 24;
+ private static final int FIELD_PREFERRED_VIDEO_ROLE_FLAGS = 25;
@Override
public Bundle toBundle() {
@@ -1079,8 +1114,8 @@ public class TrackSelectionParameters implements Bundleable {
bundle.putBoolean(keyForField(FIELD_FORCE_LOWEST_BITRATE), forceLowestBitrate);
bundle.putBoolean(
keyForField(FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE), forceHighestSupportedBitrate);
- bundle.putBundle(
- keyForField(FIELD_SELECTION_OVERRIDE_KEYS), trackSelectionOverrides.toBundle());
+ bundle.putParcelableArrayList(
+ keyForField(FIELD_SELECTION_OVERRIDES), toBundleArrayList(overrides.values()));
bundle.putIntArray(keyForField(FIELD_DISABLED_TRACK_TYPE), Ints.toArray(disabledTrackTypes));
return bundle;
diff --git a/library/common/src/test/java/com/google/android/exoplayer2/trackselection/TrackSelectionOverrideTest.java b/library/common/src/test/java/com/google/android/exoplayer2/trackselection/TrackSelectionOverrideTest.java
new file mode 100644
index 0000000000..7034903c47
--- /dev/null
+++ b/library/common/src/test/java/com/google/android/exoplayer2/trackselection/TrackSelectionOverrideTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.android.exoplayer2.trackselection;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertThrows;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import com.google.android.exoplayer2.Format;
+import com.google.android.exoplayer2.source.TrackGroup;
+import com.google.common.collect.ImmutableList;
+import java.util.Arrays;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** Unit tests for {@link TrackSelectionOverride}. */
+@RunWith(AndroidJUnit4.class)
+public final class TrackSelectionOverrideTest {
+
+ @Test
+ public void newTrackSelectionOverride_withJustTrackGroup_selectsAllTracks() {
+ TrackSelectionOverride trackSelectionOverride =
+ new TrackSelectionOverride(newTrackGroupWithIds(1, 2));
+
+ assertThat(trackSelectionOverride.trackGroup).isEqualTo(newTrackGroupWithIds(1, 2));
+ assertThat(trackSelectionOverride.trackIndices).containsExactly(0, 1).inOrder();
+ }
+
+ @Test
+ public void newTrackSelectionOverride_withTracks_selectsOnlySpecifiedTracks() {
+ TrackSelectionOverride trackSelectionOverride =
+ new TrackSelectionOverride(newTrackGroupWithIds(1, 2), ImmutableList.of(1));
+
+ assertThat(trackSelectionOverride.trackGroup).isEqualTo(newTrackGroupWithIds(1, 2));
+ assertThat(trackSelectionOverride.trackIndices).containsExactly(1);
+ }
+
+ @Test
+ public void newTrackSelectionOverride_with0Tracks_selectsAllSpecifiedTracks() {
+ TrackSelectionOverride trackSelectionOverride =
+ new TrackSelectionOverride(newTrackGroupWithIds(1, 2), ImmutableList.of());
+
+ assertThat(trackSelectionOverride.trackGroup).isEqualTo(newTrackGroupWithIds(1, 2));
+ assertThat(trackSelectionOverride.trackIndices).isEmpty();
+ }
+
+ @Test
+ public void newTrackSelectionOverride_withInvalidIndex_throws() {
+ assertThrows(
+ IndexOutOfBoundsException.class,
+ () -> new TrackSelectionOverride(newTrackGroupWithIds(1, 2), ImmutableList.of(2)));
+ }
+
+ private static TrackGroup newTrackGroupWithIds(int... ids) {
+ return new TrackGroup(
+ Arrays.stream(ids)
+ .mapToObj(id -> new Format.Builder().setId(id).build())
+ .toArray(Format[]::new));
+ }
+}
diff --git a/library/common/src/test/java/com/google/android/exoplayer2/trackselection/TrackSelectionOverridesTest.java b/library/common/src/test/java/com/google/android/exoplayer2/trackselection/TrackSelectionOverridesTest.java
deleted file mode 100644
index 5fe642ac48..0000000000
--- a/library/common/src/test/java/com/google/android/exoplayer2/trackselection/TrackSelectionOverridesTest.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.android.exoplayer2.trackselection;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.assertThrows;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import com.google.android.exoplayer2.C;
-import com.google.android.exoplayer2.Format;
-import com.google.android.exoplayer2.source.TrackGroup;
-import com.google.android.exoplayer2.trackselection.TrackSelectionOverrides.TrackSelectionOverride;
-import com.google.android.exoplayer2.util.MimeTypes;
-import com.google.common.collect.ImmutableList;
-import java.util.Arrays;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/** Unit tests for {@link TrackSelectionOverrides}. */
-@RunWith(AndroidJUnit4.class)
-public final class TrackSelectionOverridesTest {
-
- public static final TrackGroup AAC_TRACK_GROUP =
- new TrackGroup(new Format.Builder().setSampleMimeType(MimeTypes.AUDIO_AAC).build());
-
- private static TrackGroup newTrackGroupWithIds(int... ids) {
- return new TrackGroup(
- Arrays.stream(ids)
- .mapToObj(id -> new Format.Builder().setId(id).build())
- .toArray(Format[]::new));
- }
-
- @Test
- public void newTrackSelectionOverride_withJustTrackGroup_selectsAllTracks() {
- TrackSelectionOverride trackSelectionOverride =
- new TrackSelectionOverride(newTrackGroupWithIds(1, 2));
-
- assertThat(trackSelectionOverride.trackGroup).isEqualTo(newTrackGroupWithIds(1, 2));
- assertThat(trackSelectionOverride.trackIndices).containsExactly(0, 1).inOrder();
- }
-
- @Test
- public void newTrackSelectionOverride_withTracks_selectsOnlySpecifiedTracks() {
- TrackSelectionOverride trackSelectionOverride =
- new TrackSelectionOverride(newTrackGroupWithIds(1, 2), ImmutableList.of(1));
-
- assertThat(trackSelectionOverride.trackGroup).isEqualTo(newTrackGroupWithIds(1, 2));
- assertThat(trackSelectionOverride.trackIndices).containsExactly(1);
- }
-
- @Test
- public void newTrackSelectionOverride_with0Tracks_selectsAllSpecifiedTracks() {
- TrackSelectionOverride trackSelectionOverride =
- new TrackSelectionOverride(newTrackGroupWithIds(1, 2), ImmutableList.of());
-
- assertThat(trackSelectionOverride.trackGroup).isEqualTo(newTrackGroupWithIds(1, 2));
- assertThat(trackSelectionOverride.trackIndices).isEmpty();
- }
-
- @Test
- public void newTrackSelectionOverride_withInvalidIndex_throws() {
- assertThrows(
- IndexOutOfBoundsException.class,
- () -> new TrackSelectionOverride(newTrackGroupWithIds(1, 2), ImmutableList.of(2)));
- }
-
- @Test
- public void roundTripViaBundle_withOverrides_yieldsEqualInstance() {
- TrackSelectionOverrides trackSelectionOverrides =
- new TrackSelectionOverrides.Builder()
- .setOverrideForType(
- new TrackSelectionOverride(newTrackGroupWithIds(3, 4), ImmutableList.of(1)))
- .addOverride(new TrackSelectionOverride(newTrackGroupWithIds(5, 6)))
- .build();
-
- TrackSelectionOverrides fromBundle =
- TrackSelectionOverrides.CREATOR.fromBundle(trackSelectionOverrides.toBundle());
-
- assertThat(fromBundle).isEqualTo(trackSelectionOverrides);
- assertThat(fromBundle.asList()).isEqualTo(trackSelectionOverrides.asList());
- }
-
- @Test
- public void builder_byDefault_isEmpty() {
- TrackSelectionOverrides trackSelectionOverrides = new TrackSelectionOverrides.Builder().build();
-
- assertThat(trackSelectionOverrides.asList()).isEmpty();
- assertThat(trackSelectionOverrides).isEqualTo(TrackSelectionOverrides.EMPTY);
- }
-
- @Test
- public void addOverride_onDifferentGroups_addsOverride() {
- TrackSelectionOverride override1 = new TrackSelectionOverride(newTrackGroupWithIds(1));
- TrackSelectionOverride override2 = new TrackSelectionOverride(newTrackGroupWithIds(2));
-
- TrackSelectionOverrides trackSelectionOverrides =
- new TrackSelectionOverrides.Builder().addOverride(override1).addOverride(override2).build();
-
- assertThat(trackSelectionOverrides.asList()).containsExactly(override1, override2);
- assertThat(trackSelectionOverrides.getOverride(override1.trackGroup)).isEqualTo(override1);
- assertThat(trackSelectionOverrides.getOverride(override2.trackGroup)).isEqualTo(override2);
- }
-
- @Test
- public void addOverride_onSameGroup_replacesOverride() {
- TrackGroup trackGroup = newTrackGroupWithIds(1, 2, 3);
- TrackSelectionOverride override1 =
- new TrackSelectionOverride(trackGroup, /* trackIndices= */ ImmutableList.of(0));
- TrackSelectionOverride override2 =
- new TrackSelectionOverride(trackGroup, /* trackIndices= */ ImmutableList.of(1));
-
- TrackSelectionOverrides trackSelectionOverrides =
- new TrackSelectionOverrides.Builder().addOverride(override1).addOverride(override2).build();
-
- assertThat(trackSelectionOverrides.asList()).containsExactly(override2);
- assertThat(trackSelectionOverrides.getOverride(override2.trackGroup)).isEqualTo(override2);
- }
-
- @Test
- public void setOverrideForType_onSameType_replacesOverride() {
- TrackSelectionOverride override1 = new TrackSelectionOverride(newTrackGroupWithIds(1));
- TrackSelectionOverride override2 = new TrackSelectionOverride(newTrackGroupWithIds(2));
-
- TrackSelectionOverrides trackSelectionOverrides =
- new TrackSelectionOverrides.Builder()
- .setOverrideForType(override1)
- .setOverrideForType(override2)
- .build();
-
- assertThat(trackSelectionOverrides.asList()).containsExactly(override2);
- assertThat(trackSelectionOverrides.getOverride(override2.trackGroup)).isEqualTo(override2);
- }
-
- @Test
- public void clearOverridesOfType_ofTypeAudio_removesAudioOverride() {
- TrackSelectionOverride override1 = new TrackSelectionOverride(AAC_TRACK_GROUP);
- TrackSelectionOverride override2 = new TrackSelectionOverride(newTrackGroupWithIds(1));
- TrackSelectionOverrides trackSelectionOverrides =
- new TrackSelectionOverrides.Builder()
- .addOverride(override1)
- .addOverride(override2)
- .clearOverridesOfType(C.TRACK_TYPE_AUDIO)
- .build();
-
- assertThat(trackSelectionOverrides.asList()).containsExactly(override2);
- assertThat(trackSelectionOverrides.getOverride(override2.trackGroup)).isEqualTo(override2);
- }
-
- @Test
- public void clearOverride_ofTypeGroup_removesOverride() {
- TrackSelectionOverride override1 = new TrackSelectionOverride(AAC_TRACK_GROUP);
- TrackSelectionOverride override2 = new TrackSelectionOverride(newTrackGroupWithIds(1));
- TrackSelectionOverrides trackSelectionOverrides =
- new TrackSelectionOverrides.Builder()
- .addOverride(override1)
- .addOverride(override2)
- .clearOverride(override2.trackGroup)
- .build();
-
- assertThat(trackSelectionOverrides.asList()).containsExactly(override1);
- assertThat(trackSelectionOverrides.getOverride(override1.trackGroup)).isEqualTo(override1);
- }
-}
diff --git a/library/common/src/test/java/com/google/android/exoplayer2/trackselection/TrackSelectionParametersTest.java b/library/common/src/test/java/com/google/android/exoplayer2/trackselection/TrackSelectionParametersTest.java
index 519b1d4bed..c65ec2f966 100644
--- a/library/common/src/test/java/com/google/android/exoplayer2/trackselection/TrackSelectionParametersTest.java
+++ b/library/common/src/test/java/com/google/android/exoplayer2/trackselection/TrackSelectionParametersTest.java
@@ -22,7 +22,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.source.TrackGroup;
-import com.google.android.exoplayer2.trackselection.TrackSelectionOverrides.TrackSelectionOverride;
import com.google.android.exoplayer2.util.MimeTypes;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@@ -33,6 +32,9 @@ import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public final class TrackSelectionParametersTest {
+ private static final TrackGroup AAC_TRACK_GROUP =
+ new TrackGroup(new Format.Builder().setSampleMimeType(MimeTypes.AUDIO_AAC).build());
+
@Test
public void defaultValue_withoutChange_isAsExpected() {
TrackSelectionParameters parameters = TrackSelectionParameters.DEFAULT_WITHOUT_CONTEXT;
@@ -63,22 +65,19 @@ public final class TrackSelectionParametersTest {
// General
assertThat(parameters.forceLowestBitrate).isFalse();
assertThat(parameters.forceHighestSupportedBitrate).isFalse();
- assertThat(parameters.trackSelectionOverrides.asList()).isEmpty();
+ assertThat(parameters.overrides).isEmpty();
assertThat(parameters.disabledTrackTypes).isEmpty();
}
@Test
public void parametersSet_fromDefault_isAsExpected() {
- TrackSelectionOverrides trackSelectionOverrides =
- new TrackSelectionOverrides.Builder()
- .addOverride(new TrackSelectionOverride(new TrackGroup(new Format.Builder().build())))
- .addOverride(
- new TrackSelectionOverride(
- new TrackGroup(
- new Format.Builder().setId(4).build(),
- new Format.Builder().setId(5).build()),
- /* trackIndices= */ ImmutableList.of(1)))
- .build();
+ TrackSelectionOverride override1 =
+ new TrackSelectionOverride(new TrackGroup(new Format.Builder().build()));
+ TrackSelectionOverride override2 =
+ new TrackSelectionOverride(
+ new TrackGroup(
+ new Format.Builder().setId(4).build(), new Format.Builder().setId(5).build()),
+ /* trackIndices= */ ImmutableList.of(1));
TrackSelectionParameters parameters =
TrackSelectionParameters.DEFAULT_WITHOUT_CONTEXT
.buildUpon()
@@ -107,7 +106,13 @@ public final class TrackSelectionParametersTest {
// General
.setForceLowestBitrate(false)
.setForceHighestSupportedBitrate(true)
- .setTrackSelectionOverrides(trackSelectionOverrides)
+ .addOverride(new TrackSelectionOverride(new TrackGroup(new Format.Builder().build())))
+ .addOverride(
+ new TrackSelectionOverride(
+ new TrackGroup(
+ new Format.Builder().setId(4).build(),
+ new Format.Builder().setId(5).build()),
+ /* trackIndices= */ ImmutableList.of(1)))
.setDisabledTrackTypes(ImmutableSet.of(C.TRACK_TYPE_AUDIO, C.TRACK_TYPE_TEXT))
.build();
@@ -141,7 +146,8 @@ public final class TrackSelectionParametersTest {
// General
assertThat(parameters.forceLowestBitrate).isFalse();
assertThat(parameters.forceHighestSupportedBitrate).isTrue();
- assertThat(parameters.trackSelectionOverrides).isEqualTo(trackSelectionOverrides);
+ assertThat(parameters.overrides)
+ .containsExactly(override1.trackGroup, override1, override2.trackGroup, override2);
assertThat(parameters.disabledTrackTypes)
.containsExactly(C.TRACK_TYPE_AUDIO, C.TRACK_TYPE_TEXT);
}
@@ -182,4 +188,101 @@ public final class TrackSelectionParametersTest {
assertThat(parameters.viewportHeight).isEqualTo(Integer.MAX_VALUE);
assertThat(parameters.viewportOrientationMayChange).isTrue();
}
+
+ @Test
+ public void roundTripViaBundle_withOverride_yieldsEqualInstance() {
+ TrackSelectionOverride override =
+ new TrackSelectionOverride(
+ newTrackGroupWithIds(3, 4), /* trackIndices= */ ImmutableList.of(1));
+ TrackSelectionParameters trackSelectionParameters =
+ new TrackSelectionParameters.Builder(getApplicationContext()).addOverride(override).build();
+
+ TrackSelectionParameters fromBundle =
+ TrackSelectionParameters.CREATOR.fromBundle(trackSelectionParameters.toBundle());
+
+ assertThat(fromBundle).isEqualTo(trackSelectionParameters);
+ assertThat(trackSelectionParameters.overrides).containsExactly(override.trackGroup, override);
+ }
+
+ @Test
+ public void addOverride_onDifferentGroups_addsOverride() {
+ TrackSelectionOverride override1 = new TrackSelectionOverride(newTrackGroupWithIds(1));
+ TrackSelectionOverride override2 = new TrackSelectionOverride(newTrackGroupWithIds(2));
+
+ TrackSelectionParameters trackSelectionParameters =
+ new TrackSelectionParameters.Builder(getApplicationContext())
+ .addOverride(override1)
+ .addOverride(override2)
+ .build();
+
+ assertThat(trackSelectionParameters.overrides)
+ .containsExactly(override1.trackGroup, override1, override2.trackGroup, override2);
+ }
+
+ @Test
+ public void addOverride_onSameGroup_replacesOverride() {
+ TrackGroup trackGroup = newTrackGroupWithIds(1, 2, 3);
+ TrackSelectionOverride override1 =
+ new TrackSelectionOverride(trackGroup, /* trackIndices= */ ImmutableList.of(0));
+ TrackSelectionOverride override2 =
+ new TrackSelectionOverride(trackGroup, /* trackIndices= */ ImmutableList.of(1));
+
+ TrackSelectionParameters trackSelectionParameters =
+ new TrackSelectionParameters.Builder(getApplicationContext())
+ .addOverride(override1)
+ .addOverride(override2)
+ .build();
+
+ assertThat(trackSelectionParameters.overrides).containsExactly(override2.trackGroup, override2);
+ }
+
+ @Test
+ public void setOverrideForType_onSameType_replacesOverride() {
+ TrackSelectionOverride override1 = new TrackSelectionOverride(newTrackGroupWithIds(1));
+ TrackSelectionOverride override2 = new TrackSelectionOverride(newTrackGroupWithIds(2));
+
+ TrackSelectionParameters trackSelectionParameters =
+ new TrackSelectionParameters.Builder(getApplicationContext())
+ .setOverrideForType(override1)
+ .setOverrideForType(override2)
+ .build();
+
+ assertThat(trackSelectionParameters.overrides).containsExactly(override2.trackGroup, override2);
+ }
+
+ @Test
+ public void clearOverridesOfType_ofTypeAudio_removesAudioOverride() {
+ TrackSelectionOverride override1 = new TrackSelectionOverride(AAC_TRACK_GROUP);
+ TrackSelectionOverride override2 = new TrackSelectionOverride(newTrackGroupWithIds(1));
+ TrackSelectionParameters trackSelectionParameters =
+ new TrackSelectionParameters.Builder(getApplicationContext())
+ .addOverride(override1)
+ .addOverride(override2)
+ .clearOverridesOfType(C.TRACK_TYPE_AUDIO)
+ .build();
+
+ assertThat(trackSelectionParameters.overrides).containsExactly(override2.trackGroup, override2);
+ }
+
+ @Test
+ public void clearOverride_ofTypeGroup_removesOverride() {
+ TrackSelectionOverride override1 = new TrackSelectionOverride(AAC_TRACK_GROUP);
+ TrackSelectionOverride override2 = new TrackSelectionOverride(newTrackGroupWithIds(1));
+ TrackSelectionParameters trackSelectionParameters =
+ new TrackSelectionParameters.Builder(getApplicationContext())
+ .addOverride(override1)
+ .addOverride(override2)
+ .clearOverride(override2.trackGroup)
+ .build();
+
+ assertThat(trackSelectionParameters.overrides).containsExactly(override1.trackGroup, override1);
+ }
+
+ private static TrackGroup newTrackGroupWithIds(int... ids) {
+ Format[] formats = new Format[ids.length];
+ for (int i = 0; i < ids.length; i++) {
+ formats[i] = new Format.Builder().setId(ids[i]).build();
+ }
+ return new TrackGroup(formats);
+ }
}
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelector.java b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelector.java
index ac2b6cbb25..ea3c00efab 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelector.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelector.java
@@ -43,7 +43,6 @@ import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray;
-import com.google.android.exoplayer2.trackselection.TrackSelectionOverrides.TrackSelectionOverride;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.BundleableUtil;
import com.google.android.exoplayer2.util.MimeTypes;
@@ -593,9 +592,32 @@ public class DefaultTrackSelector extends MappingTrackSelector {
}
@Override
- public ParametersBuilder setTrackSelectionOverrides(
- TrackSelectionOverrides trackSelectionOverrides) {
- super.setTrackSelectionOverrides(trackSelectionOverrides);
+ public ParametersBuilder addOverride(TrackSelectionOverride override) {
+ super.addOverride(override);
+ return this;
+ }
+
+ @Override
+ public ParametersBuilder clearOverride(TrackGroup trackGroup) {
+ super.clearOverride(trackGroup);
+ return this;
+ }
+
+ @Override
+ public ParametersBuilder setOverrideForType(TrackSelectionOverride override) {
+ super.setOverrideForType(override);
+ return this;
+ }
+
+ @Override
+ public ParametersBuilder clearOverridesOfType(@C.TrackType int trackType) {
+ super.clearOverridesOfType(trackType);
+ return this;
+ }
+
+ @Override
+ public ParametersBuilder clearOverrides() {
+ super.clearOverrides();
return this;
}
@@ -700,7 +722,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* @param groups The {@link TrackGroupArray} for which the override should be applied.
* @param override The override.
* @return This builder.
- * @deprecated Use {@link TrackSelectionParameters.Builder#setTrackSelectionOverrides}.
+ * @deprecated Use {@link TrackSelectionParameters.Builder#addOverride(TrackSelectionOverride)}.
*/
@Deprecated
public final ParametersBuilder setSelectionOverride(
@@ -725,7 +747,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* @param rendererIndex The renderer index.
* @param groups The {@link TrackGroupArray} for which the override should be cleared.
* @return This builder.
- * @deprecated Use {@link TrackSelectionParameters.Builder#setTrackSelectionOverrides}.
+ * @deprecated Use {@link TrackSelectionParameters.Builder#clearOverride(TrackGroup)}.
*/
@Deprecated
public final ParametersBuilder clearSelectionOverride(
@@ -748,7 +770,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
*
* @param rendererIndex The renderer index.
* @return This builder.
- * @deprecated Use {@link TrackSelectionParameters.Builder#setTrackSelectionOverrides}.
+ * @deprecated Use {@link TrackSelectionParameters.Builder#clearOverridesOfType(int)}.
*/
@Deprecated
public final ParametersBuilder clearSelectionOverrides(int rendererIndex) {
@@ -766,7 +788,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* Clears all track selection overrides for all renderers.
*
* @return This builder.
- * @deprecated Use {@link TrackSelectionParameters.Builder#setTrackSelectionOverrides}.
+ * @deprecated Use {@link TrackSelectionParameters.Builder#clearOverrides()}.
*/
@Deprecated
public final ParametersBuilder clearSelectionOverrides() {
@@ -1017,7 +1039,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* @return Whether there is an override.
* @deprecated Only works to retrieve the overrides set with the deprecated {@link
* ParametersBuilder#setSelectionOverride(int, TrackGroupArray, SelectionOverride)}. Use
- * {@link TrackSelectionParameters#trackSelectionOverrides} instead.
+ * {@link TrackSelectionParameters#overrides} instead.
*/
@Deprecated
public final boolean hasSelectionOverride(int rendererIndex, TrackGroupArray groups) {
@@ -1034,7 +1056,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* @return The override, or null if no override exists.
* @deprecated Only works to retrieve the overrides set with the deprecated {@link
* ParametersBuilder#setSelectionOverride(int, TrackGroupArray, SelectionOverride)}. Use
- * {@link TrackSelectionParameters#trackSelectionOverrides} instead.
+ * {@link TrackSelectionParameters#overrides} instead.
*/
@Deprecated
@Nullable
@@ -1653,9 +1675,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
TrackGroupArray rendererTrackGroups = mappedTrackInfo.getTrackGroups(rendererIndex);
for (int j = 0; j < rendererTrackGroups.length; j++) {
maybeUpdateApplicableOverrides(
- applicableOverrides,
- params.trackSelectionOverrides.getOverride(rendererTrackGroups.get(j)),
- rendererIndex);
+ applicableOverrides, params.overrides.get(rendererTrackGroups.get(j)), rendererIndex);
}
}
// Also iterate unmapped groups to see if they have overrides.
@@ -1663,7 +1683,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
for (int i = 0; i < unmappedGroups.length; i++) {
maybeUpdateApplicableOverrides(
applicableOverrides,
- params.trackSelectionOverrides.getOverride(unmappedGroups.get(i)),
+ params.overrides.get(unmappedGroups.get(i)),
/* rendererIndex= */ C.INDEX_UNSET);
}
return applicableOverrides;
diff --git a/library/core/src/test/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelectorTest.java b/library/core/src/test/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelectorTest.java
index e56d4bfb49..f9affe7b98 100644
--- a/library/core/src/test/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelectorTest.java
+++ b/library/core/src/test/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelectorTest.java
@@ -52,7 +52,6 @@ import com.google.android.exoplayer2.testutil.FakeTimeline;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.Parameters;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.ParametersBuilder;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.SelectionOverride;
-import com.google.android.exoplayer2.trackselection.TrackSelectionOverrides.TrackSelectionOverride;
import com.google.android.exoplayer2.trackselection.TrackSelector.InvalidationListener;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.util.MimeTypes;
@@ -169,10 +168,8 @@ public final class DefaultTrackSelectorTest {
trackSelector.setParameters(
trackSelector
.buildUponParameters()
- .setTrackSelectionOverrides(
- new TrackSelectionOverrides.Builder()
- .addOverride(new TrackSelectionOverride(VIDEO_TRACK_GROUP, ImmutableList.of()))
- .build()));
+ .addOverride(new TrackSelectionOverride(VIDEO_TRACK_GROUP, ImmutableList.of()))
+ .build());
TrackSelectorResult result =
trackSelector.selectTracks(RENDERER_CAPABILITIES, TRACK_GROUPS, periodId, TIMELINE);
@@ -223,18 +220,16 @@ public final class DefaultTrackSelectorTest {
trackSelector.setParameters(
trackSelector
.buildUponParameters()
- .setTrackSelectionOverrides(
- new TrackSelectionOverrides.Builder()
- .addOverride(
- new TrackSelectionOverride(
- videoGroupHighBitrate, /* trackIndices= */ ImmutableList.of()))
- .addOverride(
- new TrackSelectionOverride(
- videoGroupMidBitrate, /* trackIndices= */ ImmutableList.of(0)))
- .addOverride(
- new TrackSelectionOverride(
- videoGroupLowBitrate, /* trackIndices= */ ImmutableList.of()))
- .build()));
+ .addOverride(
+ new TrackSelectionOverride(
+ videoGroupHighBitrate, /* trackIndices= */ ImmutableList.of()))
+ .addOverride(
+ new TrackSelectionOverride(
+ videoGroupMidBitrate, /* trackIndices= */ ImmutableList.of(0)))
+ .addOverride(
+ new TrackSelectionOverride(
+ videoGroupLowBitrate, /* trackIndices= */ ImmutableList.of()))
+ .build());
TrackSelectorResult result =
trackSelector.selectTracks(
@@ -258,12 +253,10 @@ public final class DefaultTrackSelectorTest {
trackSelector.setParameters(
trackSelector
.buildUponParameters()
- .setTrackSelectionOverrides(
- new TrackSelectionOverrides.Builder()
- .setOverrideForType(
- new TrackSelectionOverride(
- new TrackGroup(VIDEO_FORMAT, VIDEO_FORMAT), ImmutableList.of()))
- .build()));
+ .setOverrideForType(
+ new TrackSelectionOverride(
+ new TrackGroup(VIDEO_FORMAT, VIDEO_FORMAT), ImmutableList.of()))
+ .build());
TrackSelectorResult result =
trackSelector.selectTracks(
@@ -307,10 +300,8 @@ public final class DefaultTrackSelectorTest {
trackSelector.setParameters(
trackSelector
.buildUponParameters()
- .setTrackSelectionOverrides(
- new TrackSelectionOverrides.Builder()
- .setOverrideForType(new TrackSelectionOverride(videoGroupH264))
- .build()));
+ .setOverrideForType(new TrackSelectionOverride(videoGroupH264))
+ .build());
TrackSelectorResult result =
trackSelector.selectTracks(
new RendererCapabilities[] {rendererCapabilitiesH264, rendererCapabilitiesAv1},
@@ -326,10 +317,8 @@ public final class DefaultTrackSelectorTest {
trackSelector.setParameters(
trackSelector
.buildUponParameters()
- .setTrackSelectionOverrides(
- new TrackSelectionOverrides.Builder()
- .setOverrideForType(new TrackSelectionOverride(videoGroupAv1))
- .build()));
+ .setOverrideForType(new TrackSelectionOverride(videoGroupAv1))
+ .build());
result =
trackSelector.selectTracks(
new RendererCapabilities[] {rendererCapabilitiesH264, rendererCapabilitiesAv1},
@@ -359,10 +348,8 @@ public final class DefaultTrackSelectorTest {
trackSelector.setParameters(
trackSelector
.buildUponParameters()
- .setTrackSelectionOverrides(
- new TrackSelectionOverrides.Builder()
- .setOverrideForType(new TrackSelectionOverride(audioGroupUnsupported))
- .build()));
+ .setOverrideForType(new TrackSelectionOverride(audioGroupUnsupported))
+ .build());
TrackSelectorResult result =
trackSelector.selectTracks(
new RendererCapabilities[] {VIDEO_CAPABILITIES, audioRendererCapabilties},
@@ -2395,13 +2382,10 @@ public final class DefaultTrackSelectorTest {
.setRendererDisabled(1, true)
.setRendererDisabled(3, true)
.setRendererDisabled(5, false)
- .setTrackSelectionOverrides(
- new TrackSelectionOverrides.Builder()
- .setOverrideForType(
- new TrackSelectionOverride(
- new TrackGroup(AUDIO_FORMAT, AUDIO_FORMAT, AUDIO_FORMAT, AUDIO_FORMAT),
- /* trackIndices= */ ImmutableList.of(0, 2, 3)))
- .build())
+ .setOverrideForType(
+ new TrackSelectionOverride(
+ new TrackGroup(AUDIO_FORMAT, AUDIO_FORMAT, AUDIO_FORMAT, AUDIO_FORMAT),
+ /* trackIndices= */ ImmutableList.of(0, 2, 3)))
.setDisabledTrackTypes(ImmutableSet.of(C.TRACK_TYPE_AUDIO))
.build();
}
diff --git a/library/ui/src/main/java/com/google/android/exoplayer2/ui/StyledPlayerControlView.java b/library/ui/src/main/java/com/google/android/exoplayer2/ui/StyledPlayerControlView.java
index 82715eddf7..4efcc9db85 100644
--- a/library/ui/src/main/java/com/google/android/exoplayer2/ui/StyledPlayerControlView.java
+++ b/library/ui/src/main/java/com/google/android/exoplayer2/ui/StyledPlayerControlView.java
@@ -67,8 +67,7 @@ import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.TracksInfo;
import com.google.android.exoplayer2.TracksInfo.TrackGroupInfo;
import com.google.android.exoplayer2.source.TrackGroup;
-import com.google.android.exoplayer2.trackselection.TrackSelectionOverrides;
-import com.google.android.exoplayer2.trackselection.TrackSelectionOverrides.TrackSelectionOverride;
+import com.google.android.exoplayer2.trackselection.TrackSelectionOverride;
import com.google.android.exoplayer2.trackselection.TrackSelectionParameters;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.RepeatModeUtil;
@@ -1908,7 +1907,7 @@ public class StyledPlayerControlView extends FrameLayout {
holder.textView.setText(R.string.exo_track_selection_auto);
// hasSelectionOverride is true means there is an explicit track selection, not "Auto".
TrackSelectionParameters parameters = checkNotNull(player).getTrackSelectionParameters();
- boolean hasSelectionOverride = hasSelectionOverride(parameters.trackSelectionOverrides);
+ boolean hasSelectionOverride = hasSelectionOverride(parameters);
holder.checkView.setVisibility(hasSelectionOverride ? INVISIBLE : VISIBLE);
holder.itemView.setOnClickListener(
v -> {
@@ -1917,12 +1916,6 @@ public class StyledPlayerControlView extends FrameLayout {
}
TrackSelectionParameters trackSelectionParameters =
player.getTrackSelectionParameters();
- TrackSelectionOverrides trackSelectionOverrides =
- trackSelectionParameters
- .trackSelectionOverrides
- .buildUpon()
- .clearOverridesOfType(C.TRACK_TYPE_AUDIO)
- .build();
Set<@C.TrackType Integer> disabledTrackTypes =
new HashSet<>(trackSelectionParameters.disabledTrackTypes);
disabledTrackTypes.remove(C.TRACK_TYPE_AUDIO);
@@ -1930,7 +1923,7 @@ public class StyledPlayerControlView extends FrameLayout {
.setTrackSelectionParameters(
trackSelectionParameters
.buildUpon()
- .setTrackSelectionOverrides(trackSelectionOverrides)
+ .clearOverridesOfType(C.TRACK_TYPE_AUDIO)
.setDisabledTrackTypes(disabledTrackTypes)
.build());
settingsAdapter.setSubTextAtPosition(
@@ -1940,10 +1933,10 @@ public class StyledPlayerControlView extends FrameLayout {
});
}
- private boolean hasSelectionOverride(TrackSelectionOverrides trackSelectionOverrides) {
+ private boolean hasSelectionOverride(TrackSelectionParameters trackSelectionParameters) {
for (int i = 0; i < tracks.size(); i++) {
TrackGroup trackGroup = tracks.get(i).trackGroupInfo.getTrackGroup();
- if (trackSelectionOverrides.getOverride(trackGroup) != null) {
+ if (trackSelectionParameters.overrides.containsKey(trackGroup)) {
return true;
}
}
@@ -1966,7 +1959,7 @@ public class StyledPlayerControlView extends FrameLayout {
getResources().getString(R.string.exo_track_selection_none));
// TODO(insun) : Make the audio item in main settings (settingsAdapater)
// to be non-clickable.
- } else if (!hasSelectionOverride(params.trackSelectionOverrides)) {
+ } else if (!hasSelectionOverride(params)) {
settingsAdapter.setSubTextAtPosition(
SETTINGS_AUDIO_TRACK_SELECTION_POSITION,
getResources().getString(R.string.exo_track_selection_auto));
@@ -2017,8 +2010,7 @@ public class StyledPlayerControlView extends FrameLayout {
TrackInformation track = tracks.get(position - 1);
TrackGroup trackGroup = track.trackGroupInfo.getTrackGroup();
TrackSelectionParameters params = checkNotNull(player).getTrackSelectionParameters();
- boolean explicitlySelected =
- params.trackSelectionOverrides.getOverride(trackGroup) != null && track.isSelected();
+ boolean explicitlySelected = params.overrides.get(trackGroup) != null && track.isSelected();
holder.textView.setText(track.trackName);
holder.checkView.setVisibility(explicitlySelected ? VISIBLE : INVISIBLE);
holder.itemView.setOnClickListener(
@@ -2028,14 +2020,6 @@ public class StyledPlayerControlView extends FrameLayout {
}
TrackSelectionParameters trackSelectionParameters =
player.getTrackSelectionParameters();
- TrackSelectionOverrides overrides =
- trackSelectionParameters
- .trackSelectionOverrides
- .buildUpon()
- .setOverrideForType(
- new TrackSelectionOverride(
- trackGroup, ImmutableList.of(track.trackIndex)))
- .build();
Set<@C.TrackType Integer> disabledTrackTypes =
new HashSet<>(trackSelectionParameters.disabledTrackTypes);
disabledTrackTypes.remove(track.trackGroupInfo.getTrackType());
@@ -2043,7 +2027,9 @@ public class StyledPlayerControlView extends FrameLayout {
.setTrackSelectionParameters(
trackSelectionParameters
.buildUpon()
- .setTrackSelectionOverrides(overrides)
+ .setOverrideForType(
+ new TrackSelectionOverride(
+ trackGroup, ImmutableList.of(track.trackIndex)))
.setDisabledTrackTypes(disabledTrackTypes)
.build());
onTrackSelection(track.trackName);