Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dev: adding sorting for TrackSelectionDialog and TrackSelectionDialog… #7798

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ public void onPrepared(@NonNull DownloadHelper helper) {
/* allowAdaptiveSelections =*/ false,
/* allowMultipleOverrides= */ true,
/* onClickListener= */ this,
/* onDismissListener= */ this);
/* onDismissListener= */ this, null);
trackSelectionDialog.show(fragmentManager, /* tag= */ null);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.PlaybackPreparer;
import com.google.android.exoplayer2.Player;
Expand Down Expand Up @@ -64,6 +65,8 @@
import java.net.CookiePolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;

/** An activity that plays media using {@link SimpleExoPlayer}. */
Expand Down Expand Up @@ -242,15 +245,30 @@ public void onClick(View view) {
if (view == selectTracksButton
&& !isShowingTrackSelectionDialog
&& TrackSelectionDialog.willHaveContent(trackSelector)) {
HashMap<Integer, Comparator<Format>> comparatorHashMap = new HashMap<>();
comparatorHashMap.put(getRendererTypeIndex(C.TRACK_TYPE_AUDIO), (o1, o2) -> o1.bitrate - o2.bitrate);
comparatorHashMap.put(getRendererTypeIndex(C.TRACK_TYPE_VIDEO), (o1, o2) -> o2.bitrate - o1.bitrate);
isShowingTrackSelectionDialog = true;
TrackSelectionDialog trackSelectionDialog =
TrackSelectionDialog.createForTrackSelector(
trackSelector,
/* onDismissListener= */ dismissedDialog -> isShowingTrackSelectionDialog = false);
/* onDismissListener= */ dismissedDialog -> isShowingTrackSelectionDialog = false, comparatorHashMap);
trackSelectionDialog.show(getSupportFragmentManager(), /* tag= */ null);
}
}

private Integer getRendererTypeIndex(int trackType) {
MappedTrackInfo mappedTrackInfo = trackSelector.getCurrentMappedTrackInfo();
for(int i = 0; i < mappedTrackInfo.getRendererCount(); i++) {
TrackGroupArray trackGroupArray = mappedTrackInfo.getTrackGroups(i);
if(trackGroupArray.length == 0) return null;
if(trackType == mappedTrackInfo.getRendererType(i)) {
return i;
}
}
return null;
}

// PlaybackPreparer implementation

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.SelectionOverride;
Expand All @@ -42,6 +43,8 @@
import com.google.android.material.tabs.TabLayout;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;

/** Dialog to select tracks. */
Expand All @@ -53,6 +56,7 @@ public final class TrackSelectionDialog extends DialogFragment {
private int titleId;
private DialogInterface.OnClickListener onClickListener;
private DialogInterface.OnDismissListener onDismissListener;
private HashMap<Integer, Comparator<Format>> comparators = new HashMap<>();

/**
* Returns whether a track selection dialog will have content to display if initialized with the
Expand Down Expand Up @@ -85,7 +89,8 @@ public static boolean willHaveContent(MappedTrackInfo mappedTrackInfo) {
* dismissed.
*/
public static TrackSelectionDialog createForTrackSelector(
DefaultTrackSelector trackSelector, DialogInterface.OnDismissListener onDismissListener) {
DefaultTrackSelector trackSelector, DialogInterface.OnDismissListener onDismissListener,
HashMap<Integer, Comparator<Format>> comparators) {
MappedTrackInfo mappedTrackInfo =
Assertions.checkNotNull(trackSelector.getCurrentMappedTrackInfo());
TrackSelectionDialog trackSelectionDialog = new TrackSelectionDialog();
Expand Down Expand Up @@ -115,7 +120,8 @@ public static TrackSelectionDialog createForTrackSelector(
}
trackSelector.setParameters(builder);
},
onDismissListener);
onDismissListener,
comparators);
return trackSelectionDialog;
}

Expand All @@ -140,7 +146,8 @@ public static TrackSelectionDialog createForMappedTrackInfoAndParameters(
boolean allowAdaptiveSelections,
boolean allowMultipleOverrides,
DialogInterface.OnClickListener onClickListener,
DialogInterface.OnDismissListener onDismissListener) {
DialogInterface.OnDismissListener onDismissListener,
@Nullable HashMap<Integer, Comparator<Format>> comparators) {
TrackSelectionDialog trackSelectionDialog = new TrackSelectionDialog();
trackSelectionDialog.init(
titleId,
Expand All @@ -149,7 +156,8 @@ public static TrackSelectionDialog createForMappedTrackInfoAndParameters(
allowAdaptiveSelections,
allowMultipleOverrides,
onClickListener,
onDismissListener);
onDismissListener,
comparators);
return trackSelectionDialog;
}

