Odtwarzacz to element aplikacji, który umożliwia odtwarzanie elementów multimedialnych.
Interfejs Media3 Player
określa zarys funkcji zwykle obsługiwanych przez odtwarzacz. Obejmuje to:
- Wpływ na elementy sterujące odtwarzaniem, takie jak odtwarzanie, wstrzymywanie i przewijanie
- Zapytanie o właściwości aktualnie odtwarzanych multimediów, takie jak pozycja odtwarzania
- Zarządzanie playlistą lub kolejką elementów multimedialnych
- Konfigurowanie właściwości odtwarzania, takich jak losowe, powtarzanie, prędkość 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 odtwarzacza jest implementowany przez kilka komponentów Media3, np.:
Komponent | Opis i informacje o działaniu |
---|---|
ExoPlayer |
Interfejs API odtwarzacza multimediów i domyślna implementacja interfejsu Player . |
MediaController |
Wchodzi w interakcję z elementem MediaSession , aby wysłać polecenia odtwarzania. Jeśli Twoje Player i MediaSession znajdują się w Service innej niż Activity lub Fragment , gdzie działa interfejs odtwarzacza, możesz przypisać MediaController jako odtwarzacz w swoim interfejsie PlayerView . Wywołania metody odtwarzania i playlist są wysyłane na urządzenie Player przez MediaSession .
|
MediaBrowser |
Oprócz funkcji oferowanych przez MediaController korzysta też z MediaLibrarySession , aby przeglądać dostępne treści multimedialne.
|
ForwardingPlayer |
Implementacja Player , która przekierowuje wywołania metody do innego komponentu Player . Użyj tej klasy do pomijania lub modyfikowania określonych operacji przez zastąpienie odpowiednich metod.
|
SimpleBasePlayer |
Implementacja Player , która zmniejsza do minimum liczbę metod implementacji. Przydaje się, gdy korzystasz z niestandardowego odtwarzacza, który chcesz połączyć z urządzeniem MediaSession .
|
CastPlayer |
Implementacja Player , która komunikuje się z aplikacją odbiornika. Sposób działania zależy od sesji przesyłania.
|
Chociaż element MediaSession
nie implementuje interfejsu Player
, do jego tworzenia wymagany jest element Player
. Jego celem jest zapewnienie dostępu do Player
z poziomu 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 wysyłać polecenia odtwarzania. Możesz zareklamować odtwarzanie i przyznać kontrolę odtwarzania w przypadku źródeł zewnętrznych, implementując MediaSession
. Te źródła zewnętrzne implementują MediaController
, który ułatwia nawiązanie połączenia z sesją multimediów i wydawanie żądań odtwarzania.
Gdy odtwarzasz multimedia w tle, musisz przechowywać sesję multimediów i odtwarzacz w interfejsie MediaSessionService
lub MediaLibraryService
, które działają jako usługa na pierwszym planie. W ten sposób możesz oddzielić odtwarzacz od aktywności w aplikacji, która zawiera interfejs sterowania odtwarzaniem. Może to wymagać użycia
kontrolera multimediów.
Stan odtwarzacza
Stan odtwarzacza multimedialnego z implementacją interfejsu Player
obejmuje głównie 4 kategorie informacji:
- Stan odtwarzania:
- Pobierz za pomocą
getPlaybackState()
. - Wartości stanu zdefiniowane w interfejsie to
STATE_IDLE
,STATE_BUFFERING
,STATE_READY
iSTATE_ENDED
.
- Pobierz za pomocą
- Playlista z elementami multimedialnymi
- Sekwencja
MediaItem
instancji do odtwarzania. - Pobierz za pomocą
getCurrentTimeline()
- Instancje
Player
mogą udostępniać metody operacji związanych z playlistami, takie jak dodawanie lub usuwanie elementuMediaItem
, oraz metody zapewniające wygodę, takie jakgetCurrentMediaItem()
.
- Sekwencja
- Usługi odtwarzania/wstrzymywania, takie jak:
playWhenReady
: wskazanie, czy użytkownik chce odtwarzać multimedia, gdy to możliwe, czy ma być wstrzymane.- Przyczyna wstrzymania odtwarzania: wskazanie przyczyny wstrzymania odtwarzania (w stosownych przypadkach), nawet jeśli parametr
playWhenReady
ma wartośćtrue
isPlaying
: informacja o tym, czy odtwarzacz w danej chwili gra. Ma wartośćtrue
, jeśli stan odtwarzania toSTATE_READY
,playWhenReady
totrue
, a odtwarzanie nie jest wstrzymane.
- Pozycja odtwarzania, w tym:
- Bieżący indeks elementu multimedialnego: indeks bieżącego elementu
MediaItem
na playliście. isPlayingAd
: wskazuje, czy wstawiona reklama jest odtwarzana.- Bieżąca pozycja odtwarzania:
bieżąca pozycja odtwarzania w ramach bieżącego fragmentu filmu (
MediaItem
) lub wstawionej reklamy.
- Bieżący indeks elementu multimedialnego: indeks bieżącego elementu
Oprócz tego interfejs Player
zapewnia dostęp do dostępnych ścieżek, metadanych multimediów, prędkości odtwarzania, głośności i innych właściwości pomocniczych związanych z odtwarzaniem.
Wykrywaj zmiany
Użyj funkcji Player.Listener
, aby nasłuchiwać zmian w elemencie Player
. Szczegółowe informacje o tym, jak utworzyć detektor i używać go, znajdziesz w dokumentacji ExoPlayer dotyczącej zdarzeń odtwarzacza.
Pamiętaj, że interfejs odbiornika nie zawiera żadnych wywołań zwrotnych umożliwiających śledzenie normalnego postępu odtwarzania. Aby stale monitorować postęp odtwarzania, np. skonfigurować interfejs paska postępu, wysyłaj zapytania o bieżącą pozycję w odpowiednich odstępach czasu.
Kotlin
val handler = Handler(Looper.getMainLooper()) fun checkPlaybackPosition(delayMs: Long): Boolean = handler.postDelayed( { val currentPosition = player.currentPosition // Update UI based on currentPosition checkPlaybackPosition(delayMs) }, delayMs)
Java
Handler handler = new Handler(Looper.getMainLooper()); boolean checkPlaybackPosition(long delayMs) { return handler.postDelayed(() -> { long currentPosition = player.getCurrentPosition(); // Update UI based on currentPosition checkPlaybackPosition(delayMs); }, delayMs); }
Sterowanie odtwarzaniem
Interfejs Player
oferuje wiele sposobów na manipulowanie stanem i odtwarzaniem:
- Podstawowe elementy sterujące odtwarzaniem,
takie jak
play()
,pause()
,prepare()
istop()
. - Operacje na playliście, np.
addMediaItem()
lubremoveMediaItem()
. - Przewijanie w celu zmiany bieżącego elementu lub pozycji.
- Ustaw tryby powtarzania i tryb tasowania.
- Zaktualizuj ustawienia wyboru ścieżki.
- Ustaw szybkość odtwarzania.
Niestandardowe implementacje typu Player
Aby utworzyć własny odtwarzacz, możesz rozszerzyć SimpleBasePlayer
z Media3. Ta klasa udostępnia podstawową implementację interfejsu Player
, która pozwala do minimum ograniczyć liczbę metod, które trzeba wdrożyć.
Zacznij od zastąpienia metody getState()
. Po wywołaniu metoda ta powinna zapełniać bieżący stan odtwarzacza, w tym:
- Zestaw dostępnych poleceń
- Właściwości odtwarzania: np. 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 : SimpleBasePlayer(looper) { override fun getState(): State { return State.Builder() .setAvailableCommands(...) // 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
public class CustomPlayer extends SimpleBasePlayer { public CustomPlayer(Looper looper) { super(looper); } @Override protected State getState() { return new State.Builder() .setAvailableCommands(...) // 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ć słuchaczy
i informować słuchaczy o zmianach w poszczególnych stanach. Jeśli musisz ręcznie aktywować aktualizację stanu, wywołaj metodę invalidateState()
.
Oprócz metody getState()
musisz implementować tylko metody używane w poleceniach zadeklarowanych przez odtwarzacz jako dostępne. Znajdź metodę zastępowania z możliwością zastępowania odpowiadającą funkcji, którą chcesz zaimplementować. Na przykład zastąp metodę handleSeek()
, aby obsługiwać operacje takie jak COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM
i COMMAND_SEEK_TO_NEXT_MEDIA_ITEM
.