Un player è il componente dell'app che facilita la riproduzione di elementi multimediali.
L'interfaccia di Media3 Player
configura uno schema delle funzionalità generalmente gestite da un player. Ciò
include:
- Interessano i controlli di riproduzione, ad esempio la riproduzione, la messa in pausa e la ricerca
- Esecuzione di query sulle proprietà del supporto attualmente in riproduzione, come la posizione di riproduzione
- Gestione di una playlist/coda di elementi multimediali
- Configurare le proprietà di riproduzione, come riproduzione casuale, ripetizione, velocità e volume
- Rendering del video sullo schermo
Media3 fornisce anche un'implementazione dell'interfaccia di Player
, chiamata
ExoPlayer
.
Un'interfaccia comune tra i componenti
Diversi componenti di Media3 implementano l'interfaccia del player, ad esempio:
Component | Note sulla descrizione e sul comportamento |
---|---|
ExoPlayer |
Un'API Media Player e l'implementazione predefinita dell'interfaccia Player . |
MediaController |
Interazione con MediaSession per inviare comandi di riproduzione. Se Player e MediaSession si trovano in un Service separato da Activity o Fragment dove si trova l'interfaccia utente del player, puoi assegnare MediaController come player per l'interfaccia utente di PlayerView . Le chiamate relative ai metodi di riproduzione e playlist vengono inviate
al tuo Player tramite il tuo MediaSession .
|
MediaBrowser |
Oltre alle funzionalità offerte da un MediaController , interagisce con un MediaLibrarySession per sfogliare i contenuti multimediali disponibili.
|
ForwardingPlayer |
Un'implementazione Player che inoltra le chiamate al metodo a
un altro Player . Utilizza questa classe per eliminare o modificare operazioni specifiche eseguendo l'override dei rispettivi metodi.
|
SimpleBasePlayer |
Un'implementazione Player che riduce al minimo il numero di metodi da implementare. Utile quando utilizzi un player personalizzato che vuoi collegare a MediaSession .
|
CastPlayer |
Un'implementazione Player che comunica con un'app
ricevitore di trasmissione. Il comportamento dipende dalla sessione di trasmissione sottostante.
|
Anche se MediaSession
non implementa l'interfaccia Player
, richiede
un Player
durante la creazione di una. 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 relativi metodi per emettere
comandi di riproduzione. Puoi pubblicizzare la tua riproduzione e concedere il controllo di riproduzione a sorgenti esterne implementando un MediaSession
. Queste sorgenti esterne implementano un MediaController
, che facilita la connessione a una sessione multimediale e l'invio di richieste di comando di riproduzione.
Quando riproduci contenuti multimediali in background, devi ospitare la sessione multimediale e il player all'interno di un dispositivo MediaSessionService
o MediaLibraryService
eseguito come servizio in primo piano. In questo caso, puoi separare il player dall'attività della tua app, che contiene la UI per il controllo di riproduzione. Potrebbe essere necessario
utilizzare un controller multimediale.
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
MediaItem
istanze per la riproduzione. - Recupera con
getCurrentTimeline()
- Le istanze
Player
possono fornire metodi operativi alle playlist come l'aggiunta o la rimozione diMediaItem
e metodi pratici comegetCurrentMediaItem()
.
- Una sequenza di
- Proprietà di riproduzione/pausa, come:
playWhenReady
: indica se l'utente vuole riprodurre contenuti multimediali quando possibile o rimanere in pausa- Motivo dell'eliminazione della riproduzione:
un'indicazione del motivo per cui la riproduzione è stata soppressa, se applicabile, anche se
playWhenReady
ètrue
isPlaying
: un'indicazione del fatto che il player sia attualmente in riproduzione, che saràtrue
solo se lo stato di riproduzione èSTATE_READY
,playWhenReady
ètrue
e la riproduzione non viene soppressa
- Posizione di riproduzione, tra cui:
- Indice degli elementi multimediali attuali:
l'indice del valore corrente di
MediaItem
nella playlist. isPlayingAd
: Un'indicazione che indica se un annuncio inserito è in riproduzione.- Posizione di riproduzione corrente:
la posizione di riproduzione corrente nell'annuncio
MediaItem
o inserito corrente.
- Indice degli elementi multimediali attuali:
l'indice del valore corrente di
Inoltre, l'interfaccia di Player
consente di accedere alle
tracce disponibili, ai
metadati 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
. Consulta la documentazione di ExoPlayer sugli eventi Player per i dettagli su come creare e utilizzare un listener.
Tieni presente che l'interfaccia listener non include callback per monitorare il normale avanzamento della riproduzione. Per monitorare continuamente l'avanzamento della riproduzione, ad esempio per configurare l'interfaccia utente di una barra di avanzamento, devi eseguire query sulla posizione corrente a intervalli appropriati.
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); }
Controllare la riproduzione
L'interfaccia Player
offre molti modi per gestire lo stato e controllare la riproduzione:
- Controlli di riproduzione di base come
play()
,pause()
,prepare()
estop()
. - Operazioni relative alle playlist, ad esempio
addMediaItem()
oremoveMediaItem()
. - Cercare di modificare l'elemento o la posizione correnti.
- Imposta le modalità di ripetizione e la modalità di riproduzione casuale.
- Aggiorna le preferenze di selezione della traccia.
- Imposta la velocità di riproduzione.
Implementazioni Player
personalizzate
Per creare un player personalizzato, puoi estendere la funzionalità SimpleBasePlayer
inclusa in Media3. Questa classe fornisce un'implementazione di base dell'interfaccia Player
per ridurre al minimo il numero di metodi da implementare.
Per iniziare, esegui l'override del metodo getState()
. Questo metodo dovrebbe completare
lo stato attuale del player quando viene richiamato, inclusi:
- L'insieme di comandi disponibili
- Proprietà di riproduzione, ad esempio se il player deve avviare la riproduzione quando lo stato di riproduzione è
STATE_READY
, l'indice dell'elemento multimediale attualmente in riproduzione e la posizione di riproduzione all'interno dell'elemento corrente
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
richiederà la creazione di State
con una combinazione valida di valori di stato. Gestirà anche i listener e informando
gli ascoltatori dei cambiamenti di stato. Se devi attivare manualmente un aggiornamento dello stato,
chiama il numero 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 gestore override corrispondente alla funzionalità che vuoi implementare. Ad esempio,
esegui l'override del metodo handleSeek()
per supportare operazioni come COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM
e COMMAND_SEEK_TO_NEXT_MEDIA_ITEM
.