From b4e05e00f213efb05eb76f702fbe0fd76ad09b85 Mon Sep 17 00:00:00 2001 From: olly Date: Mon, 28 Feb 2022 13:05:17 +0000 Subject: [PATCH] TrackSelectionParameters: Simplify disabling of track types As evidenced by the somewhat awkward logic in PlayerControlView, the previous design wasn't very friendly to expected usage. There will be more usage when the track selection dialog components are migrated, which would be similarly awkward without this change. PiperOrigin-RevId: 431407675 --- docs/track-selection.md | 10 ++-- .../TrackSelectionParameters.java | 46 ++++++++++++++----- .../TrackSelectionParametersTest.java | 4 +- .../trackselection/DefaultTrackSelector.java | 8 ++++ .../DefaultTrackSelectorTest.java | 11 +++-- .../ui/StyledPlayerControlView.java | 41 ++++++----------- 6 files changed, 70 insertions(+), 50 deletions(-) diff --git a/docs/track-selection.md b/docs/track-selection.md index bb9bc8d4fe..4df5821473 100644 --- a/docs/track-selection.md +++ b/docs/track-selection.md @@ -134,21 +134,21 @@ player.setTrackSelectionParameters( ### Disabling track types or groups -Track types, like video, audio or text, can be disabled completely by using -`TrackSelectionParameters.Builder.setDisabledTrackTypes`. This will apply -unconditionally and will also affect other playlist items. +Track types, like video, audio or text, can be disabled completely using +`TrackSelectionParameters.Builder.setTrackTypeDisabled`. A disabled track type +will be disabled for all media items: ~~~ player.setTrackSelectionParameters( player.getTrackSelectionParameters() .buildUpon() - .setDisabledTrackTypes(ImmutableSet.of(C.TRACK_TYPE_VIDEO)) + .setTrackTypeDisabled(C.TRACK_TYPE_VIDEO, /* disabled= */ true) .build()); ~~~ {: .language-java} Alternatively, it's possible to prevent the selection of tracks from a specific -`TrackGroup` only by specifying an empty override for that group: +`TrackGroup` by specifying an empty override for that group: ~~~ player.setTrackSelectionParameters( diff --git a/library/common/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionParameters.java b/library/common/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionParameters.java index ad83f1a6fe..91e80e79f3 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionParameters.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionParameters.java @@ -40,6 +40,7 @@ import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Locale; @@ -101,7 +102,7 @@ public class TrackSelectionParameters implements Bundleable { private boolean forceLowestBitrate; private boolean forceHighestSupportedBitrate; private HashMap overrides; - private ImmutableSet<@C.TrackType Integer> disabledTrackTypes; + private HashSet<@C.TrackType Integer> disabledTrackTypes; /** * @deprecated {@link Context} constraints will not be set using this constructor. Use {@link @@ -133,7 +134,7 @@ public class TrackSelectionParameters implements Bundleable { forceLowestBitrate = false; forceHighestSupportedBitrate = false; overrides = new HashMap<>(); - disabledTrackTypes = ImmutableSet.of(); + disabledTrackTypes = new HashSet<>(); } /** @@ -238,21 +239,22 @@ public class TrackSelectionParameters implements Bundleable { bundle.getBoolean( keyForField(FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE), DEFAULT_WITHOUT_CONTEXT.forceHighestSupportedBitrate); - overrides = new HashMap<>(); List overrideList = fromBundleNullableList( TrackSelectionOverride.CREATOR, bundle.getParcelableArrayList(keyForField(FIELD_SELECTION_OVERRIDES)), ImmutableList.of()); + overrides = new HashMap<>(); for (int i = 0; i < overrideList.size(); i++) { TrackSelectionOverride override = overrideList.get(i); overrides.put(override.trackGroup, override); } - disabledTrackTypes = - ImmutableSet.copyOf( - Ints.asList( - firstNonNull( - bundle.getIntArray(keyForField(FIELD_DISABLED_TRACK_TYPE)), new int[0]))); + int[] disabledTrackTypeArray = + firstNonNull(bundle.getIntArray(keyForField(FIELD_DISABLED_TRACK_TYPE)), new int[0]); + disabledTrackTypes = new HashSet<>(); + for (@C.TrackType int disabledTrackType : disabledTrackTypeArray) { + disabledTrackTypes.add(disabledTrackType); + } } /** Overrides the value of the builder with the value of {@link TrackSelectionParameters}. */ @@ -292,7 +294,7 @@ public class TrackSelectionParameters implements Bundleable { // General forceLowestBitrate = parameters.forceLowestBitrate; forceHighestSupportedBitrate = parameters.forceHighestSupportedBitrate; - disabledTrackTypes = parameters.disabledTrackTypes; + disabledTrackTypes = new HashSet<>(parameters.disabledTrackTypes); overrides = new HashMap<>(parameters.overrides); } @@ -693,13 +695,33 @@ public class TrackSelectionParameters implements Bundleable { /** * Sets the disabled track types, preventing all tracks of those types from being selected for - * playback. + * playback. Any previously disabled track types are cleared. * * @param disabledTrackTypes The track types to disable. * @return This builder. + * @deprecated Use {@link #setTrackTypeDisabled(int, boolean)}. */ + @Deprecated public Builder setDisabledTrackTypes(Set<@C.TrackType Integer> disabledTrackTypes) { - this.disabledTrackTypes = ImmutableSet.copyOf(disabledTrackTypes); + this.disabledTrackTypes.clear(); + this.disabledTrackTypes.addAll(disabledTrackTypes); + return this; + } + + /** + * Sets whether a track type is disabled. If disabled, no tracks of the specified type will be + * selected for playback. + * + * @param trackType The track type. + * @param disabled Whether the track type should be disabled. + * @return This builder. + */ + public Builder setTrackTypeDisabled(@C.TrackType int trackType, boolean disabled) { + if (disabled) { + disabledTrackTypes.add(trackType); + } else { + disabledTrackTypes.remove(trackType); + } return this; } @@ -931,7 +953,7 @@ public class TrackSelectionParameters implements Bundleable { this.forceLowestBitrate = builder.forceLowestBitrate; this.forceHighestSupportedBitrate = builder.forceHighestSupportedBitrate; this.overrides = ImmutableMap.copyOf(builder.overrides); - this.disabledTrackTypes = builder.disabledTrackTypes; + this.disabledTrackTypes = ImmutableSet.copyOf(builder.disabledTrackTypes); } /** Creates a new {@link Builder}, copying the initial values from this instance. */ diff --git a/library/common/src/test/java/com/google/android/exoplayer2/trackselection/TrackSelectionParametersTest.java b/library/common/src/test/java/com/google/android/exoplayer2/trackselection/TrackSelectionParametersTest.java index c65ec2f966..7c7c5618ea 100644 --- a/library/common/src/test/java/com/google/android/exoplayer2/trackselection/TrackSelectionParametersTest.java +++ b/library/common/src/test/java/com/google/android/exoplayer2/trackselection/TrackSelectionParametersTest.java @@ -24,7 +24,6 @@ import com.google.android.exoplayer2.Format; 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.ImmutableSet; import org.junit.Test; import org.junit.runner.RunWith; @@ -113,7 +112,8 @@ public final class TrackSelectionParametersTest { 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)) + .setTrackTypeDisabled(C.TRACK_TYPE_AUDIO, /* disabled= */ true) + .setTrackTypeDisabled(C.TRACK_TYPE_TEXT, /* disabled= */ true) .build(); // Video diff --git a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelector.java b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelector.java index 02fe223245..70d7a08e72 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelector.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelector.java @@ -622,11 +622,19 @@ public class DefaultTrackSelector extends MappingTrackSelector { } @Override + @Deprecated + @SuppressWarnings("deprecation") public ParametersBuilder setDisabledTrackTypes(Set<@C.TrackType Integer> disabledTrackTypes) { super.setDisabledTrackTypes(disabledTrackTypes); return this; } + @Override + public ParametersBuilder setTrackTypeDisabled(@C.TrackType int trackType, boolean disabled) { + super.setTrackTypeDisabled(trackType, disabled); + return this; + } + /** * Sets whether to exceed renderer capabilities when no selection can be made otherwise. * diff --git a/library/core/src/test/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelectorTest.java b/library/core/src/test/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelectorTest.java index f9affe7b98..9be3c4bb56 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelectorTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelectorTest.java @@ -390,7 +390,9 @@ public final class DefaultTrackSelectorTest { public void selectVideoAudioTracks_withDisabledAudioType_onlyVideoIsSelected() throws ExoPlaybackException { trackSelector.setParameters( - defaultParameters.buildUpon().setDisabledTrackTypes(ImmutableSet.of(C.TRACK_TYPE_AUDIO))); + defaultParameters + .buildUpon() + .setTrackTypeDisabled(C.TRACK_TYPE_AUDIO, /* disabled= */ true)); TrackSelectorResult result = trackSelector.selectTracks( @@ -405,11 +407,12 @@ public final class DefaultTrackSelectorTest { /** Tests that a disabled track type can be enabled again. */ @Test + @SuppressWarnings("deprecation") public void selectTracks_withClearedDisabledTrackType_selectsAll() throws ExoPlaybackException { trackSelector.setParameters( trackSelector .buildUponParameters() - .setDisabledTrackTypes(ImmutableSet.of(C.TRACK_TYPE_AUDIO)) + .setTrackTypeDisabled(C.TRACK_TYPE_AUDIO, /* disabled= */ true) .setDisabledTrackTypes(ImmutableSet.of())); TrackSelectorResult result = @@ -424,7 +427,9 @@ public final class DefaultTrackSelectorTest { public void selectTracks_withDisabledNoneTracksAndNoSampleRenderer_disablesNoSampleRenderer() throws ExoPlaybackException { trackSelector.setParameters( - defaultParameters.buildUpon().setDisabledTrackTypes(ImmutableSet.of(C.TRACK_TYPE_NONE))); + defaultParameters + .buildUpon() + .setTrackTypeDisabled(C.TRACK_TYPE_NONE, /* disabled= */ true)); TrackSelectorResult result = trackSelector.selectTracks( diff --git a/library/ui/src/main/java/com/google/android/exoplayer2/ui/StyledPlayerControlView.java b/library/ui/src/main/java/com/google/android/exoplayer2/ui/StyledPlayerControlView.java index 4efcc9db85..7cd646772f 100644 --- a/library/ui/src/main/java/com/google/android/exoplayer2/ui/StyledPlayerControlView.java +++ b/library/ui/src/main/java/com/google/android/exoplayer2/ui/StyledPlayerControlView.java @@ -73,15 +73,12 @@ import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.RepeatModeUtil; import com.google.android.exoplayer2.util.Util; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Formatter; -import java.util.HashSet; import java.util.List; import java.util.Locale; -import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; /** @@ -1873,11 +1870,7 @@ public class StyledPlayerControlView extends FrameLayout { player.setTrackSelectionParameters( trackSelectionParameters .buildUpon() - .setDisabledTrackTypes( - new ImmutableSet.Builder<@C.TrackType Integer>() - .addAll(trackSelectionParameters.disabledTrackTypes) - .add(C.TRACK_TYPE_TEXT) - .build()) + .setTrackTypeDisabled(C.TRACK_TYPE_TEXT, /* disabled= */ true) .build()); settingsWindow.dismiss(); } @@ -1916,15 +1909,12 @@ public class StyledPlayerControlView extends FrameLayout { } TrackSelectionParameters trackSelectionParameters = player.getTrackSelectionParameters(); - Set<@C.TrackType Integer> disabledTrackTypes = - new HashSet<>(trackSelectionParameters.disabledTrackTypes); - disabledTrackTypes.remove(C.TRACK_TYPE_AUDIO); castNonNull(player) .setTrackSelectionParameters( trackSelectionParameters .buildUpon() .clearOverridesOfType(C.TRACK_TYPE_AUDIO) - .setDisabledTrackTypes(disabledTrackTypes) + .setTrackTypeDisabled(C.TRACK_TYPE_AUDIO, /* disabled= */ false) .build()); settingsAdapter.setSubTextAtPosition( SETTINGS_AUDIO_TRACK_SELECTION_POSITION, @@ -2001,6 +1991,7 @@ public class StyledPlayerControlView extends FrameLayout { @Override public void onBindViewHolder(SubSettingViewHolder holder, int position) { + @Nullable Player player = StyledPlayerControlView.this.player; if (player == null) { return; } @@ -2009,29 +2000,23 @@ public class StyledPlayerControlView extends FrameLayout { } else { TrackInformation track = tracks.get(position - 1); TrackGroup trackGroup = track.trackGroupInfo.getTrackGroup(); - TrackSelectionParameters params = checkNotNull(player).getTrackSelectionParameters(); + TrackSelectionParameters params = player.getTrackSelectionParameters(); boolean explicitlySelected = params.overrides.get(trackGroup) != null && track.isSelected(); holder.textView.setText(track.trackName); holder.checkView.setVisibility(explicitlySelected ? VISIBLE : INVISIBLE); holder.itemView.setOnClickListener( v -> { - if (player == null) { - return; - } TrackSelectionParameters trackSelectionParameters = player.getTrackSelectionParameters(); - Set<@C.TrackType Integer> disabledTrackTypes = - new HashSet<>(trackSelectionParameters.disabledTrackTypes); - disabledTrackTypes.remove(track.trackGroupInfo.getTrackType()); - checkNotNull(player) - .setTrackSelectionParameters( - trackSelectionParameters - .buildUpon() - .setOverrideForType( - new TrackSelectionOverride( - trackGroup, ImmutableList.of(track.trackIndex))) - .setDisabledTrackTypes(disabledTrackTypes) - .build()); + player.setTrackSelectionParameters( + trackSelectionParameters + .buildUpon() + .setOverrideForType( + new TrackSelectionOverride( + trackGroup, ImmutableList.of(track.trackIndex))) + .setTrackTypeDisabled( + track.trackGroupInfo.getTrackType(), /* disabled= */ false) + .build()); onTrackSelection(track.trackName); settingsWindow.dismiss(); });