Sterowanie multimediami za pomocą MediaSession

1. Wprowadzenie

Ostatnia aktualizacja: 9.09.2020

Jakie są zalety dodania sesji MediaSession w związku z odtwarzaniem filmu?

Sesje multimediów to nieodłączne połączenie platformy Androida i aplikacji do multimediów. Nie tylko informuje Androida o odtwarzanych multimediach, dając możliwość przekazywania działań związanych z multimediami do odpowiedniej sesji, ale też informuje platformę, co jest odtwarzane i jak można nią sterować.

Udostępnianie sesji MediaSession w aplikacji przynosi różne korzyści użytkownikom. Oto kilka doskonałych przykładów.

Asystent Google

Użytkownicy mogą łatwo korzystać z multimediów w aplikacji za pomocą poleceń głosowych, takich jak „Wstrzymaj”, „Wznów”, i „Dalej”. Metadane z multimediów mogą być też używane do uzyskiwania odpowiedzi na temat aktualnie odtwarzanego materiału.

Android TV

Na dużym ekranie aplikacja na Androida TV może używać tradycyjnych pilotów na telewizorach obsługujących HDMI-CEC. Polecenia te są przekazywane do aplikacji.

Sterowanie multimediami na ekranie

Począwszy od Androida 4.0 (poziom interfejsu API 14) system ma dostęp do metadanych i stanu odtwarzania sesji multimediów. Ta funkcja umożliwia wyświetlanie na ekranie blokady elementów sterujących multimediami i grafikę. Działanie to zależy od wersji Androida.

Multimedia w tle

W każdym z tych scenariuszy można sterować multimediami, nawet jeśli aplikacja odtwarza multimedia w tle.

Obliczenia Ambient

Udostępnianie multimediów z danymi o odtwarzanym materiale i sposobach jego sterowania umożliwia pomost między urządzeniami, dzięki czemu użytkownicy mogą wchodzić z nimi w interakcję na różne sposoby.

Co utworzysz

W ramach tego ćwiczenia w Codelabs rozszerzysz dotychczasowy przykład o odtwarzacz Exo, aby dodać obsługę sesji multimedialnych. Twoja aplikacja będzie:

  • prawidłowo odzwierciedlać aktywny stan sesji multimedialnej,
  • Przekazywanie opcji sterowania multimediami do ExoPlayer
  • Przekazywanie metadanych elementów z kolejki do sesji multimediów

Czego się nauczysz

  • Dlaczego sesje multimedialne zapewniają użytkownikom lepsze wrażenia
  • Jak utworzyć sesję multimediów i zarządzać jej stanem
  • Jak połączyć sesję multimediów z exoPlayerem
  • Jak dołączyć metadane elementów z kolejki odtwarzania podczas sesji multimediów
  • Dodawanie działań dodatkowych (niestandardowych)

To ćwiczenia z programowania koncentrują się na pakiecie SDK MediaSession. Nieistotne pojęcia ani bloki kodu, w tym szczegóły implementacji ExoPlayer, nie są omawiane. Można je po prostu skopiować i wkleić.

Czego potrzebujesz

  • Mieć najnowszą wersję Android Studio (3.5 lub nowszą).
  • Podstawowa wiedza o tworzeniu aplikacji na Androida

2. Przygotowanie

Od czego zacząć?

Punktem wyjścia jest główna wersja demonstracyjna platformy ExoPlayer. Ta wersja demonstracyjna zawiera filmy z wyświetlanymi na ekranie elementami sterującymi odtwarzaniem, ale nie wykorzystuje sesji multimedialnych. To świetne miejsce, żebyśmy mogli je dodać.

Pobieranie próbki ExoPlayer

Zacznijmy od fragmentu ExoPlayer. Sklonuj repozytorium GitHub, uruchamiają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 w aplikacji demos/main.

