Novedades de productos

Media3 1.9.0: novedades

Lectura de 6 minutos
Kristina Simakova
Responsable de Ingeniería

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

  • media3-inspector - Extraer metadatos y fotogramas fuera de la reproducción
  • media3-ui-compose-material3 - Crea una interfaz de usuario multimedia básica de Material 3 Compose en solo unos pasos
  • media3-cast: gestiona automáticamente las transiciones entre la emisión y la reproducción local
  • media3-decoder-av1: reproducción de AV1 coherente con el decodificador de extensión reescrito basado en la biblioteca dav1d

También hemos añadido mejoras en la gestión de la memoria y el almacenamiento en caché a PreloadManager, y hemos simplificado ExoPlayerTransformer y MediaSession

Esta versión también te ofrece el primer acceso experimental a CompositionPlayer para previsualizar las ediciones de contenido multimedia.  


Sigue leyendo para obtener más información y, como siempre, consulta las notas de la versión para ver un resumen completo de los cambios de esta versión.

Extraer metadatos y fotogramas fuera de la reproducción

Hay muchos casos en los que quieres inspeccionar contenido multimedia sin iniciar la reproducción. Por ejemplo, puede que quieras detectar qué formatos contiene o cuál es su duración, o bien recuperar miniaturas.

El nuevo módulo media3-inspector combina todas las utilidades para inspeccionar contenido multimedia sin reproducirlo en un mismo 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 sustituto directo de la clase MediaExtractor de la plataforma Android para obtener información detallada sobre las muestras del archivo.

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

  suspend fun extractThumbnail(mediaItem: MediaItem) {

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

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

  } 

}

Crear una interfaz de usuario multimedia básica de Material 3 con Compose en solo unos pasos

En versiones anteriores, empezamos a proporcionar código de conector entre los elementos de la interfaz de usuario de Compose y tu instancia de Player. Con Media3 1.9.0, hemos añadido un nuevo módulo, media3-ui-compose-material3, con botones y elementos de contenido de Material3 con estilos completos. Te permiten crear una interfaz de usuario multimedia en unos pocos pasos y, al mismo tiempo, te ofrecen toda la flexibilidad necesaria para personalizar el estilo. Si prefieres crear tu propio estilo de interfaz de usuario, puedes usar los componentes que se encargan de toda la lógica de actualización y conexión, de modo que solo tengas que centrarte en diseñar el elemento de interfaz de usuario. Consulta nuestras páginas de guías ampliadas sobre los módulos de la interfaz de usuario de Compose.

También estamos trabajando en más componentes de Compose, como una barra de progreso precompilada, un sustituto completo y listo para usar de 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)
    }
  }
}

 

imagen.png

Interfaz de usuario sencilla de Compose con elementos predefinidos

Gestionar automáticamente las transiciones entre la reproducción en Chromecast y la reproducción local

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

Cuando configures tu MediaSession, solo tienes que crear un CastPlayer alrededor de tu ExoPlayer y añadir un MediaRouteButton a tu interfaz de usuario. ¡Ya lo tienes!

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

}
imagen.png

Nueva integración de CastPlayer en la aplicación de demostración de sesiones 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 extensiones, ten en cuenta que requiere compilación desde la fuente  para empaquetar correctamente el código nativo pertinente. Incluir un decodificador proporciona coherencia y compatibilidad de formatos en todos los dispositivos, pero como ejecuta la decodificación en tu proceso, es más adecuado para el contenido en el que confías. 

Integrar la gestión de caché y memoria en PreloadManager

También hemos mejorado nuestro PreloadManager. Ya te permitía precargar contenido multimedia en la memoria fuera de la reproducción y, después, transferirlo sin problemas a un reproductor cuando fuera necesario. Aunque era bastante eficiente, debías tener cuidado de no superar los límites de memoria precargando demasiado contenido por error. Por eso, con Media3 1.9.0, hemos añadido dos funciones que hacen que esto sea mucho más fácil y estable:

  1. Compatibilidad con el almacenamiento en caché: al definir el nivel de precarga, ahora puede elegir PreloadStatus.specifiedRangeCached(0, 5000) como estado de destino de los elementos precargados. De esta forma, se añadirá el intervalo especificado a la caché del disco en lugar de cargar los datos en la memoria. De esta forma, puedes proporcionar una gama de elementos mucho más amplia para la precarga, ya que los que estén más lejos del elemento actual ya no tienen que ocupar memoria. Ten en cuenta que para ello debes definir un Cache en DefaultPreloadManager.Builder.
  2. Gestión automática de la memoria: también hemos actualizado nuestra interfaz LoadControl para gestionar mejor el caso de precarga. Ahora puedes definir un límite superior de memoria explícito para todos los elementos precargados en la memoria. El valor predeterminado es 144 MB, pero puedes configurar el límite en DefaultLoadControl.Builder. La DefaultPreloadManager dejará de precargar automáticamente cuando se alcance el límite y liberará automáticamente la memoria de los elementos de menor prioridad si es necesario.

