HLS

ExoPlayer est compatible avec HLS avec plusieurs formats de conteneur. Les formats d'échantillons audio et vidéo contenus doivent également être compatibles (pour en savoir plus, consultez la section Formats d'échantillons). Nous encourageons vivement les producteurs de contenus HLS à générer des flux HLS de haute qualité, comme décrit ici.

Fonctionnalité Compatible Commentaires
Conteneurs
MPEG-TS OUI
FMP4/CMAF OUI
ADTS (AAC) OUI
MP3 OUI
Sous-titres
CEA-608 OUI
CEA-708 OUI
WebVTT OUI
Métadonnées
ID3 OUI
SCTE-35 NON
Protection du contenu
AES-128 OUI
Exemple AES-128 NON
Widevine OUI API 19 ou version ultérieure ("cenc") et 25 ou version ultérieure ("cbcs")
PlayReady SL2000 OUI Android TV uniquement
Contrôle du serveur
Mises à jour delta OUI
Bloquer le rechargement de la playlist OUI
Blocage du chargement des indices de préchargement OUI À l'exception des plages d'octets dont la longueur n'est pas définie
Lecture en direct
Lecture en direct régulière OUI
HLS à faible latence (Apple) OUI
HLS à faible latence (communauté) NON
CMCD (Common Media Client Data) OUI Guide d'intégration

Utiliser MediaItem

Pour lire un flux HLS, vous devez dépendre du module HLS.

Kotlin

implementation("androidx.media3:media3-exoplayer-hls:1.4.1")

Groovy

implementation "androidx.media3:media3-exoplayer-hls:1.4.1"

Vous pouvez ensuite créer un MediaItem pour un URI de playlist HLS et le transmettre au lecteur.

Kotlin

// Create a player instance.
val player = ExoPlayer.Builder(context).build()
// Set the media item to be played.
player.setMediaItem(MediaItem.fromUri(hlsUri))
// Prepare the player.
player.prepare()

Java

// Create a player instance.
ExoPlayer player = new ExoPlayer.Builder(context).build();
// Set the media item to be played.
player.setMediaItem(MediaItem.fromUri(hlsUri));
// Prepare the player.
player.prepare();

Si votre URI ne se termine pas par .m3u8, vous pouvez transmettre MimeTypes.APPLICATION_M3U8 à setMimeType de MediaItem.Builder pour indiquer explicitement le type de contenu.

L'URI de l'élément multimédia peut pointer vers une playlist multimédia ou une playlist multivariée. Si l'URI pointe vers une playlist multivariante qui déclare plusieurs balises #EXT-X-STREAM-INF, ExoPlayer s'adapte automatiquement entre les variantes, en tenant compte à la fois de la bande passante disponible et des fonctionnalités de l'appareil.

Utiliser HlsMediaSource

Pour plus d'options de personnalisation, vous pouvez créer un HlsMediaSource et le transmettre directement au lecteur au lieu d'un MediaItem.

Kotlin

// Create a data source factory.
val dataSourceFactory: DataSource.Factory = DefaultHttpDataSource.Factory()
// Create a HLS media source pointing to a playlist uri.
val hlsMediaSource =
  HlsMediaSource.Factory(dataSourceFactory).createMediaSource(MediaItem.fromUri(hlsUri))
// Create a player instance.
val player = ExoPlayer.Builder(context).build()
// Set the HLS media source as the playlist with a single media item.
player.setMediaSource(hlsMediaSource)
// Prepare the player.
player.prepare()

Java

// Create a data source factory.
DataSource.Factory dataSourceFactory = new DefaultHttpDataSource.Factory();
// Create a HLS media source pointing to a playlist uri.
HlsMediaSource hlsMediaSource =
    new HlsMediaSource.Factory(dataSourceFactory).createMediaSource(MediaItem.fromUri(hlsUri));
// Create a player instance.
ExoPlayer player = new ExoPlayer.Builder(context).build();
// Set the HLS media source as the playlist with a single media item.
player.setMediaSource(hlsMediaSource);
// Prepare the player.
player.prepare();

