Descripción general de la arquitectura de las apps de contenido multimedia

En esta sección, se explica cómo separar una app de reproductor multimedia en un controlador multimedia (para la IU) y una sesión multimedia (para el reproductor). Se describen dos arquitecturas de apps: un diseño cliente-servidor que funciona bien con apps de audio y un diseño de actividad individual para reproductores de video. También se muestra cómo hacer que las apps de contenido multimedia respondan a los controles de hardware y funcionen junto con otras apps que usan el flujo de salida de audio.

IU y reproductor

Una aplicación de contenido multimedia que reproduce audio o video suele tener dos partes:

  • Un reproductor que toma el contenido multimedia digital y lo renderiza como video o audio.
  • Una IU con controles de transporte para ejecutar el reproductor y, de manera opcional, mostrar su estado.

iu-y-reproductor

En Android, puedes compilar tu propio reproductor desde cero o puedes elegir entre estas opciones:

  • La clase MediaPlayer proporciona las funciones básicas para un reproductor sencillo que admita los formatos de audio y video y las fuentes de datos más comunes.
  • ExoPlayer es una biblioteca de código abierto que expone las API de audio de Android de niveles inferiores. ExoPlayer admite funciones de alto rendimiento, como la transmisión DASH y HLS, que no están disponibles en MediaPlayer. Puedes personalizar el código de ExoPlayer para facilitar la incorporación de componentes nuevos. ExoPlayer solo se puede usar con la versión 4.1 y versiones posteriores de Android.

Controlador multimedia y sesión multimedia

Si bien las API para la IU y el reproductor pueden ser arbitrarias, la naturaleza de la interacción entre las dos partes es básicamente la misma para todas las apps de reproductores multimedia. El marco de trabajo de Android define dos clases (una sesión multimedia y un controlador multimedia) que imponen una estructura bien definida para compilar una app de reproductor multimedia.

La sesión multimedia y el controlador multimedia se comunican entre sí mediante devoluciones de llamada predefinidas que corresponden a acciones estándar del reproductor (reproducir, pausar, detener, etc.), además de llamadas personalizadas extensibles que utilizas para definir comportamientos especiales únicos de tu app.

controlador-y-sesión

Sesión multimedia

Una sesión multimedia se encarga de toda la comunicación con el reproductor. Oculta la API del reproductor del resto de la app. Solo se llama al reproductor desde la sesión multimedia que lo controla.

La sesión mantiene una representación del estado del reproductor (reproducción/pausa) y la información sobre lo que se está reproduciendo. Una sesión puede recibir devoluciones de llamada desde uno o más controladores multimedia. Esto permite que la IU de tu app y los dispositivos complementarios que ejecutan Wear OS y Android Auto controlen el reproductor. La lógica que responde a las devoluciones de llamada debe ser coherente. La respuesta a una devolución de llamada MediaSession debe ser la misma sin importar qué app cliente inició la devolución de llamada.

Controlador multimedia

Un controlador multimedia aísla tu IU. El código de la IU se comunica solamente con el controlador multimedia, no con el reproductor en sí. El controlador multimedia convierte las acciones del control de transporte en devoluciones de llamada a la sesión multimedia. También recibe devoluciones de llamada de la sesión multimedia cada vez que cambia el estado de la sesión. Esto brinda un mecanismo para actualizar automáticamente la IU asociada. Un controlador multimedia puede conectarse a una sola sesión multimedia por vez.

Cuando utilizas un controlador multimedia y una sesión multimedia, puedes implementar diferentes interfaces y reproductores en el entorno de ejecución. Puedes cambiar la apariencia y el rendimiento de tu app de forma independiente según las capacidades del dispositivo en el que se ejecuta.

Diferencias entre apps de video y apps de audio

Cuando reproduces un video, usas la vista y el oído. Al reproducir audio, usas el oído, pero también puedes trabajar con una app diferente al mismo tiempo. Hay un diseño distinto para cada caso práctico.

App de video