Expand All @@ -167,10 +175,12 @@ private void init(
boolean allowAdaptiveSelections,
boolean allowMultipleOverrides,
DialogInterface.OnClickListener onClickListener,
DialogInterface.OnDismissListener onDismissListener) {
DialogInterface.OnDismissListener onDismissListener,
HashMap<Integer, Comparator<Format>> comparators) {
this.titleId = titleId;
this.onClickListener = onClickListener;
this.onDismissListener = onDismissListener;
this.comparators = comparators;
for (int i = 0; i < mappedTrackInfo.getRendererCount(); i++) {
if (showTabForRenderer(mappedTrackInfo, i)) {
int trackType = mappedTrackInfo.getRendererType(/* rendererIndex= */ i);
Expand All @@ -182,7 +192,9 @@ private void init(
initialParameters.getRendererDisabled(/* rendererIndex= */ i),
initialParameters.getSelectionOverride(/* rendererIndex= */ i, trackGroupArray),
allowAdaptiveSelections,
allowMultipleOverrides);
allowMultipleOverrides,
this.comparators.get(i) != null ? comparators.get(i) : null
);
tabFragments.put(i, tabFragment);
tabTrackTypes.add(trackType);
}
Expand Down Expand Up @@ -314,6 +326,7 @@ public static final class TrackSelectionViewFragment extends Fragment
private int rendererIndex;
private boolean allowAdaptiveSelections;
private boolean allowMultipleOverrides;
private Comparator<Format> comparator;

/* package */ boolean isDisabled;
/* package */ List<SelectionOverride> overrides;
Expand All @@ -329,10 +342,12 @@ public void init(
boolean initialIsDisabled,
@Nullable SelectionOverride initialOverride,
boolean allowAdaptiveSelections,
boolean allowMultipleOverrides) {
boolean allowMultipleOverrides,
@Nullable Comparator<Format> comparator) {
this.mappedTrackInfo = mappedTrackInfo;
this.rendererIndex = rendererIndex;
this.isDisabled = initialIsDisabled;
this.comparator = comparator;
this.overrides =
initialOverride == null
? Collections.emptyList()
Expand All @@ -354,7 +369,7 @@ public View onCreateView(
trackSelectionView.setAllowMultipleOverrides(allowMultipleOverrides);
trackSelectionView.setAllowAdaptiveSelections(allowAdaptiveSelections);
trackSelectionView.init(
mappedTrackInfo, rendererIndex, isDisabled, overrides, /* listener= */ this);
mappedTrackInfo, rendererIndex, isDisabled, overrides, /* listener= */ this, comparator);
return rootView;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@
import android.view.LayoutInflater;
import android.view.View;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.SelectionOverride;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo;
import com.google.android.exoplayer2.trackselection.TrackSelectionUtil;
import java.lang.reflect.Constructor;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/** Builder for a dialog with a {@link TrackSelectionView}. */
Expand Down Expand Up @@ -60,6 +62,7 @@ public interface DialogCallback {
@Nullable private TrackNameProvider trackNameProvider;
private boolean isDisabled;
private List<SelectionOverride> overrides;
private Comparator<Format> comparator;
yoobi marked this conversation as resolved.
Show resolved Hide resolved

/**
* Creates a builder for a track selection dialog.
Expand Down Expand Up @@ -195,6 +198,12 @@ public TrackSelectionDialogBuilder setShowDisableOption(boolean showDisableOptio
return this;
}

public void setComparator(Comparator<Format> comparator) {
if(this.comparator != comparator) {
yoobi marked this conversation as resolved.
Show resolved Hide resolved
this.comparator = comparator;
}
}

/**
* Sets the {@link TrackNameProvider} used to generate the user visible name of each track and
* updates the view with track names queried from the specified provider.
Expand Down Expand Up @@ -274,7 +283,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, comparator);
return (dialog, which) ->
callback.onTracksSelected(selectionView.getIsDisabled(), selectionView.getOverrides());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import android.widget.LinearLayout;
import androidx.annotation.AttrRes;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray;
Expand All @@ -35,6 +36,7 @@
import com.google.android.exoplayer2.util.Assertions;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.RequiresNonNull;
Expand Down Expand Up @@ -64,6 +66,9 @@ public interface TrackSelectionListener {
private boolean allowAdaptiveSelections;
private boolean allowMultipleOverrides;

@Nullable private Comparator<Format> comparator;
private TrackGroupArray sortedTrackGroups;

private TrackNameProvider trackNameProvider;
private CheckedTextView[][] trackViews;

Expand Down Expand Up @@ -203,11 +208,13 @@ public void init(
int rendererIndex,
boolean isDisabled,
List<SelectionOverride> overrides,
@Nullable TrackSelectionListener listener) {
@Nullable TrackSelectionListener listener,
@Nullable Comparator<Format> comparator) {
yoobi marked this conversation as resolved.
Show resolved Hide resolved
this.mappedTrackInfo = mappedTrackInfo;
this.rendererIndex = rendererIndex;
this.isDisabled = isDisabled;
this.listener = listener;
this.comparator = comparator;
int maxOverrides = allowMultipleOverrides ? overrides.size() : Math.min(overrides.size(), 1);
for (int i = 0; i < maxOverrides; i++) {
SelectionOverride override = overrides.get(i);
Expand Down Expand Up @@ -251,12 +258,13 @@ private void updateViews() {
defaultView.setEnabled(true);

trackGroups = mappedTrackInfo.getTrackGroups(rendererIndex);
sortedTrackGroups = sortedTrackGroups != null ? sortedTrackGroups : initSortedTrackGroups(trackGroups);
yoobi marked this conversation as resolved.
Show resolved Hide resolved

// Add per-track views.
trackViews = new CheckedTextView[trackGroups.length][];
trackViews = new CheckedTextView[sortedTrackGroups.length][];
boolean enableMultipleChoiceForMultipleOverrides = shouldEnableMultiGroupSelection();
for (int groupIndex = 0; groupIndex < trackGroups.length; groupIndex++) {
TrackGroup group = trackGroups.get(groupIndex);
for (int groupIndex = 0; groupIndex < sortedTrackGroups.length; groupIndex++) {
TrackGroup group = sortedTrackGroups.get(groupIndex);
boolean enableMultipleChoiceForAdaptiveSelections = shouldEnableAdaptiveSelection(groupIndex);
trackViews[groupIndex] = new CheckedTextView[group.length];
for (int trackIndex = 0; trackIndex < group.length; trackIndex++) {
Expand Down Expand Up @@ -294,7 +302,12 @@ private void updateViewStates() {
for (int i = 0; i < trackViews.length; i++) {
SelectionOverride override = overrides.get(i);
for (int j = 0; j < trackViews[i].length; j++) {
trackViews[i][j].setChecked(override != null && override.containsTrack(j));
if(override != null) {
int sortedIndex = getSortedIndexFromInitialTrackGroup(override.groupIndex, j);
trackViews[i][j].setChecked(override.containsTrack(sortedIndex));
} else {
trackViews[i][j].setChecked(false);
}
}
}
}
Expand Down Expand Up @@ -328,7 +341,7 @@ private void onTrackViewClicked(View view) {
@SuppressWarnings("unchecked")
Pair<Integer, Integer> tag = (Pair<Integer, Integer>) Assertions.checkNotNull(view.getTag());
int groupIndex = tag.first;
int trackIndex = tag.second;
int trackIndex = getSortedIndexFromInitialTrackGroup(tag.first, tag.second);
SelectionOverride override = overrides.get(groupIndex);
Assertions.checkNotNull(mappedTrackInfo);
if (override == null) {
Expand Down Expand Up @@ -367,6 +380,48 @@ private void onTrackViewClicked(View view) {
}
}

private TrackGroupArray initSortedTrackGroups(TrackGroupArray trackGroups) {
yoobi marked this conversation as resolved.
Show resolved Hide resolved
TrackGroupArray trackGroupArray = trackGroups;
if(comparator != null) {
TrackGroupArray trackGroupsArray = mappedTrackInfo.getTrackGroups(rendererIndex);
yoobi marked this conversation as resolved.
Show resolved Hide resolved
for (int groupIndex = 0; groupIndex < trackGroupsArray.length; groupIndex++) {
TrackGroup group = trackGroupsArray.get(groupIndex);
Format[] listFormats = new Format[group.length];
for (int formatIndex = 0; formatIndex < group.length; formatIndex++) {
listFormats[formatIndex] = group.getFormat(formatIndex);
}
Arrays.sort(listFormats, comparator);
trackGroupArray = new TrackGroupArray(new TrackGroup(listFormats));
}
}
return trackGroupArray;
}

/**
* The correspondence between trackGroup and sortedTrackGroup indexes.
* initial array (only quality for this example) : [480,720,256,1080]
* asc sorted array (only quality for this example) : [256,480,720,1080]
* initial array index for 480 is 0, but for sorted array index is 1.
* Initial array index is @param trackIndex, and the @return result is sorted array index
* @param groupIndex which TrackGroup you want to browse into
* @param trackIndex which index of the initial array
* @return index of the sorted array that correspond to the same element in the initial array
*/
private int getSortedIndexFromInitialTrackGroup(int groupIndex, int trackIndex) {
int sortedTrackIndex = trackIndex;
if(sortedTrackGroups != trackGroups) {
Format selectedFormat = sortedTrackGroups.get(rendererIndex).getFormat(trackIndex);
int trackHash = selectedFormat.hashCode();
for (int formatIndex = 0; formatIndex < trackGroups.get(groupIndex).length; formatIndex++) {
if(trackGroups.get(groupIndex).getFormat(formatIndex).hashCode() == trackHash) {
yoobi marked this conversation as resolved.
Show resolved Hide resolved
sortedTrackIndex = formatIndex;
break;
}
}
}
return sortedTrackIndex;
}

@RequiresNonNull("mappedTrackInfo")
private boolean shouldEnableAdaptiveSelection(int groupIndex) {
return allowAdaptiveSelections
Expand Down