Aprovecha los nuevos comportamientos predeterminados simplificados de ExoPlayer

Como siempre, también hemos añadido muchas mejoras incrementales a ExoPlayer. Por mencionar solo algunos:

  • Silenciar y activar el sonido: ya teníamos un método setVolume, pero ahora hemos añadido los métodos mute y unmute para restaurar fácilmente el volumen anterior sin tener que hacer un seguimiento.
  • Detección de reproductor bloqueado: en algunos casos poco frecuentes, el reproductor puede quedarse bloqueado en un estado de almacenamiento en búfer o de reproducción sin avanzar, por ejemplo, debido a problemas con el códec o a errores de configuración. Tus usuarios se molestarán, pero tú nunca verás estos problemas en tus analíticas. Para que sea más evidente, el reproductor ahora muestra un StuckPlayerException cuando detecta que se ha quedado bloqueado.
  • Wakelock de forma predeterminada: antes, la gestión de wake lock era opcional, lo que provocaba que fuera difícil encontrar casos límite en los que el progreso de la reproducción se podía retrasar mucho al ejecutarse en segundo plano. Ahora, esta función es opcional, por lo que no tienes que preocuparte por ella y también puedes eliminar toda la gestión manual de los wake lock durante la reproducción.
  • Ajuste simplificado de la lógica del botón CC: cambiar TrackSelectionParameters para que diga "activar o desactivar los subtítulos" era sorprendentemente difícil de hacer bien, así que hemos añadido una opción booleana sencilla selectTextByDefault para este caso práctico.

Simplifica tus preferencias de botones multimedia en MediaSession

Hasta ahora, para definir qué botones debían aparecer en el panel de notificaciones multimedia de Android Auto o WearOS, era necesario definir comandos y botones personalizados, aunque solo quisieras activar un método de reproductor estándar.

Media3 1.9.0 incluye una nueva función que simplifica mucho este proceso: ahora puedes definir tus preferencias de botones multimedia con un comando de reproductor estándar, sin necesidad de gestionar 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()
))
imagen.png

Preferencias de los botones multimedia con el botón de avance rápido

CompositionPlayer para obtener una vista previa en tiempo real

En la versión 1.9.0 se introduce CompositionPlayer con una nueva anotación @ExperimentalApi. La anotación indica que se puede experimentar con ella, pero que aún está en desarrollo. 

CompositionPlayer es un nuevo componente de las APIs de edición de Media3 diseñado para previsualizar en tiempo real las ediciones de contenido multimedia. CompositionPlayer se basa en la interfaz familiar de Media3 Player y permite a los usuarios ver los cambios en acción antes de confirmar el proceso de exportación. Usa el mismo objeto Composition que pasarías a Transformer para exportar, lo que agiliza el flujo de trabajo de edición al unificar el modelo de datos para la vista previa y la exportación.

Te animamos a que empieces a usar CompositionPlayer y a que nos envíes tus comentarios. Además, estate atento a las próximas publicaciones y actualizaciones de la documentación para obtener más información.

InAppMuxer como muxer predeterminado en Transformer

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

Ten en cuenta que, aunque 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. Hemos introducido 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 sustituye al método anterior de uso de Effects#createExperimentalSpeedChangingEffects(), que hemos retirado y eliminaremos en una futura versión.

Presentamos los tipos de pistas de EditedMediaItemSequence 

En la versión 1.9.0, EditedMediaItemSequence requiere que se especifiquen los tipos de pistas de salida deseados durante la creación de la secuencia. Este cambio asegura que la gestión de las pistas sea más explícita y sólida en toda la composición. 

Para ello, se usa un nuevo constructor EditedMediaItemSequence.Builder que acepta un conjunto de tipos de seguimiento (por ejemplo, C.TRACK_TYPE_AUDIO, C.TRACK_TYPE_VIDEO). 

Para simplificar la creación, hemos añadido nuevos métodos estáticos de conveniencia:

  • 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 que las definiciones de las secuencias sean más claras y fiables.

Ejemplo de creación de una secuencia solo de vídeo:

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

Ponte en contacto con nosotros a través del gestor de incidencias de Media3 si detectas algún error o si tienes alguna pregunta o solicitud de función. Esperamos recibir noticias tuyas.

Escrito por:

Seguir leyendo