O ExoPlayer oferece suporte ao HLS com vários formatos de contêiner. Os formatos de amostra de áudio e vídeo contidos também precisam ser compatíveis. Consulte a seção Formatos de amostra para saber mais. Recomendamos que os produtores de conteúdo HLS gerem streams 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/closed captions | ||
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 | |
Bloquear a recarga da playlist | SIM | |
Bloqueio do carregamento de dicas de pré-carregamento | SIM | Exceto para byteranges com comprimentos indefinidos |
Reprodução ao vivo | ||
Reprodução ao vivo normal | 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, você precisa depender do módulo HLS.
Kotlin
implementation("androidx.media3:media3-exoplayer-hls:1.4.1")
Groovy
implementation "androidx.media3:media3-exoplayer-hls:1.4.1"
Em seguida, crie um MediaItem
para um URI de playlist HLS e transmita-o ao
reprodutor.
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();
Se o URI não terminar com .m3u8
, transmita MimeTypes.APPLICATION_M3U8
para setMimeType
de MediaItem.Builder
para indicar explicitamente o tipo do
conteúdo.
O URI do item de mídia pode apontar para uma playlist de mídia ou uma playlist
multivariante. Se o URI apontar para uma playlist multivariante que declara várias
tags #EXT-X-STREAM-INF
, o ExoPlayer se adaptará automaticamente entre
as variantes, considerando a largura de banda e os recursos do dispositivo disponíveis.
Como usar o HlsMediaSource
Para mais opções de personalização, você pode criar um HlsMediaSource
e transmiti-lo
diretamente para o jogador em vez de uma 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 extrair o manifesto atual chamando Player.getCurrentManifest
.
Para HLS, você precisa transmitir o objeto retornado para HlsManifest
. O
callback onTimelineChanged
de Player.Listener
também é chamado sempre que
o manifesto é carregado. Isso acontecerá uma vez para conteúdo sob demanda e
possivelmente várias vezes para conteúdo ao vivo. O snippet de código a seguir mostra como um app
pode fazer algo sempre que o manifesto é 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 as necessidades do app. Consulte a página de personalização para conferir exemplos.
Como desativar a preparação sem separações em blocos
Por padrão, o ExoPlayer vai usar a preparação sem separações em blocos. Isso significa que o ExoPlayer
usará apenas as informações na playlist de variantes múltiplas para preparar o
stream, o que funciona se as tags #EXT-X-STREAM-INF
contiverem o atributo
CODECS
.
Talvez seja necessário desativar esse recurso se os segmentos de mídia tiverem faixas
com legendas multiplexadas que não foram declaradas na playlist multivariante com uma
tag #EXT-X-MEDIA:TYPE=CLOSED-CAPTIONS
. Caso contrário, essas faixas de legenda
não serão detectadas e reproduzidas. É possível desativar a preparação sem blocos no
HlsMediaSource.Factory
, conforme mostrado no snippet abaixo. Isso
vai aumentar o tempo de inicialização, já que o ExoPlayer precisa fazer o download de um segmento de mídia para
descobrir essas outras faixas, e é preferível declarar as
faixas de legenda 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));
Criar conteúdo HLS de alta qualidade
Para aproveitar ao máximo o ExoPlayer, siga algumas diretrizes para melhorar seu conteúdo HLS. Leia nossa postagem do Medium sobre a reprodução de HLS no ExoPlayer para uma explicação completa. Os pontos principais são:
- Use durações de segmento precisas.
- Use uma transmissão de mídia contínua. Evite mudanças na estrutura de mídia em segmentos.
- Use a tag
#EXT-X-INDEPENDENT-SEGMENTS
. - Prefira streams desmultiplexados, 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 é ótimo.