HLS

ExoPlayer obsługuje HLS w wielu formatach kontenera. Muszą być też obsługiwane formaty próbek audio i wideo (szczegóły znajdziesz w sekcji Formaty próbek). Gorąco zachęcamy twórców treści HLS do generowania strumieni HLS wysokiej jakości, jak opisano tutaj.

Funkcja Obsługiwane Komentarze
Kontenery
MPEG-TS TAK
FMP4/CMAF TAK
ADTS (AAC) TAK
MP3 TAK
Napisy
CEA-608 TAK
CEA-708 TAK
WebVTT TAK
Metadane
ID3 TAK
SCTE-35 NIE
Ochrona treści
AES-128 TAK
Przykład AES-128 NIE
Widevine TAK Interfejs API 19+ (schemat „cenc”) i 25+ (schemat „cbcs”)
PlayReady SL2000 TAK Tylko Android TV
Zarządzanie serwerem
Aktualizacje delta TAK
Blokowanie ponownego wczytywania playlisty TAK
Blokowanie wczytywania wskazówek dotyczących wstępnego wczytywania TAK Z wyjątkiem zakresów bajtów o nieokreślonej długości
Odtwarzanie na żywo
Odtwarzanie na żywo TAK
HLS o niskim opóźnieniu (Apple) TAK
HLS o niskim opóźnieniu (wersja dla społeczności) NIE
Common Media Client Data (CMCD) TAK Przewodnik integracji

Korzystanie z MediaItem

Aby odtworzyć strumień HLS, musisz polegać na module HLS.

Kotlin

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

Groovy

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

Następnie możesz utworzyć MediaItem dla URI playlisty HLS i przekazać go do odtwarzacza.

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();

Jeśli adres URI nie kończy się na .m3u8, możesz przekazać parametr MimeTypes.APPLICATION_M3U8 do metody setMimeType obiektu MediaItem.Builder, aby wyraźnie wskazać typ treści.

Identyfikator URI elementu multimedialnego może wskazywać playlistę multimediów lub playlistę wielowariantową. Jeśli adres URI wskazuje na playlistę wielowariantową, która deklaruje wiele tagów #EXT-X-STREAM-INF, ExoPlayer automatycznie dostosowuje się do wariantów, biorąc pod uwagę zarówno dostępną przepustowość, jak i możliwości urządzenia.

Korzystanie z HlsMediaSource

Aby uzyskać więcej opcji dostosowywania, możesz utworzyć HlsMediaSource i przekazać go bezpośrednio do odtwarzacza zamiast 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();

Dostęp do pliku manifestu

Bieżący plik manifestu możesz pobrać, wywołując Player.getCurrentManifest. W przypadku HLS zwracany obiekt należy rzutować na HlsManifest. Po wczytaniu pliku manifestu wywoływane jest również wywołanie zwrotne onTimelineChanged funkcji Player.Listener. W przypadku treści dostępnych na żądanie będzie to miało miejsce raz, a w przypadku transmisji na żywo – wielokrotnie. Ten fragment kodu pokazuje, jak aplikacja może wykonać jakąś czynność po załadowaniu pliku manifestu.

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.
        }
      }
    });

Dostosowywanie odtwarzania

ExoPlayer udostępnia wiele sposobów na dostosowanie odtwarzania do potrzeb aplikacji. Przykłady znajdziesz na stronie personalizacji.

Wyłączanie przygotowania bez podziału na części

Domyślnie ExoPlayer używa przygotowania bez fragmentów. Oznacza to, że ExoPlayer będzie używać tylko informacji z playlisty wielowariantowej do przygotowania strumienia. Działa to, jeśli tagi #EXT-X-STREAM-INF zawierają atrybut CODECS.

Jeśli segmenty multimediów zawierają zmiksowane ścieżki z napisami, które nie są zadeklarowane w multiwariantowej playliście za pomocą tagu #EXT-X-MEDIA:TYPE=CLOSED-CAPTIONS, konieczne może być wyłączenie tej funkcji. W przeciwnym razie te ścieżki z napisami nie zostaną wykryte i odtworzone. Możesz wyłączyć przygotowanie bez segmentów w HlsMediaSource.Factory, jak pokazano w tym fragmencie kodu. Pamiętaj, że zwiększy to czas uruchamiania, ponieważ ExoPlayer musi pobrać segment multimediów, aby wykryć te dodatkowe ścieżki. Lepiej jest zamiast tego zadeklarować ścieżki z napisami na liście odtwarzania z wieloma wariantami.

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));

Tworzenie wysokiej jakości treści HLS

Aby w pełni wykorzystać możliwości ExoPlayera, możesz postępować zgodnie z pewnymi wytycznymi, które pomogą Ci ulepszyć zawartość HLS. Aby uzyskać pełne wyjaśnienie, przeczytaj post na Medium na temat odtwarzania HLS w ExoPlayerze. Najważniejsze kwestie:

  • Używaj dokładnych długości segmentów.
  • Używaj ciągłego strumienia multimediów. Unikaj zmian w strukturze multimediów w różnych segmentach.
  • Użyj tagu #EXT-X-INDEPENDENT-SEGMENTS.
  • Preferuj strumienie demuxowane zamiast plików zawierających zarówno obraz, jak i dźwięk.
  • Uwzględnij wszystkie możliwe informacje na playlistzie z wieloma wariantami.

W przypadku transmisji na żywo obowiązują te wytyczne:

  • Użyj tagu #EXT-X-PROGRAM-DATE-TIME.
  • Użyj tagu #EXT-X-DISCONTINUITY-SEQUENCE.
  • Długi czas trwania transmisji na żywo. Co najmniej 1 minuta.