Un reproductor es el componente de tu app que facilita la reproducción de elementos multimedia.
La interfaz Player
de Media3 establece un esquema para la funcionalidad que suele controlar un reproductor. Esto incluye lo siguiente:
- Afectan los controles de reproducción, como reproducir, pausar y buscar.
- Consultar las propiedades del contenido multimedia que se está reproduciendo, como la posición de reproducción
- Administrar una playlist o fila de elementos multimedia
- Configurar las propiedades de reproducción, como la reproducción aleatoria, la repetición, la velocidad y el volumen
- Renderizar video en la pantalla
Media3 también proporciona una implementación de la interfaz Player
, llamada ExoPlayer
.
Una interfaz común entre los componentes
Varios componentes de Media3 implementan la interfaz Player, por ejemplo:
Componente | Notas de descripción y comportamiento |
---|---|
ExoPlayer |
Es una API de reproductor multimedia y la implementación predeterminada de la interfaz Player . |
MediaController |
Interactúa con un MediaSession para enviar comandos de reproducción. Si tus elementos Player y MediaSession se encuentran en un elemento Service separado del elemento Activity o Fragment en el que se encuentra la IU del reproductor, puedes asignar tu elemento MediaController como el reproductor de tu IU de PlayerView . Las llamadas a métodos de reproducción y de playlist se envían a tu Player a través de tu MediaSession .
|
MediaBrowser |
Además de la funcionalidad que ofrece un MediaController , interactúa con un MediaLibrarySession para explorar el contenido multimedia disponible.
|
SimpleBasePlayer |
Implementación de Player que reduce al mínimo la cantidad de métodos que se deben implementar. Es útil cuando se usa un reproductor personalizado que se desea conectar a un MediaSession .
|
ForwardingSimpleBasePlayer |
Una subclase de SimpleBasePlayer diseñada para reenviar operaciones de reproducción a otro Player y, al mismo tiempo, permitir las mismas personalizaciones de comportamiento coherentes que SimpleBasePlayer . Usa esta clase para suprimir o modificar operaciones de reproducción específicas.
|
CastPlayer |
Implementación de Player que se comunica con una app receptora de Cast. El comportamiento depende de la sesión de Cast subyacente.
|
Aunque un MediaSession
no implementa la interfaz Player
, requiere un Player
cuando se crea uno. Su propósito es proporcionar acceso al Player
desde otros procesos o subprocesos.
Arquitectura de reproducción de Media3
Si tienes acceso a un objeto Player
, debes llamar a sus métodos directamente para emitir comandos de reproducción. Puedes anunciar tu reproducción y otorgar a fuentes externas el control de reproducción implementando un MediaSession
. Estas fuentes externas implementan un MediaController
, que facilita la conexión a una sesión multimedia y la emisión de solicitudes de comandos de reproducción.
Cuando reproduzcas contenido multimedia en segundo plano, deberás alojar tu sesión multimedia y tu reproductor dentro de un MediaSessionService
o MediaLibraryService
que se ejecute como un servicio en primer plano. Si lo haces, puedes separar el reproductor de la actividad de tu app que contiene la IU para el control de la reproducción. Esto puede requerir que uses un controlador de medios.

