Novedades de productos

Media3 1.9.0: Novedades

Lectura de 6 min
Kristina Simakova
Gerente de ingeniería

Ya está disponible Media3 1.9.0. Además de las correcciones de errores y las mejoras de rendimiento habituales, la versión más reciente también contiene cuatro módulos nuevos o reescritos en gran medida:

  • media3-inspector - Extrae metadatos y fotogramas fuera de la reproducción.
  • media3-ui-compose-material3: Compila una IU de medios básica de Material3 Compose en unos pocos pasos.
  • media3-cast - Controla automáticamente las transiciones entre Cast y las reproducciones locales.
  • media3-decoder-av1: Reproducción de AV1 coherente con el decodificador de extensión reescrito basado en la biblioteca dav1d.

También agregamos mejoras de almacenamiento en caché y administración de memoria a PreloadManager y proporcionamos varias simplificaciones nuevas de ExoPlayer, Transformer y MediaSession

Esta versión también te brinda el primer acceso experimental a CompositionPlayer para obtener una vista previa de las ediciones de contenido multimedia.  


Sigue leyendo para obtener más información y, como siempre, consulta las notas de la versión completas para obtener una descripción general completa de los cambios en esta versión.

Extrae metadatos y fotogramas fuera de la reproducción

Hay muchos casos en los que deseas inspeccionar contenido multimedia sin iniciar una reproducción. Por ejemplo, es posible que desees detectar qué formatos contiene o cuál es su duración, o recuperar miniaturas.

El nuevo módulo media3-inspector combina todas las utilidades para inspeccionar contenido multimedia sin reproducción en un solo lugar:

  • MetadataRetriever para leer la duración, el formato y los metadatos estáticos de un MediaItem.
  • FrameExtractor para obtener fotogramas o miniaturas de un elemento.
  • MediaExtractorCompat como reemplazo directo de la clase MediaExtractor de la plataforma de Android para obtener información detallada sobre las muestras del archivo.

MetadataRetriever y FrameExtractor siguen un patrón AutoCloseable simple. Consulta nuestras nuevas páginas de guía para obtener más detalles.

suspend fun extractThumbnail(mediaItem: MediaItem) {

  FrameExtractor.Builder(context, mediaItem).build().use {

    val thumbnail = frameExtractor.getThumbnail().await()

  } 

}

Compila una IU de medios básica de Material3 Compose en unos pocos pasos

En versiones anteriores, comenzamos a proporcionar código de conector entre los elementos de la IU de Compose y tu instancia de Player. Con Media3 1.9.0, agregamos un nuevo módulo media3-ui-compose-material3 con botones y elementos de contenido de Material3 con estilo completo. Te permiten compilar una IU de medios en unos pocos pasos, al tiempo que proporcionan toda la flexibilidad para personalizar el estilo. Si prefieres compilar tu propio estilo de IU, puedes usar los bloques de compilación que se encargan de toda la lógica de actualización y conexión, por lo que solo debes concentrarte en diseñar el elemento de la IU. Consulta nuestras páginas de guía extendidas para los módulos de la IU de Compose.

También seguimos trabajando en más componentes de Compose, como una barra deslizante de búsqueda precompilada, un reemplazo completo y listo para usar para PlayerView, así como la integración de subtítulos y anuncios.

@Composable
fun SimplePlayerUI(player: Player, modifier: Modifier = Modifier) {
  Column(modifier) {
    ContentFrame(player)  // Video surface and shutter logic
    Row (Modifier.align(Alignment.CenterHorizontally)) {                 
      SeekBackButton(player)   // Simple controls
      PlayPauseButton(player)
      SeekForwardButton(player)
    }
  }
}

 

image.png

IU de reproductor de Compose simple con elementos listos para usar

Controla automáticamente las transiciones entre Cast y las reproducciones locales

Se reescribió CastPlayer en el módulo media3-cast para controlar automáticamente las transiciones entre la reproducción local (por ejemplo, con ExoPlayer) y la reproducción remota de Cast.

Cuando configures tu MediaSession, simplemente compila un CastPlayer alrededor de tu ExoPlayer y agrega un MediaRouteButton a tu IU, y listo.

// MediaSession setup with CastPlayer 

val exoPlayer = ExoPlayer.Builder(context).build()

val castPlayer = CastPlayer.Builder(context).setLocalPlayer(exoPlayer).build()

val session = MediaSession.Builder(context, castPlayer).build()

