1. Wprowadzenie
Ostatnia aktualizacja: 9 września 2020 r.
Jakie są zalety dodania MediaSession w przypadku odtwarzania filmu?
Sesje multimediów stanowią integralne połączenie między platformą Androida a aplikacjami multimedialnymi. Nie tylko informuje Androida o odtwarzaniu multimediów, aby mógł przekazać działania związane z multimediami do odpowiedniej sesji, ale także informuje platformę, co jest odtwarzane i jak można to kontrolować.
Udostępnianie MediaSession w aplikacji niesie za sobą różne korzyści dla użytkowników. Oto kilka świetnych przykładów.
Asystent Google
Użytkownicy mogą łatwo wchodzić w interakcje z multimediami w aplikacji za pomocą poleceń głosowych, takich jak „Wstrzymaj”, „Dalej” 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
Na dużym ekranie aplikacja na Androida TV może korzystać z tradycyjnych pilotów w przypadku telewizorów obsługujących HDMI-CEC. Polecenia wydawane przez przyciski odtwarzania/wstrzymywania, zatrzymania, następnego i poprzedniego są przekazywane do aplikacji.
Sterowanie multimediami na ekranie
Począwszy od Androida 4.0 (interfejs API na poziomie 14) system może uzyskać dostęp do stanu odtwarzania i metadanych sesji multimediów. Ta funkcja umożliwia wyświetlanie na ekranie blokady elementów sterujących multimediami i grafiki. Sposób działania zależy od wersji Androida.
Tło (multimedia)
W każdym z tych scenariuszy można sterować multimediami, nawet jeśli aplikacja odtwarzająca multimedia działa w tle.
przetwarzanie otoczenia,
Wyświetlanie multimediów z danymi o tym, co jest odtwarzane i jak można to kontrolować, może łączyć urządzenia, dzięki czemu użytkownicy mogą korzystać z multimediów na różne sposoby.
Co utworzysz
W tym ćwiczeniu rozszerzysz istniejący przykładowy kod Exoplayer, aby dodać obsługę sesji multimediów. Twoja aplikacja będzie:
- prawidłowo odzwierciedlać aktywny stan sesji multimediów;
- Przekazywanie elementów sterujących multimediami do ExoPlayera
- Przekazywanie metadanych elementów z kolejki do sesji multimediów
Czego się nauczysz
- Dlaczego sesje multimedialne zapewniają użytkownikom bogatsze wrażenia
- Jak utworzyć sesję multimediów i zarządzać jej stanem
- Łączenie sesji multimediów z ExoPlayerem
- Jak uwzględnić metadane elementów w kolejce odtwarzania w sesji multimediów
- Dodawanie dodatkowych (niestandardowych) działań
Ten warsztat dotyczy pakietu MediaSession SDK. Nieistotne koncepcje i bloki kodu, w tym szczegóły dotyczące implementacji ExoPlayer, nie są omawiane, ale można je po prostu skopiować i wkleić.
Czego potrzebujesz
- najnowsza wersja Android Studio (3.5 lub nowsza),
- podstawowa wiedza o tworzeniu aplikacji na Androida;
2. Konfiguracja
Co jest punktem wyjścia?
Naszym punktem wyjścia jest główne demo ExoPlayera. Ten film demonstracyjny zawiera filmy z kontrolkami odtwarzania na ekranie, ale nie korzysta z sesji multimediów. To świetne miejsce, aby dodać je do listy.
Pobieranie przykładowego projektu ExoPlayer
Aby zacząć, zacznijmy od przykładu ExoPlayer. Sklonuj repozytorium GitHub, wykonując podany niżej kod.
git clone https://github.com/google/ExoPlayer.git
Otwórz demonstrację
W Android Studio otwórz główny projekt demonstracyjny, który znajduje się w sekcji demos/main
.
Android Studio wyświetli prośbę o ustawienie ścieżki pakietu SDK. Jeśli wystąpią problemy, możesz skorzystać z zaleceń dotyczących aktualizowania narzędzi IDE i 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ęść tego samouczka poświęcimy na PlayerActivity, w której multimedia są faktycznie odtwarzane. Otwórz tę klasę i przejdź do następnej sekcji.
3. Tworzenie sesji multimediów 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 filmu na ekranie. W tej części ćwiczenia połączymy ExoPlayera z sesją multimediów.
Na początku klasy zadeklaruj te 2 pola. W tej sekcji będziemy używać tych pól.
private MediaSessionCompat mediaSession;
private MediaSessionConnector mediaSessionConnector;
Musisz dodać zależność projektu „extension-mediasession” do poziomu modułu build.gradle
dla „Module: demo”:
implementation project(path: ':extension-mediasession')
Jeśli najedziesz kursorem na błąd związany z rozwiązywaniem MediaSessionConnector, Android Studio może automatycznie pomóc Ci w dodaniu tej zależności:
Na koniec rozwiązuj problemy z importem zajęć, dodając te elementy:
import android.support.v4.media.session.MediaSessionCompat;
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;
Po utworzeniu aktywności chcemy utworzyć sesję multimediów i łącznik sesji multimediów, który będzie pośredniczyć między sesją multimediów a ExoPlayerem.
Idealnym miejscem na wstawienie tego kodu jest miejsce, w którym tworzony jest ExoPlayer. W naszej aplikacji demonstracyjnej możemy dołączyć kod do końca 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ę multimediów
zwalniać sesję multimediów, gdy nie jest już potrzebna; Gdy wydamy ExoPlayera w wersji releasePlayer()
, możemy też dołączyć do niego ten kod:
private void releasePlayer() {
if (mediaSession != null) {
mediaSession.release();
}
...
}
Zarządzanie stanem sesji multimediów
Po uruchomieniu sesji multimediów musimy się upewnić, że jej stan jest prawidłowo odzwierciedlany, gdy użytkownik wchodzi w interakcję z aktywizacją.
Gdy użytkownik rozpocznie aktywność, sesja multimediów 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 multimediów była nieaktywna, gdy użytkownik przestaje korzystać z aplikacji:
@Override
public void onStop() {
super.onStop();
if (mediaSession != null) {
mediaSession.setActive(false);
}
...
}
Uruchommy demo
- Podłącz urządzenie z Androidem lub uruchom emulator.
- Upewnij się, że na pasku narzędzi Android Studio wybrana jest opcja „demo”.
- Na pasku narzędzi Androida Studio kliknij
.
- Gdy aplikacja uruchomi się na urządzeniu, wybierz strumień wideo, który chcesz odtworzyć.
- Po rozpoczęciu odtwarzania możesz sterować sesją multimedialną za pomocą tych poleceń
adb
:
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 sesję multimedialną. W szczególności możesz sprawdzić, które działania są obsługiwane, sprawdzając pole działania. Liczba widoczna tutaj to kombinacja identyfikatorów działań zadeklarowanych w obiekcie PlaybackState. Aby wyświetlić sesję multimedialną:
adb shell dumpsys media_session
- Jeśli używasz fizycznego urządzenia z mikrofonem, spróbuj wywołać Asystenta Google i wydać polecenia głosowe, takie jak „Wstrzymaj”. „Wznów”. „Przewiń do przodu o 1 minutę”.
Przykładowy ExoPlayer działający na Androidzie TV.
4. Uwzględnianie metadanych elementów w kolejce odtwarzania
Możemy teraz rozszerzyć obsługiwane funkcje sesji multimediów, w której wcześniej utworzyliśmy MediaSessionConnector w initializePlayer()
.
Dodawanie obiektu TimelineQueueNavigator
ExoPlayer reprezentuje strukturę multimediów jako osi czasu. Aby dowiedzieć się więcej, zapoznaj się z informacjami o obiekcie osi czasu w ExoPlayerze. Dzięki tej strukturze możemy otrzymywać informacje o zmianach treści i w razie potrzeby udostępniać metadane dotyczące aktualnie odtwarzanych treści.
Aby to osiągnąć, zdefiniujemy klasę TimelineQueueNavigator. Odszukaj 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 zajęć, 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 teraz odtwarzane?”.
5. Dostosowywanie działań
Być może Twój odtwarzacz nie obsługuje niektórych działań lub chcesz dodać obsługę dodatkowych działań. Przyjrzyjmy się teraz sesji multimediów, w której wcześniej utworzyliśmy MediaSessionConnector w initializePlayer()
.
Zdeklarowanie obsługiwanych działań
Spróbuj użyć mediaSessionConnector.setEnabledPlaybackActions()
, aby dostosować działania, które mają być obsługiwane przez sesję multimedialną.
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:
- Tak jak poprzednio, uruchom film.
- Sprawdź, jak Android widzi metadane z sesji multimediów, wykonując te czynności:
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ć sesję multimedialną o dodatkowe działania. W tej sekcji dodamy obsługę tylko napisów.
Napisy
Dodanie obsługi napisów do sesji multimediów pozwala użytkownikom przełączać je za pomocą głosu. W miejscu, w którym inicjujesz oprogramowanie sprzęgające sesję multimedialną, 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ąż problemy z brakami w importach.
Aby to przetestować, uruchom Asystenta Google na Androidzie TV i powiedz „Włącz napisy”. Sprawdź logi, aby zobaczyć, jak wywołanie jest wykonywane w Twoim kodzie.
6. Gratulacje
Gratulacje! Udało Ci się dodać do próbki sesje multimediów.
Otrzymasz ogromną liczbę funkcji, korzystając z tych możliwości:
- dodawanie sesji multimediów,
- łączenie sesji multimediów z instancją ExoPlayera,
- dodawanie metadanych i dodatkowych działań.
Znasz już najważniejsze kroki, które należy wykonać, aby wzbogacić aplikację multimedialną i zapewnić użytkownikom większą wszechstronność.
Ostatnie zastrzeżenie
Ten projekt został stworzony na podstawie przykładu kodu źródłowego ExoPlayer. Nie musisz używać ExoPlayer z źródła. Zamiast tego zalecamy pobranie zależności dla ExoPlayer i MediaSessionConnector, aby łatwiej było Ci aktualizować najnowsze wersje.
Aby to zrobić, wystarczy zastąpić zależności projektu, takie jak:
implementation project(modulePrefix + 'library-core')
implementation project(path: ':extension-mediasession')
do pobierania z repozytoriów Maven, takich jak:
implementation 'com.google.android.exoplayer:exoplayer-core:2.+'
implementation 'com.google.android.exoplayer:extension-mediasession:2.+'