Player
desempeña un papel clave
en la arquitectura de Media3.Estado del reproductor
El estado de un reproductor multimedia que implementa la interfaz Player
consta principalmente de 4 categorías de información:
- Estado de reproducción
- Recupera con
getPlaybackState()
. - Los valores de estado definidos por la interfaz son
STATE_IDLE
,STATE_BUFFERING
,STATE_READY
ySTATE_ENDED
.
- Recupera con
- Playlist de elementos multimedia
- Es una secuencia de instancias de
MediaItem
para la reproducción. - Recupera con
getCurrentTimeline()
- Las instancias de
Player
pueden proporcionar métodos de operación de playlist, como agregar o quitar unMediaItem
, y métodos convenientes, comogetCurrentMediaItem()
.
- Es una secuencia de instancias de
- Propiedades de reproducción/pausa, como las siguientes:
playWhenReady
: Indicación de si el usuario quiere que se reproduzca el contenido multimedia cuando sea posible o que permanezca en pausa- Motivo de la supresión de la reproducción:
Es una indicación del motivo por el que se suprime la reproducción, si corresponde, incluso si
playWhenReady
estrue
. isPlaying
: Indicación de si el reproductor está reproduciendo contenido actualmente, que solo serátrue
si el estado de reproducción esSTATE_READY
,playWhenReady
estrue
y no se suprime la reproducción
- Posición de reproducción, que incluye lo siguiente:
- Índice del elemento multimedia actual:
Índice del
MediaItem
actual en la playlist. isPlayingAd
: Es un indicador de si se está reproduciendo un anuncio insertado.- Posición de reproducción actual:
Es la posición de reproducción actual dentro del
MediaItem
o del anuncio insertado actual.
- Índice del elemento multimedia actual:
Índice del
Además, la interfaz de Player
permite acceder a las pistas disponibles, los metadatos de los medios, la velocidad de reproducción, el volumen y otras propiedades auxiliares de la reproducción.
Detecta cambios
Usa un Player.Listener
para detectar cambios en un Player
. Consulta la documentación de ExoPlayer sobre Eventos del reproductor para obtener detalles sobre cómo crear y usar un objeto de escucha.
Ten en cuenta que la interfaz del objeto de escucha no incluye ninguna devolución de llamada para hacer un seguimiento de la progresión normal de la reproducción. Para supervisar continuamente el progreso de la reproducción, por ejemplo, para configurar una IU de barra de progreso, debes consultar la posición actual en intervalos adecuados.
Kotlin
val handler = Handler(Looper.getMainLooper()) fun checkPlaybackPosition(delayMs: Long): Boolean = handler.postDelayed( { val currentPosition = player.currentPosition // Update UI based on currentPosition checkPlaybackPosition(delayMs) }, delayMs)
Java
Handler handler = new Handler(Looper.getMainLooper()); boolean checkPlaybackPosition(long delayMs) { return handler.postDelayed(() -> { long currentPosition = player.getCurrentPosition(); // Update UI based on currentPosition checkPlaybackPosition(delayMs); }, delayMs); }
Controlar la reproducción
La interfaz Player
ofrece muchas formas de manipular el estado y controlar la reproducción:
- Controles de reproducción básicos, como
play()
,pause()
,prepare()
ystop()
- Operaciones de playlist, como
addMediaItem()
oremoveMediaItem()
- Búsqueda para cambiar el elemento o la posición actuales.
- Establece los modos de repetición y el modo de reproducción aleatoria.
- Actualiza las preferencias de selección de pistas.
- Establece la velocidad de reproducción.
Implementaciones personalizadas de Player
Para crear un reproductor personalizado, puedes extender SimpleBasePlayer
, que se incluye en Media3. Esta clase proporciona una implementación base de la interfaz Player
para reducir al mínimo la cantidad de métodos que debes implementar.
Para comenzar, anula el método getState()
. Este método debe completar el estado actual del jugador cuando se lo llame, lo que incluye lo siguiente:
- El conjunto de comandos disponibles
- Propiedades de reproducción, como si el reproductor debe comenzar a reproducir cuando el estado de reproducción es
STATE_READY
, el índice del elemento multimedia que se está reproduciendo y la posición de reproducción dentro del elemento actual
Kotlin
class CustomPlayer : SimpleBasePlayer(looper) { override fun getState(): State { return State.Builder() .setAvailableCommands(...) // Set which playback commands the player can handle // Configure additional playback properties .setPlayWhenReady(true, PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST) .setCurrentMediaItemIndex(0) .setContentPositionMs(0) .build() } }
Java
public class CustomPlayer extends SimpleBasePlayer { public CustomPlayer(Looper looper) { super(looper); } @Override protected State getState() { return new State.Builder() .setAvailableCommands(...) // Set which playback commands the player can handle // Configure additional playback properties .setPlayWhenReady(true, PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST) .setCurrentMediaItemIndex(0) .setContentPositionMs(0) .build(); } }
SimpleBasePlayer
aplicará que el State
se cree con una combinación válida de valores de estado. También controlará los objetos de escucha y les informará a los objetos de escucha sobre los cambios de estado. Si necesitas activar manualmente una actualización de estado, llama a invalidateState()
.
Más allá del método getState()
, solo necesitas implementar los métodos que se usan para los comandos que tu reproductor declara como disponibles. Busca el método de controlador anulable que corresponda a la funcionalidad que deseas implementar. Por ejemplo, anula el método handleSeek()
para admitir operaciones como COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM
y COMMAND_SEEK_TO_NEXT_MEDIA_ITEM
.
Modifica las implementaciones de Player
En lugar de crear un Player
completamente personalizado, puedes usar ForwardingSimpleBasePlayer
para modificar el estado y el comportamiento de un Player
existente. Consulta la guía en la página Personalización para obtener más detalles.