Android Studio poprosi o ustawienie ścieżki pakietu SDK. W razie problemów możesz postępować zgodnie z zaleceniami dotyczącymi aktualizacji 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 podstawowymi informacjami na temat konstrukcji aplikacji. Zwróć uwagę, że masz do wyboru 2 aktywności: SampleChooserActivity i PlayActivity. Pozostałe ćwiczenia z programowania spędzimy w PlayActivity, gdzie multimedia są odtwarzane, więc otwórz te zajęcia i przejdź do następnej sekcji.

3. Tworzenie sesji multimediów i zarządzanie jej stanem

Tworzenie sesji multimediów

Otwórz pokój PlayerActivity.java. Ta klasa tworzy ExoPlayer i zarządza jego funkcjami, takimi jak renderowanie filmu na ekranie. W tym ćwiczeniu połączymy ExoPlayer z sesją multimediów.

Zadeklaruj te 2 pola na początku klasy. Wykorzystamy te pola w tej sekcji.

private MediaSessionCompat mediaSession;
private MediaSessionConnector mediaSessionConnector;

Musisz dodać rozszerzenie „extension-mediasession”. zależność projektu do funkcji build.gradle na poziomie modułu dla „Module: demo”:

implementation project(path: ':extension-mediasession')

Android Studio może pomóc w automatycznym dodawaniu tej zależności, jeśli najedziesz kursorem myszy na błąd podczas rozwiązywania problemu MediaSessionConnector:

60055e4ad54fbb97.png

Na koniec zakończ importowanie klas, dodając ten fragment:

import android.support.v4.media.session.MediaSessionCompat;
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;

Po utworzeniu działania chcemy utworzyć sesję multimediów i oprogramowanie sprzęgające sesji multimediów, które będzie pośrednikiem między sesją multimediów a głośnikiem ExoPlayer.

Idealne miejsce do wstawienia tego odtwarzacza to także miejsce, gdzie tworzony jest także odtwarzacz ExoPlayer. W aplikacji w wersji demonstracyjnej nasz kod możemy dołączyć 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);
  }
  ...
}

Zwolnienie sesji multimediów

Zwolnij sesję multimediów, gdy nie jest już potrzebna. Kiedy wprowadzamy ExoPlayer w releasePlayer(), możemy też dołączyć do tego następujący kod:

private void releasePlayer() {
  if (mediaSession != null) {
    mediaSession.release();
  }
  ...
}

Zarządzanie stanem sesji multimediów

Po utworzeniu sesji multimediów musimy się upewnić, że jej stan jest odpowiednio odzwierciedlany w czasie, gdy użytkownik wchodzi w interakcję z działaniem.

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 opuszcza aktywność:

@Override
public void onStop() {
  super.onStop();
  if (mediaSession != null) {
    mediaSession.setActive(false);
  }
  ...
}

Uruchom wersję demonstracyjną

  1. Podłącz urządzenie z Androidem lub uruchom emulator.
  2. Pamiętaj, aby wyświetlić jest wybrana do uruchamiania z paska narzędzi Android Studio. cb1ec4e50886874f.png
  3. Kliknij 9d8fb3a9ddf12827.png na pasku narzędzi w Android Studio.
  4. Po uruchomieniu aplikacji na urządzeniu wybierz strumień wideo, który chcesz odtworzyć.
  5. Po rozpoczęciu odtwarzania możesz sterować sesją multimediów 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. Sprawdź też, jak Android widzi Twoją sesję multimediów. W szczególności możesz sprawdzić, które działania są obsługiwane, patrząc na pole czynności. Widoczna w tym miejscu liczba jest kombinacją identyfikatorów działań zadeklarowanych w obiekcie PlaybackState. Aby zobaczyć uruchomioną sesję multimediów: adb shell dumpsys media_session
  2. Jeśli korzystasz z urządzenia fizycznego z mikrofonem, spróbuj wywołać Asystenta Google i wydać polecenia głosowe takie jak „Wstrzymaj”. „Wznów”. „Przewiń do przodu o minutę”.

b8dda02a6fb0f6a4.pngPrzykład z ExoPlayer działający na Androidzie TV.

4. Uwzględnia metadane elementów w kolejce odtwarzania

