Medien über MediaSession steuern

1. Einführung

Zuletzt aktualisiert:09.09.2020

Welche Vorteile bietet das Hinzufügen einer MediaSession in Bezug auf die Videowiedergabe?

Mediensitzungen sind ein wichtiges Bindeglied zwischen der Android-Plattform und den Medien-Apps. Android informiert damit nicht nur, dass Medien abgespielt werden, sodass Medienaktionen in die richtige Sitzung weitergeleitet werden können, sondern auch die Plattform, was gerade abgespielt wird und wie sie gesteuert werden kann.

Die Bereitstellung einer MediaSession über Ihre App bietet Nutzern verschiedene Vorteile. Hier sind ein paar tolle Beispiele.

Google Assistant

Nutzer können über Sprachbefehle wie „Pause“, „Fortsetzen“, und „Weiter“. Metadaten von deinen Medien können auch verwendet werden, um Informationen zu dem, was gerade abgespielt wird, zu erhalten.

Android TV

Auf großen Bildschirmen kann Ihre Android TV App für Nutzer mit Fernsehern, die HDMI-CEC unterstützen, herkömmliche Fernbedienungen verwenden. Befehle, die über die Schaltflächen „Wiedergabe/Pause“, „Stopp“, „Weiter“ und „Zurück“ ausgegeben werden, werden an Ihre App weitergeleitet.

Mediensteuerung auf dem Bildschirm

Ab Android 4.0 (API-Level 14) kann das System auf den Wiedergabestatus und die Metadaten einer Mediensitzung zugreifen. Dadurch können auf dem Sperrbildschirm Mediensteuerelemente und Artwork angezeigt werden. Dieses Verhalten variiert je nach Android-Version.

Hintergrundmedien

In jedem dieser Szenarien können Medien gesteuert werden, auch wenn die App, die die Medien abspielt, im Hintergrund ausgeführt wird.

Umgebungsverarbeitung

Wenn Sie Ihre Medien mit Daten darüber, was gerade abgespielt wird und wie sie gesteuert werden können, verfügbar machen, kann dies eine Verbindung zwischen den Geräten herstellen, sodass die Nutzer auf unterschiedliche Weise mit ihnen interagieren können.

Inhalt

In diesem Codelab erweitern Sie das vorhandene Exoplayer-Beispiel um Unterstützung für Mediensitzungen. Mit der Anwendung können Sie Folgendes tun:

  • Der aktive Status der Mediensitzung muss korrekt wiedergegeben werden.
  • Mediensteuerelemente an ExoPlayer weiterleiten
  • Metadaten der Elemente in der Warteschlange an die Mediensitzung übergeben

Aufgaben in diesem Lab

  • Warum Mediensitzungen die Nutzererfahrung verbessern
  • Mediensitzung erstellen und Status verwalten
  • So verbinden Sie eine Mediensitzung mit ExoPlayer
  • So fügen Sie der Mediensitzung Metadaten von Elementen der Wiedergabewarteschlange hinzu
  • Zusätzliche (benutzerdefinierte) Aktionen hinzufügen

In diesem Codelab geht es um das MediaSession SDK. Nicht relevante Konzepte und Codeblöcke, einschließlich Details zur ExoPlayer-Implementierung, werden nicht erörtert. Sie werden jedoch bereitgestellt, damit Sie sie einfach kopieren und einfügen können.

Voraussetzungen

  • Eine aktuelle Version von Android Studio (3.5 oder höher)
  • Grundkenntnisse in der Entwicklung von Android-Apps

2. Einrichtung

Was ist unser Ausgangspunkt?

Unser Ausgangspunkt ist die Hauptdemo von ExoPlayer. Diese Demo enthält Videos mit Steuerelementen für die Wiedergabe auf dem Bildschirm, ohne dass standardmäßig Mediensitzungen verwendet werden. Das ist der perfekte Ort, um direkt ins Detail zu gehen und sie hinzuzufügen.

ExoPlayer-Beispiel abrufen

Beginnen wir mit dem ExoPlayer-Beispiel. Klonen Sie das GitHub-Repository, indem Sie den folgenden Code ausführen.

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

Demo öffnen

Öffnen Sie in Android Studio das Hauptprojekt des Demomodus unter demos/main.

Android Studio fordert Sie auf, den SDK-Pfad festzulegen. Sie können die Empfehlungen zum Aktualisieren der IDE- und SDK-Tools befolgen, wenn Probleme auftreten.

