Medien über MediaSession steuern

1. Einführung

Zuletzt aktualisiert: 09.09.2020

Welche Vorteile bietet das Hinzufügen einer MediaSession für die Videowiedergabe?

Mediensitzungen sind ein wichtiger Bestandteil der Verbindung zwischen der Android-Plattform und Media-Apps. Dadurch wird Android nicht nur darüber informiert, dass Medien wiedergegeben werden, damit Media-Aktionen an die richtige Sitzung weitergeleitet werden können, sondern auch die Plattform erfährt, was wiedergegeben wird und wie die Wiedergabe gesteuert werden kann.

Die Bereitstellung einer MediaSession über Ihre App bietet verschiedene Vorteile für Nutzer. Hier sind einige gute Beispiele.

Google Assistant

Nutzer können ganz einfach per Sprachbefehl mit Medien in Ihrer App interagieren, z. B. mit „Pause“, „Fortsetzen“ und „Weiter“. Metadaten aus Ihren Medien können auch verwendet werden, um Antworten darauf zu erhalten, was gerade abgespielt wird.

Android TV

Auf Geräten mit großen Bildschirmen kann Ihre Android TV-App herkömmliche Fernbedienungen für Nutzer mit Fernsehern verwenden, die HDMI‑CEC unterstützen. 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. Mit dieser Funktion können auf dem Sperrbildschirm Mediensteuerelemente und Grafiken angezeigt werden. Dieses Verhalten variiert je nach Android-Version.

Hintergrundmedien

Medien können in allen diesen Szenarien gesteuert werden, auch wenn die App, die die Medien wiedergibt, im Hintergrund ausgeführt wird.

Ambient Computing

Wenn Sie Ihre Medien mit Daten dazu bereitstellen, was gerade wiedergegeben wird und wie die Wiedergabe gesteuert werden kann, können Sie eine Brücke zwischen Geräten schlagen, sodass Nutzer auf verschiedene Arten mit den Medien interagieren können.

Umfang

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

  • Den aktiven Status der Mediensitzung korrekt wiedergeben
  • Mediensteuerung an ExoPlayer weiterleiten
  • Metadaten von Elementen in der Warteschlange an die Mediensitzung übergeben

Lerninhalte

  • Warum Mediensitzungen Nutzern mehr bieten
  • Media Session erstellen und ihren Status verwalten
  • MediaSession mit ExoPlayer verbinden
  • Metadaten von Elementen in der Wiedergabeliste in die Mediensitzung einbeziehen
  • Zusätzliche (benutzerdefinierte) Aktionen hinzufügen

In diesem Codelab geht es um das MediaSession SDK. Irrelevante Konzepte und Codeblöcke, einschließlich Details zur ExoPlayer-Implementierung, werden nicht behandelt, können aber einfach kopiert und eingefügt werden.

Voraussetzungen

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

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, verwendet aber keine Media-Sessions. Hier können wir uns die Vorschläge ansehen und sie hinzufü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 Hauptdemoprojekt unter demos/main.

Sie werden in Android Studio aufgefordert, den SDK-Pfad festzulegen. Wenn Probleme auftreten, sollten Sie die Empfehlungen zum Aktualisieren der IDE und der SDK-Tools befolgen.

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 grundlegenden Design der App vertraut zu machen. Es gibt zwei Aktivitäten: „SampleChooserActivity“ und „PlayerActivity“. Den Rest des Codelabs verbringen wir in PlayerActivity, wo die Medien tatsächlich wiedergegeben werden. Öffne also diese Klasse und fahre mit dem nächsten Abschnitt fort.

3. Media Session erstellen und ihren Status verwalten

Media Session erstellen

Öffnen Sie PlayerActivity.java. In dieser Klasse wird der ExoPlayer erstellt und seine Funktionen wie das Rendern von Videos auf dem Bildschirm werden verwaltet. In dieser Aktivität verbinden wir den ExoPlayer mit einer Media-Session.

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

private MediaSessionCompat mediaSession;
private MediaSessionConnector mediaSessionConnector;

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

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

Android Studio kann Ihnen helfen, diese Abhängigkeit automatisch hinzuzufügen, wenn Sie den Mauszeiger auf den Fehler beim Auflösen von MediaSessionConnector bewegen:

60055e4ad54fbb97.png

Fügen Sie schließlich die folgenden Zeilen hinzu, um die Klassenimporte aufzulösen:

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 Media Session und einen Media Session Connector erstellen, der als Vermittler zwischen der Media Session und ExoPlayer dient.

Der ideale Ort dafür ist der, an dem auch ExoPlayer erstellt wird. In unserer Demo-App können wir den Code an das Ende von initializePlayer() anhängen. Achten Sie darauf, diese Logik nach der Instanziierung des Players hinzuzufügen.

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

Mediensitzung beenden

Gib die Mediensitzung frei, wenn sie nicht mehr benötigt wird. Wenn wir ExoPlayer in releasePlayer() veröffentlichen, können wir auch den folgenden Code einfügen:

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

Status der Mediensitzung verwalten

Nachdem wir die Mediensitzung instanziiert haben, müssen wir dafür sorgen, 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 Anwendung keine Medien im Hintergrund abspielt, ist es wichtig, dass die Mediensitzung inaktiv wird, wenn der Nutzer die Aktivität verlässt:

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

