public abstract class

TrackSelector

extends java.lang.Object

 java.lang.Object

↳androidx.media3.exoplayer.trackselection.TrackSelector

Subclasses:

DefaultTrackSelector, MappingTrackSelector, FakeTrackSelector

Gradle dependencies

compile group: 'androidx.media3', name: 'media3-exoplayer', version: '1.5.0-alpha01'

  • groupId: androidx.media3
  • artifactId: media3-exoplayer
  • version: 1.5.0-alpha01

Artifact androidx.media3:media3-exoplayer:1.5.0-alpha01 it located at Google repository (https://maven.google.com/)

Overview

The component of an ExoPlayer responsible for selecting tracks to be consumed by each of the player's Renderers. The DefaultTrackSelector implementation should be suitable for most use cases.

Interactions with the player

The following interactions occur between the player and its track selector during playback.
  • When the player is created it will initialize the track selector by calling TrackSelector.init(TrackSelector.InvalidationListener, BandwidthMeter).
  • When the player needs to make a track selection it will call TrackSelector. This typically occurs at the start of playback, when the player starts to buffer a new period of the media being played, and when the track selector invalidates its previous selections.
  • The player may perform a track selection well in advance of the selected tracks becoming active, where active is defined to mean that the renderers are actually consuming media corresponding to the selection that was made. For example when playing media containing multiple periods, the track selection for a period is made when the player starts to buffer that period. Hence if the player's buffering policy is to maintain a 30 second buffer, the selection will occur approximately 30 seconds in advance of it becoming active. In fact the selection may never become active, for example if the user seeks to some other period of the media during the 30 second gap. The player indicates to the track selector when a selection it has previously made becomes active by calling TrackSelector.onSelectionActivated(Object).
  • If the track selector wishes to indicate to the player that selections it has previously made are invalid, it can do so by calling TrackSelector.InvalidationListener.onTrackSelectionsInvalidated() on the TrackSelector.InvalidationListener that was passed to TrackSelector.init(TrackSelector.InvalidationListener, BandwidthMeter). A track selector may wish to do this if its configuration has changed, for example if it now wishes to prefer audio tracks in a particular language. This will trigger the player to make new track selections. Note that the player will have to re-buffer in the case that the new track selection for the currently playing period differs from the one that was invalidated. Implementing subclasses can trigger invalidation by calling TrackSelector.invalidate(), which will call TrackSelector.InvalidationListener.onTrackSelectionsInvalidated().
  • When the player is released, it will release the track selector by calling TrackSelector.release().

Renderer configuration

The TrackSelectorResult returned by TrackSelector contains not only TrackSelections for each renderer, but also RendererConfigurations defining configuration parameters that the renderers should apply when consuming the corresponding media. Whilst it may seem counter- intuitive for a track selector to also specify renderer configuration information, in practice the two are tightly bound together. It may only be possible to play a certain combination tracks if the renderers are configured in a particular way. Equally, it may only be possible to configure renderers in a particular way if certain tracks are selected. Hence it makes sense to determine the track selection and corresponding renderer configurations in a single step.

Threading model

All calls made by the player into the track selector are on the player's internal playback thread. The track selector may call TrackSelector.InvalidationListener.onTrackSelectionsInvalidated() from any thread.

Summary

Constructors
publicTrackSelector()

Methods
protected final BandwidthMetergetBandwidthMeter()

Returns a bandwidth meter which can be used by track selections to select tracks.

public TrackSelectionParametersgetParameters()

Returns the current parameters for track selection.

public RendererCapabilities.ListenergetRendererCapabilitiesListener()

Returns the that the concrete instance uses to listen to the renderer capabilities changes.

public voidinit(TrackSelector.InvalidationListener listener, BandwidthMeter bandwidthMeter)

Called by the player to initialize the selector.

protected final voidinvalidate()

Calls TrackSelector.InvalidationListener.onTrackSelectionsInvalidated() to invalidate all previously generated track selections.

protected final voidinvalidateForRendererCapabilitiesChange(Renderer renderer)

Calls TrackSelector.InvalidationListener.onRendererCapabilitiesChanged(Renderer) to invalidate all previously generated track selections because a renderer's capabilities have changed.

public booleanisSetParametersSupported()

Returns if this TrackSelector supports TrackSelector.setParameters(TrackSelectionParameters).

public abstract voidonSelectionActivated(java.lang.Object info)

Called by the player when a TrackSelectorResult previously generated by TrackSelector is activated.

public voidrelease()

Called by the player to release the selector.

public abstract TrackSelectorResultselectTracks(RendererCapabilities rendererCapabilities[], TrackGroupArray trackGroups, MediaSource.MediaPeriodId periodId, Timeline timeline)

Called by the player to perform a track selection.

public voidsetAudioAttributes(AudioAttributes audioAttributes)

Called by the player to set the AudioAttributes that will be used for playback.

public voidsetParameters(TrackSelectionParameters parameters)

Called by the player to provide parameters for track selection.

from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Constructors

public TrackSelector()

Methods

public void init(TrackSelector.InvalidationListener listener, BandwidthMeter bandwidthMeter)

Called by the player to initialize the selector.

Parameters:

listener: An invalidation listener that the selector can call to indicate that selections it has previously made are no longer valid.
bandwidthMeter: A bandwidth meter which can be used by track selections to select tracks.

public void release()

Called by the player to release the selector. The selector cannot be used until TrackSelector.init(TrackSelector.InvalidationListener, BandwidthMeter) is called again.

public abstract TrackSelectorResult selectTracks(RendererCapabilities rendererCapabilities[], TrackGroupArray trackGroups, MediaSource.MediaPeriodId periodId, Timeline timeline)

Called by the player to perform a track selection.

Parameters:

rendererCapabilities: The RendererCapabilities of the renderers for which tracks are to be selected.
trackGroups: The available track groups.
periodId: The MediaSource.MediaPeriodId of the period for which tracks are to be selected.
timeline: The Timeline holding the period for which tracks are to be selected.

Returns:

A TrackSelectorResult describing the track selections.

public abstract void onSelectionActivated(java.lang.Object info)

Called by the player when a TrackSelectorResult previously generated by TrackSelector is activated.

Parameters:

info: The value of TrackSelectorResult.info in the activated selection.

public TrackSelectionParameters getParameters()

Returns the current parameters for track selection.

public void setParameters(TrackSelectionParameters parameters)

Called by the player to provide parameters for track selection.

Only supported if TrackSelector.isSetParametersSupported() returns true.

Parameters:

parameters: The parameters for track selection.

public boolean isSetParametersSupported()

Returns if this TrackSelector supports TrackSelector.setParameters(TrackSelectionParameters).

The same value is always returned for a given TrackSelector instance.

public void setAudioAttributes(AudioAttributes audioAttributes)

Called by the player to set the AudioAttributes that will be used for playback.

public RendererCapabilities.Listener getRendererCapabilitiesListener()

Returns the that the concrete instance uses to listen to the renderer capabilities changes. May be null if the implementation does not listen to the renderer capabilities changes.

protected final void invalidate()

Calls TrackSelector.InvalidationListener.onTrackSelectionsInvalidated() to invalidate all previously generated track selections.

protected final void invalidateForRendererCapabilitiesChange(Renderer renderer)

Calls TrackSelector.InvalidationListener.onRendererCapabilitiesChanged(Renderer) to invalidate all previously generated track selections because a renderer's capabilities have changed.

Parameters:

renderer: The renderer whose capabilities changed.

protected final BandwidthMeter getBandwidthMeter()

Returns a bandwidth meter which can be used by track selections to select tracks. Must only be called when the track selector is initialized.

Source

/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package androidx.media3.exoplayer.trackselection;

import static androidx.media3.common.util.Assertions.checkStateNotNull;

import androidx.annotation.CallSuper;
import androidx.annotation.Nullable;
import androidx.media3.common.AudioAttributes;
import androidx.media3.common.Player;
import androidx.media3.common.Timeline;
import androidx.media3.common.TrackSelectionParameters;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.exoplayer.ExoPlaybackException;
import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.exoplayer.Renderer;
import androidx.media3.exoplayer.RendererCapabilities;
import androidx.media3.exoplayer.RendererConfiguration;
import androidx.media3.exoplayer.source.MediaSource.MediaPeriodId;
import androidx.media3.exoplayer.source.TrackGroupArray;
import androidx.media3.exoplayer.upstream.BandwidthMeter;

/**
 * The component of an {@link ExoPlayer} responsible for selecting tracks to be consumed by each of
 * the player's {@link Renderer}s. The {@link DefaultTrackSelector} implementation should be
 * suitable for most use cases.
 *
 * <h2>Interactions with the player</h2>
 *
 * The following interactions occur between the player and its track selector during playback.
 *
 * <ul>
 *   <li>When the player is created it will initialize the track selector by calling {@link
 *       #init(InvalidationListener, BandwidthMeter)}.
 *   <li>When the player needs to make a track selection it will call {@link
 *       #selectTracks(RendererCapabilities[], TrackGroupArray, MediaPeriodId, Timeline)}. This
 *       typically occurs at the start of playback, when the player starts to buffer a new period of
 *       the media being played, and when the track selector invalidates its previous selections.
 *   <li>The player may perform a track selection well in advance of the selected tracks becoming
 *       active, where active is defined to mean that the renderers are actually consuming media
 *       corresponding to the selection that was made. For example when playing media containing
 *       multiple periods, the track selection for a period is made when the player starts to buffer
 *       that period. Hence if the player's buffering policy is to maintain a 30 second buffer, the
 *       selection will occur approximately 30 seconds in advance of it becoming active. In fact the
 *       selection may never become active, for example if the user seeks to some other period of
 *       the media during the 30 second gap. The player indicates to the track selector when a
 *       selection it has previously made becomes active by calling {@link
 *       #onSelectionActivated(Object)}.
 *   <li>If the track selector wishes to indicate to the player that selections it has previously
 *       made are invalid, it can do so by calling {@link
 *       InvalidationListener#onTrackSelectionsInvalidated()} on the {@link InvalidationListener}
 *       that was passed to {@link #init(InvalidationListener, BandwidthMeter)}. A track selector
 *       may wish to do this if its configuration has changed, for example if it now wishes to
 *       prefer audio tracks in a particular language. This will trigger the player to make new
 *       track selections. Note that the player will have to re-buffer in the case that the new
 *       track selection for the currently playing period differs from the one that was invalidated.
 *       Implementing subclasses can trigger invalidation by calling {@link #invalidate()}, which
 *       will call {@link InvalidationListener#onTrackSelectionsInvalidated()}.
 *   <li>When the player is {@linkplain Player#release() released}, it will release the track
 *       selector by calling {@link #release()}.
 * </ul>
 *
 * <h2>Renderer configuration</h2>
 *
 * The {@link TrackSelectorResult} returned by {@link #selectTracks(RendererCapabilities[],
 * TrackGroupArray, MediaPeriodId, Timeline)} contains not only {@link TrackSelection}s for each
 * renderer, but also {@link RendererConfiguration}s defining configuration parameters that the
 * renderers should apply when consuming the corresponding media. Whilst it may seem counter-
 * intuitive for a track selector to also specify renderer configuration information, in practice
 * the two are tightly bound together. It may only be possible to play a certain combination tracks
 * if the renderers are configured in a particular way. Equally, it may only be possible to
 * configure renderers in a particular way if certain tracks are selected. Hence it makes sense to
 * determine the track selection and corresponding renderer configurations in a single step.
 *
 * <h2>Threading model</h2>
 *
 * All calls made by the player into the track selector are on the player's internal playback
 * thread. The track selector may call {@link InvalidationListener#onTrackSelectionsInvalidated()}
 * from any thread.
 */
@UnstableApi
public abstract class TrackSelector {

  /** Notified when selections previously made by a {@link TrackSelector} are no longer valid. */
  public interface InvalidationListener {

    /**
     * Called by a {@link TrackSelector} to indicate that selections it has previously made are no
     * longer valid. May be called from any thread.
     */
    void onTrackSelectionsInvalidated();

    /**
     * Called by a {@link TrackSelector} to indicate that selections it has previously made may no
     * longer be valid due to the renderer capabilities change. This method is called from playback
     * thread.
     *
     * @param renderer The renderer whose capabilities changed.
     */
    default void onRendererCapabilitiesChanged(Renderer renderer) {}
  }

  @Nullable private InvalidationListener listener;
  @Nullable private BandwidthMeter bandwidthMeter;

  /**
   * Called by the player to initialize the selector.
   *
   * @param listener An invalidation listener that the selector can call to indicate that selections
   *     it has previously made are no longer valid.
   * @param bandwidthMeter A bandwidth meter which can be used by track selections to select tracks.
   */
  @CallSuper
  public void init(InvalidationListener listener, BandwidthMeter bandwidthMeter) {
    this.listener = listener;
    this.bandwidthMeter = bandwidthMeter;
  }

  /**
   * Called by the player to release the selector. The selector cannot be used until {@link
   * #init(InvalidationListener, BandwidthMeter)} is called again.
   */
  @CallSuper
  public void release() {
    listener = null;
    bandwidthMeter = null;
  }

  /**
   * Called by the player to perform a track selection.
   *
   * @param rendererCapabilities The {@link RendererCapabilities} of the renderers for which tracks
   *     are to be selected.
   * @param trackGroups The available track groups.
   * @param periodId The {@link MediaPeriodId} of the period for which tracks are to be selected.
   * @param timeline The {@link Timeline} holding the period for which tracks are to be selected.
   * @return A {@link TrackSelectorResult} describing the track selections.
   * @throws ExoPlaybackException If an error occurs selecting tracks.
   */
  public abstract TrackSelectorResult selectTracks(
      RendererCapabilities[] rendererCapabilities,
      TrackGroupArray trackGroups,
      MediaPeriodId periodId,
      Timeline timeline)
      throws ExoPlaybackException;

  /**
   * Called by the player when a {@link TrackSelectorResult} previously generated by {@link
   * #selectTracks(RendererCapabilities[], TrackGroupArray, MediaPeriodId, Timeline)} is activated.
   *
   * @param info The value of {@link TrackSelectorResult#info} in the activated selection.
   */
  public abstract void onSelectionActivated(@Nullable Object info);

  /** Returns the current parameters for track selection. */
  public TrackSelectionParameters getParameters() {
    return TrackSelectionParameters.DEFAULT_WITHOUT_CONTEXT;
  }

  /**
   * Called by the player to provide parameters for track selection.
   *
   * <p>Only supported if {@link #isSetParametersSupported()} returns true.
   *
   * @param parameters The parameters for track selection.
   */
  public void setParameters(TrackSelectionParameters parameters) {
    // Default implementation doesn't support this method.
  }

  /**
   * Returns if this {@code TrackSelector} supports {@link
   * #setParameters(TrackSelectionParameters)}.
   *
   * <p>The same value is always returned for a given {@code TrackSelector} instance.
   */
  public boolean isSetParametersSupported() {
    return false;
  }

  /** Called by the player to set the {@link AudioAttributes} that will be used for playback. */
  public void setAudioAttributes(AudioAttributes audioAttributes) {
    // Default implementation is no-op.
  }

  /**
   * Returns the {@link RendererCapabilities.Listener} that the concrete instance uses to listen to
   * the renderer capabilities changes. May be {@code null} if the implementation does not listen to
   * the renderer capabilities changes.
   */
  @Nullable
  public RendererCapabilities.Listener getRendererCapabilitiesListener() {
    return null;
  }

  /**
   * Calls {@link InvalidationListener#onTrackSelectionsInvalidated()} to invalidate all previously
   * generated track selections.
   */
  protected final void invalidate() {
    if (listener != null) {
      listener.onTrackSelectionsInvalidated();
    }
  }

  /**
   * Calls {@link InvalidationListener#onRendererCapabilitiesChanged(Renderer)} to invalidate all
   * previously generated track selections because a renderer's capabilities have changed.
   *
   * @param renderer The renderer whose capabilities changed.
   */
  protected final void invalidateForRendererCapabilitiesChange(Renderer renderer) {
    if (listener != null) {
      listener.onRendererCapabilitiesChanged(renderer);
    }
  }

  /**
   * Returns a bandwidth meter which can be used by track selections to select tracks. Must only be
   * called when the track selector is {@linkplain #init(InvalidationListener, BandwidthMeter)
   * initialized}.
   */
  protected final BandwidthMeter getBandwidthMeter() {
    return checkStateNotNull(bandwidthMeter);
  }
}