1. Einführung
Zuletzt aktualisiert:9. September 2020
Welche Vorteile bietet die Einbindung einer MediaSession bei der Videowiedergabe?
Mediensitzungen sind eine wichtige Verknüpfung zwischen der Android-Plattform und Medien-Apps. Sie informiert Android nicht nur darüber, dass Medien wiedergegeben werden, damit Medienaktionen an die richtige Sitzung weitergeleitet werden können, sondern auch darüber, was wiedergegeben wird und wie es gesteuert werden kann.
Wenn Sie eine MediaSession über Ihre App freigeben, hat das verschiedene Vorteile für die Nutzer. Hier sind einige gute Beispiele.
Google Assistant
Nutzer können ganz einfach über Sprachbefehle wie „Pause“, „Weiter“ und „Zurück“ mit Medien in Ihrer App interagieren. Anhand der Metadaten Ihrer Medien können Sie auch herausfinden, was gerade abgespielt wird.
Android TV
Auf einem großen Bildschirm kann Ihre Android TV App herkömmliche Fernbedienungen für Nutzer mit Fernsehern nutzen, die HDMI-CEC unterstützen. Befehle, die über die Schaltflächen „Wiedergabe/Pause“, „Stopp“, „Weiter“ und „Zurück“ erteilt werden, werden an Ihre App weitergeleitet.
On-Screen-Mediensteuerung
Ab Android 4.0 (API-Ebene 14) kann das System auf den Wiedergabestatus und die Metadaten einer Mediensitzung zugreifen. Mit dieser Funktion können auf dem Sperrbildschirm Mediensteuerelemente und Artwork angezeigt werden. Das Verhalten variiert je nach Android-Version.
Hintergrundmedien
Medien können in jedem dieser Szenarien gesteuert werden, auch wenn die App, in der die Medien wiedergegeben werden, im Hintergrund ausgeführt wird.
Ambient Computing
Wenn du deine Medien mit Daten darüber veröffentlichst, was gerade wiedergegeben wird und wie es gesteuert werden kann, können Nutzer auf verschiedenen Geräten damit interagieren.
Umfang
In diesem Codelab erweitern Sie das vorhandene Exoplayer-Beispiel, um die Unterstützung von Mediensitzungen hinzuzufügen. Mit der Anwendung können Sie Folgendes tun:
- Der aktive Status der Mediensitzung muss korrekt wiedergegeben werden.
- Mediensteuerung an ExoPlayer weiterleiten
- Metadaten der Elemente in der Warteschlange an die Mediensitzung übergeben
Aufgaben in diesem Lab
- Warum Mediensitzungen Nutzern mehr bieten
- Mediensitzung erstellen und Status verwalten
- Mediensitzung mit ExoPlayer verbinden
- Metadaten von Elementen in der Wiedergabeliste in die Mediensitzung einbinden
- Zusätzliche (benutzerdefinierte) Aktionen hinzufügen
In diesem Codelab liegt der Schwerpunkt auf dem MediaSession SDK. Auf irrelevante Konzepte und Codeblöcke wird nicht näher eingegangen, aber Sie können die entsprechenden Codeblöcke einfach kopieren und einfügen.
Voraussetzungen
- Eine aktuelle Version von Android Studio (3.5 oder höher)
- Grundkenntnisse in der Entwicklung von Android-Anwendungen
2. Einrichtung
Wo fangen wir an?
Ausgangspunkt ist die Hauptdemo von ExoPlayer. Diese Demo enthält Videos mit Wiedergabesteuerungen auf dem Bildschirm, aber keine standardmäßigen Mediensitzungen. Das ist eine gute Gelegenheit, 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 Hauptdemoprojekt unter demos/main
.
Sie werden von Android Studio aufgefordert, den SDK-Pfad festzulegen. Wenn Probleme auftreten, folgen Sie den Empfehlungen zum Aktualisieren der IDE- und SDK-Tools.
Wenn Sie aufgefordert werden, die neueste Gradle-Version zu verwenden, aktualisieren Sie sie.
Sehen wir uns kurz an, wie die App aufgebaut ist. Es gibt zwei Aktivitäten: SampleChooserActivity und PlayerActivity. Den Rest des Codelabs verbringen wir in PlayerActivity, wo die Medien tatsächlich wiedergegeben werden. Öffnen Sie also diese Klasse und fahren Sie mit dem nächsten Abschnitt fort.
3. Mediensitzung erstellen und Status verwalten
Mediensitzungen erstellen
Öffnen Sie PlayerActivity.java
. Diese Klasse erstellt den ExoPlayer und verwaltet seine Funktionen, z. B. das Rendern von Video auf dem Bildschirm. In dieser Aktivität verbinden wir den ExoPlayer mit einer Mediensitzung.
Deklarieren Sie die folgenden beiden Felder oben in der Klasse. Diese Felder werden in diesem Abschnitt verwendet.
private MediaSessionCompat mediaSession;
private MediaSessionConnector mediaSessionConnector;
Fügen Sie die Projektabhängigkeit „extension-mediasession“ in die build.gradle
auf Modulebene für „Modul: demo“ ein:
implementation project(path: ':extension-mediasession')
Android Studio kann Ihnen beim automatischen Hinzufügen dieser Abhängigkeit helfen, wenn Sie den Mauszeiger auf den Fehler bei der Auflösung von MediaSessionConnector bewegen:
Lösen Sie abschließend die Klassenimporte, 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üssen wir eine Mediensitzung und einen Mediensitzungs-Connector erstellen, der als Vermittler zwischen der Mediensitzung und ExoPlayer dient.
Der ideale Ort für die Einfügung ist dort, wo auch ExoPlayer erstellt wird. In unserer Demo-App können wir unseren Code an das Ende von initializePlayer()
anhängen. Füge diese Logik nach der Instanziierung des Players hinzu.
private void initializePlayer() {
if (player == null) {
...
player = ...
...
mediaSession = new MediaSessionCompat(this, "sample");
mediaSessionConnector = new MediaSessionConnector(mediaSession);
mediaSessionConnector.setPlayer(player);
}
...
}
Mediensitzungen freigeben
Die Mediensitzung freigeben, 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 widergespiegelt 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 in unserer App keine Medien im Hintergrund abgespielt werden, 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);
}
...
}
Demo starten
- Schließen Sie ein Android-Gerät an oder starten Sie einen Emulator.
- Achten Sie darauf, dass „demo“ in der Android Studio-Symbolleiste ausgewählt ist.
- Klicken Sie in der Android Studio-Symbolleiste auf
.
- Wähle nach dem Starten der App auf deinem Gerät einen Videostream für die Wiedergabe aus.
- Sobald die Wiedergabe gestartet wurde, 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
- Außerdem sehen Sie, wie Android Ihre Mediensitzung sieht. Im Aktionsfeld sehen Sie, welche Aktionen unterstützt werden. Die hier angezeigte Zahl ist eine Kombination aus Aktions-IDs, wie im Objekt PlaybackState angegeben. So führen Sie die Mediensitzung aus:
adb shell dumpsys media_session
- Wenn Sie ein Gerät mit Mikrofon verwenden, können Sie Google Assistant aufrufen und Sprachbefehle wie „Pausieren“ geben. „Fortsetzen“ „1 Minute vorspulen“
ExoPlayer-Beispiel, das auf Android TV ausgeführt wird
4. Metadaten von Elementen in der Wiedergabeliste einschließen
Wir können jetzt die unterstützten Funktionen unserer Mediensitzung erweitern, in der wir zuvor unseren MediaSessionConnector in initializePlayer()
erstellt haben.
TimelineQueueNavigator hinzufügen
ExoPlayer stellt die Struktur von Medien als Zeitachse dar. Weitere Informationen dazu findest du im Hilfeartikel zum Zeitachseobjekt von ExoPlayer. So können wir informiert werden, wenn sich Inhalte ändern, und bei Bedarf Metadaten zu den aktuell wiedergegebenen Inhalten anzeigen.
Dazu definieren wir einen TimelineQueueNavigator. Suche in initializePlayer()
nach der Instanziierung von MediaSessionConnector und füge 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();
}
});
Beheben Sie die Probleme mit den Kursimporten, 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 dieses Index in der Wiedergabeliste.
Nachdem Sie einige Metadaten hinzugefügt haben, können Sie testen, ob Assistant versteht, was gerade abgespielt wird. Rufen Sie während der Wiedergabe eines Videos auf Android TV Assistant auf und fragen Sie: „Was läuft gerade?“
5. Aktionen 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 Mediensitzung genauer an, in der wir zuvor in initializePlayer()
unseren MediaSessionConnector erstellt haben.
Unterstützte Aktionen deklarieren
Mit mediaSessionConnector.setEnabledPlaybackActions()
kannst du festlegen, welche Aktionen die Mediensitzung unterstützen soll.
Der vollständige Satz besteht aus:
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 zur Verfügung gestellt werden:
- Starten Sie wie zuvor ein Video.
- So sehen Sie, wie Android die Metadaten Ihrer Mediensitzung sieht:
adb shell dumpsys media_session
- Suchen Sie die Zeile mit den Metadaten und prüfen Sie, ob der Titel und die Beschreibung enthalten und mit
com.google.android.exoplayer2.demo/sample
verknüpft sind.
Zusätzliche Aktionen hinzufügen
Wir können unsere Media-Sitzung um einige zusätzliche Aktionen erweitern. In diesem Abschnitt wird nur die Unterstützung für Untertitel hinzugefügt.
Untertitel
Wenn Sie die Untertitelung für Mediensitzungen unterstützen, können Nutzer sie per Sprachbefehl ein- und ausschalten. Fügen Sie dort, wo Sie den Media Session Connector 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.
Sie können dies testen, indem Sie Google Assistant auf Android TV aufrufen und „Untertitel aktivieren“ sagen. Sehen Sie in Logcat nach, ob es Nachrichten gibt, die Aufschluss darüber geben, wie der Code aufgerufen wird.
6. Glückwunsch
Sie haben dem Beispiel erfolgreich Mediensitzungen hinzugefügt.
Sie haben eine enorme Anzahl von Funktionen erhalten:
- eine Mediensitzung hinzufügen,
- Mediensitzungen mit einer Instanz von ExoPlayer verbinden,
- Metadaten und zusätzliche Aktionen hinzufügen.
Sie kennen jetzt die wichtigsten Schritte, um eine Medien-App zu erweitern und Nutzern mehr Funktionen zu bieten.
Eine letzte Bemerkung
Dieses Codelab basiert auf einem Beispiel aus dem ExoPlayer-Quellcode. Es ist nicht nötig, ExoPlayer aus der Quelle zu verwenden. Wir empfehlen stattdessen, die Abhängigkeiten für ExoPlayer und MediaSessionConnector abzurufen, damit du leichter auf dem neuesten Stand bleibst.
Ersetzen Sie dazu einfach die Projektabhängigkeiten, z. B.:
implementation project(modulePrefix + 'library-core')
implementation project(path: ':extension-mediasession')
um aus Maven-Repositories zu ziehen, z. B.:
implementation 'com.google.android.exoplayer:exoplayer-core:2.+'
implementation 'com.google.android.exoplayer:extension-mediasession:2.+'