10e3b5c652186d57.png

Wenn Sie aufgefordert werden, die neueste Gradle-Version zu verwenden, aktualisieren Sie sie.

Nehmen Sie sich einen Moment Zeit, um sich mit dem Aufbau der App vertraut zu machen. Beachten Sie, dass es zwei Aktivitäten gibt: SampleChooserActivity und PlayerActivity. Den Rest des Codelabs werden wir in PlayerActivity verbringen, wo die Medien tatsächlich wiedergegeben werden. Öffnen Sie also diesen Kurs und fahren Sie mit dem nächsten Abschnitt fort.

3. Mediensitzung erstellen und ihren Status verwalten

Mediensitzung erstellen

Öffnen Sie PlayerActivity.java. Diese Klasse erstellt den ExoPlayer und verwaltet seine Funktionen, z. B. das Rendern von Videos auf dem Bildschirm. In dieser Aktivität verbinden wir den ExoPlayer mit einer Mediensitzung.

Deklarieren Sie oben in der Klasse die folgenden beiden Felder. Wir werden diese Felder in diesem Abschnitt verwenden.

private MediaSessionCompat mediaSession;
private MediaSessionConnector mediaSessionConnector;

Sie müssen die Datei „extension-mediasession“ hinzufügen Projektabhängigkeit in build.gradle auf Modulebene für „Module: demo“:

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

Android Studio kann Ihnen beim automatischen Hinzufügen dieser Abhängigkeit helfen, wenn Sie den Mauszeiger über den Fehler beim Zuordnen von MediaSessionConnector bewegen:

60055e4ad54fbb97.png

Klären Sie abschließend die Klassenimporte auf, indem Sie Folgendes hinzufügen:

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

Wenn die Aktivität erstellt wird, möchten wir eine Mediensitzung und einen Mediensitzungs-Connector erstellen, der als Vermittler zwischen der Mediensitzung und dem ExoPlayer dient.

Am besten fügen Sie ihn dort ein, wo auch der ExoPlayer erstellt wird. In unserer Demo-App können wir unseren Code an das Ende von initializePlayer() anhängen. Diese Logik muss nach der Instanziierung des Players hinzugefügt werden.

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

Mediensitzung veröffentlichen

Geben Sie die Mediensitzung frei, wenn sie nicht mehr benötigt wird. Wenn wir ExoPlayer in releasePlayer() veröffentlichen, können wir dazu auch den folgenden Code einbinden:

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

Mediensitzungsstatus verwalten

Nachdem die Mediensitzung instanziiert wurde, müssen wir sicherstellen, dass ihr Status korrekt wiedergegeben wird, wenn der Nutzer mit der Aktivität interagiert.

Wenn der Nutzer die Aktivität startet, sollte die Mediensitzung aktiv werden:

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

Da unsere App keine Medien im Hintergrund abspielt, muss die Mediensitzung inaktiv werden, wenn der Nutzer die Aktivität verlässt:

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

Führen Sie die Demo aus.

  1. Schließe ein Android-Gerät an oder starte einen Emulator.
  2. Stellen Sie sicher, dass „Demo“ zur Ausführung in der Android Studio-Symbolleiste ausgewählt ist. cb1ec4e50886874f.png
  3. Klicken Sie in der Android Studio-Symbolleiste auf 9d8fb3a9ddf12827.png.
  4. Sobald die App auf Ihrem Gerät gestartet wurde, wählen Sie einen Videostream für die Wiedergabe aus.
  5. Sobald die Wiedergabe beginnt, kannst du die Mediensitzung mit den folgenden adb-Befehlen steuern:
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. Außerdem erfährst du, wie Android deine Mediensitzung sieht. Im Aktionsfeld können Sie insbesondere überprüfen, welche Aktionen unterstützt werden. Die Zahl, die du hier siehst, ist eine Kombination aus Aktions-IDs, die im PlaybackState-Objekt deklariert sind. So rufen Sie die Ausführung der Mediensitzung auf: adb shell dumpsys media_session
  2. Wenn Sie ein physisches Gerät mit Mikrofon verwenden, versuchen Sie, Google Assistant aufzurufen und Sprachbefehle wie „Pause“ zu geben. „Fortsetzen“ „Spule eine Minute vor.“

b8dda02a6fb0f6a4.pngExoPlayer-Beispiel für Android TV

4. Metadaten von Elementen in die Wiedergabewarteschlange aufnehmen

