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:
parent
4ff4263af3
commit
a75f902c81
@ -31,10 +31,13 @@ import com.google.android.exoplayer2.Bundleable;
|
|||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
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.ImmutableSet;
|
||||||
|
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.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Set;
|
||||||
import org.checkerframework.checker.initialization.qual.UnknownInitialization;
|
import org.checkerframework.checker.initialization.qual.UnknownInitialization;
|
||||||
import org.checkerframework.checker.nullness.qual.EnsuresNonNull;
|
import org.checkerframework.checker.nullness.qual.EnsuresNonNull;
|
||||||
|
|
||||||
@ -90,6 +93,7 @@ public class TrackSelectionParameters implements Bundleable {
|
|||||||
// General
|
// General
|
||||||
private boolean forceLowestBitrate;
|
private boolean forceLowestBitrate;
|
||||||
private boolean forceHighestSupportedBitrate;
|
private boolean forceHighestSupportedBitrate;
|
||||||
|
private ImmutableSet<@C.TrackType Integer> disabledTrackTypes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated {@link Context} constraints will not be set using this constructor. Use {@link
|
* @deprecated {@link Context} constraints will not be set using this constructor. Use {@link
|
||||||
@ -119,6 +123,7 @@ public class TrackSelectionParameters implements Bundleable {
|
|||||||
// General
|
// General
|
||||||
forceLowestBitrate = false;
|
forceLowestBitrate = false;
|
||||||
forceHighestSupportedBitrate = false;
|
forceHighestSupportedBitrate = false;
|
||||||
|
disabledTrackTypes = ImmutableSet.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -219,6 +224,12 @@ 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);
|
||||||
|
|
||||||
|
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}. */
|
/** Overrides the value of the builder with the value of {@link TrackSelectionParameters}. */
|
||||||
@ -226,7 +237,8 @@ public class TrackSelectionParameters implements Bundleable {
|
|||||||
"preferredVideoMimeTypes",
|
"preferredVideoMimeTypes",
|
||||||
"preferredAudioLanguages",
|
"preferredAudioLanguages",
|
||||||
"preferredAudioMimeTypes",
|
"preferredAudioMimeTypes",
|
||||||
"preferredTextLanguages"
|
"preferredTextLanguages",
|
||||||
|
"disabledTrackTypes",
|
||||||
})
|
})
|
||||||
private void init(@UnknownInitialization Builder this, TrackSelectionParameters parameters) {
|
private void init(@UnknownInitialization Builder this, TrackSelectionParameters parameters) {
|
||||||
// Video
|
// Video
|
||||||
@ -255,6 +267,7 @@ public class TrackSelectionParameters implements Bundleable {
|
|||||||
// General
|
// General
|
||||||
forceLowestBitrate = parameters.forceLowestBitrate;
|
forceLowestBitrate = parameters.forceLowestBitrate;
|
||||||
forceHighestSupportedBitrate = parameters.forceHighestSupportedBitrate;
|
forceHighestSupportedBitrate = parameters.forceHighestSupportedBitrate;
|
||||||
|
disabledTrackTypes = parameters.disabledTrackTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Overrides the value of the builder with the value of {@link TrackSelectionParameters}. */
|
/** Overrides the value of the builder with the value of {@link TrackSelectionParameters}. */
|
||||||
@ -602,6 +615,18 @@ public class TrackSelectionParameters implements Bundleable {
|
|||||||
return this;
|
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. */
|
/** Builds a {@link TrackSelectionParameters} instance with the selected values. */
|
||||||
public TrackSelectionParameters build() {
|
public TrackSelectionParameters build() {
|
||||||
return new TrackSelectionParameters(this);
|
return new TrackSelectionParameters(this);
|
||||||
@ -785,6 +810,12 @@ public class TrackSelectionParameters implements Bundleable {
|
|||||||
* other constraints. The default value is {@code false}.
|
* other constraints. The default value is {@code false}.
|
||||||
*/
|
*/
|
||||||
public final boolean forceHighestSupportedBitrate;
|
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) {
|
protected TrackSelectionParameters(Builder builder) {
|
||||||
// Video
|
// Video
|
||||||
@ -813,6 +844,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.disabledTrackTypes = builder.disabledTrackTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Creates a new {@link Builder}, copying the initial values from this instance. */
|
/** Creates a new {@link Builder}, copying the initial values from this instance. */
|
||||||
@ -854,7 +886,8 @@ public class TrackSelectionParameters implements Bundleable {
|
|||||||
&& selectUndeterminedTextLanguage == other.selectUndeterminedTextLanguage
|
&& selectUndeterminedTextLanguage == other.selectUndeterminedTextLanguage
|
||||||
// General
|
// General
|
||||||
&& forceLowestBitrate == other.forceLowestBitrate
|
&& forceLowestBitrate == other.forceLowestBitrate
|
||||||
&& forceHighestSupportedBitrate == other.forceHighestSupportedBitrate;
|
&& forceHighestSupportedBitrate == other.forceHighestSupportedBitrate
|
||||||
|
&& disabledTrackTypes.equals(other.disabledTrackTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -886,6 +919,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 + disabledTrackTypes.hashCode();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -916,6 +950,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_DISABLED_TRACK_TYPE,
|
||||||
})
|
})
|
||||||
private @interface FieldNumber {}
|
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_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_DISABLED_TRACK_TYPE = 23;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@CallSuper
|
@CallSuper
|
||||||
@ -983,6 +1019,7 @@ 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.putIntArray(keyForField(FIELD_DISABLED_TRACK_TYPE), Ints.toArray(disabledTrackTypes));
|
||||||
|
|
||||||
return bundle;
|
return bundle;
|
||||||
}
|
}
|
||||||
|
@ -55,6 +55,7 @@ import java.util.HashMap;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||||
|
|
||||||
@ -607,6 +608,12 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
return this;
|
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.
|
* 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.
|
// Apply track disabling and overriding.
|
||||||
for (int i = 0; i < rendererCount; i++) {
|
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;
|
definitions[i] = null;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1509,7 +1517,9 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
@NullableType
|
@NullableType
|
||||||
RendererConfiguration[] rendererConfigurations = new RendererConfiguration[rendererCount];
|
RendererConfiguration[] rendererConfigurations = new RendererConfiguration[rendererCount];
|
||||||
for (int i = 0; i < rendererCount; i++) {
|
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 =
|
boolean rendererEnabled =
|
||||||
!forceRendererDisabled
|
!forceRendererDisabled
|
||||||
&& (mappedTrackInfo.getRendererType(i) == C.TRACK_TYPE_NONE
|
&& (mappedTrackInfo.getRendererType(i) == C.TRACK_TYPE_NONE
|
||||||
|
@ -49,6 +49,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelector.InvalidationLi
|
|||||||
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;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.junit.Before;
|
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 TrackGroup AUDIO_TRACK_GROUP = new TrackGroup(AUDIO_FORMAT);
|
||||||
private static final TrackGroupArray TRACK_GROUPS =
|
private static final TrackGroupArray TRACK_GROUPS =
|
||||||
new TrackGroupArray(VIDEO_TRACK_GROUP, AUDIO_TRACK_GROUP);
|
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 =
|
private static final TrackSelection[] TRACK_SELECTIONS =
|
||||||
new TrackSelection[] {
|
new TrackSelection[] {VIDEO_TRACK_SELECTION, AUDIO_TRACK_SELECTION};
|
||||||
new FixedTrackSelection(VIDEO_TRACK_GROUP, 0), new FixedTrackSelection(AUDIO_TRACK_GROUP, 0)
|
|
||||||
};
|
|
||||||
private static final TrackSelection[] TRACK_SELECTIONS_WITH_NO_SAMPLE_RENDERER =
|
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();
|
private static final Timeline TIMELINE = new FakeTimeline();
|
||||||
|
|
||||||
@ -208,6 +211,58 @@ public final class DefaultTrackSelectorTest {
|
|||||||
.isEqualTo(new RendererConfiguration[] {DEFAULT, DEFAULT});
|
.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. */
|
/** Tests disabling a renderer. */
|
||||||
@Test
|
@Test
|
||||||
public void selectTracksWithDisabledRenderer() throws ExoPlaybackException {
|
public void selectTracksWithDisabledRenderer() throws ExoPlaybackException {
|
||||||
@ -1760,6 +1815,7 @@ public final class DefaultTrackSelectorTest {
|
|||||||
.setRendererDisabled(1, true)
|
.setRendererDisabled(1, true)
|
||||||
.setRendererDisabled(3, true)
|
.setRendererDisabled(3, true)
|
||||||
.setRendererDisabled(5, false)
|
.setRendererDisabled(5, false)
|
||||||
|
.setDisabledTrackTypes(ImmutableSet.of(C.TRACK_TYPE_AUDIO))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user