Accéder au fichier manifeste

Vous pouvez récupérer le fichier manifeste actuel en appelant Player.getCurrentManifest. Pour HLS, vous devez caster l'objet renvoyé en HlsManifest. Le rappel onTimelineChanged de Player.Listener est également appelé chaque fois que le fichier manifeste est chargé. Cela se produit une fois pour les contenus à la demande et peut se produire plusieurs fois pour les contenus en direct. L'extrait de code suivant montre comment une application peut effectuer une action chaque fois que le fichier manifeste est chargé.

Kotlin

player.addListener(
  object : Player.Listener {
    override fun onTimelineChanged(timeline: Timeline, @TimelineChangeReason reason: Int) {
      val manifest = player.currentManifest
      if (manifest is HlsManifest) {
        // Do something with the manifest.
      }
    }
  }
)

Java

player.addListener(
    new Player.Listener() {
      @Override
      public void onTimelineChanged(
          Timeline timeline, @Player.TimelineChangeReason int reason) {
        Object manifest = player.getCurrentManifest();
        if (manifest != null) {
          HlsManifest hlsManifest = (HlsManifest) manifest;
          // Do something with the manifest.
        }
      }
    });

Personnaliser la lecture

ExoPlayer vous permet de personnaliser l'expérience de lecture en fonction des besoins de votre application de plusieurs façons. Pour en savoir plus, consultez la page Personnalisation.

Désactiver la préparation sans bloc

Par défaut, ExoPlayer utilise la préparation sans blocs. Cela signifie qu'ExoPlayer n'utilisera que les informations de la playlist multivariée pour préparer le flux, ce qui fonctionne si les balises #EXT-X-STREAM-INF contiennent l'attribut CODECS.

Vous devrez peut-être désactiver cette fonctionnalité si vos segments multimédias contiennent des pistes de sous-titres multiplexées qui ne sont pas déclarées dans la playlist multivariante avec une balise #EXT-X-MEDIA:TYPE=CLOSED-CAPTIONS. Sinon, ces pistes de sous-titres ne seront pas détectées ni lues. Vous pouvez désactiver la préparation sans bloc dans HlsMediaSource.Factory, comme indiqué dans l'extrait de code suivant. Notez que cela augmentera le temps de démarrage, car ExoPlayer doit télécharger un segment multimédia pour découvrir ces pistes supplémentaires. Il est préférable de déclarer les pistes de sous-titres dans la playlist multivariante.

Kotlin

val hlsMediaSource =
  HlsMediaSource.Factory(dataSourceFactory)
    .setAllowChunklessPreparation(false)
    .createMediaSource(MediaItem.fromUri(hlsUri))

Java

HlsMediaSource hlsMediaSource =
    new HlsMediaSource.Factory(dataSourceFactory)
        .setAllowChunklessPreparation(false)
        .createMediaSource(MediaItem.fromUri(hlsUri));

Créer du contenu HLS de haute qualité

Pour tirer le meilleur parti d'ExoPlayer, vous pouvez suivre certaines consignes pour améliorer votre contenu HLS. Pour en savoir plus, consultez notre post sur Medium concernant la lecture HLS dans ExoPlayer. Voici les points principaux:

  • Utilisez des durées de segment précises.
  • Utilisez un flux multimédia continu. Évitez les modifications de la structure multimédia entre les segments.
  • Utilisez la balise #EXT-X-INDEPENDENT-SEGMENTS.
  • Privilégiez les flux démultiplexés plutôt que les fichiers incluant à la fois de la vidéo et de l'audio.
  • Incluez toutes les informations possibles dans la playlist multivariée.

Les consignes suivantes s'appliquent spécifiquement aux diffusions en direct:

  • Utilisez la balise #EXT-X-PROGRAM-DATE-TIME.
  • Utilisez la balise #EXT-X-DISCONTINUITY-SEQUENCE.
  • Fournissez une longue période de diffusion en direct. Une minute ou plus est idéal.