Dodaj elementy sterujące odtwarzaniem w aplikacji

Aplikacja odtwarzająca multimedia wymaga komponentów interfejsu do wyświetlania multimediów i sterowania odtwarzaniem. Biblioteka Media3 zawiera moduł interfejsu z wieloma komponentami UI. Aby skorzystać z modułu interfejsu, dodaj następującą zależność:

Kotlin

implementation("androidx.media3:media3-ui:1.3.1")

Odlotowy

implementation "androidx.media3:media3-ui:1.3.1"

Najważniejszym elementem jest PlayerView, czyli widok odtwarzania multimediów. PlayerView wyświetla podczas odtwarzania film, napisy i okładkę albumu, a także elementy sterujące odtwarzaniem.

PlayerView ma metodę setPlayer umożliwiającą podłączanie i odłączanie (omijając null) instancji odtwarzacza.

Widok odtwarzacza

PlayerView może służyć zarówno do odtwarzania filmów, jak i audio. Renderuje on film i napisy w przypadku odtwarzania filmu i może wyświetlać elementy graficzne dołączone jako metadane w plikach audio. Możesz go uwzględnić w plikach układu, tak jak każdy inny komponent UI. Na przykład obiekt PlayerView można dołączyć w tym kodzie XML:

<androidx.media3.ui.PlayerView
    android:id="@+id/player_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:show_buffering="when_playing"
    app:show_shuffle_button="true"/>

Powyższy fragment kodu pokazuje, że atrybut PlayerView ma kilka atrybutów. Tych atrybutów można używać do dostosowywania działania widoku oraz jego wyglądu i sposobu działania. Większość z tych atrybutów ma odpowiadające im metody ustawiające, których można używać do dostosowywania widoku w czasie działania. Szczegółową listę tych atrybutów i metod ustawiających znajdziesz w dokumencie Javadoc PlayerView.

Po zadeklarowaniu widoku w pliku układu można go wyszukać w metodzie onCreate aktywności:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  // ...
  playerView = findViewById(R.id.player_view)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  // ...
  playerView = findViewById(R.id.player_view);
}

Po zainicjowaniu odtwarzacza można go dołączyć do widoku, wywołując setPlayer:

Kotlin

// Instantiate the player.
val player = ExoPlayer.Builder(context).build()
// Attach player to the view.
playerView.player = player
// Set the media item to be played.
player.setMediaItem(mediaItem)
// Prepare the player.
player.prepare()

Java

// Instantiate the player.
player = new ExoPlayer.Builder(context).build();
// Attach player to the view.
playerView.setPlayer(player);
// Set the media item to be played.
player.setMediaItem(mediaItem);
// Prepare the player.
player.prepare();

Wybierz typ nawierzchni

Atrybut surface_type w polu PlayerView pozwala określić typ powierzchni używanej do odtwarzania filmu. Oprócz wartości spherical_gl_surface_view (która jest specjalną wartością w przypadku odtwarzania filmu sferycznego) i video_decoder_gl_surface_view (która dotyczy renderowania filmów z użyciem mechanizmów renderowania rozszerzeń) dozwolone są te wartości: surface_view, texture_view i none. Jeśli widok jest przeznaczony tylko do odtwarzania dźwięku, należy użyć elementu none, aby uniknąć konieczności tworzenia platformy, ponieważ może to być kosztowne.

Jeśli wyświetlenie ma na celu zwykłe odtwarzanie filmu, należy użyć właściwości surface_view lub texture_view. SurfaceView ma wiele zalet w zakresie odtwarzania filmów, a nie TextureView:

  • Wiele urządzeń oznacza znacznie niższe zużycie energii.
  • Większa dokładność czasu klatek zapewniająca płynniejsze odtwarzanie filmów.
  • Obsługa wyższej jakości filmów HDR na zgodnych urządzeniach.
  • Obsługa bezpiecznego wyjścia podczas odtwarzania treści chronionych za pomocą DRM.
  • Możliwość renderowania treści wideo w pełnej rozdzielczości ekranu na urządzeniach z Androidem TV, które przewyższają warstwę interfejsu.

Dlatego w miarę możliwości należy preferować właściwość SurfaceView zamiast TextureView. Funkcji TextureView należy używać tylko wtedy, gdy ustawienie SurfaceView nie spełnia Twoich wymagań. Jednym z przykładów jest płynne animacje lub przewijanie powierzchni wideo w wersjach starszych niż Android 7.0 (poziom interfejsu API 24), co zostało opisane w uwagach poniżej. W tym przypadku zalecamy używanie TextureView tylko wtedy, gdy SDK_INT ma wartość mniejszą niż 24 (Android 7.0), a SurfaceView w innych przypadkach.

Nawigacja za pomocą pada kierunkowego na Androidzie TV

Pilot do Androida TV ma pad kierunkowy, który wysyła polecenia przychodzące jako kluczowe zdarzenia w trybie dispatchKeyEvent(KeyEvent) na urządzeniu Activity. Musisz je przekazać do widoku odtwarzacza:

Kotlin

override fun dispatchKeyEvent(event: KeyEvent?): Boolean{
  return playerView.dispatchKeyEvent(event!!) || super.dispatchKeyEvent(event)
}

Java

@Override
public boolean dispatchKeyEvent(KeyEvent event) {
  return playerView.dispatchKeyEvent(event) || super.dispatchKeyEvent(event);
}

Prośba o zaznaczenie widoku odtwarzacza jest ważna, ponieważ umożliwia sterowanie odtwarzaniem i pomijanie reklam. Rozważ wysłanie prośby o wyróżnienie w onCreate z Activity:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  // ...
  playerView.requestFocus()
  // ...
}

Java

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // ...
    playerView.requestFocus();
    // ...
}

Jeśli używasz funkcji tworzenia wiadomości na Androidzie TV, musisz ustawić element AndroidView z możliwością zaznaczenia i przekazać zdarzenie, przesyłając odpowiednio parametr modyfikatora do funkcji AndroidView:

AndroidView(
  modifier = modifier
    .focusable()
    .onKeyEvent { playerView.dispatchKeyEvent(it.nativeKeyEvent) },
  factory = { playerView }
)

Zastąp elementy rysowalne

PlayerView używa PlayerControlView do wyświetlania elementów sterujących odtwarzaniem i paska postępu. Elementy rysowalne używane przez PlayerControlView można zastąpić elementami rysowalnymi o tych samych nazwach zdefiniowanych w aplikacji. Listę elementów sterujących, które można zastąpić, znajdziesz w dokumencie JavaPlayerControlView.

Dalsze możliwości dostosowywania

Jeśli wymagane jest dostosowanie w zakresie wykraczającym poza opisane powyżej dostosowanie, oczekujemy, że deweloperzy aplikacji będą wdrażać własne komponenty interfejsu użytkownika, zamiast korzystać z komponentów dostępnych przez moduł interfejsu Media3.