1. Wprowadzenie
Ostatnia aktualizacja: 2020-09-09
Jakie korzyści daje dodanie MediaSession do odtwarzania wideo?
Sesje multimediów stanowią integralne połączenie między platformą Android a aplikacjami do multimediów. Informuje on Androida nie tylko o tym, że odtwarzane są multimedia (aby mógł przekazywać działania związane z multimediami do odpowiedniej sesji), ale także o tym, co jest odtwarzane i jak można tym sterować.
Udostępnianie sesji multimedialnej w aplikacji ma wiele zalet, z których będą mogli korzystać użytkownicy. Oto kilka świetnych przykładów.
Asystent Google
Użytkownicy mogą łatwo wchodzić w interakcje z multimediami w Twojej aplikacji za pomocą poleceń głosowych, takich jak „Wstrzymaj”, „Wznów” i „Następny”. Metadane z multimediów mogą też służyć do uzyskiwania odpowiedzi na pytania o to, co jest obecnie odtwarzane.
Android TV
W przypadku dużych ekranów aplikacja na Androida TV może korzystać z tradycyjnych pilotów, jeśli użytkownicy mają telewizory obsługujące HDMI-CEC. Polecenia wydawane za pomocą przycisków odtwarzania/wstrzymywania, zatrzymywania, następny i poprzedni są przekazywane do aplikacji.
Sterowanie multimediami na ekranie
Począwszy od Androida 4.0 (poziom interfejsu API 14), system może uzyskiwać dostęp do stanu odtwarzania i metadanych sesji multimedialnej. Ta funkcja umożliwia wyświetlanie na ekranie blokady elementów sterujących multimediami i grafiki. To zachowanie różni się w zależności od wersji Androida.
Media w tle
W każdym z tych scenariuszy można sterować multimediami, nawet jeśli aplikacja odtwarzająca multimedia działa w tle.
Przetwarzanie rozpowszechnione
Udostępnianie multimediów wraz z informacjami o tym, co jest odtwarzane i jak można to kontrolować, może połączyć urządzenia, dzięki czemu użytkownicy będą mogli wchodzić w interakcje z multimediami na różne sposoby.
Co utworzysz
W tym ćwiczeniu rozszerzysz istniejący przykład ExoPlayera, aby dodać obsługę sesji multimedialnej. Twoja aplikacja będzie:
- prawidłowo odzwierciedlać stan aktywności sesji multimedialnej;
- Przekazywanie elementów sterujących multimediami do ExoPlayera
- Przekazywanie metadanych elementów w kolejce do sesji multimedialnej
Czego się nauczysz
- Dlaczego sesje multimedialne zapewniają użytkownikom bogatsze wrażenia
- Tworzenie sesji multimedialnej i zarządzanie jej stanem
- Jak połączyć sesję multimedialną z ExoPlayerem
- Jak uwzględnić metadane elementów w kolejce odtwarzania w sesji multimedialnej
- Dodawanie dodatkowych (niestandardowych) działań
To ćwiczenie koncentruje się na pakiecie SDK MediaSession. Nieistotne koncepcje i bloki kodu, w tym szczegóły implementacji ExoPlayera, nie są omawiane, ale można je po prostu skopiować i wkleić.
Czego potrzebujesz
- najnowsza wersja Androida Studio (3.5 lub nowsza);
- Podstawowa wiedza na temat tworzenia aplikacji na Androida
2. Przygotowania
Jaki jest nasz punkt początkowy?
Punktem początkowym jest główna wersja demonstracyjna ExoPlayera. Ta wersja demonstracyjna zawiera filmy z elementami sterującymi odtwarzaniem na ekranie, ale nie korzysta z sesji multimedialnych od razu po wyjęciu z pudełka. To świetne miejsce, aby je dodać.
Pobieranie przykładu ExoPlayer
Na początek zacznijmy od przykładu ExoPlayera. Sklonuj repozytorium GitHub, wykonując poniższy kod.
git clone https://github.com/google/ExoPlayer.git
Otwórz wersję demonstracyjną
W Android Studio otwórz główny projekt demonstracyjny znajdujący się w demos/main.
Android Studio wyświetli prośbę o ustawienie ścieżki pakietu SDK. Jeśli napotkasz problemy, możesz skorzystać z zaleceń dotyczących aktualizowania IDE i narzędzi SDK.

