Selección de pistas

Cuando un elemento multimedia contiene varias pistas, la selección de pistas es el proceso que determina cuál de ellas se elige para la reproducción. El proceso de selección de pistas se configura mediante TrackSelectionParameters, que permite muchas restricciones diferentes y anula la influencia en la selección de pistas que se especificará.

Cómo consultar los segmentos disponibles

Puedes escuchar a Player.Listener.onTracksChanged para recibir notificaciones sobre los cambios en las pistas, como los siguientes:

  • Las pistas disponibles que se conocen cuando se completa la preparación del elemento multimedia que se está reproduciendo. Ten en cuenta que el reproductor debe preparar un elemento multimedia para saber qué pistas contiene.
  • Las pistas disponibles cambian debido a la transición de la reproducción de un elemento multimedia a otro.
  • Cambios en las pistas seleccionadas.

Kotlin

player.addListener(
  object : Player.Listener {
    override fun onTracksChanged(tracks: Tracks) {
      // Update UI using current tracks.
    }
  }
)

Java

player.addListener(
    new Player.Listener() {
      @Override
      public void onTracksChanged(Tracks tracks) {
        // Update UI using current tracks.
      }
    });

También puedes llamar a player.getCurrentTracks() para consultar los segmentos actuales. El Tracks que se muestra contiene una lista de objetos Track.Group, en la que los seguimientos de una sola Group presentan el mismo contenido, pero en formatos diferentes.

A modo de ejemplo de cómo se pueden agrupar las pistas, considera una reproducción adaptable en la que se proporciona un feed de video principal con cinco tasas de bits y un feed de video alternativo (por ejemplo, un ángulo de cámara diferente en un partido deportivo) con dos tasas de bits. En este caso, habrá dos grupos de pistas de video: uno correspondiente al feed de video principal con cinco pistas y otro para el feed de video alternativo que contiene dos pistas.

Las pistas de audio cuyos idiomas difieren no se agrupan porque el contenido en diferentes idiomas no se considera el mismo. Por el contrario, se pueden agrupar las pistas de audio en el mismo idioma que solo difieren en propiedades como la tasa de bits, la tasa de muestreo y el recuento de canales. Esto también se aplica a las pistas de texto.

Se puede consultar cada Group a fin de determinar qué pistas se admiten para la reproducción, cuáles están seleccionadas actualmente y qué Format usa cada pista:

Kotlin

for (trackGroup in tracks.groups) {
  // Group level information.
  val trackType = trackGroup.type
  val trackInGroupIsSelected = trackGroup.isSelected
  val trackInGroupIsSupported = trackGroup.isSupported
  for (i in 0 until trackGroup.length) {
    // Individual track information.
    val isSupported = trackGroup.isTrackSupported(i)
    val isSelected = trackGroup.isTrackSelected(i)
    val trackFormat = trackGroup.getTrackFormat(i)
  }
}

Java

for (Tracks.Group trackGroup : tracks.getGroups()) {
  // Group level information.
  @C.TrackType int trackType = trackGroup.getType();
  boolean trackInGroupIsSelected = trackGroup.isSelected();
  boolean trackInGroupIsSupported = trackGroup.isSupported();
  for (int i = 0; i < trackGroup.length; i++) {
    // Individual track information.
    boolean isSupported = trackGroup.isTrackSupported(i);
    boolean isSelected = trackGroup.isTrackSelected(i);
    Format trackFormat = trackGroup.getTrackFormat(i);
  }
}

  • Un segmento es compatible si Player puede decodificar y renderizar sus muestras. Ten en cuenta que, incluso si se admiten varios grupos de pistas del mismo tipo (por ejemplo, varios grupos de pistas de audio), solo significa que se admiten de manera individual y el reproductor no necesariamente puede reproducirlos al mismo tiempo.
  • Se selecciona una pista si se seleccionó para la reproducción según el TrackSelectionParameters actual. Si se seleccionan varias pistas dentro de un grupo de pistas, el reproductor las usa para la reproducción adaptable (por ejemplo, varias pistas de video con distintas tasas de bits). Ten en cuenta que solo se reproducirá una de estas pistas a la vez.

