A API de playlist é baseada em instâncias MediaItem, que podem ser
criadas de forma conveniente usando MediaItem.Builder. Dentro do player, um
MediaItem é convertido em um MediaSource reproduzível por um
MediaSource.Factory. Sem uma
configuração personalizada, essa conversão é realizada
por um DefaultMediaSourceFactory, que é capaz de criar fontes de mídia
complexas correspondentes às propriedades do item de mídia. Algumas das
propriedades que podem ser definidas em itens de mídia são descritas nas seções
abaixo.
Itens de mídia simples
Um item de mídia que consiste apenas no URI do stream pode ser criado com o método de conveniência
fromUri:
Kotlin
val mediaItem = MediaItem.fromUri(videoUri)
Java
MediaItem mediaItem = MediaItem.fromUri(videoUri);
Em todos os outros casos, é possível usar um MediaItem.Builder. No exemplo a seguir, um item de mídia é criado com um ID e alguns metadados anexados:
Kotlin
val mediaItem = MediaItem.Builder().setMediaId(mediaId).setTag(myAppData).setUri(videoUri).build()
Java
MediaItem mediaItem = new MediaItem.Builder().setMediaId(mediaId).setTag(myAppData).setUri(videoUri).build();
Anexar metadados pode ser útil para atualizar a interface do app quando ocorrem transições de playlist.
Imagens
A reprodução de imagens requer uma duração no item de mídia para especificar por quanto tempo a imagem precisa ser mostrada durante a reprodução. Consulte a página do guia Imagens para mais informações sobre Fotos com movimento e bibliotecas de carregamento de imagens (por exemplo, Glide).
Kotlin
val mediaItem = MediaItem.Builder().setUri(imageUri).setImageDurationMs(3000).build()
Java
MediaItem mediaItem = new MediaItem.Builder().setUri(imageUri).setImageDurationMs(3_000).build();
Extensões de arquivo não padrão para mídia adaptável
O ExoPlayer oferece fontes de mídia adaptáveis para DASH, HLS e SmoothStreaming. Se o URI de um item de mídia adaptável terminar com uma extensão de arquivo padrão, a fonte de mídia correspondente será criada automaticamente. Se o URI tiver uma extensão não padrão ou nenhuma extensão, o tipo MIME poderá ser definido explicitamente para indicar o tipo do item de mídia:
Kotlin
val mediaItem = MediaItem.Builder().setUri(hlsUri).setMimeType(MimeTypes.APPLICATION_M3U8).build()
Java
MediaItem mediaItem = new MediaItem.Builder().setUri(hlsUri).setMimeType(MimeTypes.APPLICATION_M3U8).build();
Para streams de mídia progressivos, um tipo MIME não é obrigatório.
Conteúdo protegido
Para conteúdo protegido, as propriedades de DRM do item de mídia precisam ser definidas. O UUID é obrigatório, todas as outras propriedades são opcionais.
Um exemplo de configuração para reproduzir um item protegido com o DRM do Widevine em que o URI da licença não está disponível diretamente na mídia (por exemplo, em uma playlist DASH) e várias sessões são necessárias (por exemplo, devido à rotação de chaves):
Kotlin
val mediaItem = MediaItem.Builder() .setUri(videoUri) .setDrmConfiguration( MediaItem.DrmConfiguration.Builder(C.WIDEVINE_UUID) .setLicenseUri(licenseUri) .setMultiSession(true) .setLicenseRequestHeaders(httpRequestHeaders) .build() ) .build()
Java
MediaItem mediaItem = new MediaItem.Builder() .setUri(videoUri) .setDrmConfiguration( new MediaItem.DrmConfiguration.Builder(C.WIDEVINE_UUID) .setLicenseUri(licenseUri) .setMultiSession(true) .setLicenseRequestHeaders(httpRequestHeaders) .build()) .build();
Dentro do player, o DefaultMediaSourceFactory vai transmitir essas propriedades para um
DrmSessionManagerProvider para receber um DrmSessionManager, que é
injetado no MediaSource criado. O comportamento do DRM pode ser
personalizado ainda mais de acordo com suas necessidades.
Sideloading de faixas de legenda
Para fazer o sideload de faixas de legenda, as instâncias MediaItem.Subtitle podem ser adicionadas ao
criar um item de mídia:
Kotlin
val subtitle = MediaItem.SubtitleConfiguration.Builder(subtitleUri) .setMimeType(mimeType) // The correct MIME type (required). .setLanguage(language) // The subtitle language (optional). .setSelectionFlags(selectionFlags) // Selection flags for the track (optional). .build() val mediaItem = MediaItem.Builder().setUri(videoUri).setSubtitleConfigurations(listOf(subtitle)).build()
Java
MediaItem.SubtitleConfiguration subtitle = new MediaItem.SubtitleConfiguration.Builder(subtitleUri) .setMimeType(mimeType) // The correct MIME type (required). .setLanguage(language) // The subtitle language (optional). .setSelectionFlags(selectionFlags) // Selection flags for the track (optional). .build(); MediaItem mediaItem = new MediaItem.Builder() .setUri(videoUri) .setSubtitleConfigurations(ImmutableList.of(subtitle)) .build();
Internamente, o DefaultMediaSourceFactory vai usar um MergingMediaSource para
combinar a origem de mídia de conteúdo com um SingleSampleMediaSource para cada
faixa de legenda. O DefaultMediaSourceFactory não é compatível com o sideload de legendas para DASH de vários períodos.
Como cortar um stream de mídia
Para cortar o conteúdo referenciado por um item de mídia, defina posições de início e fim personalizadas:
Kotlin
val mediaItem = MediaItem.Builder() .setUri(videoUri) .setClippingConfiguration( MediaItem.ClippingConfiguration.Builder() .setStartPositionMs(startPositionMs) .setEndPositionMs(endPositionMs) .build() ) .build()
Java
MediaItem mediaItem = new MediaItem.Builder() .setUri(videoUri) .setClippingConfiguration( new ClippingConfiguration.Builder() .setStartPositionMs(startPositionMs) .setEndPositionMs(endPositionMs) .build()) .build();
Internamente, o DefaultMediaSourceFactory vai usar um ClippingMediaSource para envolver
a origem de mídia do conteúdo. Há outras propriedades de corte. Consulte o
Javadoc de MediaItem.Builder para mais detalhes.
Inserção de anúncios
Para inserir anúncios, a propriedade de URI da tag de anúncio de um item de mídia precisa ser definida:
Kotlin
val mediaItem = MediaItem.Builder() .setUri(videoUri) .setAdsConfiguration(MediaItem.AdsConfiguration.Builder(adTagUri).build()) .build()
Java
MediaItem mediaItem = new MediaItem.Builder() .setUri(videoUri) .setAdsConfiguration(new MediaItem.AdsConfiguration.Builder(adTagUri).build()) .build();
Internamente, o DefaultMediaSourceFactory vai unir a origem de mídia de conteúdo em
um AdsMediaSource para inserir anúncios conforme definido pela tag de anúncio. Para que isso funcione,
o player também precisa ter o DefaultMediaSourceFactory
configurado de acordo.