-
Notifications
You must be signed in to change notification settings - Fork 4
/
TrackSelectionDialog.java
239 lines (210 loc) · 9.8 KB
/
TrackSelectionDialog.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
package live.videosdk.android.hlsdemo.viewerMode;
import android.annotation.SuppressLint;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Tracks;
import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.trackselection.TrackSelectionOverride;
import com.google.android.exoplayer2.trackselection.TrackSelectionParameters;
import com.google.android.exoplayer2.ui.TrackSelectionView;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import live.videosdk.android.hlsdemo.R;
/**
* Dialog to select tracks.
*/
public final class TrackSelectionDialog extends BottomSheetDialogFragment implements TrackSelectionView.TrackSelectionListener {
@Override
public void onTrackSelectionChanged(boolean isDisabled, Map<TrackGroup, TrackSelectionOverride> overrides) {
this.isDisabled = isDisabled;
this.overrides = overrides;
}
/**
* Called when tracks are selected.
*/
public interface TrackSelectionListener {
/**
* Called when tracks are selected.
*
* @param trackSelectionParameters A {@link TrackSelectionParameters} representing the selected
* tracks. Any manual selections are defined by {@link
* TrackSelectionParameters#disabledTrackTypes} and {@link
* TrackSelectionParameters#overrides}.
*/
void onTracksSelected(TrackSelectionParameters trackSelectionParameters);
}
public static final ImmutableList<Integer> SUPPORTED_TRACK_TYPES =
ImmutableList.of(C.TRACK_TYPE_VIDEO);
private DialogInterface.OnClickListener onClickListener;
private DialogInterface.OnDismissListener onDismissListener;
private TrackSelectionView trackSelectionView;
private List<Tracks.Group> trackGroups;
private boolean allowAdaptiveSelections;
private boolean allowMultipleOverrides;
/* package */ boolean isDisabled;
/* package */ Map<TrackGroup, TrackSelectionOverride> overrides;
/**
* Returns whether a track selection dialog will have content to display if initialized with the
* specified {@link Player}.
*/
public static boolean willHaveContent(Player player) {
return willHaveContent(player.getCurrentTracks());
}
/**
* Returns whether a track selection dialog will have content to display if initialized with the
* specified {@link Tracks}.
*/
public static boolean willHaveContent(Tracks tracks) {
for (Tracks.Group trackGroup : tracks.getGroups()) {
if (SUPPORTED_TRACK_TYPES.contains(trackGroup.getType())) {
return true;
}
}
return false;
}
/**
* Creates a dialog for a given {@link Player}, whose parameters will be automatically updated
* when tracks are selected.
*
* @param player The {@link Player}.
* @param onDismissListener A {@link DialogInterface.OnDismissListener} to call when the dialog is
* dismissed.
*/
public static TrackSelectionDialog createForPlayer(
Player player, DialogInterface.OnDismissListener onDismissListener) {
return createForTracksAndParameters(
player.getCurrentTracks(),
player.getTrackSelectionParameters(),
/* allowAdaptiveSelections= */ false,
/* allowMultipleOverrides= */ false,
player::setTrackSelectionParameters,
onDismissListener);
}
/**
* Creates a dialog for given {@link Tracks} and {@link TrackSelectionParameters}.
*
* @param tracks The {@link Tracks} describing the tracks to display.
* @param trackSelectionParameters The initial {@link TrackSelectionParameters}.
* @param allowAdaptiveSelections Whether adaptive selections (consisting of more than one track)
* can be made.
* @param allowMultipleOverrides Whether tracks from multiple track groups can be selected.
* @param trackSelectionListener Called when tracks are selected.
* @param onDismissListener {@link DialogInterface.OnDismissListener} called when the dialog is
*/
public static TrackSelectionDialog createForTracksAndParameters(
Tracks tracks,
TrackSelectionParameters trackSelectionParameters,
boolean allowAdaptiveSelections,
boolean allowMultipleOverrides,
TrackSelectionListener trackSelectionListener,
DialogInterface.OnDismissListener onDismissListener) {
TrackSelectionDialog trackSelectionDialog = new TrackSelectionDialog();
trackSelectionDialog.init(
tracks,
trackSelectionParameters,
allowAdaptiveSelections,
allowMultipleOverrides,
/* onClickListener= */ (dialog, which) -> {
TrackSelectionParameters.Builder builder = trackSelectionParameters.buildUpon();
for (int i = 0; i < SUPPORTED_TRACK_TYPES.size(); i++) {
int trackType = SUPPORTED_TRACK_TYPES.get(i);
builder.setTrackTypeDisabled(trackType, trackSelectionDialog.isDisabled);
builder.clearOverridesOfType(trackType);
Map<TrackGroup, TrackSelectionOverride> overrides = trackSelectionDialog.overrides == null ? Collections.emptyMap() : trackSelectionDialog.overrides;
for (TrackSelectionOverride override : overrides.values()) {
builder.addOverride(override);
}
}
trackSelectionListener.onTracksSelected(builder.build());
},
onDismissListener);
return trackSelectionDialog;
}
public TrackSelectionDialog() {
// Retain instance across activity re-creation to prevent losing access to init data.
setRetainInstance(true);
}
private void init(
Tracks tracks,
TrackSelectionParameters trackSelectionParameters,
boolean allowAdaptiveSelections,
boolean allowMultipleOverrides,
DialogInterface.OnClickListener onClickListener,
DialogInterface.OnDismissListener onDismissListener) {
this.onClickListener = onClickListener;
this.onDismissListener = onDismissListener;
for (int i = 0; i < SUPPORTED_TRACK_TYPES.size(); i++) {
@C.TrackType int trackType = SUPPORTED_TRACK_TYPES.get(i);
ArrayList<Tracks.Group> trackGroups = new ArrayList<>();
for (Tracks.Group trackGroup : tracks.getGroups()) {
if (trackGroup.getType() == trackType) {
trackGroups.add(trackGroup);
}
}
if (!trackGroups.isEmpty()) {
this.allowAdaptiveSelections = allowAdaptiveSelections;
this.allowMultipleOverrides = allowMultipleOverrides;
this.trackGroups = trackGroups;
this.isDisabled = trackSelectionParameters.disabledTrackTypes.contains(trackType);
this.overrides = trackSelectionParameters.overrides;
}
}
}
/**
* if you want use dialog instead of BottomSheetDialog then change TrackSelectionDialog extends DialogFragment.
* And use this method.
**/
/* @Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// We need to own the view to let tab layout work correctly on all API levels. We can't use
// AlertDialog because it owns the view itself, so we use AppCompatDialog instead, themed using
// the AlertDialog theme overlay with force-enabled title.
AppCompatDialog dialog =
new AppCompatDialog(getActivity(), R.style.TrackSelectionDialog);
dialog.setTitle("title");
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
return dialog;
}*/
@Override
public void onDismiss(DialogInterface dialog) {
super.onDismiss(dialog);
onDismissListener.onDismiss(dialog);
}
@SuppressLint("MissingInflatedId")
@Override
public View onCreateView(
LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View dialogView = inflater.inflate(R.layout.track_selection_dialog, container, false);
ImageView cancelButton = dialogView.findViewById(R.id.cancelBtn);
Button applyBtn = dialogView.findViewById(R.id.applyBtn);
trackSelectionView = dialogView.findViewById(R.id.exo_track_selection_init_view);
trackSelectionView.setShowDisableOption(true);
trackSelectionView.setAllowMultipleOverrides(allowMultipleOverrides);
trackSelectionView.setAllowAdaptiveSelections(allowAdaptiveSelections);
trackSelectionView.init(
trackGroups,
isDisabled,
overrides,
/* trackFormatComparator= */ null,
/* listener= */ this);
cancelButton.setOnClickListener(view -> dismiss());
applyBtn.setOnClickListener(
view -> {
onClickListener.onClick(getDialog(), DialogInterface.BUTTON_POSITIVE);
dismiss();
});
return dialogView;
}
}