Flatten TrackSelectionParameters

PiperOrigin-RevId: 428747243
This commit is contained in:
olly 2022-02-15 12:39:30 +00:00 committed by Ian Baker
parent de3708ee12
commit daf72f518c
11 changed files with 476 additions and 627 deletions

View File

@ -56,6 +56,9 @@
values in `Player.EventFlags`. values in `Player.EventFlags`.
* Split `AnalyticsCollector` into an interface and default implementation * Split `AnalyticsCollector` into an interface and default implementation
to allow it to be stripped by R8 if an app doesn't need it. 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: * Android 12 compatibility:
* Upgrade the Cast extension to depend on * Upgrade the Cast extension to depend on
`com.google.android.gms:play-services-cast-framework:20.1.0`. Earlier `com.google.android.gms:play-services-cast-framework:20.1.0`. Earlier

View File

@ -124,13 +124,11 @@ track group to select this audio group and prevent any other audio track groups
from being selected: from being selected:
~~~ ~~~
TrackSelectionOverrides overrides =
new TrackSelectionOverrides.Builder()
.setOverrideForType(new TrackSelectionOverride(audioTrackGroup))
.build();
player.setTrackSelectionParameters( player.setTrackSelectionParameters(
player.getTrackSelectionParameters() player.getTrackSelectionParameters()
.buildUpon().setTrackSelectionOverrides(overrides).build()); .buildUpon()
.setOverrideForType(new TrackSelectionOverride(audioTrackGroup))
.build());
~~~ ~~~
{: .language-java} {: .language-java}
@ -149,20 +147,17 @@ player.setTrackSelectionParameters(
~~~ ~~~
{: .language-java} {: .language-java}
Alternatively, it's possible to prevent the selection of track groups for the Alternatively, it's possible to prevent the selection of tracks from a specific
current playlist item only by specifying empty overrides for these groups: `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.setTrackSelectionParameters(
player.getTrackSelectionParameters() player.getTrackSelectionParameters()
.buildUpon().setTrackSelectionOverrides(overrides).build()); .buildUpon()
.addOverride(
new TrackSelectionOverride(
disabledTrackGroup, ImmutableList.of()))
.build());
~~~ ~~~
{: .language-java} {: .language-java}

View File

@ -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}.
*
* <p>If multiple tracks in {@link #trackGroup} are overridden, as many as possible will be selected
* depending on the player capabilities.
*
* <p>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<Integer> 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<Integer> 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<Integer> 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<TrackSelectionOverride> 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);
}
}

View File

@ -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}.
*
* <p>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.
*
* <p>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}.
*
* <p>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<TrackGroup, TrackSelectionOverride> overrides;
/** Creates an builder with no {@link TrackSelectionOverride}. */
public Builder() {
overrides = new HashMap<>();
}
private Builder(Map<TrackGroup, TrackSelectionOverride> 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<TrackSelectionOverride> 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}.
*
* <p>If multiple tracks in {@link #trackGroup} are overridden, as many as possible will be
* selected depending on the player capabilities.
*
* <p>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<Integer> trackIndices;
/** Constructs an instance to force all tracks in {@code trackGroup} to be selected. */
public TrackSelectionOverride(TrackGroup trackGroup) {
this.trackGroup = trackGroup;
ImmutableList.Builder<Integer> 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<Integer> 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<TrackSelectionOverride> 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<TrackGroup, TrackSelectionOverride> overrides;
private TrackSelectionOverrides(Map<TrackGroup, TrackSelectionOverride> 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<TrackSelectionOverride> 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<TrackSelectionOverrides> CREATOR =
bundle -> {
List<TrackSelectionOverride> trackSelectionOverrides =
fromBundleNullableList(
TrackSelectionOverride.CREATOR,
bundle.getParcelableArrayList(keyForField(FIELD_OVERRIDES)),
ImmutableList.of());
ImmutableMap.Builder<TrackGroup, TrackSelectionOverride> 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);
}
}

View File

@ -16,9 +16,9 @@
package com.google.android.exoplayer2.trackselection; package com.google.android.exoplayer2.trackselection;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull; 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 com.google.common.base.MoreObjects.firstNonNull;
import static java.lang.annotation.ElementType.TYPE_USE;
import android.content.Context; import android.content.Context;
import android.graphics.Point; import android.graphics.Point;
@ -30,14 +30,18 @@ import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import com.google.android.exoplayer2.Bundleable; import com.google.android.exoplayer2.Bundleable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.primitives.Ints; import com.google.common.primitives.Ints;
import java.lang.annotation.Documented; 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.lang.annotation.Target; import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Set; import java.util.Set;
import org.checkerframework.checker.initialization.qual.UnknownInitialization; import org.checkerframework.checker.initialization.qual.UnknownInitialization;
@ -96,7 +100,7 @@ public class TrackSelectionParameters implements Bundleable {
// General // General
private boolean forceLowestBitrate; private boolean forceLowestBitrate;
private boolean forceHighestSupportedBitrate; private boolean forceHighestSupportedBitrate;
private TrackSelectionOverrides trackSelectionOverrides; private HashMap<TrackGroup, TrackSelectionOverride> overrides;
private ImmutableSet<@C.TrackType Integer> disabledTrackTypes; private ImmutableSet<@C.TrackType Integer> disabledTrackTypes;
/** /**
@ -128,7 +132,7 @@ public class TrackSelectionParameters implements Bundleable {
// General // General
forceLowestBitrate = false; forceLowestBitrate = false;
forceHighestSupportedBitrate = false; forceHighestSupportedBitrate = false;
trackSelectionOverrides = TrackSelectionOverrides.EMPTY; overrides = new HashMap<>();
disabledTrackTypes = ImmutableSet.of(); disabledTrackTypes = ImmutableSet.of();
} }
@ -234,11 +238,16 @@ public class TrackSelectionParameters implements Bundleable {
bundle.getBoolean( bundle.getBoolean(
keyForField(FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE), keyForField(FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE),
DEFAULT_WITHOUT_CONTEXT.forceHighestSupportedBitrate); DEFAULT_WITHOUT_CONTEXT.forceHighestSupportedBitrate);
trackSelectionOverrides = overrides = new HashMap<>();
fromNullableBundle( List<TrackSelectionOverride> overrideList =
TrackSelectionOverrides.CREATOR, fromBundleNullableList(
bundle.getBundle(keyForField(FIELD_SELECTION_OVERRIDE_KEYS)), TrackSelectionOverride.CREATOR,
TrackSelectionOverrides.EMPTY); 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 = disabledTrackTypes =
ImmutableSet.copyOf( ImmutableSet.copyOf(
Ints.asList( Ints.asList(
@ -252,7 +261,7 @@ public class TrackSelectionParameters implements Bundleable {
"preferredAudioLanguages", "preferredAudioLanguages",
"preferredAudioMimeTypes", "preferredAudioMimeTypes",
"preferredTextLanguages", "preferredTextLanguages",
"trackSelectionOverrides", "overrides",
"disabledTrackTypes", "disabledTrackTypes",
}) })
private void init(@UnknownInitialization Builder this, TrackSelectionParameters parameters) { private void init(@UnknownInitialization Builder this, TrackSelectionParameters parameters) {
@ -283,8 +292,8 @@ public class TrackSelectionParameters implements Bundleable {
// General // General
forceLowestBitrate = parameters.forceLowestBitrate; forceLowestBitrate = parameters.forceLowestBitrate;
forceHighestSupportedBitrate = parameters.forceHighestSupportedBitrate; forceHighestSupportedBitrate = parameters.forceHighestSupportedBitrate;
trackSelectionOverrides = parameters.trackSelectionOverrides;
disabledTrackTypes = parameters.disabledTrackTypes; disabledTrackTypes = parameters.disabledTrackTypes;
overrides = new HashMap<>(parameters.overrides);
} }
/** Overrides the value of the builder with the value of {@link TrackSelectionParameters}. */ /** Overrides the value of the builder with the value of {@link TrackSelectionParameters}. */
@ -643,14 +652,42 @@ public class TrackSelectionParameters implements Bundleable {
return this; 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. * Remove any override associated with {@link TrackGroup TrackGroups} of type {@code trackType}.
*
* @param trackSelectionOverrides The track selection overrides.
* @return This builder.
*/ */
public Builder setTrackSelectionOverrides(TrackSelectionOverrides trackSelectionOverrides) { public Builder clearOverridesOfType(@C.TrackType int trackType) {
this.trackSelectionOverrides = trackSelectionOverrides; Iterator<TrackSelectionOverride> 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; return this;
} }
@ -855,8 +892,9 @@ public class TrackSelectionParameters implements Bundleable {
*/ */
public final boolean forceHighestSupportedBitrate; public final boolean forceHighestSupportedBitrate;
/** Overrides to force tracks to be selected. */ /** Overrides to force selection of specific tracks. */
public final TrackSelectionOverrides trackSelectionOverrides; public final ImmutableMap<TrackGroup, TrackSelectionOverride> overrides;
/** /**
* The track types that are disabled. No track of a disabled type will be selected, thus no track * 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 * 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 // General
this.forceLowestBitrate = builder.forceLowestBitrate; this.forceLowestBitrate = builder.forceLowestBitrate;
this.forceHighestSupportedBitrate = builder.forceHighestSupportedBitrate; this.forceHighestSupportedBitrate = builder.forceHighestSupportedBitrate;
this.trackSelectionOverrides = builder.trackSelectionOverrides; this.overrides = ImmutableMap.copyOf(builder.overrides);
this.disabledTrackTypes = builder.disabledTrackTypes; this.disabledTrackTypes = builder.disabledTrackTypes;
} }
@ -937,7 +975,7 @@ public class TrackSelectionParameters implements Bundleable {
// General // General
&& forceLowestBitrate == other.forceLowestBitrate && forceLowestBitrate == other.forceLowestBitrate
&& forceHighestSupportedBitrate == other.forceHighestSupportedBitrate && forceHighestSupportedBitrate == other.forceHighestSupportedBitrate
&& trackSelectionOverrides.equals(other.trackSelectionOverrides) && overrides.equals(other.overrides)
&& disabledTrackTypes.equals(other.disabledTrackTypes); && disabledTrackTypes.equals(other.disabledTrackTypes);
} }
@ -971,7 +1009,7 @@ public class TrackSelectionParameters implements Bundleable {
// General // General
result = 31 * result + (forceLowestBitrate ? 1 : 0); result = 31 * result + (forceLowestBitrate ? 1 : 0);
result = 31 * result + (forceHighestSupportedBitrate ? 1 : 0); result = 31 * result + (forceHighestSupportedBitrate ? 1 : 0);
result = 31 * result + trackSelectionOverrides.hashCode(); result = 31 * result + overrides.hashCode();
result = 31 * result + disabledTrackTypes.hashCode(); result = 31 * result + disabledTrackTypes.hashCode();
return result; return result;
} }
@ -980,7 +1018,6 @@ public class TrackSelectionParameters implements Bundleable {
@Documented @Documented
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@Target(TYPE_USE)
@IntDef({ @IntDef({
FIELD_PREFERRED_AUDIO_LANGUAGES, FIELD_PREFERRED_AUDIO_LANGUAGES,
FIELD_PREFERRED_AUDIO_ROLE_FLAGS, FIELD_PREFERRED_AUDIO_ROLE_FLAGS,
@ -1004,8 +1041,7 @@ public class TrackSelectionParameters implements Bundleable {
FIELD_PREFERRED_AUDIO_MIME_TYPES, FIELD_PREFERRED_AUDIO_MIME_TYPES,
FIELD_FORCE_LOWEST_BITRATE, FIELD_FORCE_LOWEST_BITRATE,
FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE, FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE,
FIELD_SELECTION_OVERRIDE_KEYS, FIELD_SELECTION_OVERRIDES,
FIELD_SELECTION_OVERRIDE_VALUES,
FIELD_DISABLED_TRACK_TYPE, FIELD_DISABLED_TRACK_TYPE,
FIELD_PREFERRED_VIDEO_ROLE_FLAGS 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_PREFERRED_AUDIO_MIME_TYPES = 20;
private static final int FIELD_FORCE_LOWEST_BITRATE = 21; private static final int FIELD_FORCE_LOWEST_BITRATE = 21;
private static final int FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE = 22; 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_OVERRIDES = 23;
private static final int FIELD_SELECTION_OVERRIDE_VALUES = 24; private static final int FIELD_DISABLED_TRACK_TYPE = 24;
private static final int FIELD_DISABLED_TRACK_TYPE = 25; private static final int FIELD_PREFERRED_VIDEO_ROLE_FLAGS = 25;
private static final int FIELD_PREFERRED_VIDEO_ROLE_FLAGS = 26;
@Override @Override
public Bundle toBundle() { 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_LOWEST_BITRATE), forceLowestBitrate);
bundle.putBoolean( bundle.putBoolean(
keyForField(FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE), forceHighestSupportedBitrate); keyForField(FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE), forceHighestSupportedBitrate);
bundle.putBundle( bundle.putParcelableArrayList(
keyForField(FIELD_SELECTION_OVERRIDE_KEYS), trackSelectionOverrides.toBundle()); keyForField(FIELD_SELECTION_OVERRIDES), toBundleArrayList(overrides.values()));
bundle.putIntArray(keyForField(FIELD_DISABLED_TRACK_TYPE), Ints.toArray(disabledTrackTypes)); bundle.putIntArray(keyForField(FIELD_DISABLED_TRACK_TYPE), Ints.toArray(disabledTrackTypes));
return bundle; return bundle;

View File

@ -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));
}
}

View File

@ -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);
}
}

View File

@ -22,7 +22,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.source.TrackGroup; 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.android.exoplayer2.util.MimeTypes;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
@ -33,6 +32,9 @@ import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
public final class TrackSelectionParametersTest { public final class TrackSelectionParametersTest {
private static final TrackGroup AAC_TRACK_GROUP =
new TrackGroup(new Format.Builder().setSampleMimeType(MimeTypes.AUDIO_AAC).build());
@Test @Test
public void defaultValue_withoutChange_isAsExpected() { public void defaultValue_withoutChange_isAsExpected() {
TrackSelectionParameters parameters = TrackSelectionParameters.DEFAULT_WITHOUT_CONTEXT; TrackSelectionParameters parameters = TrackSelectionParameters.DEFAULT_WITHOUT_CONTEXT;
@ -63,22 +65,19 @@ public final class TrackSelectionParametersTest {
// General // General
assertThat(parameters.forceLowestBitrate).isFalse(); assertThat(parameters.forceLowestBitrate).isFalse();
assertThat(parameters.forceHighestSupportedBitrate).isFalse(); assertThat(parameters.forceHighestSupportedBitrate).isFalse();
assertThat(parameters.trackSelectionOverrides.asList()).isEmpty(); assertThat(parameters.overrides).isEmpty();
assertThat(parameters.disabledTrackTypes).isEmpty(); assertThat(parameters.disabledTrackTypes).isEmpty();
} }
@Test @Test
public void parametersSet_fromDefault_isAsExpected() { public void parametersSet_fromDefault_isAsExpected() {
TrackSelectionOverrides trackSelectionOverrides = TrackSelectionOverride override1 =
new TrackSelectionOverrides.Builder() new TrackSelectionOverride(new TrackGroup(new Format.Builder().build()));
.addOverride(new TrackSelectionOverride(new TrackGroup(new Format.Builder().build()))) TrackSelectionOverride override2 =
.addOverride(
new TrackSelectionOverride( new TrackSelectionOverride(
new TrackGroup( new TrackGroup(
new Format.Builder().setId(4).build(), new Format.Builder().setId(4).build(), new Format.Builder().setId(5).build()),
new Format.Builder().setId(5).build()), /* trackIndices= */ ImmutableList.of(1));
/* trackIndices= */ ImmutableList.of(1)))
.build();
TrackSelectionParameters parameters = TrackSelectionParameters parameters =
TrackSelectionParameters.DEFAULT_WITHOUT_CONTEXT TrackSelectionParameters.DEFAULT_WITHOUT_CONTEXT
.buildUpon() .buildUpon()
@ -107,7 +106,13 @@ public final class TrackSelectionParametersTest {
// General // General
.setForceLowestBitrate(false) .setForceLowestBitrate(false)
.setForceHighestSupportedBitrate(true) .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)) .setDisabledTrackTypes(ImmutableSet.of(C.TRACK_TYPE_AUDIO, C.TRACK_TYPE_TEXT))
.build(); .build();
@ -141,7 +146,8 @@ public final class TrackSelectionParametersTest {
// General // General
assertThat(parameters.forceLowestBitrate).isFalse(); assertThat(parameters.forceLowestBitrate).isFalse();
assertThat(parameters.forceHighestSupportedBitrate).isTrue(); assertThat(parameters.forceHighestSupportedBitrate).isTrue();
assertThat(parameters.trackSelectionOverrides).isEqualTo(trackSelectionOverrides); assertThat(parameters.overrides)
.containsExactly(override1.trackGroup, override1, override2.trackGroup, override2);
assertThat(parameters.disabledTrackTypes) assertThat(parameters.disabledTrackTypes)
.containsExactly(C.TRACK_TYPE_AUDIO, C.TRACK_TYPE_TEXT); .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.viewportHeight).isEqualTo(Integer.MAX_VALUE);
assertThat(parameters.viewportOrientationMayChange).isTrue(); 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);
}
} }

View File

@ -43,7 +43,6 @@ import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId; import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray; 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.Assertions;
import com.google.android.exoplayer2.util.BundleableUtil; import com.google.android.exoplayer2.util.BundleableUtil;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
@ -593,9 +592,32 @@ public class DefaultTrackSelector extends MappingTrackSelector {
} }
@Override @Override
public ParametersBuilder setTrackSelectionOverrides( public ParametersBuilder addOverride(TrackSelectionOverride override) {
TrackSelectionOverrides trackSelectionOverrides) { super.addOverride(override);
super.setTrackSelectionOverrides(trackSelectionOverrides); 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; return this;
} }
@ -700,7 +722,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* @param groups The {@link TrackGroupArray} for which the override should be applied. * @param groups The {@link TrackGroupArray} for which the override should be applied.
* @param override The override. * @param override The override.
* @return This builder. * @return This builder.
* @deprecated Use {@link TrackSelectionParameters.Builder#setTrackSelectionOverrides}. * @deprecated Use {@link TrackSelectionParameters.Builder#addOverride(TrackSelectionOverride)}.
*/ */
@Deprecated @Deprecated
public final ParametersBuilder setSelectionOverride( public final ParametersBuilder setSelectionOverride(
@ -725,7 +747,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* @param rendererIndex The renderer index. * @param rendererIndex The renderer index.
* @param groups The {@link TrackGroupArray} for which the override should be cleared. * @param groups The {@link TrackGroupArray} for which the override should be cleared.
* @return This builder. * @return This builder.
* @deprecated Use {@link TrackSelectionParameters.Builder#setTrackSelectionOverrides}. * @deprecated Use {@link TrackSelectionParameters.Builder#clearOverride(TrackGroup)}.
*/ */
@Deprecated @Deprecated
public final ParametersBuilder clearSelectionOverride( public final ParametersBuilder clearSelectionOverride(
@ -748,7 +770,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* *
* @param rendererIndex The renderer index. * @param rendererIndex The renderer index.
* @return This builder. * @return This builder.
* @deprecated Use {@link TrackSelectionParameters.Builder#setTrackSelectionOverrides}. * @deprecated Use {@link TrackSelectionParameters.Builder#clearOverridesOfType(int)}.
*/ */
@Deprecated @Deprecated
public final ParametersBuilder clearSelectionOverrides(int rendererIndex) { public final ParametersBuilder clearSelectionOverrides(int rendererIndex) {
@ -766,7 +788,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* Clears all track selection overrides for all renderers. * Clears all track selection overrides for all renderers.
* *
* @return This builder. * @return This builder.
* @deprecated Use {@link TrackSelectionParameters.Builder#setTrackSelectionOverrides}. * @deprecated Use {@link TrackSelectionParameters.Builder#clearOverrides()}.
*/ */
@Deprecated @Deprecated
public final ParametersBuilder clearSelectionOverrides() { public final ParametersBuilder clearSelectionOverrides() {
@ -1017,7 +1039,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* @return Whether there is an override. * @return Whether there is an override.
* @deprecated Only works to retrieve the overrides set with the deprecated {@link * @deprecated Only works to retrieve the overrides set with the deprecated {@link
* ParametersBuilder#setSelectionOverride(int, TrackGroupArray, SelectionOverride)}. Use * ParametersBuilder#setSelectionOverride(int, TrackGroupArray, SelectionOverride)}. Use
* {@link TrackSelectionParameters#trackSelectionOverrides} instead. * {@link TrackSelectionParameters#overrides} instead.
*/ */
@Deprecated @Deprecated
public final boolean hasSelectionOverride(int rendererIndex, TrackGroupArray groups) { 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. * @return The override, or null if no override exists.
* @deprecated Only works to retrieve the overrides set with the deprecated {@link * @deprecated Only works to retrieve the overrides set with the deprecated {@link
* ParametersBuilder#setSelectionOverride(int, TrackGroupArray, SelectionOverride)}. Use * ParametersBuilder#setSelectionOverride(int, TrackGroupArray, SelectionOverride)}. Use
* {@link TrackSelectionParameters#trackSelectionOverrides} instead. * {@link TrackSelectionParameters#overrides} instead.
*/ */
@Deprecated @Deprecated
@Nullable @Nullable
@ -1653,9 +1675,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
TrackGroupArray rendererTrackGroups = mappedTrackInfo.getTrackGroups(rendererIndex); TrackGroupArray rendererTrackGroups = mappedTrackInfo.getTrackGroups(rendererIndex);
for (int j = 0; j < rendererTrackGroups.length; j++) { for (int j = 0; j < rendererTrackGroups.length; j++) {
maybeUpdateApplicableOverrides( maybeUpdateApplicableOverrides(
applicableOverrides, applicableOverrides, params.overrides.get(rendererTrackGroups.get(j)), rendererIndex);
params.trackSelectionOverrides.getOverride(rendererTrackGroups.get(j)),
rendererIndex);
} }
} }
// Also iterate unmapped groups to see if they have overrides. // 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++) { for (int i = 0; i < unmappedGroups.length; i++) {
maybeUpdateApplicableOverrides( maybeUpdateApplicableOverrides(
applicableOverrides, applicableOverrides,
params.trackSelectionOverrides.getOverride(unmappedGroups.get(i)), params.overrides.get(unmappedGroups.get(i)),
/* rendererIndex= */ C.INDEX_UNSET); /* rendererIndex= */ C.INDEX_UNSET);
} }
return applicableOverrides; return applicableOverrides;

View File

@ -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.Parameters;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.ParametersBuilder; import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.ParametersBuilder;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.SelectionOverride; 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.trackselection.TrackSelector.InvalidationListener;
import com.google.android.exoplayer2.upstream.BandwidthMeter; import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
@ -169,10 +168,8 @@ public final class DefaultTrackSelectorTest {
trackSelector.setParameters( trackSelector.setParameters(
trackSelector trackSelector
.buildUponParameters() .buildUponParameters()
.setTrackSelectionOverrides(
new TrackSelectionOverrides.Builder()
.addOverride(new TrackSelectionOverride(VIDEO_TRACK_GROUP, ImmutableList.of())) .addOverride(new TrackSelectionOverride(VIDEO_TRACK_GROUP, ImmutableList.of()))
.build())); .build());
TrackSelectorResult result = TrackSelectorResult result =
trackSelector.selectTracks(RENDERER_CAPABILITIES, TRACK_GROUPS, periodId, TIMELINE); trackSelector.selectTracks(RENDERER_CAPABILITIES, TRACK_GROUPS, periodId, TIMELINE);
@ -223,8 +220,6 @@ public final class DefaultTrackSelectorTest {
trackSelector.setParameters( trackSelector.setParameters(
trackSelector trackSelector
.buildUponParameters() .buildUponParameters()
.setTrackSelectionOverrides(
new TrackSelectionOverrides.Builder()
.addOverride( .addOverride(
new TrackSelectionOverride( new TrackSelectionOverride(
videoGroupHighBitrate, /* trackIndices= */ ImmutableList.of())) videoGroupHighBitrate, /* trackIndices= */ ImmutableList.of()))
@ -234,7 +229,7 @@ public final class DefaultTrackSelectorTest {
.addOverride( .addOverride(
new TrackSelectionOverride( new TrackSelectionOverride(
videoGroupLowBitrate, /* trackIndices= */ ImmutableList.of())) videoGroupLowBitrate, /* trackIndices= */ ImmutableList.of()))
.build())); .build());
TrackSelectorResult result = TrackSelectorResult result =
trackSelector.selectTracks( trackSelector.selectTracks(
@ -258,12 +253,10 @@ public final class DefaultTrackSelectorTest {
trackSelector.setParameters( trackSelector.setParameters(
trackSelector trackSelector
.buildUponParameters() .buildUponParameters()
.setTrackSelectionOverrides(
new TrackSelectionOverrides.Builder()
.setOverrideForType( .setOverrideForType(
new TrackSelectionOverride( new TrackSelectionOverride(
new TrackGroup(VIDEO_FORMAT, VIDEO_FORMAT), ImmutableList.of())) new TrackGroup(VIDEO_FORMAT, VIDEO_FORMAT), ImmutableList.of()))
.build())); .build());
TrackSelectorResult result = TrackSelectorResult result =
trackSelector.selectTracks( trackSelector.selectTracks(
@ -307,10 +300,8 @@ public final class DefaultTrackSelectorTest {
trackSelector.setParameters( trackSelector.setParameters(
trackSelector trackSelector
.buildUponParameters() .buildUponParameters()
.setTrackSelectionOverrides(
new TrackSelectionOverrides.Builder()
.setOverrideForType(new TrackSelectionOverride(videoGroupH264)) .setOverrideForType(new TrackSelectionOverride(videoGroupH264))
.build())); .build());
TrackSelectorResult result = TrackSelectorResult result =
trackSelector.selectTracks( trackSelector.selectTracks(
new RendererCapabilities[] {rendererCapabilitiesH264, rendererCapabilitiesAv1}, new RendererCapabilities[] {rendererCapabilitiesH264, rendererCapabilitiesAv1},
@ -326,10 +317,8 @@ public final class DefaultTrackSelectorTest {
trackSelector.setParameters( trackSelector.setParameters(
trackSelector trackSelector
.buildUponParameters() .buildUponParameters()
.setTrackSelectionOverrides(
new TrackSelectionOverrides.Builder()
.setOverrideForType(new TrackSelectionOverride(videoGroupAv1)) .setOverrideForType(new TrackSelectionOverride(videoGroupAv1))
.build())); .build());
result = result =
trackSelector.selectTracks( trackSelector.selectTracks(
new RendererCapabilities[] {rendererCapabilitiesH264, rendererCapabilitiesAv1}, new RendererCapabilities[] {rendererCapabilitiesH264, rendererCapabilitiesAv1},
@ -359,10 +348,8 @@ public final class DefaultTrackSelectorTest {
trackSelector.setParameters( trackSelector.setParameters(
trackSelector trackSelector
.buildUponParameters() .buildUponParameters()
.setTrackSelectionOverrides(
new TrackSelectionOverrides.Builder()
.setOverrideForType(new TrackSelectionOverride(audioGroupUnsupported)) .setOverrideForType(new TrackSelectionOverride(audioGroupUnsupported))
.build())); .build());
TrackSelectorResult result = TrackSelectorResult result =
trackSelector.selectTracks( trackSelector.selectTracks(
new RendererCapabilities[] {VIDEO_CAPABILITIES, audioRendererCapabilties}, new RendererCapabilities[] {VIDEO_CAPABILITIES, audioRendererCapabilties},
@ -2395,13 +2382,10 @@ public final class DefaultTrackSelectorTest {
.setRendererDisabled(1, true) .setRendererDisabled(1, true)
.setRendererDisabled(3, true) .setRendererDisabled(3, true)
.setRendererDisabled(5, false) .setRendererDisabled(5, false)
.setTrackSelectionOverrides(
new TrackSelectionOverrides.Builder()
.setOverrideForType( .setOverrideForType(
new TrackSelectionOverride( new TrackSelectionOverride(
new TrackGroup(AUDIO_FORMAT, AUDIO_FORMAT, AUDIO_FORMAT, AUDIO_FORMAT), new TrackGroup(AUDIO_FORMAT, AUDIO_FORMAT, AUDIO_FORMAT, AUDIO_FORMAT),
/* trackIndices= */ ImmutableList.of(0, 2, 3))) /* trackIndices= */ ImmutableList.of(0, 2, 3)))
.build())
.setDisabledTrackTypes(ImmutableSet.of(C.TRACK_TYPE_AUDIO)) .setDisabledTrackTypes(ImmutableSet.of(C.TRACK_TYPE_AUDIO))
.build(); .build();
} }

View File

@ -67,8 +67,7 @@ import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.TracksInfo; import com.google.android.exoplayer2.TracksInfo;
import com.google.android.exoplayer2.TracksInfo.TrackGroupInfo; import com.google.android.exoplayer2.TracksInfo.TrackGroupInfo;
import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.trackselection.TrackSelectionOverrides; import com.google.android.exoplayer2.trackselection.TrackSelectionOverride;
import com.google.android.exoplayer2.trackselection.TrackSelectionOverrides.TrackSelectionOverride;
import com.google.android.exoplayer2.trackselection.TrackSelectionParameters; 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.RepeatModeUtil; 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); holder.textView.setText(R.string.exo_track_selection_auto);
// hasSelectionOverride is true means there is an explicit track selection, not "Auto". // hasSelectionOverride is true means there is an explicit track selection, not "Auto".
TrackSelectionParameters parameters = checkNotNull(player).getTrackSelectionParameters(); TrackSelectionParameters parameters = checkNotNull(player).getTrackSelectionParameters();
boolean hasSelectionOverride = hasSelectionOverride(parameters.trackSelectionOverrides); boolean hasSelectionOverride = hasSelectionOverride(parameters);
holder.checkView.setVisibility(hasSelectionOverride ? INVISIBLE : VISIBLE); holder.checkView.setVisibility(hasSelectionOverride ? INVISIBLE : VISIBLE);
holder.itemView.setOnClickListener( holder.itemView.setOnClickListener(
v -> { v -> {
@ -1917,12 +1916,6 @@ public class StyledPlayerControlView extends FrameLayout {
} }
TrackSelectionParameters trackSelectionParameters = TrackSelectionParameters trackSelectionParameters =
player.getTrackSelectionParameters(); player.getTrackSelectionParameters();
TrackSelectionOverrides trackSelectionOverrides =
trackSelectionParameters
.trackSelectionOverrides
.buildUpon()
.clearOverridesOfType(C.TRACK_TYPE_AUDIO)
.build();
Set<@C.TrackType Integer> disabledTrackTypes = Set<@C.TrackType Integer> disabledTrackTypes =
new HashSet<>(trackSelectionParameters.disabledTrackTypes); new HashSet<>(trackSelectionParameters.disabledTrackTypes);
disabledTrackTypes.remove(C.TRACK_TYPE_AUDIO); disabledTrackTypes.remove(C.TRACK_TYPE_AUDIO);
@ -1930,7 +1923,7 @@ public class StyledPlayerControlView extends FrameLayout {
.setTrackSelectionParameters( .setTrackSelectionParameters(
trackSelectionParameters trackSelectionParameters
.buildUpon() .buildUpon()
.setTrackSelectionOverrides(trackSelectionOverrides) .clearOverridesOfType(C.TRACK_TYPE_AUDIO)
.setDisabledTrackTypes(disabledTrackTypes) .setDisabledTrackTypes(disabledTrackTypes)
.build()); .build());
settingsAdapter.setSubTextAtPosition( 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++) { for (int i = 0; i < tracks.size(); i++) {
TrackGroup trackGroup = tracks.get(i).trackGroupInfo.getTrackGroup(); TrackGroup trackGroup = tracks.get(i).trackGroupInfo.getTrackGroup();
if (trackSelectionOverrides.getOverride(trackGroup) != null) { if (trackSelectionParameters.overrides.containsKey(trackGroup)) {
return true; return true;
} }
} }
@ -1966,7 +1959,7 @@ public class StyledPlayerControlView extends FrameLayout {
getResources().getString(R.string.exo_track_selection_none)); getResources().getString(R.string.exo_track_selection_none));
// TODO(insun) : Make the audio item in main settings (settingsAdapater) // TODO(insun) : Make the audio item in main settings (settingsAdapater)
// to be non-clickable. // to be non-clickable.
} else if (!hasSelectionOverride(params.trackSelectionOverrides)) { } else if (!hasSelectionOverride(params)) {
settingsAdapter.setSubTextAtPosition( settingsAdapter.setSubTextAtPosition(
SETTINGS_AUDIO_TRACK_SELECTION_POSITION, SETTINGS_AUDIO_TRACK_SELECTION_POSITION,
getResources().getString(R.string.exo_track_selection_auto)); getResources().getString(R.string.exo_track_selection_auto));
@ -2017,8 +2010,7 @@ public class StyledPlayerControlView extends FrameLayout {
TrackInformation track = tracks.get(position - 1); TrackInformation track = tracks.get(position - 1);
TrackGroup trackGroup = track.trackGroupInfo.getTrackGroup(); TrackGroup trackGroup = track.trackGroupInfo.getTrackGroup();
TrackSelectionParameters params = checkNotNull(player).getTrackSelectionParameters(); TrackSelectionParameters params = checkNotNull(player).getTrackSelectionParameters();
boolean explicitlySelected = boolean explicitlySelected = params.overrides.get(trackGroup) != null && track.isSelected();
params.trackSelectionOverrides.getOverride(trackGroup) != null && track.isSelected();
holder.textView.setText(track.trackName); holder.textView.setText(track.trackName);
holder.checkView.setVisibility(explicitlySelected ? VISIBLE : INVISIBLE); holder.checkView.setVisibility(explicitlySelected ? VISIBLE : INVISIBLE);
holder.itemView.setOnClickListener( holder.itemView.setOnClickListener(
@ -2028,14 +2020,6 @@ public class StyledPlayerControlView extends FrameLayout {
} }
TrackSelectionParameters trackSelectionParameters = TrackSelectionParameters trackSelectionParameters =
player.getTrackSelectionParameters(); player.getTrackSelectionParameters();
TrackSelectionOverrides overrides =
trackSelectionParameters
.trackSelectionOverrides
.buildUpon()
.setOverrideForType(
new TrackSelectionOverride(
trackGroup, ImmutableList.of(track.trackIndex)))
.build();
Set<@C.TrackType Integer> disabledTrackTypes = Set<@C.TrackType Integer> disabledTrackTypes =
new HashSet<>(trackSelectionParameters.disabledTrackTypes); new HashSet<>(trackSelectionParameters.disabledTrackTypes);
disabledTrackTypes.remove(track.trackGroupInfo.getTrackType()); disabledTrackTypes.remove(track.trackGroupInfo.getTrackType());
@ -2043,7 +2027,9 @@ public class StyledPlayerControlView extends FrameLayout {
.setTrackSelectionParameters( .setTrackSelectionParameters(
trackSelectionParameters trackSelectionParameters
.buildUpon() .buildUpon()
.setTrackSelectionOverrides(overrides) .setOverrideForType(
new TrackSelectionOverride(
trackGroup, ImmutableList.of(track.trackIndex)))
.setDisabledTrackTypes(disabledTrackTypes) .setDisabledTrackTypes(disabledTrackTypes)
.build()); .build());
onTrackSelection(track.trackName); onTrackSelection(track.trackName);