ExoPlayer module that provides the core ExoPlayer implementation for local media playback on Android, supporting various media formats and streaming protocols
—
Track selection in ExoPlayer determines which tracks (audio, video, text) are selected for playback from the available options. The DefaultTrackSelector provides adaptive capabilities for automatic track selection based on device capabilities and network conditions.
The abstract base class for all track selectors.
public abstract class TrackSelector {
/**
* Initializes the track selector.
*
* @param listener The InvalidationListener
* @param bandwidthMeter The BandwidthMeter
*/
public final void init(InvalidationListener listener, BandwidthMeter bandwidthMeter);
/**
* Selects tracks for the given mapped track info.
*
* @param mappedTrackInfo The mapped track info
* @param rendererCapabilities The renderer capabilities
* @param mediaPeriodId The media period ID
* @param timeline The timeline
* @return The track selection result
* @throws ExoPlaybackException If track selection fails
*/
public abstract TrackSelectorResult selectTracks(MappedTrackInfo mappedTrackInfo,
RendererCapabilities[] rendererCapabilities,
MediaPeriodId mediaPeriodId,
Timeline timeline) throws ExoPlaybackException;
/**
* Called when track selections are activated.
*
* @param info The track info
* @param mediaPeriodId The media period ID
*/
public void onSelectionActivated(Object info, MediaPeriodId mediaPeriodId);
/**
* Releases the track selector.
*/
public void release();
/**
* Returns the current parameters.
*
* @return The current parameters
*/
public abstract TrackSelectionParameters getParameters();
/**
* Sets new parameters.
*
* @param parameters The new parameters
*/
public abstract void setParameters(TrackSelectionParameters parameters);
/**
* Returns whether parameter setting is supported.
*
* @return Whether parameter setting is supported
*/
public abstract boolean isSetParametersSupported();
}The default track selector with adaptive capabilities and extensive configuration options.
public class DefaultTrackSelector extends MappingTrackSelector {
/**
* Builder for DefaultTrackSelector.
*/
public static final class Builder {
/**
* Creates a builder.
*
* @param context The context
*/
public Builder(Context context);
/**
* Sets whether to force the lowest bitrate.
*
* @param forceLowestBitrate Whether to force lowest bitrate
* @return This builder
*/
public Builder setForceLowestBitrate(boolean forceLowestBitrate);
/**
* Sets whether to force the highest supported bitrate.
*
* @param forceHighestSupportedBitrate Whether to force highest supported bitrate
* @return This builder
*/
public Builder setForceHighestSupportedBitrate(boolean forceHighestSupportedBitrate);
/**
* Sets whether tunneling is enabled.
*
* @param tunnelingEnabled Whether tunneling is enabled
* @return This builder
*/
public Builder setTunnelingEnabled(boolean tunnelingEnabled);
/**
* Builds the DefaultTrackSelector.
*
* @return The built DefaultTrackSelector
*/
public DefaultTrackSelector build();
}
/**
* Sets the parameters for track selection.
*
* @param parameters The parameters
*/
public void setParameters(Parameters parameters);
/**
* Gets the current parameters.
*
* @return The current parameters
*/
public Parameters getParameters();
/**
* Creates a parameters builder based on current parameters.
*
* @return A parameters builder
*/
public Parameters.Builder buildUponParameters();
/**
* Gets information about currently mapped tracks.
*
* @return The mapped track info, or null if not available
*/
@Nullable public MappedTrackInfo getCurrentMappedTrackInfo();
}Configuration parameters for track selection behavior.
public static final class Parameters extends TrackSelectionParameters {
/**
* Builder for Parameters.
*/
public static final class Builder extends TrackSelectionParameters.Builder {
/**
* Creates a builder.
*
* @param context The context
*/
public Builder(Context context);
/**
* Creates a builder from existing parameters.
*
* @param initialValues The initial parameter values
*/
public Builder(Parameters initialValues);
// Video parameters
public Builder setMaxVideoSizeSd();
public Builder clearVideoSizeConstraints();
public Builder setMaxVideoSize(int maxVideoWidth, int maxVideoHeight);
public Builder setMaxVideoFrameRate(int maxVideoFrameRate);
public Builder setMaxVideoBitrate(int maxVideoBitrate);
public Builder setMinVideoSize(int minVideoWidth, int minVideoHeight);
public Builder setMinVideoFrameRate(int minVideoFrameRate);
public Builder setMinVideoBitrate(int minVideoBitrate);
public Builder setViewportSizeToPhysicalDisplaySize(Context context, boolean viewportOrientationMayChange);
public Builder clearViewportSizeConstraints();
public Builder setViewportSize(int viewportWidth, int viewportHeight, boolean viewportOrientationMayChange);
public Builder setPreferredVideoMimeType(@Nullable String mimeType);
public Builder setPreferredVideoMimeTypes(String... mimeTypes);
public Builder setPreferredVideoRoleFlags(@C.RoleFlags int preferredVideoRoleFlags);
// Audio parameters
public Builder setMaxAudioChannelCount(int maxAudioChannelCount);
public Builder setMaxAudioBitrate(int maxAudioBitrate);
public Builder setPreferredAudioLanguage(@Nullable String preferredAudioLanguage);
public Builder setPreferredAudioLanguages(String... preferredAudioLanguages);
public Builder setPreferredAudioMimeType(@Nullable String mimeType);
public Builder setPreferredAudioMimeTypes(String... mimeTypes);
public Builder setPreferredAudioRoleFlags(@C.RoleFlags int preferredAudioRoleFlags);
// Text parameters
public Builder setPreferredTextLanguage(@Nullable String preferredTextLanguage);
public Builder setPreferredTextLanguages(String... preferredTextLanguages);
public Builder setPreferredTextRoleFlags(@C.RoleFlags int preferredTextRoleFlags);
public Builder setIgnoredTextSelectionFlags(@C.SelectionFlags int ignoredTextSelectionFlags);
public Builder setSelectUndeterminedTextLanguage(boolean selectUndeterminedTextLanguage);
// General parameters
public Builder setForceLowestBitrate(boolean forceLowestBitrate);
public Builder setForceHighestSupportedBitrate(boolean forceHighestSupportedBitrate);
public Builder addOverride(TrackSelectionOverride override);
public Builder setOverrideForType(TrackSelectionOverride override);
public Builder clearOverride(TrackGroup trackGroup);
public Builder clearOverridesOfType(@C.TrackType int trackType);
public Builder setDisabledTrackTypes(Set<Integer> disabledTrackTypes);
public Builder setTrackTypeDisabled(@C.TrackType int trackType, boolean disabled);
public Builder setTunnelingEnabled(boolean tunnelingEnabled);
public Builder setAllowMultipleAdaptiveSelections(boolean allowMultipleAdaptiveSelections);
/**
* Builds the Parameters.
*
* @return The built Parameters
*/
public Parameters build();
}
// Video constraints
public final int maxVideoWidth;
public final int maxVideoHeight;
public final int maxVideoFrameRate;
public final int maxVideoBitrate;
public final int minVideoWidth;
public final int minVideoHeight;
public final int minVideoFrameRate;
public final int minVideoBitrate;
public final int viewportWidth;
public final int viewportHeight;
public final boolean viewportOrientationMayChange;
public final ImmutableList<String> preferredVideoMimeTypes;
@C.RoleFlags public final int preferredVideoRoleFlags;
// Audio constraints
public final int maxAudioChannelCount;
public final int maxAudioBitrate;
public final ImmutableList<String> preferredAudioLanguages;
public final ImmutableList<String> preferredAudioMimeTypes;
@C.RoleFlags public final int preferredAudioRoleFlags;
// Text constraints
public final ImmutableList<String> preferredTextLanguages;
@C.RoleFlags public final int preferredTextRoleFlags;
@C.SelectionFlags public final int ignoredTextSelectionFlags;
public final boolean selectUndeterminedTextLanguage;
// General selection constraints
public final boolean forceLowestBitrate;
public final boolean forceHighestSupportedBitrate;
public final ImmutableMap<TrackGroup, TrackSelectionOverride> overrides;
public final ImmutableSet<Integer> disabledTrackTypes;
public final boolean tunnelingEnabled;
public final boolean allowMultipleAdaptiveSelections;
}Interface for track selections with ExoPlayer-specific functionality.
public interface ExoTrackSelection extends TrackSelection {
/**
* Called when the selection is enabled.
*
* @param mediaPeriodId The media period ID
* @param positionUs The position in microseconds
*/
void enable();
/**
* Called when playback starts.
*/
void start();
/**
* Called when the playback speed changes.
*
* @param playbackSpeed The new playback speed
*/
void onPlaybackSpeed(float playbackSpeed);
/**
* Updates the selected track for the current playback position.
*
* @param playbackPositionUs The playback position in microseconds
* @param bufferedDurationUs The buffered duration in microseconds
* @param availableDurationUs The available duration in microseconds
* @param queue The queue of loaded media chunks
* @param mediaChunkIterators Iterators for obtaining future chunks
*/
void updateSelectedTrack(long playbackPositionUs, long bufferedDurationUs, long availableDurationUs,
List<? extends MediaChunk> queue, MediaChunkIterator[] mediaChunkIterators);
/**
* Returns whether ongoing loads should be canceled.
*
* @param playbackPositionUs The playback position in microseconds
* @param loadingChunk The currently loading chunk
* @param queue The queue of loaded chunks
* @return Whether to cancel the load
*/
boolean shouldCancelChunkLoad(long playbackPositionUs, Chunk loadingChunk, List<? extends MediaChunk> queue);
/**
* Blacklists a track for the specified duration.
*
* @param trackIndex The index of the track to blacklist
* @param blacklistDurationMs The blacklist duration in milliseconds
*/
boolean blacklist(int trackIndex, long blacklistDurationMs);
/**
* Returns the latest bitrate estimate.
*
* @return The bitrate estimate in bits per second
*/
long getLatestBitrateEstimate();
}// Create default track selector
DefaultTrackSelector trackSelector = new DefaultTrackSelector.Builder(context).build();
// Use with ExoPlayer
ExoPlayer player = new ExoPlayer.Builder(context)
.setTrackSelector(trackSelector)
.build();DefaultTrackSelector trackSelector = new DefaultTrackSelector.Builder(context).build();
// Configure parameters
DefaultTrackSelector.Parameters.Builder parametersBuilder = trackSelector.buildUponParameters();
// Video constraints
parametersBuilder
.setMaxVideoSizeSd() // Limit to SD resolution
.setMaxVideoBitrate(2_000_000) // 2 Mbps max
.setPreferredVideoMimeType(MimeTypes.VIDEO_H264); // Prefer H.264
// Audio constraints
parametersBuilder
.setMaxAudioChannelCount(2) // Stereo max
.setPreferredAudioLanguage("en") // Prefer English
.setMaxAudioBitrate(128_000); // 128 kbps max
// Text constraints
parametersBuilder
.setPreferredTextLanguage("en") // Prefer English subtitles
.setSelectUndeterminedTextLanguage(false); // Don't select undetermined language
// Apply parameters
trackSelector.setParameters(parametersBuilder.build());// Get mapped track info
MappedTrackInfo mappedTrackInfo = trackSelector.getCurrentMappedTrackInfo();
if (mappedTrackInfo != null) {
// Find video renderer
for (int rendererIndex = 0; rendererIndex < mappedTrackInfo.getRendererCount(); rendererIndex++) {
if (mappedTrackInfo.getRendererType(rendererIndex) == C.TRACK_TYPE_VIDEO) {
TrackGroupArray trackGroups = mappedTrackInfo.getTrackGroups(rendererIndex);
// Create override for specific track
TrackGroup trackGroup = trackGroups.get(0); // First track group
List<Integer> trackIndices = Arrays.asList(0); // First track in group
TrackSelectionOverride override = new TrackSelectionOverride(trackGroup, trackIndices);
// Apply override
DefaultTrackSelector.Parameters newParameters = trackSelector.buildUponParameters()
.setOverrideForType(override)
.build();
trackSelector.setParameters(newParameters);
break;
}
}
}// Force lowest bitrate (for testing or poor network)
DefaultTrackSelector.Parameters lowBitrateParams = trackSelector.buildUponParameters()
.setForceLowestBitrate(true)
.build();
trackSelector.setParameters(lowBitrateParams);
// Force highest supported bitrate
DefaultTrackSelector.Parameters highBitrateParams = trackSelector.buildUponParameters()
.setForceHighestSupportedBitrate(true)
.build();
trackSelector.setParameters(highBitrateParams);
// Custom constraints
DefaultTrackSelector.Parameters customParams = trackSelector.buildUponParameters()
.setMaxVideoBitrate(1_000_000) // 1 Mbps max
.setMinVideoBitrate(500_000) // 500 kbps min
.build();
trackSelector.setParameters(customParams);DefaultTrackSelector.Parameters params = trackSelector.buildUponParameters()
// Multiple preferred audio languages (in order of preference)
.setPreferredAudioLanguages("en", "es", "fr")
// Multiple preferred text languages
.setPreferredTextLanguages("en", "es")
// Prefer audio descriptions for accessibility
.setPreferredAudioRoleFlags(C.ROLE_FLAG_DESCRIBES_VIDEO)
// Prefer SDH subtitles
.setPreferredTextRoleFlags(C.ROLE_FLAG_DESCRIBES_MUSIC_AND_SOUND)
.build();
trackSelector.setParameters(params);// Disable text tracks (subtitles/captions)
DefaultTrackSelector.Parameters noTextParams = trackSelector.buildUponParameters()
.setTrackTypeDisabled(C.TRACK_TYPE_TEXT, true)
.build();
trackSelector.setParameters(noTextParams);
// Disable multiple track types
Set<Integer> disabledTypes = new HashSet<>();
disabledTypes.add(C.TRACK_TYPE_TEXT);
disabledTypes.add(C.TRACK_TYPE_METADATA);
DefaultTrackSelector.Parameters params = trackSelector.buildUponParameters()
.setDisabledTrackTypes(disabledTypes)
.build();
trackSelector.setParameters(params);// Set viewport size for adaptive selection
DefaultTrackSelector.Parameters params = trackSelector.buildUponParameters()
.setViewportSizeToPhysicalDisplaySize(context, true) // Use device display size
.build();
trackSelector.setParameters(params);
// Custom viewport size
DefaultTrackSelector.Parameters customViewportParams = trackSelector.buildUponParameters()
.setViewportSize(1920, 1080, false) // 1080p viewport
.build();
trackSelector.setParameters(customViewportParams);Install with Tessl CLI
npx tessl i tessl/maven-androidx-media3--media3-exoplayer