Controllo dei contenuti multimediali tramite MediaSession

1. Introduzione

Ultimo aggiornamento: 09-09-2020

Quali sono i vantaggi dell'aggiunta di una MediaSession per la riproduzione dei video?

Le sessioni multimediali sono un collegamento fondamentale tra la piattaforma Android e le app multimediali. Non solo informa Android che i contenuti multimediali sono in riproduzione, in modo che possa inoltrare le azioni multimediali alla sessione corretta, ma comunica anche alla piattaforma cosa è in riproduzione e come può essere controllato.

L'esposizione di una MediaSession tramite la tua app offre agli utenti diversi vantaggi. Ecco alcuni ottimi esempi.

Assistente Google

Gli utenti possono interagire facilmente con i contenuti multimediali nella tua app tramite comandi vocali come "Metti in pausa", "Riproduci" e "Avanti". I metadati dei tuoi contenuti multimediali possono essere utilizzati anche per ricevere risposte su ciò che è attualmente in riproduzione.

Android TV

Per le esperienze sullo schermo di casa, la tua app Android TV può utilizzare i telecomandi tradizionali per gli utenti con TV che supportano HDMI-CEC. I comandi emessi dai pulsanti di riproduzione/pausa, stop, avanti e precedente vengono inoltrati all'app.

Controlli multimediali sullo schermo

A partire da Android 4.0 (livello API 14), il sistema può accedere allo stato di riproduzione e ai metadati di una sessione multimediale. Questa funzionalità consente alla schermata di blocco di mostrare i controlli multimediali e l'artwork. Questo comportamento varia in base alla versione di Android.

Contenuti multimediali in background

I contenuti multimediali possono essere controllati in uno di questi scenari anche se l'app che li riproduce è in esecuzione in background.

Computing ambientale

Se mostri i tuoi contenuti multimediali con dati su cosa viene riprodotto e su come può essere controllato, puoi creare un ponte tra i dispositivi in modo che gli utenti possano interagire con i contenuti in vari modi.

Cosa creerai

In questo codelab espandi l'esempio Exoplayer esistente per aggiungere il supporto della sessione multimediale. La tua app sarà in grado di:

  • Riflettere correttamente lo stato attivo della sessione multimediale
  • Inoltra i controlli multimediali a ExoPlayer
  • Passare i metadati degli elementi in coda alla sessione multimediale

Cosa imparerai a fare

  • Perché le sessioni multimediali offrono agli utenti un'esperienza più completa
  • Come creare una sessione multimediale e gestirne lo stato
  • Come collegare una sessione multimediale a ExoPlayer
  • Come includere i metadati degli elementi nella coda di riproduzione nella sessione multimediale
  • Come aggiungere azioni aggiuntive (personalizzate)

Questo codelab è incentrato sull'SDK MediaSession. Concetti e blocchi di codice non pertinenti, inclusi i dettagli sull'implementazione di ExoPlayer, non vengono discussi, ma sono forniti solo per operazioni di copia e incolla.

Che cosa ti serve

  • Una versione recente di Android Studio (3.5 o successive)
  • Conoscenza di base dello sviluppo di applicazioni per Android

2. Preparazione

Qual è il nostro punto di partenza?

Il nostro punto di partenza è la demo principale di ExoPlayer. Questa demo contiene video con controlli di riproduzione sullo schermo, ma non utilizza le sessioni multimediali out-of-the-box. È un'ottima opportunità per noi di aggiungerli.

Ottieni l'esempio ExoPlayer

Per iniziare, iniziamo con l'esempio ExoPlayer. Clona il repository GitHub eseguendo il codice riportato di seguito.

git clone https://github.com/google/ExoPlayer.git

Apri la demo

In Android Studio, apri il progetto demo principale in demos/main.

Android Studio ti chiederà di impostare il percorso dell'SDK. In caso di problemi, ti consigliamo di seguire i consigli per aggiornare gli strumenti IDE e SDK.

10e3b5c652186d57.png

Se ti viene chiesto di utilizzare la versione più recente di Gradle, aggiornala.

Prenditi un momento per comprendere i concetti di base della progettazione dell'app. Tieni presente che esistono due attività: SampleChooserActivity e PlayerActivity. Trascorreremo il resto del codelab in PlayerActivity, dove vengono riprodotti i contenuti multimediali, quindi apri questa classe e vai alla sezione successiva.

3. Creare una sessione multimediale e gestirne lo stato

Creare la sessione multimediale

Apri PlayerActivity.java. Questa classe crea ExoPlayer e gestisce le sue funzioni, ad esempio il rendering del video sullo schermo. In questa attività collegheremo ExoPlayer a una sessione multimediale.

Dichiara i due campi seguenti nella parte superiore della classe. Useremo questi campi in tutta la sezione.