// MediaRouteButton in UI 

@Composable fun UIWithMediaRouteButton() {

  MediaRouteButton()

}
image.png

Nueva integración de CastPlayer en la app de demostración de la sesión de Media3

Reproducción de AV1 coherente con la extensión reescrita basada en dav1d

La versión 1.9.0 contiene un módulo de extensión AV1 completamente reescrito basado en la popular biblioteca dav1d

Al igual que con todos los módulos de decodificador de extensión, ten en cuenta que requiere la compilación desde la fuente para agrupar correctamente el código nativo pertinente. Agrupar un decodificador proporciona coherencia y compatibilidad de formato en todos los dispositivos, pero, como ejecuta la decodificación en tu proceso, es más adecuado para el contenido en el que puedes confiar. 

Integra el almacenamiento en caché y la administración de memoria en PreloadManager

También mejoramos nuestro PreloadManager. Ya te permitía precargar contenido multimedia en la memoria fuera de la reproducción y, luego, entregarlo sin problemas a un reproductor cuando fuera necesario. Aunque es bastante eficiente, aún debías tener cuidado de no exceder los límites de memoria precargando demasiado por accidente. Por lo tanto, con Media3 1.9.0, agregamos dos funciones que hacen que esto sea mucho más fácil y estable:

  1. Compatibilidad con el almacenamiento en caché : Cuando definas qué tan lejos precargar, ahora puedes elegir PreloadStatus.specifiedRangeCached(0, 5000) como un estado objetivo para los elementos precargados. Esto agregará el rango especificado a tu caché en el disco en lugar de cargar los datos en la memoria. Con esto, puedes proporcionar un rango mucho más grande de elementos para la precarga, ya que los que están más lejos del elemento actual ya no necesitan ocupar memoria. Ten en cuenta que esto requiere configurar un Cache en DefaultPreloadManager.Builder.
  2. Administración automática de memoria : También actualizamos nuestra interfaz LoadControl para controlar mejor el caso de precarga, de modo que ahora puedas establecer un límite superior de memoria explícito para todos los elementos precargados en la memoria. Es de 144 MB de forma predeterminada y puedes configurar el límite en DefaultLoadControl.Builder. DefaultPreloadManager dejará de precargar automáticamente una vez que se alcance el límite y liberará automáticamente la memoria de los elementos de menor prioridad si es necesario.

Confía en los nuevos comportamientos predeterminados simplificados en ExoPlayer

Como siempre, también agregamos muchas mejoras incrementales a ExoPlayer. Por nombrar solo algunas:

  • Silenciar y activar el sonido : Ya teníamos un método setVolume, pero ahora agregamos los métodos de conveniencia mute y unmute para restablecer fácilmente el volumen anterior sin tener que hacer un seguimiento por tu cuenta.
  • Detección de reproductores bloqueados : En algunos casos poco frecuentes, el reproductor puede quedar bloqueado en un estado de almacenamiento en búfer o reproducción sin avanzar, por ejemplo, debido a problemas de códec o configuraciones incorrectas. Tus usuarios se molestarán, pero nunca verás estos problemas en tus estadísticas. Para que esto sea más obvio, el reproductor ahora informa una StuckPlayerException cuando detecta un estado bloqueado.
  • Wakelock de forma predeterminada : Anteriormente, la administración de bloqueo de activación era opcional, lo que generaba casos extremos difíciles de encontrar en los que el progreso de la reproducción podía demorarse mucho cuando se ejecutaba en segundo plano. Ahora, esta función es de exclusión, por lo que no tienes que preocuparte por ella y también puedes quitar todo el control manual de bloqueo de activación alrededor de la reproducción.
  • Configuración simplificada para la lógica del botón CC : Cambiar TrackSelectionParameters para decir "activar o desactivar los subtítulos" fue sorprendentemente difícil de hacer correctamente, por lo que agregamos una opción booleana simple selectTextByDefault para este caso de uso.

Simplifica tus preferencias de botones de contenido multimedia en MediaSession

Hasta ahora, definir tus preferencias sobre qué botones deberían aparecer en el panel de notificaciones de contenido multimedia en Android Auto o WearOS requería definir comandos y botones personalizados, incluso si solo querías activar un método de reproductor estándar.

Media3 1.9.0 tiene una nueva funcionalidad para que esto sea mucho más simple: ahora puedes definir tus preferencias de botones de contenido multimedia con un comando de reproductor estándar, sin necesidad de controlar comandos personalizados.

