HLS

O ExoPlayer oferece suporte a HLS com vários formatos de contêiner. O áudio contido e formatos de exemplo de vídeo também devem ser suportados (consulte a exemplos de formatos para mais detalhes). Qa incentivar os produtores de conteúdo HLS a gerar transmissões HLS de alta qualidade, conforme descrito aqui.

Recurso Compatível Comentários
Contêineres
MPEG-TS SIM
FMP4/CMAF SIM
ADTS (AAC) SIM
MP3 SIM
Legendas legendas
Certificado CEA-608 SIM
Certificado CEA 708 SIM
WebVTT SIM
Metadados
ID3 SIM
SCTE-35 NÃO
Proteção de conteúdo
AES-128 SIM
Exemplo de AES-128 NÃO
Widevine SIM API 19+ ("esquema cenc") e 25+ ("esquema cbcs")
PlayReady SL2000 SIM Somente no Android TV
Controle do servidor
Atualizações Delta SIM
Bloqueando a atualização da playlist SIM
Bloqueio do carregamento de dicas de pré-carregamento SIM Exceto para intervalos de bytes com comprimentos indefinidos
Reprodução ao vivo
Reprodução ao vivo regular SIM
HLS de baixa latência (Apple) SIM
HLS de baixa latência (Comunidade) NÃO
Dados comuns do cliente de mídia (CMCD, na sigla em inglês) SIM Guia de integração

Como usar o MediaItem

Para reproduzir uma transmissão HLS, é preciso depender do módulo HLS.

Kotlin

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

Groovy

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

Você pode criar um MediaItem para um URI de playlist HLS e transmiti-lo ao de futebol.

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

Caso o URI não termine com .m3u8, transmita MimeTypes.APPLICATION_M3U8. setMimeType de MediaItem.Builder para indicar explicitamente o tipo de conteúdo.

O URI do item de mídia pode apontar para uma playlist de mídia ou para uma multivariante lista de reprodução. Se o URI apontar para uma playlist multivariante que declara vários #EXT-X-STREAM-INF, então o ExoPlayer se adaptará automaticamente entre de serviço, considerando a largura de banda disponível e os recursos do dispositivo.

Como usar HlsMediaSource

Para mais opções de personalização, você pode criar um HlsMediaSource e transmiti-lo diretamente ao player em vez de um 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();

Como acessar o manifesto

É possível recuperar o manifesto atual chamando Player.getCurrentManifest. Para HLS, transmita o objeto retornado para HlsManifest. A O callback onTimelineChanged de Player.Listener também é chamado sempre que o manifesto é carregado. Isso acontecerá uma vez para conteúdo on demand e possivelmente várias vezes em conteúdo ao vivo. O snippet de código a seguir mostra como um app pode fazer algo sempre que o manifesto for carregado.

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

Como personalizar a reprodução

O ExoPlayer oferece várias maneiras de personalizar a experiência de reprodução de acordo com seu às necessidades do seu app. Consulte a página "Personalização" para ver exemplos.

Como desativar a preparação sem separações em blocos

Por padrão, o ExoPlayer usará a preparação sem partes. Isso significa que o ExoPlayer só usará as informações na playlist multivariante para preparar o stream, que funciona se as tags #EXT-X-STREAM-INF contiverem o CODECS. .

Talvez seja necessário desativar esse recurso se os segmentos de mídia tiverem multiplexados faixas de legenda descritiva que não são declaradas na playlist multivariante com um #EXT-X-MEDIA:TYPE=CLOSED-CAPTIONS. Caso contrário, as faixas de legenda não serão detectados nem reproduzidos. É possível desativar a preparação sem separações em HlsMediaSource.Factory, conforme mostrado no snippet a seguir. Observe que este vai aumentar o tempo de inicialização, já que o ExoPlayer precisa fazer o download de um segmento de mídia para essas faixas adicionais e é preferível declarar os faixas de legenda descritiva na 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));

Como criar conteúdo HLS de alta qualidade

Para aproveitar ao máximo o ExoPlayer, você precisa seguir algumas diretrizes seguir para melhorar seu conteúdo de HLS. Leia nossa postagem do Medium sobre a reprodução de HLS em ExoPlayer (em inglês) para uma explicação completa. Os pontos principais são:

  • Use durações de segmento precisas.
  • Usar um stream de mídia contínuo evitar mudanças na estrutura de mídia em segmentos.
  • Use a tag #EXT-X-INDEPENDENT-SEGMENTS.
  • Prefira transmissões com multiplexação revertida em vez de arquivos que incluem vídeo e áudio.
  • Inclua todas as informações possíveis na playlist multivariante.

As seguintes diretrizes se aplicam especificamente às transmissões ao vivo:

  • Use a tag #EXT-X-PROGRAM-DATE-TIME.
  • Use a tag #EXT-X-DISCONTINUITY-SEQUENCE.
  • Forneça uma janela ativa longa. Um minuto ou mais é suficiente.