diff --git a/library/ui/src/main/java/com/google/android/exoplayer2/ui/TrackSelectionDialogBuilder.java b/library/ui/src/main/java/com/google/android/exoplayer2/ui/TrackSelectionDialogBuilder.java index 30098054ef7..ecc629c13b2 100644 --- a/library/ui/src/main/java/com/google/android/exoplayer2/ui/TrackSelectionDialogBuilder.java +++ b/library/ui/src/main/java/com/google/android/exoplayer2/ui/TrackSelectionDialogBuilder.java @@ -59,6 +59,7 @@ public interface DialogCallback { private boolean showDisableOption; @Nullable private TrackNameProvider trackNameProvider; private boolean isDisabled; + private boolean sortTrackAscending = false; private List overrides; /** @@ -207,6 +208,18 @@ public TrackSelectionDialogBuilder setTrackNameProvider( return this; } + /** + * + * Sets Whether the TrackGroupArray of the {@code rendererIndex} specified should be + * display in ascending order + * @param sort Whether to sort in ascending order or let it as it is received + * @return This builder, for convenience. + */ + public TrackSelectionDialogBuilder setSortTrack(boolean sort) { + this.sortTrackAscending = sort; + return this; + } + /** Builds the dialog. */ public Dialog build() { @Nullable Dialog dialog = buildForAndroidX(); @@ -274,7 +287,7 @@ private Dialog.OnClickListener setUpDialogView(View dialogView) { if (trackNameProvider != null) { selectionView.setTrackNameProvider(trackNameProvider); } - selectionView.init(mappedTrackInfo, rendererIndex, isDisabled, overrides, /* listener= */ null); + selectionView.init(mappedTrackInfo, rendererIndex, isDisabled, overrides, /* listener= */ null, sortTrackAscending); return (dialog, which) -> callback.onTracksSelected(selectionView.getIsDisabled(), selectionView.getOverrides()); } diff --git a/library/ui/src/main/java/com/google/android/exoplayer2/ui/TrackSelectionView.java b/library/ui/src/main/java/com/google/android/exoplayer2/ui/TrackSelectionView.java index b47feb2a718..7b08029e2ab 100644 --- a/library/ui/src/main/java/com/google/android/exoplayer2/ui/TrackSelectionView.java +++ b/library/ui/src/main/java/com/google/android/exoplayer2/ui/TrackSelectionView.java @@ -33,6 +33,7 @@ import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.SelectionOverride; import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo; import com.google.android.exoplayer2.util.Assertions; +import com.google.android.exoplayer2.Format; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -63,6 +64,7 @@ public interface TrackSelectionListener { private boolean allowAdaptiveSelections; private boolean allowMultipleOverrides; + private boolean sortTrackAscending; private TrackNameProvider trackNameProvider; private CheckedTextView[][] trackViews; @@ -203,11 +205,13 @@ public void init( int rendererIndex, boolean isDisabled, List overrides, - @Nullable TrackSelectionListener listener) { + @Nullable TrackSelectionListener listener, + boolean sortTrackAscending) { this.mappedTrackInfo = mappedTrackInfo; this.rendererIndex = rendererIndex; this.isDisabled = isDisabled; this.listener = listener; + this.sortTrackAscending = sortTrackAscending; int maxOverrides = allowMultipleOverrides ? overrides.size() : Math.min(overrides.size(), 1); for (int i = 0; i < maxOverrides; i++) { SelectionOverride override = overrides.get(i); @@ -216,6 +220,15 @@ public void init( updateViews(); } + public void init( + MappedTrackInfo mappedTrackInfo, + int rendererIndex, + boolean isDisabled, + List overrides, + @Nullable TrackSelectionListener listener) { + init(mappedTrackInfo, rendererIndex, isDisabled, overrides, listener, false); + } + /** Returns whether the renderer is disabled. */ public boolean getIsDisabled() { return isDisabled; @@ -250,7 +263,7 @@ private void updateViews() { disableView.setEnabled(true); defaultView.setEnabled(true); - trackGroups = mappedTrackInfo.getTrackGroups(rendererIndex); + trackGroups = sortTrackGroups(mappedTrackInfo, rendererIndex, sortTrackAscending); // Add per-track views. trackViews = new CheckedTextView[trackGroups.length][]; @@ -288,6 +301,30 @@ private void updateViews() { updateViewStates(); } + private TrackGroupArray sortTrackGroups(MappedTrackInfo mappedTrackInfo, int rendererIndex, boolean asc) { + TrackGroupArray trackGroups = mappedTrackInfo.getTrackGroups(rendererIndex); + if(asc) { + Format[][] listFormats = new Format[trackGroups.length][]; + for(int groupIndex = 0; groupIndex < trackGroups.length; groupIndex++) { + TrackGroup group = trackGroups.get(groupIndex); + listFormats[groupIndex] = new Format[group.length]; + for (int formatIndex = 0; formatIndex < group.length; formatIndex++) { + listFormats[groupIndex][formatIndex] = group.getFormat(formatIndex); + } + } + + // Ascending order by comparing bitrate (works for Video and Audio) + Arrays.sort(listFormats[0], (o1, o2) -> Integer.compare(o1.bitrate, o2.bitrate)); + TrackGroup[] tg = new TrackGroup[listFormats.length]; + for(int trackIndex = 0; trackIndex < listFormats.length; trackIndex++) { + tg[trackIndex] = new TrackGroup(listFormats[trackIndex]); + } + trackGroups = new TrackGroupArray(tg); + } + + return trackGroups; + } + private void updateViewStates() { disableView.setChecked(isDisabled); defaultView.setChecked(!isDisabled && overrides.size() == 0); @@ -372,8 +409,8 @@ private boolean shouldEnableAdaptiveSelection(int groupIndex) { return allowAdaptiveSelections && trackGroups.get(groupIndex).length > 1 && mappedTrackInfo.getAdaptiveSupport( - rendererIndex, groupIndex, /* includeCapabilitiesExceededTracks= */ false) - != RendererCapabilities.ADAPTIVE_NOT_SUPPORTED; + rendererIndex, groupIndex, /* includeCapabilitiesExceededTracks= */ false) + != RendererCapabilities.ADAPTIVE_NOT_SUPPORTED; } private boolean shouldEnableMultiGroupSelection() {