Demo ausführen

  1. Schließen Sie ein Android-Gerät an oder starten Sie einen Emulator.
  2. Achten Sie darauf, dass „demo“ ausgewählt ist, um die Ausführung über die Android Studio-Symbolleiste zu starten. cb1ec4e50886874f.png
  3. Klicken Sie in der Android Studio-Symbolleiste auf 9d8fb3a9ddf12827.png.
  4. Wähle nach dem Starten der App auf deinem Gerät einen Videostream aus, der abgespielt werden soll.
  5. Sobald die Wiedergabe beginnt, können Sie 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 erfahren Sie, wie Android Ihre Mediensitzung sieht. Insbesondere können Sie im Feld „Aktion“ nachsehen, welche Aktionen unterstützt werden. Die hier angezeigte Zahl ist eine Kombination aus Aktions-IDs, wie im PlaybackState-Objekt deklariert. So sehen Sie die Ausführung der Mediensitzung: adb shell dumpsys media_session
  2. Wenn Sie ein physisches Gerät mit einem Mikrofon verwenden, versuchen Sie, Google Assistant zu aktivieren und Sprachbefehle wie „Pausiere“ zu geben. „Fortsetzen“ „Spule eine Minute vor.“

b8dda02a6fb0f6a4.png *ExoPlayer-Beispiel auf Android TV.*

4. Metadaten von Elementen in der Wiedergabeliste einbeziehen

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

TimelineQueueNavigator hinzufügen

In ExoPlayer wird die Struktur von Media als Zeitachse dargestellt. Weitere Informationen zur Funktionsweise finden Sie im Timeline-Objekt von ExoPlayer. Durch diese Struktur können wir informiert werden, wenn sich Inhalte ändern, und auf Anfrage Metadaten zu den aktuell wiedergegebenen Inhalten bereitstellen.

Dazu definieren wir einen TimelineQueueNavigator. Suchen Sie in initializePlayer() nach der Instanziierung von MediaSessionConnector und fügen Sie eine Implementierung von TimelineQueueNavigator nach mediaSession ein.

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

Beheben Sie die Klassenimporte, indem Sie Folgendes hinzufügen:

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

Der Parameter windowIndex entspricht dem Element mit diesem Index in der Wiedergabeliste.

Nachdem Sie einige Metadaten hinzugefügt haben, können Sie testen, ob Assistant versteht, was gerade wiedergegeben wird. Rufen Sie während der Wiedergabe eines Videos auf Android TV Assistant auf und fragen Sie „Was läuft gerade?“.

6c7fc0cb853cbc38.png

5. Gesten anpassen

Vielleicht unterstützt dein Player einige Aktionen nicht oder du möchtest Unterstützung für weitere Aktionen hinzufügen. Sehen wir uns nun die Media-Sitzung genauer an, in der wir zuvor unseren MediaSessionConnector in initializePlayer() erstellt haben.

Unterstützte Aktionen deklarieren

Mit mediaSessionConnector.setEnabledPlaybackActions() kannst du anpassen, welche Aktionen die Mediensitzung unterstützen soll.

Das vollständige Set ist:

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 auf der Plattform verfügbar gemacht werden:

  1. Starten Sie wie gewohnt ein Video.
  2. Führen Sie adb shell dumpsys media_session aus, um zu sehen, wie Android die Metadaten aus Ihrer Mediensitzung interpretiert.
  3. Suchen Sie die Zeile mit den Metadaten und prüfen Sie, ob Titel und Beschreibung enthalten 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 erweitern. In diesem Abschnitt fügen wir nur Unterstützung für Untertitel hinzu.

Untertitel

Durch die Unterstützung von Untertiteln in Mediensitzungen können Nutzer sie per Sprachbefehl ein- und ausschalten. Fügen Sie Folgendes an der Stelle hinzu, an der Sie den Media-Session-Connector initialisiert haben:

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 schließlich alle fehlenden Importe.

Sie können dies testen, indem Sie Google Assistant auf Android TV aufrufen und „Untertitel aktivieren“ sagen. Sehen Sie in Logcat nach, wie diese Aufrufe in Ihren Code erfolgen.

6. Glückwunsch

Sehr gut, Sie haben dem Beispiel Media-Sitzungen hinzugefügt.

Sie haben eine enorme Menge an Funktionen erhalten, indem Sie:

  • eine Media Session hinzufügen,
  • Mediensitzungen mit einer Instanz von ExoPlayer verbinden
  • Metadaten und zusätzliche Aktionen hinzufügen

Sie kennen jetzt die wichtigsten Schritte, die erforderlich sind, um eine Media-App zu optimieren und Nutzern eine vielseitigere Nutzung zu ermöglichen.

Eine letzte Anmerkung

Dieses Codelab basiert auf einem Beispiel aus dem ExoPlayer-Quellcode. Sie müssen ExoPlayer nicht aus der Quelle verwenden. Es wird empfohlen, stattdessen die Abhängigkeiten für ExoPlayer und MediaSessionConnector abzurufen, damit Sie leichter auf dem neuesten Stand bleiben können.

Ersetzen Sie dazu einfach die Projektabhängigkeiten, z. B.:

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

um aus Maven-Repositories abzurufen, z. B.:

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

Referenzdokumente