Jeśli pojawi się prośba o użycie najnowszej wersji Gradle, zaktualizuj ją.
Poświęć chwilę, aby poznać podstawowe założenia projektowe aplikacji. Zwróć uwagę, że są 2 aktywności: SampleChooserActivity i PlayerActivity. Pozostałą część tego laboratorium poświęcimy klasie PlayerActivity, w której odtwarzane są multimedia. Otwórz tę klasę i przejdź do następnej sekcji.
3. Tworzenie sesji multimedialnej i zarządzanie jej stanem
Tworzenie sesji multimedialnej
Otwórz pokój PlayerActivity.java. Ta klasa tworzy ExoPlayera i zarządza jego funkcjami, np. renderowaniem wideo na ekranie. W tym ćwiczeniu połączymy ExoPlayera z sesją multimedialną.
Zadeklaruj te 2 pola u góry klasy. W tej sekcji będziemy używać tych pól.
private MediaSessionCompat mediaSession;
private MediaSessionConnector mediaSessionConnector;
Musisz dodać zależność projektu „extension-mediasession” do pliku build.gradle na poziomie modułu „Module: demo”:
implementation project(path: ':extension-mediasession')
Pamiętaj, że Android Studio może pomóc Ci w automatycznym dodaniu tej zależności, jeśli najedziesz kursorem myszy na błąd związany z rozwiązywaniem problemu z MediaSessionConnector:

Na koniec rozwiąż problemy z importowaniem klas, dodając ten kod:
import android.support.v4.media.session.MediaSessionCompat;
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;
Po utworzeniu aktywności chcemy utworzyć sesję multimedialną i łącznik sesji multimedialnej, który będzie pośredniczyć między sesją multimedialną a ExoPlayerem.
Najlepiej wstawić go w miejscu, w którym tworzony jest ExoPlayer. W naszej aplikacji demonstracyjnej możemy dodać kod na końcu initializePlayer(). Pamiętaj, aby dodać tę logikę po utworzeniu instancji odtwarzacza.
private void initializePlayer() {
if (player == null) {
...
player = ...
...
mediaSession = new MediaSessionCompat(this, "sample");
mediaSessionConnector = new MediaSessionConnector(mediaSession);
mediaSessionConnector.setPlayer(player);
}
...
}
Zwolnij sesję multimedialną
Zwalniaj sesję multimedialną, gdy nie jest już potrzebna. Gdy udostępnimy ExoPlayer w releasePlayer(), możemy też dodać ten kod:
private void releasePlayer() {
if (mediaSession != null) {
mediaSession.release();
}
...
}
Zarządzanie stanem sesji multimedialnej
Po utworzeniu instancji sesji multimedialnej musimy zadbać o to, aby jej stan był prawidłowo odzwierciedlany podczas interakcji użytkownika z aktywnością.
Gdy użytkownik rozpocznie aktywność, sesja multimedialna powinna stać się aktywna:
@Override
public void onStart() {
...
if (mediaSession != null) {
mediaSession.setActive(true);
}
}
Nasza aplikacja nie odtwarza multimediów w tle, dlatego ważne jest, aby sesja multimedialna stała się nieaktywna, gdy użytkownik opuści aktywność:
@Override
public void onStop() {
super.onStop();
if (mediaSession != null) {
mediaSession.setActive(false);
}
...
}
Uruchommy wersję demonstracyjną
- Podłącz urządzenie z Androidem lub uruchom emulator.
- Upewnij się, że na pasku narzędzi Android Studio jest wybrana opcja „demo”.

