Un player è il componente della tua app che facilita la riproduzione degli elementi multimediali.
L'interfaccia Player di Media3
configura una struttura per le funzionalità generalmente gestite da un player. Queste includono:
- Influenza sui controlli di riproduzione, ad esempio riproduzione, pausa e ricerca
- Esecuzione di query sulle proprietà dei contenuti multimediali in riproduzione, ad esempio la posizione di riproduzione
- Gestione di una playlist/coda di elementi multimediali
- Configurazione delle proprietà di riproduzione, ad esempio riproduzione casuale, ripetizione, velocità e volume
- Rendering dei video sullo schermo
Media3 fornisce anche un'implementazione dell'interfaccia Player, chiamata
ExoPlayer.
Un'interfaccia comune tra i componenti
Diversi componenti di Media3 implementano l'interfaccia Player, ad esempio:
| Componente | Note sulla descrizione e sul comportamento |
|---|---|
ExoPlayer |
Un'API di media player e l'implementazione predefinita dell'interfaccia Player. |
MediaController |
Interagisce con un MediaSession per inviare comandi di riproduzione. Se
i tuoi Player e MediaSession si trovano in un
Service separato da Activity o
Fragment in cui si trova l'interfaccia utente del player, puoi assegnare il tuo
MediaController come player per il tuo
componente dell'interfaccia utente, ad esempio PlayerView o Player
Composable. Le chiamate ai metodi di riproduzione e playlist vengono inviate
a Player tramite MediaSession.
|
MediaBrowser |
Oltre alle funzionalità offerte da un
MediaController, interagisce con un
MediaLibrarySession per sfogliare i contenuti multimediali disponibili.
|
SimpleBasePlayer |
Un'implementazione di Player che riduce al minimo il numero di metodi
da implementare. Utile quando utilizzi un player personalizzato che
vuoi connettere a un MediaSession.
|
ForwardingSimpleBasePlayer |
Una sottoclasse SimpleBasePlayer progettata per inoltrare le operazioni di riproduzione a un altro Player consentendo al contempo le stesse personalizzazioni del comportamento coerenti di SimpleBasePlayer. Utilizza
questa classe per sopprimere o modificare operazioni di riproduzione specifiche.
|
RemoteCastPlayer |
Un'implementazione di Player per controllare la riproduzione su un'app ricevitore Cast remota.
|
CastPlayer |
Un'implementazione di Player per controllare la riproduzione Cast sia locale che remota.
|
Sebbene un MediaSession non implementi l'interfaccia Player, richiede un Player durante la creazione. Il suo scopo è fornire l'accesso a Player da altri processi o thread.
Architettura di riproduzione di Media3
Se hai accesso a un Player, devi chiamare direttamente i suoi metodi per inviare comandi di riproduzione. Puoi pubblicizzare la riproduzione e concedere il controllo della riproduzione a fonti esterne implementando un MediaSession. Queste fonti esterne implementano un MediaController, che facilita la connessione a una sessione multimediale e l'invio di richieste di comandi di riproduzione.
Quando riproduci contenuti multimediali in background, devi ospitare la sessione multimediale e il player all'interno di un MediaSessionService o MediaLibraryService che viene eseguito come servizio in primo piano. In questo modo, puoi separare il player dall'attività nell'app che contiene l'interfaccia utente per il controllo della riproduzione. Ciò potrebbe richiedere l'utilizzo di un controller multimediale.
Player svolge un ruolo chiave
nell'architettura di Media3.Stato del player
Lo stato di un media player che implementa l'interfaccia Player è costituito principalmente da quattro categorie di informazioni:
- Stato di riproduzione
- Recupera con
getPlaybackState(). - I valori di stato definiti dall'interfaccia sono
STATE_IDLE,STATE_BUFFERING,STATE_READY, eSTATE_ENDED.
- Recupera con
- Playlist di elementi multimediali
- Una sequenza di istanze
MediaItemper la riproduzione. - Recupera con
getCurrentTimeline() - Le istanze
Playerpossono fornire metodi di operazioni sulle playlist, ad esempio l'aggiunta o la rimozione di unMediaItem, e metodi pratici comegetCurrentMediaItem().
- Una sequenza di istanze
- Proprietà di riproduzione/pausa, ad esempio:
playWhenReady: indica se l'utente vuole che i contenuti multimediali vengano riprodotti quando possibile o rimangano in pausa- Motivo della soppressione della riproduzione:
Indica il motivo per cui la riproduzione viene soppressa, se applicabile, anche se
playWhenReadyètrue isPlaying: indica se il player è attualmente in riproduzione, che saràtruesolo se lo stato di riproduzione èSTATE_READY,playWhenReadyètruee la riproduzione non è soppressa
- Posizione di riproduzione, tra cui:
- Indice dell'elemento multimediale corrente:
L'indice dell'elemento
MediaItemcorrente nella playlist. isPlayingAd: indica se è in riproduzione un annuncio inserito.- Posizione di riproduzione corrente:
La posizione di riproduzione corrente all'interno dell'elemento
MediaItemo dell'annuncio inserito.
- Indice dell'elemento multimediale corrente:
L'indice dell'elemento
Inoltre, l'interfaccia Player consente l'accesso alle
tracce disponibili,
ai metadati dei contenuti multimediali,
alla velocità di riproduzione,
al volume e ad altre
proprietà ausiliarie della riproduzione.
Ascoltare le modifiche
Utilizza un Player.Listener
per ascoltare le modifiche in un Player. Per informazioni dettagliate su come creare e utilizzare un listener, consulta la documentazione di ExoPlayer sugli
eventi del player per
dettagli.
Tieni presente che l'interfaccia del listener non include callback per monitorare la normale progressione della riproduzione. Per monitorare continuamente l'avanzamento della riproduzione, ad esempio per configurare un'interfaccia utente della barra di avanzamento, devi eseguire una query sulla posizione corrente a intervalli appropriati.
Kotlin
fun checkPlaybackPosition(delayMs: Long): Boolean = handler.postDelayed( { val currentPosition = player.currentPosition // Update UI based on currentPosition checkPlaybackPosition(delayMs) }, delayMs, )
Java
boolean checkPlaybackPosition(long delayMs) { return handler.postDelayed( () -> { long currentPosition = player.getCurrentPosition(); // Update UI based on currentPosition checkPlaybackPosition(delayMs); }, delayMs); }
Controllare la riproduzione
L'interfaccia Player offre molti modi per manipolare lo stato e controllare la riproduzione:
- Controlli di riproduzione di base
come
play(),pause(),prepare()estop(). - Operazioni sulle playlist come
addMediaItem()oremoveMediaItem(). - Ricerca per modificare l' elemento o la posizione corrente.
- Imposta le modalità repeat e la modalità shuffle.
- Aggiorna le preferenze di selezione delle tracce.
- Imposta la velocità di riproduzione.
Implementazioni personalizzate di Player
Per creare un player personalizzato, puoi estendere il
SimpleBasePlayer
incluso in Media3. Questa classe fornisce un'implementazione di base dell'interfaccia Player per ridurre al minimo il numero di metodi da implementare.
Inizia sostituendo il metodo getState(). Questo metodo deve popolare lo stato del player corrente quando viene chiamato, tra cui:
- L'insieme dei comandi disponibili
- Proprietà di riproduzione, ad esempio se il player deve iniziare la riproduzione quando lo stato di riproduzione è
STATE_READY, l'indice dell'elemento multimediale in riproduzione e la posizione di riproduzione all'interno dell'elemento corrente
Kotlin
class CustomPlayer(looper: Looper) : SimpleBasePlayer(looper) { override fun getState(): State { return State.Builder() .setAvailableCommands(Commands.EMPTY) // 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
private static final class CustomPlayer extends SimpleBasePlayer { public CustomPlayer(Looper looper) { super(looper); } @Override protected State getState() { return new State.Builder() .setAvailableCommands(Commands.EMPTY) // 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 imporrà la creazione di State con una combinazione valida di valori di stato. Gestirà anche i listener e informerà i listener delle modifiche dello stato. Se devi attivare manualmente un aggiornamento dello stato,
chiama invalidateState().
Oltre al metodo getState(), devi implementare solo i metodi utilizzati per i comandi che il player dichiara di essere disponibili. Trova il metodo di gestione sostituibile che corrisponde alla funzionalità che vuoi implementare. Ad esempio,
sostituisci il handleSeek()
metodo per supportare operazioni come COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM
e COMMAND_SEEK_TO_NEXT_MEDIA_ITEM.
Modificare le implementazioni di Player
Anziché creare un Player completamente personalizzato, puoi utilizzare
ForwardingSimpleBasePlayer per modificare lo stato e il comportamento di un
Player esistente. Per ulteriori dettagli, consulta la guida nella pagina Personalizzazione per
altri dettagli.