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ónmedia3-ui-compose-material3: Crea una IU de Compose Media básica de Material 3 en solo unos pasosmedia3-cast: Controla automáticamente las transiciones entre las reproducciones de Cast y las localesmedia3-decoder-av1: Se agregó una reproducción de AV1 coherente con el decodificador de extensión reescrito basado en la biblioteca dav1d.
También agregamos mejoras en el almacenamiento en caché y la administración de la 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 de los cambios de esta versión.
Extrae metadatos y fotogramas fuera de la reproducción
Hay muchos casos en los que querrás inspeccionar el contenido multimedia sin iniciar una reproducción. Por ejemplo, es posible 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 reproducción en un solo lugar:
MetadataRetrieverpara leer la duración, el formato y los metadatos estáticos de unMediaItemFrameExtractorpara obtener fotogramas o miniaturas de un elementoMediaExtractorCompatcomo 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ías para obtener más detalles.
suspend fun extractThumbnail(mediaItem: MediaItem) {
FrameExtractor.Builder(context, mediaItem).build().use {
val thumbnail = frameExtractor.getThumbnail().await()
}
}Crea una IU de Compose Media básica de Material 3 en solo unos 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 diseño completo. Te permiten compilar una IU de contenido multimedia en solo unos pasos y, al mismo tiempo, proporcionan toda la flexibilidad para personalizar el estilo. Si prefieres crear tu propio estilo de IU, puedes usar los componentes básicos que se encargan de toda la lógica de actualización y conexión, de modo que solo debas concentrarte en diseñar el elemento de la IU. Consulta nuestras páginas de guías extendidas para los módulos de IU de Compose.
También seguimos trabajando en más componentes de Compose, como una barra deslizante de búsqueda precompilada, un reemplazo completo 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)
}
}
}
IU del reproductor de Compose simple con elementos listos para usar
Controla automáticamente las transiciones entre las reproducciones locales y de Cast.
Se reescribió el 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. ¡Eso es todo!
// 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()
}
Nueva integración de CastPlayer en la app 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 se requiere compilar desde la fuente para empaquetar el código nativo correspondiente de forma correcta. La vinculación de un decodificador proporciona coherencia y compatibilidad con formatos en todos los dispositivos, pero, como ejecuta la decodificación en tu proceso, es más adecuada para el contenido en el que puedes confiar.
Integra el almacenamiento en caché y la administración de la 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 tiene un buen rendimiento, de todas formas, 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:
- Compatibilidad con el almacenamiento en caché: Cuando definas hasta dónde realizar la carga previa, ahora podrás elegir
PreloadStatus.specifiedRangeCached(0, 5000)como estado de destino para los elementos cargados previamente. Esto agregará el rango especificado a tu caché en el disco en lugar de cargar los datos en la memoria. Esto te permite proporcionar un rango mucho más amplio de elementos para la carga previa, ya que los que están más lejos del elemento actual ya no necesitan ocupar memoria. Ten en cuenta que, para ello, se debe establecer unCacheenDefaultPreloadManager.Builder. - Administración automática de la memoria : También actualizamos nuestra interfaz de
LoadControlpara controlar mejor el caso de carga previa, de modo que ahora puedas establecer un límite de memoria superior explícito para todos los elementos precargados en la memoria. De forma predeterminada, es de 144 MB, y puedes configurar el límite enDefaultLoadControl.Builder. ElDefaultPreloadManagerdejará de precargar automáticamente una vez que se alcance el límite y, si es necesario, liberará automáticamente la memoria de los elementos de menor prioridad.
Confía en los nuevos comportamientos predeterminados simplificados de ExoPlayer
Como siempre, también agregamos muchas mejoras incrementales a ExoPlayer. A continuación, te mostramos algunas de ellas:
- Silenciar y activar sonido: Ya teníamos un método
setVolume, pero ahora agregamos los métodos de convenienciamuteyunmutepara restablecer fácilmente el volumen anterior sin tener que hacer un seguimiento de él. - Detección de reproductor bloqueado: En algunos casos excepcionales, el reproductor puede quedar bloqueado en un estado de almacenamiento en búfer o de reproducción sin avanzar, por ejemplo, debido a problemas de códec o parámetros de configuración incorrectos. Tus usuarios se molestarán, pero nunca verás estos problemas en tus estadísticas. Para que esto sea más evidente, el reproductor ahora informa un
StuckPlayerExceptioncuando detecta un estado de bloqueo. - Bloqueo de activación de forma predeterminada: La administración del bloqueo de activación antes era opcional, lo que generaba casos extremos difíciles de encontrar en los que el progreso de la reproducción se podía retrasar mucho cuando se ejecutaba en segundo plano. Ahora, esta función es de inhabilitación, por lo que no tienes que preocuparte por ella y también puedes quitar todo el control manual de los bloqueos de activación en torno a la reproducción.
- Configuración simplificada para la lógica del botón de subtítulos: Cambiar
TrackSelectionParameterspara que diga "activar/desactivar subtítulos" fue sorprendentemente difícil de lograr, por lo que agregamos una opción booleana simpleselectTextByDefaultpara este caso de uso.
Simplifica tus preferencias de botones multimedia en MediaSession
Hasta ahora, para definir tus preferencias sobre qué botones debían aparecer en el panel de notificaciones de contenido multimedia en Android Auto o WearOS, debías 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 sencillo: ahora puedes definir tus preferencias de botones 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()
))
Preferencias de botones multimedia con el botón de avance rápido
CompositionPlayer para la 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 experimentación, pero aún está en desarrollo.
CompositionPlayer es un componente nuevo de las APIs de edición de Media3 diseñado para obtener una vista previa en tiempo real de las ediciones de contenido multimedia. Basado en la conocida interfaz Player de Media3, CompositionPlayer permite que los usuarios vean sus 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 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. Además, mantente al tanto de 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 contenedores de contenido multimedia. De forma interna, 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 el MediaMuxer de la plataforma de 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. Introdujimos métodos nuevos 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 dejamos de usar y quitaremos en una versión futura.
Presentamos los tipos de pistas para 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 garantiza que el manejo de pistas sea más explícito y sólido en toda la Composition.
Esto se hace a través de un nuevo constructor EditedMediaItemSequence.Builder 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 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 obtener definiciones de secuencias 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 de la herramienta de seguimiento de errores de Media3 si tienes algún problema, pregunta o solicitud de función. Esperamos noticias tuyas.
-
Novedades de productosLas apps que se orienten a la próxima versión de Android ya no podrán escribir directamente en los contactos con el permiso WRITE_CONTACTS.
Roxanna Aliabadi Walker • Lectura de 6 min -
Novedades de productosA medida que se acelera el desarrollo basado en agentes, la ingeniería de Android alcanza una nueva y emocionante frontera: pasar de la finalización de código asistida a agentes que ejecutan tareas de extremo a extremo bajo tu dirección. Tienes total libertad y flexibilidad para elegir los modelos y agentes que usas.
Jason Buchel • Lectura de 3 min -
Novedades de productosHoy, compartimos cómo estamos llevando nuestra visión de “más que una tienda” al siguiente nivel. Desde la pestaña Tú, que ahora es la base personal de más de 250 millones de usuarios activos por mes, hasta nuestra plataforma de juegos unificada que conecta a más de 700 millones de perfiles de gamer, Google Play llega a los usuarios dondequiera que estén.
Paul Feng • Lectura de 3 min
Recibe la información más reciente sobre el desarrollo de Android en tu bandeja de entrada todas las semanas.