- Na pasku narzędzi Androida Studio kliknij
. - Po uruchomieniu aplikacji na urządzeniu wybierz strumień wideo, który chcesz odtworzyć.
- Po rozpoczęciu odtwarzania możesz używać tych poleceń
adbdo sterowania sesją multimedialną:
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
- Dowiedz się też, jak Android postrzega Twoją sesję multimedialną. Możesz sprawdzić, które działania są obsługiwane, sprawdzając pole działania. Liczba, którą tu widzisz, to kombinacja identyfikatorów działań zadeklarowanych w obiekcie PlaybackState. Aby zobaczyć działanie sesji multimedialnej:
adb shell dumpsys media_session - Jeśli używasz urządzenia fizycznego z mikrofonem, spróbuj wywołać Asystenta Google i wydać polecenia głosowe, np. „Wstrzymaj”. „Wznów”. „Przewiń do przodu o minutę”.
*Przykładowa aplikacja ExoPlayer działająca na Androidzie TV.*
4. w tym metadane elementów w kolejce odtwarzania;
Możemy teraz rozszerzyć obsługiwane funkcje sesji multimedialnej, w której wcześniej utworzyliśmy MediaSessionConnector w initializePlayer().
Dodawanie elementu TimelineQueueNavigator
ExoPlayer przedstawia strukturę multimediów jako oś czasu. Aby dowiedzieć się, jak to działa, przeczytaj informacje o obiekcie osi czasu ExoPlayera. Dzięki tej strukturze możemy otrzymywać informacje o zmianach w treściach i na żądanie udostępniać metadane dotyczące tego, co jest aktualnie odtwarzane.
W tym celu zdefiniujemy element TimelineQueueNavigator. Znajdź instancję MediaSessionConnector w initializePlayer() i dodaj implementację TimelineQueueNavigator po zainicjowaniu 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();
}
});
Rozwiąż problemy z importem klas, dodając:
import android.support.v4.media.MediaDescriptionCompat;
import com.google.android.exoplayer2.ext.mediasession.TimelineQueueNavigator;
Zwróć uwagę, że parametr windowIndex odpowiada elementowi o tym indeksie w kolejce odtwarzania.
Po dodaniu metadanych możesz sprawdzić, czy Asystent rozumie, co jest odtwarzane. Podczas odtwarzania filmu na Androidzie TV wywołaj Asystenta i zapytaj „Co jest odtwarzane?”.

5. Dostosowywanie działań
Być może Twój odtwarzacz nie obsługuje niektórych działań lub chcesz dodać obsługę kolejnych? Przyjrzyjmy się teraz bliżej sesji multimedialnej, w której wcześniej utworzyliśmy element MediaSessionConnector w initializePlayer().
Deklarowanie obsługiwanych działań
Spróbuj użyć mediaSessionConnector.setEnabledPlaybackActions(), aby dostosować działania, które ma obsługiwać sesja multimedialna.
Pamiętaj, że pełny zestaw to:
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
);
Zobaczmy jeszcze raz, jak te dane są udostępniane platformie:
- Jak wcześniej, rozpocznij film.
- Sprawdź, jak Android widzi metadane z sesji multimedialnej, wykonując to polecenie:
adb shell dumpsys media_session - Znajdź wiersz zawierający metadane i sprawdź, czy tytuł i opis są uwzględnione i powiązane z
com.google.android.exoplayer2.demo/sample.
Dodawanie dodatkowych działań
Sesję multimedialną możemy rozszerzyć o dodatkowe działania. W tej sekcji dodamy tylko obsługę napisów.
Napisy
Dodanie obsługi napisów do sesji multimedialnych umożliwia użytkownikom włączanie i wyłączanie ich za pomocą głosu. W miejscu, w którym zainicjowano łącznik sesji multimedialnej, dodaj ten kod:
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;
}
}
);
Na koniec rozwiąż problemy z brakującymi importami.
Możesz to sprawdzić, wywołując Asystenta Google na Androidzie TV i mówiąc „Włącz napisy”. Sprawdź Logcat pod kątem wiadomości, aby zobaczyć, jak wywołuje on Twój kod.
6. Gratulacje
Udało Ci się dodać sesje multimedialne do przykładu.
Zyskujesz ogromną funkcjonalność dzięki:
- dodawanie sesji multimediów,
- łączenie sesji multimedialnych z instancją ExoPlayera,
- dodawanie metadanych i dodatkowych działań.
Znasz już najważniejsze kroki, które pozwolą Ci wzbogacić aplikację do multimediów i zapewnić użytkownikom większe możliwości.
Końcowa uwaga
To laboratorium zostało utworzone na podstawie przykładu z kodu źródłowego ExoPlayera. Nie musisz używać ExoPlayera z kodu źródłowego. Zamiast tego zalecamy pobranie zależności dla ExoPlayera i MediaSessionConnector, aby łatwiej było Ci korzystać z najnowszych wersji.
Aby to zrobić, zastąp zależności projektu, takie jak:
implementation project(modulePrefix + 'library-core')
implementation project(path: ':extension-mediasession')
pobierać dane z repozytoriów Maven, takich jak:
implementation 'com.google.android.exoplayer:exoplayer-core:2.+'
implementation 'com.google.android.exoplayer:extension-mediasession:2.+'