Itens de mídia

A API Playlist é baseada em instâncias de MediaItem, que podem ser criadas usando MediaItem.Builder. No player, um MediaItem é convertido em um MediaSource reproduzível por um MediaSource.Factory. Sem 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. Confira abaixo algumas das propriedades que podem ser definidas em itens de mídia.

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

Para todos os outros casos, é possível usar um MediaItem.Builder. No exemplo abaixo, 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();

A anexação de metadados pode ser útil para atualizar a interface do app quando as transições de playlist ocorrem.

Imagens

A reprodução de imagens exige uma duração no item de mídia para especificar por quanto tempo a imagem será mostrada durante a reprodução. Consulte a página de guia Imagens para mais informações sobre Motion Photos 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 adaptativa

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 transmissões de mídia progressivas, não é necessário um tipo MIME.

Conteúdo protegido

Para conteúdo protegido, as propriedades 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 DRM 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();

No player, DefaultMediaSourceFactory vai transmitir essas propriedades para um DrmSessionManagerProvider para receber um DrmSessionManager, que é injetado no MediaSource criado. O comportamento do DRM pode ser personalizado de acordo com suas necessidades.

Sideload 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 =
  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 oferece suporte ao sideload de legendas para DASH de vários períodos.

Como recortar um stream de mídia

Para cortar o conteúdo mencionado por um item de mídia, defina posições inicial e final 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 agrupar a fonte de mídia de conteúdo. Há outras propriedades de recorte. Consulte o Javadoc MediaItem.Builder para mais detalhes.

Inserção de anúncios

Para inserir anúncios, a propriedade do 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())

Java

MediaItem mediaItem =
    new MediaItem.Builder()
        .setUri(videoUri)
        .setAdsConfiguration(new MediaItem.AdsConfiguration.Builder(adTagUri).build())
        .build();

Internamente, o DefaultMediaSourceFactory vai agrupar a origem da 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 corretamente.