1. Wprowadzenie
Ostatnia aktualizacja: 9 września 2020 r.
Jakie korzyści daje dodanie MediaSession do odtwarzania wideo?
Sesje multimedialne są integralnym połączeniem między platformą Android a aplikacjami multimedialnymi. Nie tylko informują Androida o tym, że odtwarzane są multimedia, aby mógł on przekazywać działania związane z multimediami do odpowiedniej sesji, ale też informują platformę o tym, co jest odtwarzane i jak można tym sterować.
Udostępnianie MediaSession w aplikacji ma wiele zalet, z których będą mogli korzystać użytkownicy. Oto kilka przykładów.
Asystent Google
Użytkownicy mogą łatwo wchodzić w interakcję z multimediami w Twojej aplikacji za pomocą poleceń głosowych, takich jak „Wstrzymaj”, „Wznów” i „Następny”. Metadane z Twoich multimediów mogą też służyć do uzyskiwania odpowiedzi na pytania o to, co jest aktualnie odtwarzane.
Android TV
W przypadku dużych ekranów aplikacja na Androida TV może korzystać z tradycyjnych pilotów do telewizorów obsługujących HDMI-CEC. Polecenia wydawane za pomocą przycisków odtwarzania/wstrzymywania, zatrzymywania, następnego i poprzedniego są przekazywane do Twojej aplikacji.
Opcje sterowania multimediami na ekranie
Począwszy od Androida 4.0 (interfejs API na poziomie 14), system może uzyskiwać dostęp do stanu odtwarzania i metadanych sesji multimedialnej. Ta funkcja umożliwia wyświetlanie na ekranie blokady opcji sterowania multimediami i grafiki. To zachowanie różni się w zależności od wersji Androida.
Multimedia w tle
Multimediami można sterować w każdym z tych scenariuszy, nawet jeśli aplikacja odtwarzająca multimedia działa w tle.
Ambient computing
Udostępnianie multimediów z informacjami o tym, co jest odtwarzane i jak można tym sterować, może łączyć urządzenia, dzięki czemu użytkownicy mogą wchodzić z nimi w interakcję na różne sposoby.
Co stworzysz
W tym ćwiczeniu rozszerzysz istniejący przykład ExoPlayera, aby dodać obsługę sesji multimedialnych. Twoja aplikacja będzie:
- prawidłowo odzwierciedlać aktywny stan sesji multimedialnej;
- przekazywać opcje sterowania multimediami do ExoPlayera;
- przekazywać metadane elementów w kolejce do sesji multimedialnej.
Czego się nauczysz
- Dlaczego sesje multimedialne zapewniają użytkownikom lepsze wrażenia
- Jak utworzyć sesję multimedialną i zarządzać jej stanem
- Jak połączyć sesję multimedialną z ExoPlayerem
- Jak uwzględnić w sesji multimedialnej metadane elementów w kolejce odtwarzania
- Jak dodać dodatkowe (niestandardowe) działania
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 Android Studio (3.5 lub nowsza)
- Podstawowa wiedza na temat tworzenia aplikacji na Androida
2. Przygotowania
Jaki jest nasz punkt początkowy?
Naszym 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. To świetne miejsce, aby je dodać.
Pobieranie przykładu ExoPlayera
Aby szybko zacząć, zacznijmy od przykładu ExoPlayera. Skopiuj repozytorium GitHub, uruchamiając kod poniżej.
git clone https://github.com/google/ExoPlayer.git
Otwieranie wersji demonstracyjnej
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 pakietu SDK.

Jeśli pojawi się prośba o użycie najnowszej wersji Gradle, zaktualizuj ją.
Poświęć chwilę na zapoznanie się z podstawową strukturą aplikacji. Pamiętaj, że są 2 aktywności: SampleChooserActivity i PlayerActivity. Pozostałą część ćwiczenia spędzimy w PlayerActivity, gdzie faktycznie odtwarzane są multimedia, więc otwórz tę klasę i przejdź do następnej sekcji.
3. Tworzenie sesji multimedialnej i zarządzanie jej stanem
Tworzenie sesji multimedialnej
Otwórz PlayerActivity.java. Ta klasa tworzy ExoPlayera i zarządza jego funkcjami, takimi jak renderowanie obrazu na ekranie. W tej aktywności połączymy ExoPlayera z sesją multimedialną.
U góry klasy zadeklaruj te 2 pola. Będziemy ich używać w tej sekcji.
private MediaSessionCompat mediaSession;
private MediaSessionConnector mediaSessionConnector;
Musisz dodać zależność projektu „extension-mediasession” do pliku build.gradle na poziomie modułu w przypadku „Module: demo”:
implementation project(path: ':extension-mediasession')
Pamiętaj, że Android Studio może automatycznie dodać tę zależność, jeśli najedziesz kursorem na błąd związany z rozwiązywaniem MediaSessionConnector:

Na koniec rozwiąż importy klas, dodając:
import android.support.v4.media.session.MediaSessionCompat;
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;
Gdy aktywność zostanie utworzona, utworzymy sesję multimedialną i łącznik sesji multimedialnej, który będzie pośredniczyć między sesją multimedialną a ExoPlayerem.
Idealnym miejscem na wstawienie tego kodu jest miejsce, w którym tworzony jest też ExoPlayer. W naszej aplikacji w wersji demonstracyjnej możemy dołączyć 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);
}
...
}
Zwalnianie sesji multimedialnej
Zwolnij sesję multimedialną, gdy nie jest już potrzebna. Gdy zwalniamy ExoPlayera 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 się upewnić, że jej stan jest prawidłowo odzwierciedlany, gdy użytkownik wchodzi w interakcję z aktywnością.
Gdy użytkownik uruchomi aktywność, sesja multimedialna powinna stać się aktywna:
@Override
public void onStart() {
...
if (mediaSession != null) {
mediaSession.setActive(true);
}
}
Ponieważ nasza aplikacja nie odtwarza multimediów w tle, musimy się upewnić, że sesja multimedialna stanie się nieaktywna, gdy użytkownik opuści aktywność:
@Override
public void onStop() {
super.onStop();
if (mediaSession != null) {
mediaSession.setActive(false);
}
...
}
Uruchamianie wersji demonstracyjnej
- 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 Android Studio kliknij
. - Gdy aplikacja uruchomi się na urządzeniu, wybierz strumień wideo do odtworzenia.
- Po rozpoczęciu odtwarzania użyj tych poleceń
adb, aby sterować 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
- Sprawdź też, jak Android widzi Twoją sesję multimedialną. Możesz na przykład 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łającą sesję multimedialną, wpisz:
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 1 minutę”.
Przykład ExoPlayera działający na Androidzie TV.
4. Uwzględnianie metadanych elementów w kolejce odtwarzania
Możemy teraz rozszerzyć obsługiwane funkcje naszej sesji multimedialnej, w której wcześniej utworzyliśmy MediaSessionConnector w initializePlayer().
Dodawanie TimelineQueueNavigator
ExoPlayer przedstawia strukturę multimediów jako oś czasu. Aby dowiedzieć się więcej o tym, jak to działa, przeczytaj informacje o obiekcie Timeline ExoPlayera. Dzięki tej strukturze możemy otrzymywać informacje o zmianach treści i udostępniać metadane tego, co jest aktualnie odtwarzane.
Aby to zrobić, zdefiniujemy TimelineQueueNavigator. Znajdź instancję MediaSessionConnector w initializePlayer() i dodaj implementację TimelineQueueNavigator po mediaSession jest zainicjowany.
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ąż importy klas, dodając:
import android.support.v4.media.MediaDescriptionCompat;
import com.google.android.exoplayer2.ext.mediasession.TimelineQueueNavigator;
Zauważ, ż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ę większej liczby działań. Przyjrzyjmy się teraz bliżej sesji multimedialnej, w której wcześniej utworzyliśmy MediaSessionConnector w initializePlayer().
Deklarowanie obsługiwanych działań
Użyj 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, uruchom film.
- Sprawdź, jak Android widzi metadane z Twojej sesji multimedialnej, wykonując 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ń
Możemy rozszerzyć naszą sesję multimedialną o dodatkowe działania. W tej sekcji dodamy tylko obsługę napisów.
Obsługa napisów
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:
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ąż brakujące importy.
Możesz to sprawdzić, wywołując Asystenta Google na Androidzie TV i mówiąc „Włącz napisy”. Sprawdź Logcat, aby zobaczyć, jak te wywołania są przekazywane do Twojego kodu.
6. Gratulacje
Udało Ci się dodać sesje multimedialne do przykładu.
Dzięki temu zyskujesz ogromną liczbę funkcji:
- dodanie sesji multimedialnej;
- łą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.
Ostatnia uwaga
To ćwiczenie zostało oparte na przykładzie z kodu źródłowego ExoPlayera. Nie musisz używać ExoPlayera ze źródła. Zalecamy, aby zamiast tego pobrać zależności ExoPlayera i MediaSessionConnector, aby łatwiej było Ci korzystać z najnowszych wersji.
Aby to zrobić, po prostu zastąp zależności projektu, takie jak:
implementation project(modulePrefix + 'library-core')
implementation project(path: ':extension-mediasession')
aby pobrać z repozytoriów Maven, takich jak:
implementation 'com.google.android.exoplayer:exoplayer-core:2.+'
implementation 'com.google.android.exoplayer:extension-mediasession:2.+'