private MediaSessionCompat mediaSession;
private MediaSessionConnector mediaSessionConnector;

Dovrai aggiungere la dipendenza del progetto "extension-mediasession" al file build.gradle a livello di modulo per "Modulo: demo":

implementation project(path: ':extension-mediasession')

Tieni presente che Android Studio può aiutarti ad aggiungere automaticamente questa dipendenza se passi il mouse sopra l'errore relativo alla risoluzione di MediaSessionConnector:

60055e4ad54fbb97.png

Infine, risolvi le importazioni dei corsi aggiungendo quanto segue:

import android.support.v4.media.session.MediaSessionCompat;
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;

Quando viene creata l'attività, dobbiamo creare una sessione multimediale e un connettore di sessione multimediale che fungano da intermediari tra la sessione multimediale ed ExoPlayer.

Il luogo ideale per inserirlo è anche dove viene creato ExoPlayer. Nella nostra app di dimostrazione, possiamo aggiungere il nostro codice alla fine di initializePlayer(). Assicurati di aggiungere questa logica dopo l'inizializzazione del player.

private void initializePlayer() {
  if (player == null) {
    ...
    player = ...
    ...
    mediaSession = new MediaSessionCompat(this, "sample");
    mediaSessionConnector = new MediaSessionConnector(mediaSession);
    mediaSessionConnector.setPlayer(player);
  }
  ...
}

Rilasciare la sessione multimediale

Rilascia la sessione multimediale quando non è più necessaria. Quando rilasciamo ExoPlayer in releasePlayer(), possiamo includere anche il seguente codice:

private void releasePlayer() {
  if (mediaSession != null) {
    mediaSession.release();
  }
  ...
}

Gestire lo stato della sessione multimediale

Ora che abbiamo creato l'istanza della sessione multimediale, dobbiamo assicurarci che il relativo stato venga riportato correttamente quando l'utente interagisce con l'attività.

Quando l'utente avvia l'attività, la sessione multimediale deve diventare attiva:

@Override
public void onStart() {
  ...
  if (mediaSession != null) {
    mediaSession.setActive(true);
  }
}

Poiché la nostra applicazione non riproduce i contenuti multimediali in background, è essenziale assicurarsi che la sessione multimediale diventi inattiva quando l'utente esce dall'attività:

@Override
public void onStop() {
  super.onStop();
  if (mediaSession != null) {
    mediaSession.setActive(false);
  }
  ...
}

Eseguiamo la demo

  1. Collega un dispositivo Android o avvia un emulatore.
  2. Assicurati che sia selezionata l'opzione "demo" per l'esecuzione dalla barra degli strumenti di Android Studio. cb1ec4e50886874f.png
  3. Fai clic su 9d8fb3a9ddf12827.png nella barra degli strumenti di Android Studio.
  4. Una volta avviata l'app sul dispositivo, seleziona uno stream video da riprodurre.
  5. Una volta avviata la riproduzione, usa i seguenti comandi adb per controllare la sessione multimediale:
adb shell media dispatch pause
adb shell media dispatch play
adb shell media dispatch play-pause
adb shell media dispatch fast-forward
adb shell media dispatch rewind
  1. Scopri anche come Android vede la tua sessione multimediale. In particolare, puoi controllare quali azioni sono supportate dal campo delle azioni. Il numero visualizzato qui è una combinazione di ID azione, come dichiarato nell'oggetto PlaybackState. Per visualizzare l'esecuzione della sessione multimediale: adb shell dumpsys media_session
  2. Se utilizzi un dispositivo fisico con microfono, prova a richiamare l'Assistente Google e a emettere comandi vocali, ad esempio "Metti in pausa". "Riprendi." "Vai avanti veloce di 1 minuto."

b8dda02a6fb0f6a4.pngEsempio di ExoPlayer in esecuzione su Android TV.

4. Includere i metadati degli elementi nella coda di riproduzione

Ora possiamo espandere le funzionalità supportate della nostra sessione multimediale in cui abbiamo creato in precedenza MediaSessionConnector in initializePlayer().

Aggiunta di un TimelineQueueNavigator

ExoPlayer rappresenta la struttura dei contenuti multimediali come una sequenza temporale. Per informazioni dettagliate su come funziona, consulta l'articolo sull'oggetto Timeline di ExoPlayer. Grazie a questa struttura, possiamo essere informati quando i contenuti cambiano ed esporre i metadati di ciò che viene riprodotto al momento, se richiesto.

Per farlo, definiamo un TimelineQueueNavigator. Individua l'istanza di MediaSessionConnector in initializePlayer() e aggiungi un'implementazione di TimelineQueueNavigator dopo l'inizializzazione di mediaSession.