Una app de video necesita una ventana para ver el contenido. Por este motivo, estas apps se suelen implementar como una sola actividad de Android. La pantalla en la que aparece el video es parte de la actividad.

actividad del reproductor de video

App de audio

Un reproductor de audio no siempre necesita que su IU esté visible. Una vez que comienza a reproducir audio, puede ejecutarse como una tarea en segundo plano. El usuario puede usar otra app y seguir escuchando el contenido.

Si quieres implementar este diseño en Android, puedes compilar una app de audio utilizando dos componentes: una actividad para la IU y un servicio para el reproductor. Si el usuario cambia a otra app, el servicio se puede ejecutar en segundo plano. Al incluir las dos partes de una app de audio en componentes separados, cada una puede ejecutarse de manera más eficiente por sí misma. Una IU suele tener una duración corta en comparación con un reproductor, que puede ejecutarse durante mucho tiempo sin una IU.

Actividad de audio y BrowserService

La biblioteca de compatibilidad proporciona dos clases para implementar este enfoque cliente-servidor: MediaBrowserService y MediaBrowser. El componente del servicio se implementa como una subclase de MediaBrowserService que contiene la sesión multimedia y su reproductor. La actividad con la IU y el controlador multimedia debe incluir un MediaBrowser, que se comunica con el MediaBrowserService.

Usar MediaBrowserService permite que los dispositivos complementarios (como Android Auto y Wear) descubran tu app, se conecten a ella, busquen contenido y controlen la reproducción sin tener que acceder a la actividad de la IU de tu app. De hecho, pueden conectarse varias apps al mismo MediaBrowserService a la vez, cada aplicación con su propio MediaController. Una app que ofrece un MediaBrowserService debería poder manejar múltiples conexiones simultáneas.

Aplicaciones de contenido multimedia y la infraestructura de audio de Android

Una aplicación de contenido bien diseñada debe funcionar sin problemas junto con otras apps que reproducen audio. Debe estar preparada para compartir el teléfono y cooperar con otras apps de tu dispositivo que usan audio. También debe responder a los controles de hardware en el dispositivo.

funciona-con-otras-apps

Todo este comportamiento se describe en Cómo controlar la salida de audio.

La biblioteca media-compat

La biblioteca media-compat contiene clases que son útiles para compilar apps que reproducen audio y video. Estas clases son compatibles con dispositivos que ejecutan Android 2.3 (API nivel 9) y versiones posteriores. También admiten otras funciones de Android para crear una experiencia de Android agradable y conocida.

La implementación recomendada de las sesiones multimedia y los controladores multimedia son las clases MediaSessionCompat y MediaControllerCompat, que se definen en la biblioteca de compatibilidad media-compat. Estas reemplazan las versiones anteriores de las clases MediaSession y MediaController que se introdujeron en Android 5.0 (API nivel 21). Las clases compat ofrecen las mismas funciones, pero facilitan el desarrollo de tu app, ya que solo necesitas escribir código en una API. La biblioteca se encarga de la retrocompatibilidad. Para ello, convierte los métodos de la sesión multimedia en los métodos equivalentes en versiones anteriores de la plataforma cuando están disponibles.

Si ya tienes una app en funcionamiento que usa las clases anteriores, te recomendamos que actualices a las clases compat. Cuando usas las versiones de compat, puedes quitar todas las llamadas a registerMediaButtonReceiver() y cualquier método de RemoteControlClient.

Cómo medir el rendimiento

En Android 8.0 (API nivel 26) y versiones posteriores, el método getMetrics() está disponible para algunas clases de contenido multimedia. Muestra un objeto PersistableBundle que contiene información sobre la configuración y el rendimiento expresada como un mapa de atributos y valores. El método getMetrics() se define para estas clases de contenido multimedia:

Las métricas se recopilan por separado para cada instancia y se conservan durante su ciclo de vida. Si no hay métricas disponibles, el método muestra un valor nulo. Las métricas reales que se muestran dependen de la clase.