Sterowanie multimediami za pomocą MediaSession

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.

10e3b5c652186d57.png

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:

60055e4ad54fbb97.png

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

  1. Podłącz urządzenie z Androidem lub uruchom emulator.
  2. Upewnij się, że na pasku narzędzi Android Studio wybrana jest opcja „demo”. cb1ec4e50886874f.png
  3. Na pasku narzędzi Androida Studio kliknij 9d8fb3a9ddf12827.png.
  4. Gdy aplikacja uruchomi się na urządzeniu, wybierz strumień wideo, który chcesz odtworzyć.
  5. 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
  1. 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
  2. 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ę”.

b8dda02a6fb0f6a4.pngPrzykł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?”.

6c7fc0cb853cbc38.png

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:

  1. Tak jak poprzednio, uruchom film.
  2. Sprawdź, jak Android widzi metadane z sesji multimediów, wykonując te czynności: adb shell dumpsys media_session
  3. 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.+'

Dokumenty referencyjne