Elementos multimedia

La API de playlist se basa en instancias de MediaItem, que se pueden compilar de forma conveniente con MediaItem.Builder. Dentro del reproductor, un MediaSource.Factory convierte un MediaItem en un MediaSource reproducible. Sin configuración personalizada, una DefaultMediaSourceFactory realiza esta conversión, que puede compilar fuentes de contenido multimedia complejas correspondientes a las propiedades del elemento multimedia. A continuación, se describen algunas de las propiedades que se pueden configurar en los elementos multimedia.

Elementos multimedia simples

Se puede compilar un elemento multimedia que solo contenga el URI de la transmisión con el método conveniente fromUri:

Kotlin

val mediaItem = MediaItem.fromUri(videoUri)

Java

MediaItem mediaItem = MediaItem.fromUri(videoUri);

En todos los demás casos, se puede usar un MediaItem.Builder. En el siguiente ejemplo, se compila un elemento multimedia con un ID y algunos metadatos adjuntos:

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

Adjuntar metadatos puede ser útil para actualizar la IU de tu app cuando se producen transiciones de playlist.

Imágenes

La reproducción de imágenes requiere una duración en el elemento multimedia para especificar durante cuánto tiempo se debe mostrar la imagen durante la reproducción. Consulta la página de la guía Imágenes para obtener más información sobre las imágenes en movimiento y las bibliotecas de carga de imágenes (por ejemplo, Glide).

Kotlin

val mediaItem = MediaItem.Builder().setUri(imageUri).setImageDurationMs(3000).build()

Java

MediaItem mediaItem =
    new MediaItem.Builder().setUri(imageUri).setImageDurationMs(3_000).build();

Extensiones de archivo no estándar para contenido multimedia adaptable

ExoPlayer proporciona fuentes multimedia adaptables para DASH, HLS y SmoothStreaming. Si el URI de un elemento multimedia adaptable termina con una extensión de archivo estándar, se crea automáticamente la fuente de medios correspondiente. Si el URI tiene una extensión no estándar o no tiene ninguna, el tipo MIME se puede establecer de forma explícita para indicar el tipo de elemento multimedia:

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 las transmisiones de contenido multimedia progresivas, no se requiere un tipo de MIME.

Contenido protegido

En el caso del contenido protegido, se deben establecer las propiedades de DRM del elemento multimedia. El UUID es obligatorio, y todas las demás propiedades son opcionales.

Ejemplo de configuración para reproducir un elemento protegido con DRM de Widevine en el que el URI de la licencia no está disponible directamente en el contenido multimedia (p.ej., en una playlist de DASH) y se requieren varias sesiones (p.ej., debido a la rotación de claves):

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 del reproductor, DefaultMediaSourceFactory pasará estas propiedades a un DrmSessionManagerProvider para obtener un DrmSessionManager, que luego se insertará en el MediaSource creado. El comportamiento de la DRM se puede personalizar aún más según tus necesidades.

Transferencia de pistas de subtítulos

Para transferir pistas de subtítulos, se pueden agregar instancias de MediaItem.Subtitle cuando se compila un elemento multimedia:

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

De forma interna, DefaultMediaSourceFactory usará un MergingMediaSource para combinar la fuente de contenido multimedia con un SingleSampleMediaSource para cada pista de subtítulos. DefaultMediaSourceFactory no admite la transferencia lateral de subtítulos para DASH de varios períodos.

Cómo recortar una transmisión de contenido multimedia

Para recortar el contenido al que hace referencia un elemento multimedia, establece posiciones de inicio y fin 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();

De forma interna, DefaultMediaSourceFactory usará un ClippingMediaSource para unir la fuente de contenido multimedia. Hay propiedades de recorte adicionales. Consulta el Javadoc de MediaItem.Builder para obtener más detalles.

Inserción de anuncios

Para insertar anuncios, se debe configurar la propiedad URI de la etiqueta de anuncio de un elemento multimedia:

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

De forma interna, DefaultMediaSourceFactory unirá la fuente de contenido multimedia en un AdsMediaSource para insertar anuncios según lo definido por la etiqueta de anuncio. Para que esto funcione, el reproductor también debe tener su DefaultMediaSourceFactory configurado de manera adecuada.