mediaSessionConnector.setQueueNavigator(new TimelineQueueNavigator(mediaSession) {
  @Override
  public MediaDescriptionCompat getMediaDescription(Player player, int windowIndex) {
    return new MediaDescriptionCompat.Builder()
            .setTitle(player.getCurrentMediaItem().mediaMetadata.title)
            .setDescription("MediaDescription description for " + windowIndex)
            .setSubtitle("MediaDescription subtitle")
            .build();
  }
});

Risolvi le importazioni dei corsi aggiungendo:

import android.support.v4.media.MediaDescriptionCompat;
import com.google.android.exoplayer2.ext.mediasession.TimelineQueueNavigator;

Tieni presente che il parametro windowIndex corrisponde all'elemento di quell'indice nella coda di riproduzione.

Ora che hai aggiunto alcuni metadati, puoi verificare che l'assistente capisca cosa viene riprodotto. Mentre riproduci un video su Android TV, invoca l'assistente e chiedi "Cosa c'è in riproduzione?"

6c7fc0cb853cbc38.png

5. Personalizzare le azioni

Forse il tuo player non supporta alcune azioni o vorresti includere il supporto per altre? Ora esaminiamo più da vicino la sessione multimediale in cui abbiamo creato in precedenza MediaSessionConnector in initializePlayer().

Dichiarare le azioni supportate

Prova a utilizzare mediaSessionConnector.setEnabledPlaybackActions() per personalizzare le azioni che vuoi che la sessione multimediale supporti.

Tieni presente che il set completo è:

mediaSessionConnector.setEnabledPlaybackActions(
        PlaybackStateCompat.ACTION_PLAY_PAUSE
                | PlaybackStateCompat.ACTION_PLAY
                | PlaybackStateCompat.ACTION_PAUSE
                | PlaybackStateCompat.ACTION_SEEK_TO
                | PlaybackStateCompat.ACTION_FAST_FORWARD
                | PlaybackStateCompat.ACTION_REWIND
                | PlaybackStateCompat.ACTION_STOP
                | PlaybackStateCompat.ACTION_SET_REPEAT_MODE
                | PlaybackStateCompat.ACTION_SET_SHUFFLE_MODE
);

Vediamo di nuovo come questi dati vengono esposti alla piattaforma:

  1. Come prima, avvia un video.
  2. Scopri come Android vede i metadati della sessione multimediale eseguendo: adb shell dumpsys media_session
  3. Individua la riga contenente i metadati e verifica che il titolo e la descrizione siano inclusi e associati a com.google.android.exoplayer2.demo/sample.

Aggiunta di azioni aggiuntive

Possiamo espandere la sessione multimediale con alcune azioni aggiuntive. In questa sezione aggiungeremo solo il supporto per i sottotitoli codificati.

Sottotitoli codificati di supporto

L'aggiunta del supporto dei sottotitoli codificati alle sessioni multimediali consente agli utenti di attivarli e disattivarli tramite comandi vocali. Dove hai inizializzato il connettore della sessione multimediale, aggiungi quanto segue:

mediaSessionConnector.setCaptionCallback(new MediaSessionConnector.CaptionCallback() {
      @Override
      public void onSetCaptioningEnabled(Player player, boolean enabled) {
        Log.d("MediaSession", "onSetCaptioningEnabled: enabled=" + enabled);
      }

      @Override
      public boolean hasCaptions(Player player) {
        return true;
      }

      @Override
      public boolean onCommand(Player player, ControlDispatcher controlDispatcher, String command, Bundle extras, ResultReceiver cb) {
        return false;
      }
    }
);

Infine, risolvi eventuali importazioni mancanti.

Puoi verificare chiedendo all'Assistente Google su Android TV di attivare i sottotitoli codificati. Controlla i messaggi di Logcat per vedere come vengono chiamate nel codice.

6. Complimenti

Complimenti, hai aggiunto correttamente le sessioni multimediali al Sample.

Hai ottenuto una quantità enorme di funzionalità:

  • aggiungendo una sessione multimediale.
  • la connessione delle sessioni multimediali a un'istanza di ExoPlayer,
  • aggiungendo metadati e azioni aggiuntive.

Ora conosci i passaggi chiave necessari per arricchire un'app multimediale e offrire agli utenti un'esperienza più versatile.

Un ultimo commento

Questo codelab è stato creato su un esempio del codice sorgente di ExoPlayer. Non è necessario utilizzare ExoPlayer dal codice sorgente e ti consigliamo di estrarre le dipendenze per ExoPlayer e MediaSessionConnector per aggiornarti più facilmente con le ultime release.

A tal fine, sostituisci le dipendenze del progetto, ad esempio:

implementation project(modulePrefix + 'library-core')
implementation project(path: ':extension-mediasession')

per estrarre i dati dai repository Maven, ad esempio:

implementation 'com.google.android.exoplayer:exoplayer-core:2.+'
implementation 'com.google.android.exoplayer:extension-mediasession:2.+'

Documentazione di riferimento