Add track type disabling to Track selection parameters

This will allow to disable video/audio... through the player
interface.

PiperOrigin-RevId: 397183548
This commit is contained in:
krocard 2021-09-16 23:31:59 +01:00 committed by Oliver Woodman
parent 4ff4263af3
commit a75f902c81
3 changed files with 111 additions and 8 deletions

View File

@ -31,10 +31,13 @@ import com.google.android.exoplayer2.Bundleable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.util.Util;
import com.google.common.collect.ImmutableList;
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.util.Locale;
import java.util.Set;
import org.checkerframework.checker.initialization.qual.UnknownInitialization;
import org.checkerframework.checker.nullness.qual.EnsuresNonNull;
@ -90,6 +93,7 @@ public class TrackSelectionParameters implements Bundleable {
// General
private boolean forceLowestBitrate;
private boolean forceHighestSupportedBitrate;
private ImmutableSet<@C.TrackType Integer> disabledTrackTypes;
/**
* @deprecated {@link Context} constraints will not be set using this constructor. Use {@link
@ -119,6 +123,7 @@ public class TrackSelectionParameters implements Bundleable {
// General
forceLowestBitrate = false;
forceHighestSupportedBitrate = false;
disabledTrackTypes = ImmutableSet.of();
}
/**
@ -219,6 +224,12 @@ public class TrackSelectionParameters implements Bundleable {
bundle.getBoolean(
keyForField(FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE),
DEFAULT_WITHOUT_CONTEXT.forceHighestSupportedBitrate);
disabledTrackTypes =
ImmutableSet.copyOf(
Ints.asList(
firstNonNull(
bundle.getIntArray(keyForField(FIELD_DISABLED_TRACK_TYPE)), new int[0])));
}
/** Overrides the value of the builder with the value of {@link TrackSelectionParameters}. */
@ -226,7 +237,8 @@ public class TrackSelectionParameters implements Bundleable {
"preferredVideoMimeTypes",
"preferredAudioLanguages",
"preferredAudioMimeTypes",
"preferredTextLanguages"
"preferredTextLanguages",
"disabledTrackTypes",
})
private void init(@UnknownInitialization Builder this, TrackSelectionParameters parameters) {
// Video
@ -255,6 +267,7 @@ public class TrackSelectionParameters implements Bundleable {
// General
forceLowestBitrate = parameters.forceLowestBitrate;
forceHighestSupportedBitrate = parameters.forceHighestSupportedBitrate;
disabledTrackTypes = parameters.disabledTrackTypes;
}
/** Overrides the value of the builder with the value of {@link TrackSelectionParameters}. */
@ -602,6 +615,18 @@ public class TrackSelectionParameters implements Bundleable {
return this;
}
/**
* Sets the disabled track types, preventing all tracks of those types from being selected for
* playback.
*
* @param disabledTrackTypes The track types to disable.
* @return This builder.
*/
public Builder setDisabledTrackTypes(Set<@C.TrackType Integer> disabledTrackTypes) {
this.disabledTrackTypes = ImmutableSet.copyOf(disabledTrackTypes);
return this;
}
/** Builds a {@link TrackSelectionParameters} instance with the selected values. */
public TrackSelectionParameters build() {
return new TrackSelectionParameters(this);
@ -785,6 +810,12 @@ public class TrackSelectionParameters implements Bundleable {
* other constraints. The default value is {@code false}.
*/
public final boolean forceHighestSupportedBitrate;
/**
* 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
* (empty set).
*/
public final ImmutableSet<@C.TrackType Integer> disabledTrackTypes;
protected TrackSelectionParameters(Builder builder) {
// Video
@ -813,6 +844,7 @@ public class TrackSelectionParameters implements Bundleable {
// General
this.forceLowestBitrate = builder.forceLowestBitrate;
this.forceHighestSupportedBitrate = builder.forceHighestSupportedBitrate;
this.disabledTrackTypes = builder.disabledTrackTypes;
}
/** Creates a new {@link Builder}, copying the initial values from this instance. */
@ -854,7 +886,8 @@ public class TrackSelectionParameters implements Bundleable {
&& selectUndeterminedTextLanguage == other.selectUndeterminedTextLanguage
// General
&& forceLowestBitrate == other.forceLowestBitrate
&& forceHighestSupportedBitrate == other.forceHighestSupportedBitrate;
&& forceHighestSupportedBitrate == other.forceHighestSupportedBitrate
&& disabledTrackTypes.equals(other.disabledTrackTypes);
}
@Override
@ -886,6 +919,7 @@ public class TrackSelectionParameters implements Bundleable {
// General
result = 31 * result + (forceLowestBitrate ? 1 : 0);
result = 31 * result + (forceHighestSupportedBitrate ? 1 : 0);
result = 31 * result + disabledTrackTypes.hashCode();
return result;
}
@ -916,6 +950,7 @@ public class TrackSelectionParameters implements Bundleable {
FIELD_PREFERRED_AUDIO_MIME_TYPES,
FIELD_FORCE_LOWEST_BITRATE,
FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE,
FIELD_DISABLED_TRACK_TYPE,
})
private @interface FieldNumber {}
@ -941,6 +976,7 @@ 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_DISABLED_TRACK_TYPE = 23;
@Override
@CallSuper
@ -983,6 +1019,7 @@ public class TrackSelectionParameters implements Bundleable {
bundle.putBoolean(keyForField(FIELD_FORCE_LOWEST_BITRATE), forceLowestBitrate);
bundle.putBoolean(
keyForField(FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE), forceHighestSupportedBitrate);
bundle.putIntArray(keyForField(FIELD_DISABLED_TRACK_TYPE), Ints.toArray(disabledTrackTypes));
return bundle;
}

View File

@ -55,6 +55,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import org.checkerframework.checker.nullness.compatqual.NullableType;
@ -607,6 +608,12 @@ public class DefaultTrackSelector extends MappingTrackSelector {
return this;
}
@Override
public ParametersBuilder setDisabledTrackTypes(Set<@C.TrackType Integer> trackTypes) {
super.setDisabledTrackTypes(trackTypes);
return this;
}
/**
* Sets whether to exceed renderer capabilities when no selection can be made otherwise.
*
@ -1484,7 +1491,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
// Apply track disabling and overriding.
for (int i = 0; i < rendererCount; i++) {
if (params.getRendererDisabled(i)) {
@C.TrackType int rendererType = mappedTrackInfo.getRendererType(i);
if (params.getRendererDisabled(i) || params.disabledTrackTypes.contains(rendererType)) {
definitions[i] = null;
continue;
}
@ -1509,7 +1517,9 @@ public class DefaultTrackSelector extends MappingTrackSelector {
@NullableType
RendererConfiguration[] rendererConfigurations = new RendererConfiguration[rendererCount];
for (int i = 0; i < rendererCount; i++) {
boolean forceRendererDisabled = params.getRendererDisabled(i);
@C.TrackType int rendererType = mappedTrackInfo.getRendererType(i);
boolean forceRendererDisabled =
params.getRendererDisabled(i) || params.disabledTrackTypes.contains(rendererType);
boolean rendererEnabled =
!forceRendererDisabled
&& (mappedTrackInfo.getRendererType(i) == C.TRACK_TYPE_NONE

View File

@ -49,6 +49,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelector.InvalidationLi
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.Util;
import com.google.common.collect.ImmutableSet;
import java.util.HashMap;
import java.util.Map;
import org.junit.Before;
@ -101,12 +102,14 @@ public final class DefaultTrackSelectorTest {
private static final TrackGroup AUDIO_TRACK_GROUP = new TrackGroup(AUDIO_FORMAT);
private static final TrackGroupArray TRACK_GROUPS =
new TrackGroupArray(VIDEO_TRACK_GROUP, AUDIO_TRACK_GROUP);
private static final TrackSelection VIDEO_TRACK_SELECTION =
new FixedTrackSelection(VIDEO_TRACK_GROUP, 0);
private static final TrackSelection AUDIO_TRACK_SELECTION =
new FixedTrackSelection(AUDIO_TRACK_GROUP, 0);
private static final TrackSelection[] TRACK_SELECTIONS =
new TrackSelection[] {
new FixedTrackSelection(VIDEO_TRACK_GROUP, 0), new FixedTrackSelection(AUDIO_TRACK_GROUP, 0)
};
new TrackSelection[] {VIDEO_TRACK_SELECTION, AUDIO_TRACK_SELECTION};
private static final TrackSelection[] TRACK_SELECTIONS_WITH_NO_SAMPLE_RENDERER =
new TrackSelection[] {new FixedTrackSelection(VIDEO_TRACK_GROUP, 0), null};
new TrackSelection[] {VIDEO_TRACK_SELECTION, null};
private static final Timeline TIMELINE = new FakeTimeline();
@ -208,6 +211,58 @@ public final class DefaultTrackSelectorTest {
.isEqualTo(new RendererConfiguration[] {DEFAULT, DEFAULT});
}
/** Tests disabling a track type. */
@Test
public void selectVideoAudioTracks_withDisabledAudioType_onlyVideoIsSelected()
throws ExoPlaybackException {
trackSelector.setParameters(
defaultParameters.buildUpon().setDisabledTrackTypes(ImmutableSet.of(C.TRACK_TYPE_AUDIO)));
TrackSelectorResult result =
trackSelector.selectTracks(
RENDERER_CAPABILITIES,
new TrackGroupArray(VIDEO_TRACK_GROUP, AUDIO_TRACK_GROUP),
periodId,
TIMELINE);
assertThat(result.selections).asList().containsExactly(VIDEO_TRACK_SELECTION, null).inOrder();
assertThat(result.rendererConfigurations).asList().containsExactly(DEFAULT, null);
}
/** Tests that a disabled track type can be enabled again. */
@Test
public void selectTracks_withClearedDisabledTrackType_selectsAll() throws ExoPlaybackException {
trackSelector.setParameters(
trackSelector
.buildUponParameters()
.setDisabledTrackTypes(ImmutableSet.of(C.TRACK_TYPE_AUDIO))
.setDisabledTrackTypes(ImmutableSet.of()));
TrackSelectorResult result =
trackSelector.selectTracks(RENDERER_CAPABILITIES, TRACK_GROUPS, periodId, TIMELINE);
assertThat(result.selections).asList().containsExactlyElementsIn(TRACK_SELECTIONS).inOrder();
assertThat(result.rendererConfigurations).asList().containsExactly(DEFAULT, DEFAULT).inOrder();
}
/** Tests disabling NONE track type rendering. */
@Test
public void selectTracks_withDisabledNoneTracksAndNoSampleRenderer_disablesNoSampleRenderer()
throws ExoPlaybackException {
trackSelector.setParameters(
defaultParameters.buildUpon().setDisabledTrackTypes(ImmutableSet.of(C.TRACK_TYPE_NONE)));
TrackSelectorResult result =
trackSelector.selectTracks(
new RendererCapabilities[] {VIDEO_CAPABILITIES, NO_SAMPLE_CAPABILITIES},
TRACK_GROUPS,
periodId,
TIMELINE);
assertThat(result.selections).asList().containsExactly(VIDEO_TRACK_SELECTION, null).inOrder();
assertThat(result.rendererConfigurations).asList().containsExactly(DEFAULT, null).inOrder();
}
/** Tests disabling a renderer. */
@Test
public void selectTracksWithDisabledRenderer() throws ExoPlaybackException {
@ -1760,6 +1815,7 @@ public final class DefaultTrackSelectorTest {
.setRendererDisabled(1, true)
.setRendererDisabled(3, true)
.setRendererDisabled(5, false)
.setDisabledTrackTypes(ImmutableSet.of(C.TRACK_TYPE_AUDIO))
.build();
}