Możemy teraz rozszerzyć obsługiwane funkcje sesji multimedialnej, podczas których utworzyliśmy narzędzie MediaSessionConnector w usłudze initializePlayer().

Dodawanie osi czasuQueueNavigator

ExoPlayer reprezentuje strukturę multimediów jako oś czasu. Aby dowiedzieć się, jak to działa, poczytaj o obiekcie osi czasu ExoPlayer. Dzięki tej strukturze możemy być informowany o zmianach w treści i ujawniać metadane tego, co jest obecnie odtwarzane.

W tym celu zdefiniujemy obiekt BillingQueueNavigator. Znajdź wystąpienie obiektu MediaSessionConnector w komponencie initializePlayer() i dodaj implementację osi czasuQueueNavigator po zainicjowaniu tagu 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ąż problem z importowaniem zajęć, dodając:

import android.support.v4.media.MediaDescriptionCompat;
import com.google.android.exoplayer2.ext.mediasession.TimelineQueueNavigator;

Zwróć uwagę, że parametr windowIndex odpowiada elementowi tego indeksu 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?”.

6c7fc0cb853cbc38.png

5. Dostosowywanie działań

Być może Twój odtwarzacz nie obsługuje niektórych działań lub chcesz uzyskać dodatkowe wsparcie? Przyjrzyjmy się teraz bliżej sesji medialnej, w ramach której utworzyliśmy narzędzie MediaSessionConnector w usłudze initializePlayer().

Deklarowanie obsługiwanych działań

Spróbuj użyć narzędzia mediaSessionConnector.setEnabledPlaybackActions(), aby określić, które działania mają być obsługiwane przez sesję multimediów.

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
);

Ponownie zobaczmy, w jaki sposób dane są udostępniane na platformie:

  1. Tak jak poprzednio rozpocznij film.
  2. Sprawdź, jak Android widzi metadane z sesji multimediów, wykonując: adb shell dumpsys media_session
  3. Odszukaj wiersz zawierający metadane i sprawdź, czy tytuł i opis są zawarte i powiązane z atrybutem com.google.android.exoplayer2.demo/sample.

Dodawanie dodatkowych działań

Możemy rozszerzyć sesję medialną o kilka dodatkowych działań. W tej sekcji dodamy obsługę napisów.

Dodatkowe napisy

Dodanie obsługi napisów do sesji multimediów umożliwia użytkownikom przełączanie ich za pomocą głosu. Miejsce zainicjowania oprogramowania sprzęgającego sesji multimediów 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 napraw wszelkie brakujące importy.

Aby to sprawdzić, wywołaj Asystenta Google na Androidzie TV i powiedz „Włącz napisy”. Sprawdź, czy w aplikacji Logcat są wysyłane wiadomości, aby zobaczyć, jak to wywołuje Twój kod.

6. Gratulacje

Gratulacje! Udało Ci się dodać sesje multimedialne do próbki.

Masz mnóstwo funkcji dzięki:

  • dodanie sesji multimedialnej,
  • łączenie sesji multimediów z instancją ExoPlayer,
  • dodawania metadanych i dodatkowych działań.

Znasz już najważniejsze czynności, które trzeba wykonać, aby wzbogacić aplikację do multimediów i zapewnić użytkownikom jej bardziej uniwersalne rozwiązanie.

Ostateczna uwaga

To ćwiczenie w Codelabs zostało utworzone na podstawie przykładowego kodu źródłowego ExoPlayer. Nie musisz korzystać z biblioteki ExoPlayer ze źródła. Zamiast tego zalecamy pobranie zależności między komponentami ExoPlayer i MediaSessionConnector, aby być na bieżąco z najnowszymi wersjami.

Aby to zrobić, wystarczy zastąpić zależności projektu takie jak:

implementation project(modulePrefix + 'library-core')
implementation project(path: ':extension-mediasession')

które można pobrać z repozytoriów Maven, na przykład:

implementation 'com.google.android.exoplayer:exoplayer-core:2.+'
implementation 'com.google.android.exoplayer:extension-mediasession:2.+'

Dokumentacja