Odtwarzacz to komponent aplikacji, który umożliwia odtwarzanie elementów multimedialnych.
Interfejs Media3 Player określa funkcje, które zwykle obsługuje odtwarzacz. Obejmuje to:
- wpływają na elementy sterujące odtwarzaniem, takie jak odtwarzanie, wstrzymywanie i przewijanie;
- odpytywanie o właściwości aktualnie odtwarzanych multimediów, np. pozycję odtwarzania;
- zarządzanie playlistą lub kolejką elementów multimedialnych;
- konfigurowanie właściwości odtwarzania, takich jak odtwarzanie losowe, powtarzanie, szybkość i głośność;
- Renderowanie filmu na ekranie
Media3 udostępnia też implementację interfejsu Player o nazwie ExoPlayer.
wspólny interfejs między komponentami,
Interfejs Player jest implementowany przez kilka komponentów w Media3, na przykład:
| Komponent | Opis i uwagi dotyczące działania |
|---|---|
ExoPlayer |
Interfejs API odtwarzacza multimediów i domyślna implementacja interfejsu Player. |
MediaController |
Wchodzi w interakcję z MediaSession, aby wysyłać polecenia odtwarzania. Jeśli Player i MediaSession znajdują się w Service oddzielnym od Activity lub Fragment, w którym znajduje się interfejs odtwarzacza, możesz przypisać MediaController jako odtwarzacz do komponentu interfejsu, takiego jak PlayerView lub Player Composable. Wywołania metod odtwarzania i playlisty są wysyłane do Player przez MediaSession.
|
MediaBrowser |
Oprócz funkcji oferowanych przez MediaController współdziała z MediaLibrarySession, aby przeglądać dostępne treści multimedialne.
|
SimpleBasePlayer |
Implementacja Player, która ogranicza liczbę metod do zaimplementowania do minimum. Przydatne, gdy używasz niestandardowego odtwarzacza, który chcesz połączyć z MediaSession.
|
ForwardingSimpleBasePlayer |
Podklasa SimpleBasePlayer, która przekazuje operacje odtwarzania do innego obiektu Player, umożliwiając jednocześnie takie same dostosowania zachowania jak SimpleBasePlayer. Użyj tej klasy, aby pominąć lub zmodyfikować określone operacje odtwarzania.
|
RemoteCastPlayer |
Implementacja Player do sterowania odtwarzaniem w zdalnej aplikacji odbiornika Cast.
|
CastPlayer |
Implementacja Player do sterowania odtwarzaniem lokalnym i zdalnym Cast.
|
Chociaż MediaSession nie implementuje interfejsu Player, wymaga Player podczas tworzenia. Jego celem jest zapewnienie dostępu do Player z innych procesów lub wątków.
Architektura odtwarzania Media3
Jeśli masz dostęp do obiektu Player, wywołaj jego metody bezpośrednio, aby wydawać polecenia odtwarzania. Możesz przekazywać informacje o odtwarzaniu i przyznawać źródłom zewnętrznym kontrolę nad odtwarzaniem, implementując MediaSession. Te źródła zewnętrzne implementują interfejs MediaController, który ułatwia łączenie się z sesją multimedialną i wysyłanie żądań poleceń odtwarzania.
Podczas odtwarzania multimediów w tle sesja multimedialna i odtwarzacz muszą znajdować się w MediaSessionService lub MediaLibraryService, które działają jako usługa na pierwszym planie. Dzięki temu możesz oddzielić odtwarzacz od aktywności w aplikacji, która zawiera interfejs do sterowania odtwarzaniem. Może to wymagać użycia
kontrolera multimediów.
Player odgrywa kluczową rolę w architekturze Media3.Stan odtwarzacza
Stan odtwarzacza multimedialnego, który implementuje interfejs Player, składa się głównie z 4 kategorii informacji:
- Stan odtwarzania
- Pobierz za pomocą
getPlaybackState(). - Wartości stanu zdefiniowane przez interfejs to
STATE_IDLE,STATE_BUFFERING,STATE_READYiSTATE_ENDED.
- Pobierz za pomocą
- Playlista z elementami multimedialnymi
- Sekwencja instancji
MediaItemdo odtworzenia. - Pobieranie za pomocą
getCurrentTimeline() - Instancje
Playermogą udostępniać metody operacji na playlistach, takie jak dodawanie lub usuwanie elementuMediaItem, oraz metody ułatwiające, takie jakgetCurrentMediaItem().
- Sekwencja instancji
- Właściwości odtwarzania/wstrzymywania, takie jak:
playWhenReady: wskazuje, czy użytkownik chce, aby multimedia były odtwarzane, gdy jest to możliwe, czy też mają pozostać wstrzymane.- Przyczyna wstrzymania odtwarzania:
wskazanie przyczyny wstrzymania odtwarzania (jeśli dotyczy), nawet jeśli
playWhenReadytotrue. isPlaying: informacja o tym, czy odtwarzacz aktualnie odtwarza treści. Będzie mieć wartośćtruetylko wtedy, gdy stan odtwarzania toSTATE_READY,playWhenReadytotrue, a odtwarzanie nie jest wstrzymane.
- Pozycja odtwarzania, w tym:
- Current media item index: indeks bieżącego elementu multimedialnego
MediaItemna playliście. isPlayingAd: informacja o tym, czy wstawiona reklama jest odtwarzana.- Bieżąca pozycja odtwarzania: bieżąca pozycja odtwarzania w bieżącym elemencie
MediaItemlub wstawionej reklamie.
- Current media item index: indeks bieżącego elementu multimedialnego
Interfejs Player umożliwia też dostęp do dostępnych ścieżek, metadanych multimediów, szybkości odtwarzania, głośności i innych właściwości pomocniczych odtwarzania.
Sprawdzanie zmian
Użyj Player.Listener, aby monitorować zmiany w Player. Szczegółowe informacje o tworzeniu i używaniu detektora znajdziesz w dokumentacji ExoPlayera dotyczącej zdarzeń odtwarzacza.
Pamiętaj, że interfejs detektora nie zawiera żadnych wywołań zwrotnych do śledzenia normalnego postępu odtwarzania. Aby stale monitorować postęp odtwarzania, np. w celu skonfigurowania interfejsu paska postępu, należy sprawdzać bieżącą pozycję w odpowiednich odstępach czasu.
Kotlin
fun checkPlaybackPosition(delayMs: Long): Boolean = handler.postDelayed( { val currentPosition = player.currentPosition // Update UI based on currentPosition checkPlaybackPosition(delayMs) }, delayMs, )
Java
boolean checkPlaybackPosition(long delayMs) { return handler.postDelayed( () -> { long currentPosition = player.getCurrentPosition(); // Update UI based on currentPosition checkPlaybackPosition(delayMs); }, delayMs); }
sterować odtwarzaniem.
Interfejs Player oferuje wiele sposobów manipulowania stanem i sterowania odtwarzaniem:
- Podstawowe elementy sterujące odtwarzaniem, takie jak
play(),pause(),prepare()istop(). - Operacje na playlistach, takie jak
addMediaItem()lubremoveMediaItem(). - Przewijanie, aby zmienić bieżący element lub pozycję.
- ustawiać tryby powtarzania i tryb odtwarzania losowego.
- Zaktualizuj ustawienia wyboru ścieżki.
- Ustaw szybkość odtwarzania.
Niestandardowe implementacje Player
Aby utworzyć odtwarzacz niestandardowy, możesz rozszerzyć klasę SimpleBasePlayer zawartą w Media3. Ta klasa zapewnia podstawową implementację interfejsu Player, aby ograniczyć do minimum liczbę metod, które musisz zaimplementować.
Zacznij od zastąpienia metody getState(). Ta metoda powinna po wywołaniu wypełniać bieżący stan odtwarzacza, w tym:
- zestaw dostępnych poleceń,
- właściwości odtwarzania, takie jak to, czy odtwarzacz powinien rozpocząć odtwarzanie, gdy stan odtwarzania to
STATE_READY, indeks aktualnie odtwarzanego elementu multimedialnego i pozycja odtwarzania w bieżącym elemencie;
Kotlin
class CustomPlayer(looper: Looper) : SimpleBasePlayer(looper) { override fun getState(): State { return State.Builder() .setAvailableCommands(Commands.EMPTY) // Set which playback commands the player can handle // Configure additional playback properties .setPlayWhenReady(true, PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST) .setCurrentMediaItemIndex(0) .setContentPositionMs(0) .build() } }
Java
private static final class CustomPlayer extends SimpleBasePlayer { public CustomPlayer(Looper looper) { super(looper); } @Override protected State getState() { return new State.Builder() .setAvailableCommands(Commands.EMPTY) // Set which playback commands the player can handle // Configure additional playback properties .setPlayWhenReady(true, PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST) .setCurrentMediaItemIndex(0) .setContentPositionMs(0) .build(); } }
SimpleBasePlayer wymusi utworzenie State z prawidłową kombinacją wartości stanu. Będzie też obsługiwać detektory i informować je o zmianach stanu. Jeśli chcesz ręcznie wywołać aktualizację stanu, wywołaj invalidateState().
Oprócz metody getState() musisz zaimplementować tylko metody używane w przypadku poleceń, które odtwarzacz deklaruje jako dostępne. Znajdź metodę modułu obsługi, którą można zastąpić, odpowiadającą funkcji, którą chcesz zaimplementować. Możesz na przykład zastąpić metodę handleSeek(), aby obsługiwać operacje takie jak COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM i COMMAND_SEEK_TO_NEXT_MEDIA_ITEM.
Modyfikowanie implementacji Player
Zamiast tworzyć całkowicie niestandardowy element Player, możesz użyć ForwardingSimpleBasePlayer, aby zmodyfikować stan i zachowanie istniejącego elementu Player. Więcej informacji znajdziesz w przewodniku na stronie Dostosowywanie.