Creare un'app di media player di base utilizzando Media3 ExoPlayer

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:

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.1"
implementation "androidx.media3:media3-ui:1.4.1"
implementation "androidx.media3:media3-common:1.4.1"

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.1 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:

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:

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.1"

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 principale diversa, oppure un 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

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 radice MediaItem di una struttura ad albero di contenuti
  • onGetChildren() quando un client richiede gli elementi secondari di un MediaItem nell'albero dei contenuti
  • onGetSearchResult() 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.