Cómo modificar los parámetros de selección de pistas

El proceso de selección de pistas se puede configurar mediante Player.setTrackSelectionParameters. Puedes hacerlo antes y durante la reproducción. En el siguiente ejemplo, se muestra cómo obtener el TrackSelectionParameters actual del reproductor, modificarlos y actualizar el Player con el resultado modificado:

Kotlin

player.trackSelectionParameters =
  player.trackSelectionParameters
    .buildUpon()
    .setMaxVideoSizeSd()
    .setPreferredAudioLanguage("hu")
    .build()

Java

player.setTrackSelectionParameters(
    player
        .getTrackSelectionParameters()
        .buildUpon()
        .setMaxVideoSizeSd()
        .setPreferredAudioLanguage("hu")
        .build());

Selección de segmentos basados en restricciones

La mayoría de las opciones en TrackSelectionParameters te permiten especificar restricciones, que son independientes de las pistas que realmente están disponibles. Las restricciones disponibles incluyen las siguientes:

  • Ancho, altura, velocidad de fotogramas y tasa de bits máximos y mínimos del video
  • Cantidad máxima de canales de audio y tasa de bits.
  • Tipos de MIME preferidos para video y audio
  • Idiomas de audio preferidos y marcas de función
  • Idiomas de texto preferidos y marcas de función

ExoPlayer usa valores predeterminados confidenciales para estas restricciones, por ejemplo, para restringir la resolución de video al tamaño de la pantalla y priorizar el idioma del audio que coincide con la configuración regional del sistema del usuario.

Existen varios beneficios de usar la selección de pistas basada en restricciones en lugar de seleccionar pistas específicas entre las que están disponibles:

  • Puedes especificar restricciones antes de saber qué seguimiento proporciona un elemento multimedia. Esto significa que se pueden especificar las restricciones antes de que el reproductor prepare un elemento multimedia, mientras que la selección de pistas específicas requiere que el código de la aplicación espere hasta que se conozcan las pistas disponibles.
  • Las restricciones se aplican a todos los elementos multimedia de una playlist, incluso cuando esos elementos tienen diferentes pistas disponibles. Por ejemplo, se aplicará automáticamente una restricción de idioma de audio preferido para todos los elementos multimedia, incluso si el Format de la pista en ese idioma varía de un elemento multimedia al siguiente. Esto no sucede cuando seleccionas segmentos específicos, como se describe a continuación.

Cómo seleccionar pistas específicas

Es posible seleccionar pistas específicas mediante TrackSelectionParameters. Primero, se deben consultar las pistas disponibles actualmente del jugador mediante Player.getCurrentTracks. En segundo lugar, una vez identificados los segmentos que se deben seleccionar, se pueden configurar en TrackSelectionParameters mediante un TrackSelectionOverride. Por ejemplo, para seleccionar la primera pista de un audioTrackGroup específico, haz lo siguiente:

Kotlin

player.trackSelectionParameters =
  player.trackSelectionParameters
    .buildUpon()
    .setOverrideForType(
      TrackSelectionOverride(audioTrackGroup.mediaTrackGroup, /* trackIndex= */ 0)
    )
    .build()

Java

player.setTrackSelectionParameters(
    player
        .getTrackSelectionParameters()
        .buildUpon()
        .setOverrideForType(
            new TrackSelectionOverride(
                audioTrackGroup.getMediaTrackGroup(), /* trackIndex= */ 0))
        .build());

Una TrackSelectionOverride solo se aplicará a los elementos multimedia que contengan una TrackGroup que coincida exactamente con el especificado en la anulación. Por lo tanto, es posible que una anulación no se aplique a un elemento multimedia posterior si ese elemento contiene pistas diferentes.