Wir können jetzt die unterstützten Funktionen unserer Mediensitzung, in der wir zuvor den MediaSessionConnector in initializePlayer() erstellt haben, erweitern.

TimelineQueueNavigator hinzufügen

ExoPlayer stellt die Struktur von Medien als Zeitachse dar. Nehmen Sie sich einen Moment Zeit, um mehr über das ExoPlayer-Zeitachsenobjekt zu erfahren, um zu erfahren, wie das funktioniert. Wenn wir diese Struktur nutzen, werden wir informiert, wenn sich Inhalte ändern, und können Metadaten zu dem, was gerade abgespielt wird, auf Anfrage anzeigen.

Um dies zu erreichen, definieren wir einen TimelineQueueNavigator. Suchen Sie die Instanziierung von MediaSessionConnector in initializePlayer() und fügen Sie eine Implementierung von TimelineQueueNavigator hinzu, nachdem mediaSession initialisiert wurde.

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();
  }
});

Schließen Sie die Klassenimporte auf, indem Sie Folgendes hinzufügen:

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

Der windowIndex-Parameter entspricht dem Element dieses Index in der Wiedergabewarteschlange.

Nachdem du einige Metadaten hinzugefügt hast, kannst du testen, ob Assistant versteht, was gerade abgespielt wird. Während du ein Video auf Android TV abspielst, kannst du Assistant aufrufen und fragen: „Was läuft gerade?“

6c7fc0cb853cbc38.png

5. Aktionen anpassen

Vielleicht unterstützt dein Player einige Aktionen nicht oder möchtest du weitere hinzufügen? Sehen wir uns nun die Mediensitzung, in der wir zuvor in initializePlayer() den MediaSessionConnector erstellt haben, etwas genauer an.

Unterstützte Aktionen deklarieren

Verwende mediaSessionConnector.setEnabledPlaybackActions(), um festzulegen, welche Aktionen von der Mediensitzung unterstützt werden sollen.

Beachten Sie, dass der vollständige Satz:

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
);

Sehen wir uns noch einmal an, wie diese Daten der Plattform zugänglich gemacht werden:

  1. Starte wie zuvor ein Video.
  2. So können Sie herausfinden, wie Android die Metadaten Ihrer Mediensitzung sieht, indem Sie Folgendes ausführen: adb shell dumpsys media_session
  3. Suche die Zeile mit den Metadaten und achte darauf, dass Titel und Beschreibung enthalten sind und mit com.google.android.exoplayer2.demo/sample verknüpft sind.

Zusätzliche Aktionen hinzufügen

Wir können unsere Mediensitzung mit einigen zusätzlichen Aktionen ausweiten. In diesem Abschnitt werden nur Untertitel unterstützt.

Unterstützende Untertitel

Durch die Unterstützung von Untertiteln in Mediensitzungen können Nutzer diese per Sprachbefehl aktivieren und deaktivieren. Fügen Sie an der Stelle, an der Sie den Connector für Mediensitzungen initialisiert haben, Folgendes hinzu:

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;
      }
    }
);

Beheben Sie abschließend alle fehlenden Importe.

Das kannst du testen, indem du Google Assistant auf Android TV aufrufst und „Untertitel aktivieren“ sagst. Suchen Sie in Logcat nach Nachrichten, um zu sehen, wie dadurch Ihr Code aufgerufen wird.

6. Glückwunsch

Sie haben der Leseprobe nun Mediensitzungen hinzugefügt.

Diese enorme Funktionalität bietet:

  • eine Mediensitzung hinzufügen,
  • Verbindung von Mediensitzungen mit einer Instanz von ExoPlayer
  • Metadaten und weitere Aktionen hinzufügen.

Du kennst jetzt die wichtigsten Schritte, die erforderlich sind, um eine Medien-App zu optimieren und den Nutzern eine vielseitigere Oberfläche zu bieten.

Abschließende Bemerkung

Dieses Codelab baut auf einem Beispiel aus dem ExoPlayer-Quellcode auf. ExoPlayer muss nicht aus der Quelle verwendet werden. Stattdessen wird empfohlen, stattdessen die Abhängigkeiten für ExoPlayer und MediaSessionConnector abzurufen, damit Sie immer die neuesten Versionen kennen.

Ersetzen Sie dazu einfach die folgenden Projektabhängigkeiten:

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

aus Maven-Repositories abrufen können, z. B.:

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

Referenzdokumente