session.setMediaButtonPreferences(listOf(
    CommandButton.Builder(CommandButton.ICON_FAST_FORWARD) // choose an icon
      .setDisplayName(R.string.skip_forward)
      .setPlayerCommand(Player.COMMAND_SEEK_FORWARD) // choose an action 
      .build()
))
image.png

Preferencias de botones de contenido multimedia con botón para adelantar

CompositionPlayer para obtener una vista previa en tiempo real

La versión 1.9.0 presenta CompositionPlayer con una nueva anotación @ExperimentalApi. La anotación indica que está disponible para la experimentación, pero aún está en desarrollo. 

CompositionPlayer es un componente nuevo en las APIs de edición de Media3 diseñado para obtener una vista previa en tiempo real de las ediciones de contenido multimedia. Compilado sobre la interfaz familiar de Media3 PlayerCompositionPlayer permite a los usuarios ver sus cambios en acción antes de confirmar el proceso de exportación. Usa el mismo objeto Composition que pasarías a Transformer para la exportación, lo que optimiza el flujo de trabajo de edición unificando el modelo de datos para la vista previa y la exportación.

Te recomendamos que comiences a usar CompositionPlayer y compartas tus comentarios, y que estés atento a las próximas publicaciones y actualizaciones de la documentación para obtener más detalles.

InAppMuxer como multiplexor predeterminado en Transformer

Transformer ahora usa InAppMp4Muxer como el multiplexor predeterminado para escribir archivos de contenedor de contenido multimedia. Internamente, InAppMp4Muxer depende del módulo Muxer de Media3, lo que proporciona un comportamiento coherente en todas las versiones de la API. 

Ten en cuenta que, si bien Transformer ya no usa MediaMuxer de la plataforma Android de forma predeterminada, puedes proporcionar FrameworkMuxer.Factory a través de setMuxerFactory si tu caso de uso lo requiere.

Nuevas APIs de ajuste de velocidad

La versión 1.9.0 simplifica las APIs de ajuste de velocidad para la edición de contenido multimedia. Presentamos nuevos métodos directamente en EditedMediaItem.Builder para controlar la velocidad, lo que hace que la API sea más intuitiva. Ahora puedes cambiar la velocidad de un clip llamando a setSpeed(SpeedProvider provider) en EditedMediaItem.Builder:

val speedProvider = object : SpeedProvider {
    override fun getSpeed(presentationTimeUs: Long): Float {
        return speed
    }

    override fun getNextSpeedChangeTimeUs(timeUs: Long): Long {
        return C.TIME_UNSET
    }
}

EditedMediaItem speedEffectItem = EditedMediaItem.Builder(mediaItem)
    .setSpeed(speedProvider)
    .build()

Este nuevo enfoque reemplaza el método anterior de usar Effects#createExperimentalSpeedChangingEffects(), que ya no está disponible y que quitaremos en una versión futura.

Presentamos los tipos de pistas para EditedMediaItemSequence

En la versión 1.9.0, EditedMediaItemSequence requiere especificar los tipos de pistas de salida deseados durante la creación de la secuencia. Este cambio garantiza que el control de pistas sea más explícito y sólido en toda la composición. 

Esto se realiza a través de un nuevo EditedMediaItemSequence.Builder constructor que acepta un conjunto de tipos de pistas (p.ej., C.TRACK_TYPE_AUDIO, C.TRACK_TYPE_VIDEO). 

Para simplificar la creación, agregamos nuevos métodos de conveniencia estáticos:

  • EditedMediaItemSequence.withAudioFrom(List<EditedMediaItem>)
  • EditedMediaItemSequence.withVideoFrom(List<EditedMediaItem>)
  • EditedMediaItemSequence.withAudioAndVideoFrom(List<EditedMediaItem>)

Te recomendamos que migres al nuevo constructor o a los métodos de conveniencia para obtener definiciones de secuencia más claras y confiables.

Ejemplo de creación de una secuencia solo de video:

EditedMediaItemSequence videoOnlySequence =
    EditedMediaItemSequence.Builder(setOf(C.TRACK_TYPE_VIDEO))
        .addItem(editedMediaItem)
        .build()

Comunícate con nosotros a través del rastreador de errores de Media3 si encuentras algún error o si tienes preguntas o solicitudes de funciones. Esperamos noticias tuyas.

Escrito por:

Seguir leyendo