Inhabilitación de tipos de segmentos o grupos

Los tipos de pistas como video, audio o texto se pueden inhabilitar por completo con TrackSelectionParameters.Builder.setTrackTypeDisabled. Los tipos de segmentos inhabilitados se inhabilitarán para todos los elementos multimedia:

Kotlin

player.trackSelectionParameters =
  player.trackSelectionParameters
    .buildUpon()
    .setTrackTypeDisabled(C.TRACK_TYPE_VIDEO, /* disabled= */ true)
    .build()

Java

player.setTrackSelectionParameters(
    player
        .getTrackSelectionParameters()
        .buildUpon()
        .setTrackTypeDisabled(C.TRACK_TYPE_VIDEO, /* disabled= */ true)
        .build());

Como alternativa, es posible evitar la selección de pistas de un TrackGroup específico si especificas una anulación vacía para ese grupo:

Kotlin

player.trackSelectionParameters =
  player.trackSelectionParameters
    .buildUpon()
    .addOverride(
      TrackSelectionOverride(disabledTrackGroup.mediaTrackGroup, /* trackIndices= */ listOf())
    )
    .build()

Java

player.setTrackSelectionParameters(
    player
        .getTrackSelectionParameters()
        .buildUpon()
        .addOverride(
            new TrackSelectionOverride(
                disabledTrackGroup.getMediaTrackGroup(),
                /* trackIndices= */ ImmutableList.of()))
        .build());

Cómo personalizar el selector de pistas

La selección de segmentos es responsabilidad de un TrackSelector. Se puede proporcionar una instancia de esta cada vez que se compila un ExoPlayer y se obtiene más tarde con ExoPlayer.getTrackSelector().

Kotlin

val trackSelector = DefaultTrackSelector(context)
val player = ExoPlayer.Builder(context).setTrackSelector(trackSelector).build()

Java

DefaultTrackSelector trackSelector = new DefaultTrackSelector(context);
ExoPlayer player = new ExoPlayer.Builder(context).setTrackSelector(trackSelector).build();

DefaultTrackSelector es un TrackSelector flexible, adecuado para la mayoría de los casos de uso. Usa el conjunto TrackSelectionParameters en Player, pero también proporciona algunas opciones de personalización avanzadas que se pueden especificar en DefaultTrackSelector.ParametersBuilder:

Kotlin

trackSelector.setParameters(
  trackSelector.buildUponParameters().setAllowVideoMixedMimeTypeAdaptiveness(true))
)

Java

trackSelector.setParameters(
    trackSelector.buildUponParameters().setAllowVideoMixedMimeTypeAdaptiveness(true));

Uso de túneles

Puedes habilitar la reproducción en túnel en los casos en que la combinación de procesadores y pistas seleccionadas lo admita. Para ello, usa DefaultTrackSelector.ParametersBuilder.setTunnelingEnabled(true).

Descarga de audio

Puedes habilitar la reproducción de audio descargada en casos en los que la combinación de renderizadores y pistas seleccionadas lo admita. Para ello, especifica AudioOffloadModePreferences en tu TrackSelectionParameters.

Kotlin

val audioOffloadPreferences =
  AudioOffloadPreferences.Builder()
      .setAudioOffloadMode(AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_ENABLED)
      // Add additional options as needed
      .setIsGaplessSupportRequired(true)
      .build()
player.trackSelectionParameters =
  player.trackSelectionParameters
    .buildUpon()
    .setAudioOffloadPreferences(audioOffloadPreferences)
    .build()

Java

AudioOffloadPreferences audioOffloadPreferences =
  new AudioOffloadPreferences.Builder()
      .setAudioOffloadMode(AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_ENABLED)
      // Add additional options as needed
      .setIsGaplessSupportRequired(true)
      .build();
player.setTrackSelectionParameters(
  player.getTrackSelectionParameters()
    .buildUpon()
    .setAudioOffloadPreferences(audioOffloadPreferences)
    .build());
);