1*30877f79SAndroid Build Coastguard Worker---
2*30877f79SAndroid Build Coastguard Workertitle: Track selection
3*30877f79SAndroid Build Coastguard Worker---
4*30877f79SAndroid Build Coastguard Worker
5*30877f79SAndroid Build Coastguard WorkerTrack selection determines which of the available media tracks are played by the
6*30877f79SAndroid Build Coastguard Workerplayer. This process is configured by [`TrackSelectionParameters`][], which
7*30877f79SAndroid Build Coastguard Workersupport many different options to specify constraints and overrides.
8*30877f79SAndroid Build Coastguard Worker
9*30877f79SAndroid Build Coastguard Worker## Information about existing tracks
10*30877f79SAndroid Build Coastguard Worker
11*30877f79SAndroid Build Coastguard WorkerThe player needs to prepare the media to know which tracks are available for
12*30877f79SAndroid Build Coastguard Workerselection. You can listen to `Player.Listener.onTracksInfoChanged` to get
13*30877f79SAndroid Build Coastguard Workernotified about changes, which may happen
14*30877f79SAndroid Build Coastguard Worker * When preparation completes
15*30877f79SAndroid Build Coastguard Worker * When the available or selected tracks change
16*30877f79SAndroid Build Coastguard Worker * When the playlist item changes
17*30877f79SAndroid Build Coastguard Worker
18*30877f79SAndroid Build Coastguard Worker~~~
19*30877f79SAndroid Build Coastguard Workerplayer.addListener(new Player.Listener() {
20*30877f79SAndroid Build Coastguard Worker  @Override
21*30877f79SAndroid Build Coastguard Worker  public void onTracksInfoChanged(TracksInfo tracksInfo) {
22*30877f79SAndroid Build Coastguard Worker    // Update UI using current TracksInfo.
23*30877f79SAndroid Build Coastguard Worker  }
24*30877f79SAndroid Build Coastguard Worker});
25*30877f79SAndroid Build Coastguard Worker~~~
26*30877f79SAndroid Build Coastguard Worker{: .language-java}
27*30877f79SAndroid Build Coastguard Worker
28*30877f79SAndroid Build Coastguard WorkerYou can also retrieve the current `TracksInfo` by calling
29*30877f79SAndroid Build Coastguard Worker`player.getCurrentTracksInfo()`.
30*30877f79SAndroid Build Coastguard Worker
31*30877f79SAndroid Build Coastguard Worker`TracksInfo` contains a list of `TrackGroupInfo`s with information about the
32*30877f79SAndroid Build Coastguard Workertrack type, format details, player support and selection status of each
33*30877f79SAndroid Build Coastguard Workeravailable track. Tracks are grouped together into one `TrackGroup` if they
34*30877f79SAndroid Build Coastguard Workerrepresent the same content that can be used interchangeably by the player (for
35*30877f79SAndroid Build Coastguard Workerexample, all audio tracks of a single language, but with different bitrates).
36*30877f79SAndroid Build Coastguard Worker
37*30877f79SAndroid Build Coastguard Worker~~~
38*30877f79SAndroid Build Coastguard Workerfor (TrackGroupInfo groupInfo : tracksInfo.getTrackGroupInfos()) {
39*30877f79SAndroid Build Coastguard Worker  // Group level information.
40*30877f79SAndroid Build Coastguard Worker  @C.TrackType int trackType = groupInfo.getTrackType();
41*30877f79SAndroid Build Coastguard Worker  boolean trackInGroupIsSelected = groupInfo.isSelected();
42*30877f79SAndroid Build Coastguard Worker  boolean trackInGroupIsSupported = groupInfo.isSupported();
43*30877f79SAndroid Build Coastguard Worker  TrackGroup group = groupInfo.getTrackGroup();
44*30877f79SAndroid Build Coastguard Worker  for (int i = 0; i < group.length; i++) {
45*30877f79SAndroid Build Coastguard Worker    // Individual track information.
46*30877f79SAndroid Build Coastguard Worker    boolean isSupported = groupInfo.isTrackSupported(i);
47*30877f79SAndroid Build Coastguard Worker    boolean isSelected = groupInfo.isTrackSelected(i);
48*30877f79SAndroid Build Coastguard Worker    Format trackFormat = group.getFormat(i);
49*30877f79SAndroid Build Coastguard Worker  }
50*30877f79SAndroid Build Coastguard Worker}
51*30877f79SAndroid Build Coastguard Worker~~~
52*30877f79SAndroid Build Coastguard Worker{: .language-java}
53*30877f79SAndroid Build Coastguard Worker
54*30877f79SAndroid Build Coastguard Worker* A track is 'supported' if the `Player` is able to decode and render its
55*30877f79SAndroid Build Coastguard Worker  samples. Note that even if multiple track groups of the same type (for example
56*30877f79SAndroid Build Coastguard Worker  multiple audio track groups) are supported, it only means that they are
57*30877f79SAndroid Build Coastguard Worker  supported individually and the player is not necessarily able to play them at
58*30877f79SAndroid Build Coastguard Worker  the same time.
59*30877f79SAndroid Build Coastguard Worker* A track is 'selected' if the track selector chose this track for playback
60*30877f79SAndroid Build Coastguard Worker  using the current `TrackSelectionParameters`. If multiple tracks within one
61*30877f79SAndroid Build Coastguard Worker  track group are selected, the player uses these tracks for adaptive playback
62*30877f79SAndroid Build Coastguard Worker  (for example, multiple video tracks with different bitrates). Note that only
63*30877f79SAndroid Build Coastguard Worker  one of these tracks will be played at any one time. If you want to be notified
64*30877f79SAndroid Build Coastguard Worker  of in-playback changes to the adaptive video track you can listen to
65*30877f79SAndroid Build Coastguard Worker  `Player.Listener.onVideoSizeChanged`.
66*30877f79SAndroid Build Coastguard Worker
67*30877f79SAndroid Build Coastguard Worker## Modifying track selection parameters
68*30877f79SAndroid Build Coastguard Worker
69*30877f79SAndroid Build Coastguard WorkerThe selection process can be configured by setting `TrackSelectionParameters` on
70*30877f79SAndroid Build Coastguard Workerthe `Player` with `Player.setTrackSelectionParameters`. These updates can be
71*30877f79SAndroid Build Coastguard Workerdone before and during playback. In most cases, it's advisable to obtain the
72*30877f79SAndroid Build Coastguard Workercurrent parameters and only modify the required aspects with the
73*30877f79SAndroid Build Coastguard Worker`TrackSelectionParameters.Builder`. The builder class also allows chaining to
74*30877f79SAndroid Build Coastguard Workerspecify multiple options with one command:
75*30877f79SAndroid Build Coastguard Worker
76*30877f79SAndroid Build Coastguard Worker~~~
77*30877f79SAndroid Build Coastguard Workerplayer.setTrackSelectionParameters(
78*30877f79SAndroid Build Coastguard Worker    player.getTrackSelectionParameters()
79*30877f79SAndroid Build Coastguard Worker        .buildUpon()
80*30877f79SAndroid Build Coastguard Worker        .setMaxVideoSizeSd()
81*30877f79SAndroid Build Coastguard Worker        .setPreferredAudioLanguage("hu")
82*30877f79SAndroid Build Coastguard Worker        .build());
83*30877f79SAndroid Build Coastguard Worker~~~
84*30877f79SAndroid Build Coastguard Worker{: .language-java}
85*30877f79SAndroid Build Coastguard Worker
86*30877f79SAndroid Build Coastguard Worker### Constraint based track selection
87*30877f79SAndroid Build Coastguard Worker
88*30877f79SAndroid Build Coastguard WorkerMost options in `TrackSelectionParameters` allow you to specify constraints,
89*30877f79SAndroid Build Coastguard Workerwhich are independent of the tracks that are actually available. Typical
90*30877f79SAndroid Build Coastguard Workerconstraints are:
91*30877f79SAndroid Build Coastguard Worker
92*30877f79SAndroid Build Coastguard Worker * Maximum or minimum video width, height, frame rate, or bitrate.
93*30877f79SAndroid Build Coastguard Worker * Maximum audio channel count or bitrate.
94*30877f79SAndroid Build Coastguard Worker * Preferred MIME types for video or audio.
95*30877f79SAndroid Build Coastguard Worker * Preferred audio languages or role flags.
96*30877f79SAndroid Build Coastguard Worker * Preferred text languages or role flags.
97*30877f79SAndroid Build Coastguard Worker
98*30877f79SAndroid Build Coastguard WorkerNote that ExoPlayer already applies sensible defaults for most of these values,
99*30877f79SAndroid Build Coastguard Workerfor example restricting video resolution to the display size or preferring the
100*30877f79SAndroid Build Coastguard Workeraudio language that matches the user's system Locale setting.
101*30877f79SAndroid Build Coastguard Worker
102*30877f79SAndroid Build Coastguard WorkerThere are several benefits to using constraint based track selection instead of
103*30877f79SAndroid Build Coastguard Workerspecifying specific tracks directly:
104*30877f79SAndroid Build Coastguard Worker
105*30877f79SAndroid Build Coastguard Worker* You can specify constraints before knowing what tracks the media provides.
106*30877f79SAndroid Build Coastguard Worker  This allows to immediately select the appropriate tracks for faster startup
107*30877f79SAndroid Build Coastguard Worker  time and also simplifies track selection code as you don't have to listen for
108*30877f79SAndroid Build Coastguard Worker  changes in the available tracks.
109*30877f79SAndroid Build Coastguard Worker* Constraints can be applied consistently across all items in a playlist. For
110*30877f79SAndroid Build Coastguard Worker  example, selecting an audio language based on user preference will
111*30877f79SAndroid Build Coastguard Worker  automatically apply to the next playlist item too, whereas overriding a
112*30877f79SAndroid Build Coastguard Worker  specific track will only apply to the current playlist item for which the
113*30877f79SAndroid Build Coastguard Worker  track exists.
114*30877f79SAndroid Build Coastguard Worker
115*30877f79SAndroid Build Coastguard Worker### Selecting specific tracks
116*30877f79SAndroid Build Coastguard Worker
117*30877f79SAndroid Build Coastguard WorkerIt's possible to specify specific tracks in `TrackSelectionParameters` that
118*30877f79SAndroid Build Coastguard Workershould be selected for the current set of tracks. Note that a change in the
119*30877f79SAndroid Build Coastguard Workeravailable tracks, for example when changing items in a playlist, will also
120*30877f79SAndroid Build Coastguard Workerinvalidate such a track override.
121*30877f79SAndroid Build Coastguard Worker
122*30877f79SAndroid Build Coastguard WorkerThe simplest way to specify track overrides is to specify the `TrackGroup` that
123*30877f79SAndroid Build Coastguard Workershould be selected for its track type. For example, you can specify an audio
124*30877f79SAndroid Build Coastguard Workertrack group to select this audio group and prevent any other audio track groups
125*30877f79SAndroid Build Coastguard Workerfrom being selected:
126*30877f79SAndroid Build Coastguard Worker
127*30877f79SAndroid Build Coastguard Worker~~~
128*30877f79SAndroid Build Coastguard WorkerTrackSelectionOverrides overrides =
129*30877f79SAndroid Build Coastguard Worker    new TrackSelectionOverrides.Builder()
130*30877f79SAndroid Build Coastguard Worker        .setOverrideForType(new TrackSelectionOverride(audioTrackGroup))
131*30877f79SAndroid Build Coastguard Worker        .build();
132*30877f79SAndroid Build Coastguard Workerplayer.setTrackSelectionParameters(
133*30877f79SAndroid Build Coastguard Worker    player.getTrackSelectionParameters()
134*30877f79SAndroid Build Coastguard Worker        .buildUpon().setTrackSelectionOverrides(overrides).build());
135*30877f79SAndroid Build Coastguard Worker~~~
136*30877f79SAndroid Build Coastguard Worker{: .language-java}
137*30877f79SAndroid Build Coastguard Worker
138*30877f79SAndroid Build Coastguard Worker### Disabling track types or groups
139*30877f79SAndroid Build Coastguard Worker
140*30877f79SAndroid Build Coastguard WorkerTrack types, like video, audio or text, can be disabled completely by using
141*30877f79SAndroid Build Coastguard Worker`TrackSelectionParameters.Builder.setDisabledTrackTypes`. This will apply
142*30877f79SAndroid Build Coastguard Workerunconditionally and will also affect other playlist items.
143*30877f79SAndroid Build Coastguard Worker
144*30877f79SAndroid Build Coastguard Worker~~~
145*30877f79SAndroid Build Coastguard Workerplayer.setTrackSelectionParameters(
146*30877f79SAndroid Build Coastguard Worker    player.getTrackSelectionParameters()
147*30877f79SAndroid Build Coastguard Worker        .buildUpon()
148*30877f79SAndroid Build Coastguard Worker        .setDisabledTrackTypes(ImmutableSet.of(C.TRACK_TYPE_VIDEO))
149*30877f79SAndroid Build Coastguard Worker        .build());
150*30877f79SAndroid Build Coastguard Worker~~~
151*30877f79SAndroid Build Coastguard Worker{: .language-java}
152*30877f79SAndroid Build Coastguard Worker
153*30877f79SAndroid Build Coastguard WorkerAlternatively, it's possible to prevent the selection of track groups for the
154*30877f79SAndroid Build Coastguard Workercurrent playlist item only by specifying empty overrides for these groups:
155*30877f79SAndroid Build Coastguard Worker
156*30877f79SAndroid Build Coastguard Worker~~~
157*30877f79SAndroid Build Coastguard WorkerTrackSelectionOverrides overrides =
158*30877f79SAndroid Build Coastguard Worker    new TrackSelectionOverrides.Builder()
159*30877f79SAndroid Build Coastguard Worker        .addOverride(
160*30877f79SAndroid Build Coastguard Worker             new TrackSelectionOverride(
161*30877f79SAndroid Build Coastguard Worker                disabledTrackGroup,
162*30877f79SAndroid Build Coastguard Worker                /* select no tracks for this group */ ImmutableList.of()))
163*30877f79SAndroid Build Coastguard Worker        .build();
164*30877f79SAndroid Build Coastguard Workerplayer.setTrackSelectionParameters(
165*30877f79SAndroid Build Coastguard Worker    player.getTrackSelectionParameters()
166*30877f79SAndroid Build Coastguard Worker        .buildUpon().setTrackSelectionOverrides(overrides).build());
167*30877f79SAndroid Build Coastguard Worker~~~
168*30877f79SAndroid Build Coastguard Worker{: .language-java}
169*30877f79SAndroid Build Coastguard Worker
170*30877f79SAndroid Build Coastguard Worker## Customizing the track selector
171*30877f79SAndroid Build Coastguard Worker
172*30877f79SAndroid Build Coastguard WorkerTrack selection is the responsibility of a `TrackSelector`, an instance
173*30877f79SAndroid Build Coastguard Workerof which can be provided whenever an `ExoPlayer` is built and later obtained
174*30877f79SAndroid Build Coastguard Workerwith `ExoPlayer.getTrackSelector()`.
175*30877f79SAndroid Build Coastguard Worker
176*30877f79SAndroid Build Coastguard Worker~~~
177*30877f79SAndroid Build Coastguard WorkerDefaultTrackSelector trackSelector = new DefaultTrackSelector(context);
178*30877f79SAndroid Build Coastguard WorkerExoPlayer player =
179*30877f79SAndroid Build Coastguard Worker    new ExoPlayer.Builder(context)
180*30877f79SAndroid Build Coastguard Worker        .setTrackSelector(trackSelector)
181*30877f79SAndroid Build Coastguard Worker        .build();
182*30877f79SAndroid Build Coastguard Worker~~~
183*30877f79SAndroid Build Coastguard Worker{: .language-java}
184*30877f79SAndroid Build Coastguard Worker
185*30877f79SAndroid Build Coastguard Worker`DefaultTrackSelector` is a flexible `TrackSelector` suitable for most use
186*30877f79SAndroid Build Coastguard Workercases. It uses the `TrackSelectionParameters` set in the `Player`, but also
187*30877f79SAndroid Build Coastguard Workerprovides some advanced customization options that can be specified in the
188*30877f79SAndroid Build Coastguard Worker`DefaultTrackSelector.ParametersBuilder`:
189*30877f79SAndroid Build Coastguard Worker
190*30877f79SAndroid Build Coastguard Worker~~~
191*30877f79SAndroid Build Coastguard WorkertrackSelector.setParameters(
192*30877f79SAndroid Build Coastguard Worker    trackSelector
193*30877f79SAndroid Build Coastguard Worker        .buildUponParameters()
194*30877f79SAndroid Build Coastguard Worker        .setAllowVideoMixedMimeTypeAdaptiveness(true));
195*30877f79SAndroid Build Coastguard Worker~~~
196*30877f79SAndroid Build Coastguard Worker{: .language-java}
197*30877f79SAndroid Build Coastguard Worker
198*30877f79SAndroid Build Coastguard Worker### Tunneling
199*30877f79SAndroid Build Coastguard Worker
200*30877f79SAndroid Build Coastguard WorkerTunneled playback can be enabled in cases where the combination of renderers and
201*30877f79SAndroid Build Coastguard Workerselected tracks supports it. This can be done by using
202*30877f79SAndroid Build Coastguard Worker`DefaultTrackSelector.ParametersBuilder.setTunnelingEnabled(true)`.
203*30877f79SAndroid Build Coastguard Worker
204*30877f79SAndroid Build Coastguard Worker[`TrackSelectionParameters`]: {{ site.exo_sdk }}/trackselection/TrackSelectionParameters.html
205