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  for (int i = 0; i < groupInfo.length; i++) {
44*30877f79SAndroid Build Coastguard Worker    // Individual track information.
45*30877f79SAndroid Build Coastguard Worker    boolean isSupported = groupInfo.isTrackSupported(i);
46*30877f79SAndroid Build Coastguard Worker    boolean isSelected = groupInfo.isTrackSelected(i);
47*30877f79SAndroid Build Coastguard Worker    Format trackFormat = groupInfo.getTrackFormat(i);
48*30877f79SAndroid Build Coastguard Worker  }
49*30877f79SAndroid Build Coastguard Worker}
50*30877f79SAndroid Build Coastguard Worker~~~
51*30877f79SAndroid Build Coastguard Worker{: .language-java}
52*30877f79SAndroid Build Coastguard Worker
53*30877f79SAndroid Build Coastguard Worker* A track is 'supported' if the `Player` is able to decode and render its
54*30877f79SAndroid Build Coastguard Worker  samples. Note that even if multiple track groups of the same type (for example
55*30877f79SAndroid Build Coastguard Worker  multiple audio track groups) are supported, it only means that they are
56*30877f79SAndroid Build Coastguard Worker  supported individually and the player is not necessarily able to play them at
57*30877f79SAndroid Build Coastguard Worker  the same time.
58*30877f79SAndroid Build Coastguard Worker* A track is 'selected' if the track selector chose this track for playback
59*30877f79SAndroid Build Coastguard Worker  using the current `TrackSelectionParameters`. If multiple tracks within one
60*30877f79SAndroid Build Coastguard Worker  track group are selected, the player uses these tracks for adaptive playback
61*30877f79SAndroid Build Coastguard Worker  (for example, multiple video tracks with different bitrates). Note that only
62*30877f79SAndroid Build Coastguard Worker  one of these tracks will be played at any one time. If you want to be notified
63*30877f79SAndroid Build Coastguard Worker  of in-playback changes to the adaptive video track you can listen to
64*30877f79SAndroid Build Coastguard Worker  `Player.Listener.onVideoSizeChanged`.
65*30877f79SAndroid Build Coastguard Worker
66*30877f79SAndroid Build Coastguard Worker## Modifying track selection parameters
67*30877f79SAndroid Build Coastguard Worker
68*30877f79SAndroid Build Coastguard WorkerThe selection process can be configured by setting `TrackSelectionParameters` on
69*30877f79SAndroid Build Coastguard Workerthe `Player` with `Player.setTrackSelectionParameters`. These updates can be
70*30877f79SAndroid Build Coastguard Workerdone before and during playback. In most cases, it's advisable to obtain the
71*30877f79SAndroid Build Coastguard Workercurrent parameters and only modify the required aspects with the
72*30877f79SAndroid Build Coastguard Worker`TrackSelectionParameters.Builder`. The builder class also allows chaining to
73*30877f79SAndroid Build Coastguard Workerspecify multiple options with one command:
74*30877f79SAndroid Build Coastguard Worker
75*30877f79SAndroid Build Coastguard Worker~~~
76*30877f79SAndroid Build Coastguard Workerplayer.setTrackSelectionParameters(
77*30877f79SAndroid Build Coastguard Worker    player.getTrackSelectionParameters()
78*30877f79SAndroid Build Coastguard Worker        .buildUpon()
79*30877f79SAndroid Build Coastguard Worker        .setMaxVideoSizeSd()
80*30877f79SAndroid Build Coastguard Worker        .setPreferredAudioLanguage("hu")
81*30877f79SAndroid Build Coastguard Worker        .build());
82*30877f79SAndroid Build Coastguard Worker~~~
83*30877f79SAndroid Build Coastguard Worker{: .language-java}
84*30877f79SAndroid Build Coastguard Worker
85*30877f79SAndroid Build Coastguard Worker### Constraint based track selection
86*30877f79SAndroid Build Coastguard Worker
87*30877f79SAndroid Build Coastguard WorkerMost options in `TrackSelectionParameters` allow you to specify constraints,
88*30877f79SAndroid Build Coastguard Workerwhich are independent of the tracks that are actually available. Typical
89*30877f79SAndroid Build Coastguard Workerconstraints are:
90*30877f79SAndroid Build Coastguard Worker
91*30877f79SAndroid Build Coastguard Worker * Maximum or minimum video width, height, frame rate, or bitrate.
92*30877f79SAndroid Build Coastguard Worker * Maximum audio channel count or bitrate.
93*30877f79SAndroid Build Coastguard Worker * Preferred MIME types for video or audio.
94*30877f79SAndroid Build Coastguard Worker * Preferred audio languages or role flags.
95*30877f79SAndroid Build Coastguard Worker * Preferred text languages or role flags.
96*30877f79SAndroid Build Coastguard Worker
97*30877f79SAndroid Build Coastguard WorkerNote that ExoPlayer already applies sensible defaults for most of these values,
98*30877f79SAndroid Build Coastguard Workerfor example restricting video resolution to the display size or preferring the
99*30877f79SAndroid Build Coastguard Workeraudio language that matches the user's system Locale setting.
100*30877f79SAndroid Build Coastguard Worker
101*30877f79SAndroid Build Coastguard WorkerThere are several benefits to using constraint based track selection instead of
102*30877f79SAndroid Build Coastguard Workerspecifying specific tracks directly:
103*30877f79SAndroid Build Coastguard Worker
104*30877f79SAndroid Build Coastguard Worker* You can specify constraints before knowing what tracks the media provides.
105*30877f79SAndroid Build Coastguard Worker  This allows to immediately select the appropriate tracks for faster startup
106*30877f79SAndroid Build Coastguard Worker  time and also simplifies track selection code as you don't have to listen for
107*30877f79SAndroid Build Coastguard Worker  changes in the available tracks.
108*30877f79SAndroid Build Coastguard Worker* Constraints can be applied consistently across all items in a playlist. For
109*30877f79SAndroid Build Coastguard Worker  example, selecting an audio language based on user preference will
110*30877f79SAndroid Build Coastguard Worker  automatically apply to the next playlist item too, whereas overriding a
111*30877f79SAndroid Build Coastguard Worker  specific track will only apply to the current playlist item for which the
112*30877f79SAndroid Build Coastguard Worker  track exists.
113*30877f79SAndroid Build Coastguard Worker
114*30877f79SAndroid Build Coastguard Worker### Selecting specific tracks
115*30877f79SAndroid Build Coastguard Worker
116*30877f79SAndroid Build Coastguard WorkerIt's possible to specify in `TrackSelectionParameters` which of the currently
117*30877f79SAndroid Build Coastguard Workeravailable tracks should be selected. First, the player's currently available
118*30877f79SAndroid Build Coastguard Workertracks should be queried using `Player.getTracksInfo`. Second, having identified
119*30877f79SAndroid Build Coastguard Workerwhich tracks to select, they can be set on `TrackSelectionParameters` using
120*30877f79SAndroid Build Coastguard Worker`TrackSelectionOverrides`. For example, to select the first track from a
121*30877f79SAndroid Build Coastguard Workerspecific `audioTrackGroup`:
122*30877f79SAndroid Build Coastguard Worker
123*30877f79SAndroid Build Coastguard Worker~~~
124*30877f79SAndroid Build Coastguard Workerplayer.setTrackSelectionParameters(
125*30877f79SAndroid Build Coastguard Worker    player.getTrackSelectionParameters()
126*30877f79SAndroid Build Coastguard Worker        .buildUpon()
127*30877f79SAndroid Build Coastguard Worker        .setOverrideForType(
128*30877f79SAndroid Build Coastguard Worker            new TrackSelectionOverride(audioTrackGroup, /* trackIndex= */ 0))
129*30877f79SAndroid Build Coastguard Worker        .build());
130*30877f79SAndroid Build Coastguard Worker~~~
131*30877f79SAndroid Build Coastguard Worker{: .language-java}
132*30877f79SAndroid Build Coastguard Worker
133*30877f79SAndroid Build Coastguard WorkerNote that a `TrackSelectionOverride` will only apply to media items that contain
134*30877f79SAndroid Build Coastguard Workerthe `TrackGroup` specified in the override. Hence an override may not apply to
135*30877f79SAndroid Build Coastguard Workera subsequent media item if that item contains different tracks.
136*30877f79SAndroid Build Coastguard Worker
137*30877f79SAndroid Build Coastguard Worker### Disabling track types or groups
138*30877f79SAndroid Build Coastguard Worker
139*30877f79SAndroid Build Coastguard WorkerTrack types, like video, audio or text, can be disabled completely using
140*30877f79SAndroid Build Coastguard Worker`TrackSelectionParameters.Builder.setTrackTypeDisabled`. A disabled track type
141*30877f79SAndroid Build Coastguard Workerwill be disabled for all media items:
142*30877f79SAndroid Build Coastguard Worker
143*30877f79SAndroid Build Coastguard Worker~~~
144*30877f79SAndroid Build Coastguard Workerplayer.setTrackSelectionParameters(
145*30877f79SAndroid Build Coastguard Worker    player.getTrackSelectionParameters()
146*30877f79SAndroid Build Coastguard Worker        .buildUpon()
147*30877f79SAndroid Build Coastguard Worker        .setTrackTypeDisabled(C.TRACK_TYPE_VIDEO, /* disabled= */ true)
148*30877f79SAndroid Build Coastguard Worker        .build());
149*30877f79SAndroid Build Coastguard Worker~~~
150*30877f79SAndroid Build Coastguard Worker{: .language-java}
151*30877f79SAndroid Build Coastguard Worker
152*30877f79SAndroid Build Coastguard WorkerAlternatively, it's possible to prevent the selection of tracks from a specific
153*30877f79SAndroid Build Coastguard Worker`TrackGroup` by specifying an empty override for that group:
154*30877f79SAndroid Build Coastguard Worker
155*30877f79SAndroid Build Coastguard Worker~~~
156*30877f79SAndroid Build Coastguard Workerplayer.setTrackSelectionParameters(
157*30877f79SAndroid Build Coastguard Worker    player.getTrackSelectionParameters()
158*30877f79SAndroid Build Coastguard Worker        .buildUpon()
159*30877f79SAndroid Build Coastguard Worker        .addOverride(
160*30877f79SAndroid Build Coastguard Worker            new TrackSelectionOverride(
161*30877f79SAndroid Build Coastguard Worker                disabledTrackGroup, ImmutableList.of()))
162*30877f79SAndroid Build Coastguard Worker        .build());
163*30877f79SAndroid Build Coastguard Worker~~~
164*30877f79SAndroid Build Coastguard Worker{: .language-java}
165*30877f79SAndroid Build Coastguard Worker
166*30877f79SAndroid Build Coastguard Worker## Customizing the track selector
167*30877f79SAndroid Build Coastguard Worker
168*30877f79SAndroid Build Coastguard WorkerTrack selection is the responsibility of a `TrackSelector`, an instance
169*30877f79SAndroid Build Coastguard Workerof which can be provided whenever an `ExoPlayer` is built and later obtained
170*30877f79SAndroid Build Coastguard Workerwith `ExoPlayer.getTrackSelector()`.
171*30877f79SAndroid Build Coastguard Worker
172*30877f79SAndroid Build Coastguard Worker~~~
173*30877f79SAndroid Build Coastguard WorkerDefaultTrackSelector trackSelector = new DefaultTrackSelector(context);
174*30877f79SAndroid Build Coastguard WorkerExoPlayer player =
175*30877f79SAndroid Build Coastguard Worker    new ExoPlayer.Builder(context)
176*30877f79SAndroid Build Coastguard Worker        .setTrackSelector(trackSelector)
177*30877f79SAndroid Build Coastguard Worker        .build();
178*30877f79SAndroid Build Coastguard Worker~~~
179*30877f79SAndroid Build Coastguard Worker{: .language-java}
180*30877f79SAndroid Build Coastguard Worker
181*30877f79SAndroid Build Coastguard Worker`DefaultTrackSelector` is a flexible `TrackSelector` suitable for most use
182*30877f79SAndroid Build Coastguard Workercases. It uses the `TrackSelectionParameters` set in the `Player`, but also
183*30877f79SAndroid Build Coastguard Workerprovides some advanced customization options that can be specified in the
184*30877f79SAndroid Build Coastguard Worker`DefaultTrackSelector.ParametersBuilder`:
185*30877f79SAndroid Build Coastguard Worker
186*30877f79SAndroid Build Coastguard Worker~~~
187*30877f79SAndroid Build Coastguard WorkertrackSelector.setParameters(
188*30877f79SAndroid Build Coastguard Worker    trackSelector
189*30877f79SAndroid Build Coastguard Worker        .buildUponParameters()
190*30877f79SAndroid Build Coastguard Worker        .setAllowVideoMixedMimeTypeAdaptiveness(true));
191*30877f79SAndroid Build Coastguard Worker~~~
192*30877f79SAndroid Build Coastguard Worker{: .language-java}
193*30877f79SAndroid Build Coastguard Worker
194*30877f79SAndroid Build Coastguard Worker### Tunneling
195*30877f79SAndroid Build Coastguard Worker
196*30877f79SAndroid Build Coastguard WorkerTunneled playback can be enabled in cases where the combination of renderers and
197*30877f79SAndroid Build Coastguard Workerselected tracks supports it. This can be done by using
198*30877f79SAndroid Build Coastguard Worker`DefaultTrackSelector.ParametersBuilder.setTunnelingEnabled(true)`.
199*30877f79SAndroid Build Coastguard Worker
200*30877f79SAndroid Build Coastguard Worker[`TrackSelectionParameters`]: {{ site.exo_sdk }}/trackselection/TrackSelectionParameters.html
201