Jetpack Media3 definisce un'interfaccia Player
che delinea le funzionalità di base
per la riproduzione di file video e audio. ExoPlayer
è l'implementazione predefinita
di questa interfaccia in Media3. Consigliamo di utilizzare ExoPlayer, perché fornisce una
una serie completa di funzionalità che copre la maggior parte dei casi d'uso relativi alla riproduzione ed è
personalizzabili per gestire
eventuali casi d'uso aggiuntivi. Inoltre, ExoPlayer
astrae la frammentazione del dispositivo e del sistema operativo in modo che il tuo codice funzioni in modo coerente
nell'intero ecosistema Android. ExoPlayer include:
- Supporto delle playlist
- Supporto di una vasta gamma di streaming progressivo e adattivo formati
- Supporto per l'inserimento di annunci lato client e lato server
- Supporto della riproduzione con protezione DRM
In questa pagina vengono illustrati alcuni dei passaggi fondamentali per la realizzazione di una riproduzione e per ulteriori dettagli puoi consultare le nostre guide complete su ExoPlayer Media3.
Per iniziare
Per iniziare, aggiungi una dipendenza ai moduli ExoPlayer, UI e Common di Jetpack Media3:
implementation "androidx.media3:media3-exoplayer:1.4.0" implementation "androidx.media3:media3-ui:1.4.0" implementation "androidx.media3:media3-common:1.4.0"
A seconda del caso d'uso, potrebbero essere necessari anche moduli aggiuntivi di Media3,
come exoplayer-dash
, per riprodurre stream in formato DASH.
Assicurati di sostituire 1.4.0
con la tua versione preferita dell'
libreria. Puoi consultare le note di rilascio
per vedere l'ultima versione.
Creazione di un media player
Con Media3, puoi utilizzare l'implementazione inclusa dell'Player
ExoPlayer
, oppure puoi creare la tua implementazione personalizzata.
Creazione di un ExoPlayer
Il modo più semplice per creare un'istanza ExoPlayer
è il seguente:
Kotlin
val player = ExoPlayer.Builder(context).build()
Java
ExoPlayer player = new ExoPlayer.Builder(context).build();
Puoi creare il media player utilizzando il metodo del ciclo di vita onCreate()
della
Activity
, Fragment
o Service
dove si trova.
Il Builder
include
una serie di opzioni di personalizzazione che potrebbero interessarti, ad esempio:
setAudioAttributes()
per configurare la gestione del focus audiosetHandleAudioBecomingNoisy()
per configurare il comportamento di riproduzione quando un dispositivo di output audio è disconnessosetTrackSelector()
per configurare la selezione delle tracce
Media3 fornisce un componente dell'interfaccia utente PlayerView
che puoi includere
di layout. Questo componente incapsula un elemento PlayerControlView
per la riproduzione
controlli, SubtitleView
per la visualizzazione dei sottotitoli e Surface
per il rendering
video.
Preparazione del player
Aggiungi elementi multimediali a una playlist per
con metodi quali
setMediaItem()
:
e addMediaItem()
.
Quindi, chiama prepare()
per
iniziare a caricare contenuti multimediali
e acquisire le risorse necessarie.
Non eseguire questi passaggi prima che l'app sia in primo piano. Se le tue
giocatore è in un Activity
o Fragment
, questo significa preparare il player nel
onStart()
metodo del ciclo di vita sul livello API 24 e versioni successive o onResume()
del ciclo di vita con livello API 23 e precedenti. Per un giocatore in un Service
,
puoi prepararlo in onCreate()
.
Controllare il player
Dopo aver preparato il player, puoi controllare la riproduzione richiamando metodi sul player, ad esempio:
play()
epause()
per avviare e mettere in pausa la riproduzioneseekTo()
per cercare di una posizione all'interno dell'elemento multimediale correnteseekToNextMediaItem()
eseekToPreviousMediaItem()
per spostarti nella playlist
I componenti dell'interfaccia utente come PlayerView
o PlayerControlView
verranno aggiornati
di conseguenza quando associate a un player.
Rilascia il player
La riproduzione può richiedere risorse limitate, come i video
di decodifica, quindi è importante chiamare release()
sul tuo player per liberare risorse quando il player non è più necessario.
Se il player si trova in un Activity
o Fragment
, rilascia il player
onStop()
metodo del ciclo di vita sul livello API 24 e versioni successive o onPause()
di livello API 23 e precedenti. Per un giocatore in un Service
, puoi:
rilascialo in onDestroy()
.
Gestione della riproduzione con una sessione multimediale
Su Android, le sessioni multimediali offrono un modo standardizzato di interagire con un contenuto multimediale. oltre i confini del processo. Connessione di una sessione multimediale al player in corso... ti consente di pubblicizzare la tua riproduzione di contenuti multimediali esternamente e di riceverne da fonti esterne, ad esempio per l'integrazione controlli multimediali di sistema su dispositivi mobili e dispositivi dispositivi con lo schermo.
Per utilizzare le sessioni multimediali, aggiungi una dipendenza nel modulo Sessione Media3:
implementation "androidx.media3:media3-session:1.4.0"
Creare una sessione multimediale
Puoi creare un MediaSession
dopo aver inizializzato un player nel seguente modo:
Kotlin
val player = ExoPlayer.Builder(context).build() val mediaSession = MediaSession.Builder(context, player).build()
Java
ExoPlayer player = new ExoPlayer.Builder(context).build(); MediaSession mediaSession = new MediaSession.Builder(context, player).build();
Media3 sincronizza automaticamente lo stato di Player
con lo stato di
MediaSession
. Questo comando funziona con qualsiasi implementazione di tipo Player
, tra cui
ExoPlayer
, CastPlayer
o un
un'implementazione personalizzata.
Concedi il controllo ad altri clienti
Le app client possono implementare un controller multimediale
per controllare la riproduzione della sessione multimediale. Per ricevere queste richieste, imposta un valore
callback quando
crea il tuo MediaSession
.
Quando un controller sta per connettersi alla tua sessione multimediale,
onConnect()
. Puoi utilizzare il ControllerInfo
fornito
decidere se accettare
o rifiuta
la richiesta. Guarda un esempio nell'app demo Media3 Session.
Una volta collegato, un controller può inviare comandi di riproduzione alla sessione. La
poi delega questi comandi al player. Riproduzione e playlist
I comandi definiti nell'interfaccia Player
vengono gestiti automaticamente
durante la sessione.
Altri metodi di callback ti consentono di gestire, ad esempio, le richieste di
comandi di riproduzione personalizzati
e modificando la playlist. Questi callback includono in modo simile un oggetto ControllerInfo
, quindi
possono determinare il controllo dell'accesso richiesta per richiesta.
Riproduzione di contenuti multimediali in background
Per continuare a riprodurre contenuti multimediali quando la tua app non è in primo piano, ad esempio
per riprodurre musica, audiolibri o podcast anche quando l'utente non ha la tua app
aperta, i tuoi Player
e MediaSession
devono essere incapsulati in una
servizio in primo piano. Media3 fornisce
MediaSessionService
per questo scopo.
Implementazione di un MediaSessionService
Crea un corso che estenda MediaSessionService
e crea un'istanza per il tuo
MediaSession
nel metodo del ciclo di vita onCreate()
.
Kotlin
class PlaybackService : MediaSessionService() { private var mediaSession: MediaSession? = null // Create your Player and MediaSession in the onCreate lifecycle event override fun onCreate() { super.onCreate() val player = ExoPlayer.Builder(this).build() mediaSession = MediaSession.Builder(this, player).build() } // Remember to release the player and media session in onDestroy override fun onDestroy() { mediaSession?.run { player.release() release() mediaSession = null } super.onDestroy() } }
Java
public class PlaybackService extends MediaSessionService { private MediaSession mediaSession = null; @Override public void onCreate() { super.onCreate(); ExoPlayer player = new ExoPlayer.Builder(this).build(); mediaSession = new MediaSession.Builder(this, player).build(); } @Override public void onDestroy() { mediaSession.getPlayer().release(); mediaSession.release(); mediaSession = null; super.onDestroy(); } }
Nel file manifest, il corso Service
con un intent MediaSessionService
filtrare e richiedere l'autorizzazione FOREGROUND_SERVICE
per eseguire un primo piano
servizio:
<service
android:name=".PlaybackService"
android:foregroundServiceType="mediaPlayback"
android:exported="true">
<intent-filter>
<action android:name="androidx.media3.session.MediaSessionService"/>
</intent-filter>
</service>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
Infine, nella classe che hai creato, sostituisci il metodo onGetSession()
per controllare
l'accesso client alla tua sessione multimediale. Restituisci un MediaSession
per accettare il
richiesta di connessione o restituisci null
per rifiutare la richiesta.
Kotlin
// This example always accepts the connection request override fun onGetSession( controllerInfo: MediaSession.ControllerInfo ): MediaSession? = mediaSession
Java
@Override public MediaSession onGetSession(MediaSession.ControllerInfo controllerInfo) { // This example always accepts the connection request return mediaSession; }
Connessione all'interfaccia utente in corso...
Ora che la sessione multimediale si trova in un Service
separato da Activity
o
Fragment
nella UI del tuo player, puoi usare un MediaController
per collegarti
insieme. Nel metodo onStart()
di Activity
o Fragment
con
UI, crea una SessionToken
per MediaSession
, quindi usa SessionToken
per creare un MediaController
. Si verifica la creazione di un MediaController
in modo asincrono.
Kotlin
override fun onStart() { val sessionToken = SessionToken(this, ComponentName(this, PlaybackService::class.java)) val controllerFuture = MediaController.Builder(this, sessionToken).buildAsync() controllerFuture.addListener( { // Call controllerFuture.get() to retrieve the MediaController. // MediaController implements the Player interface, so it can be // attached to the PlayerView UI component. playerView.setPlayer(controllerFuture.get()) }, MoreExecutors.directExecutor() ) }
Java
@Override public void onStart() { SessionToken sessionToken = new SessionToken(this, new ComponentName(this, PlaybackService.class)); ListenableFuture<MediaController> controllerFuture = new MediaController.Builder(this, sessionToken).buildAsync(); controllerFuture.addListener(() -> { // Call controllerFuture.get() to retrieve the MediaController. // MediaController implements the Player interface, so it can be // attached to the PlayerView UI component. playerView.setPlayer(controllerFuture.get()); }, MoreExecutors.directExecutor()) }
MediaController
implementa l'interfaccia Player
, quindi puoi utilizzare la stessa
come play()
e pause()
per controllare la riproduzione. Simile ad altri
componenti, ricordati di rilasciare l'MediaController
quando non sarà più
necessaria, ad esempio il metodo del ciclo di vita onStop()
di un Activity
, richiamando
MediaController.releaseFuture()
.
Pubblicazione di una notifica
I servizi in primo piano sono tenuti a pubblicare una notifica quando sono attivi. R
MediaSessionService
creerà automaticamente un
Notifica MediaStyle
per
sotto forma di MediaNotification
.
Per fornire una notifica personalizzata, crea una
MediaNotification.Provider
con DefaultMediaNotificationProvider.Builder
oppure creando un'implementazione personalizzata dell'interfaccia del provider. Aggiungi il tuo
fornitore al tuo MediaSession
con
setMediaNotificationProvider
Pubblicizzare la raccolta di contenuti
Un MediaLibraryService
si basa su MediaSessionService
consentendo al client
app per sfogliare i contenuti multimediali forniti dalla tua app. Le app client implementano
MediaBrowser
per interagire
con il tuo MediaLibraryService
.
L'implementazione di un MediaLibraryService
è simile all'implementazione di un
MediaSessionService
, ad eccezione del fatto che in onGetSession()
devi restituire un
MediaLibrarySession
anziché MediaSession
. Rispetto a un
MediaSession.Callback
, i MediaLibrarySession.Callback
includono ulteriori
che consentono a un client del browser di esplorare i contenuti offerti dal tuo
servizio bibliotecario.
Analogamente a MediaSessionService
, dichiara il valore MediaLibraryService
nel
manifest e richiedi l'autorizzazione FOREGROUND_SERVICE
per eseguire un primo piano
servizio:
<service
android:name=".PlaybackService"
android:foregroundServiceType="mediaPlayback"
android:exported="true">
<intent-filter>
<action android:name="androidx.media3.session.MediaLibraryService"/>
<action android:name="android.media.browse.MediaBrowserService"/>
</intent-filter>
</service>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
L'esempio precedente include un filtro per intent sia per MediaLibraryService
e, per la compatibilità con le versioni precedenti, la versione MediaBrowserService
precedente. La
un filtro per intent aggiuntivo attiva le app client che utilizzano l'API MediaBrowserCompat
per riconoscere Service
.
Un MediaLibrarySession
ti consente di pubblicare la tua raccolta di contenuti in un albero
con una singola radice MediaItem
. Ogni MediaItem
nell'albero può avere
un numero qualsiasi di nodi MediaItem
secondari. Puoi pubblicare una directory radice diversa,
struttura diversa, in base alla richiesta dell'app client. Ad esempio, l'albero che
tornare a un cliente che cerca un elenco di
elementi multimediali consigliati potrebbe
contengono i nodi principali MediaItem
e un singolo livello di nodi MediaItem
secondari,
mentre la struttura ad albero che torni su un'altra app client potrebbe rappresentare
libreria completa di contenuti.
Creazione di un MediaLibrarySession
in corso...
Un MediaLibrarySession
estende l'API MediaSession
per aggiungere API di navigazione dei contenuti. Rispetto alla
chiamata di MediaSession
,
il callback MediaLibrarySession
aggiunge metodi come:
onGetLibraryRoot()
quando un client richiede la radiceMediaItem
di una struttura ad albero di contenutionGetChildren()
quando un client richiede gli elementi secondari di unMediaItem
nell'albero dei contenutionGetSearchResult()
quando un client richiede i risultati di ricerca dalla struttura ad albero dei contenuti per un query
I metodi di callback pertinenti includeranno un elemento LibraryParams
con indicatori aggiuntivi sul tipo di struttura ad albero dei contenuti che un'app client
a cui interessa.