Dodaj elementy sterujące odtwarzaniem w aplikacji

Aplikacja odtwarzająca multimedia wymaga elementów interfejsu użytkownika do wyświetlania multimediów i sterowania odtwarzaniem. Biblioteka Media3 zawiera moduł interfejsu użytkownika, który zawiera wiele komponentów interfejsu. Aby utworzyć zależność od modułu interfejsu użytkownika, dodaj tę zależność:

Kotlin

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

Odlotowe

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

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

PlayerView ma metodę setPlayer dołączania i odłączania (przez przekazywanie null) instancji odtwarzacza.

PlayerView

PlayerView może służyć do odtwarzania filmów, obrazów i dźwięku. Renderuje filmy i napisy w przypadku odtwarzania filmów, mapy bitowe do odtwarzania obrazów i może wyświetlać grafiki dołączone jako metadane w plikach audio. Możesz go umieścić w plikach układu tak samo jak każdy inny komponent UI. PlayerView może być np. zawarty 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"/>

Fragment kodu powyżej pokazuje, że PlayerView zawiera kilka atrybutów. Za pomocą tych atrybutów możesz dostosować zachowanie widoku, a także jego wygląd i wygląd. Większość z tych atrybutów ma odpowiednie metody settera, których można używać do dostosowywania widoku w czasie wykonywania. W dokumentacji Javadoc dotyczącej klasy PlayerView znajdziesz więcej informacji o tych atrybutach i metodach settera.

Gdy widok zostanie zadeklarowany w pliku układu, można go wyszukać w metodie 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 funkcję 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();

Wybieranie typu powierzchni

Atrybut surface_type elementu PlayerView pozwala określić typ powierzchni, na której wyświetlany jest film. Oprócz wartości spherical_gl_surface_view (która jest wartością specjalną dla odtwarzania filmów sferycznych) i video_decoder_gl_surface_view (która służy do renderowania filmów za pomocą rendererów rozszerzeń) dozwolone są wartości surface_view, texture_viewnone. Jeśli widok służy tylko do odtwarzania dźwięku, należy użyć opcji none, aby uniknąć tworzenia powierzchni, ponieważ może to być kosztowne.

Jeśli widok służy do odtwarzania zwykłego filmu, należy użyć parametru surface_view lub texture_view. SurfaceView ma szereg zalet w porównaniu z TextureView w przypadku odtwarzania filmów:

  • znacznie obniżyć zużycie energii na wielu urządzeniach;
  • Dokładniejsze ustalanie czasu wyświetlania klatek, co zapewnia płynniejsze odtwarzanie filmów.
  • Obsługa lepszej jakości wyjścia wideo HDR na urządzeniach obsługujących tę funkcję.
  • Obsługa bezpiecznego wyjścia podczas odtwarzania treści chronionych przez DRM.
  • Możliwość renderowania treści wideo w pełnej rozdzielczości wyświetlacza na urządzeniach z Androidem TV, które powiększają warstwę interfejsu użytkownika.

Dlatego, jeśli to możliwe, preferuj opcję SurfaceView zamiast TextureView. TextureView należy stosować tylko wtedy, gdy SurfaceView nie spełnia Twoich potrzeb. Przykładem jest płynne wyświetlanie animacji lub przewijanie powierzchni wideo w wersjach Androida 7.0 (interfejs API na poziomie 24) i starszych, jak opisano w uwagach poniżej. W tym przypadku lepiej jest użyć TextureView tylko wtedy, gdy SDK_INT jest mniejsza niż 24 (Android 7.0), a w przeciwnym razie SurfaceView.

Nawigacja za pomocą panelu kierunkowego na Androidzie TV

Pilot do Androida TV jest wyposażony w pad kierunkowy, który wysyła polecenia, które pojawiają się jako kluczowe zdarzenie na urządzeniu dispatchKeyEvent(KeyEvent) na urządzeniu Activity. Te elementy musisz 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);
}

Żądanie skupienia na widoku odtwarzacza jest ważne dla nawigacji przy użyciu elementów sterujących odtwarzaniem i pomijania reklam. Zastanów się, czy chcesz skoncentrować się na onCreate w ramach 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 Compose na Androidzie TV, musisz umożliwić skupienie na elemencie AndroidView i przekazać zdarzenie, przekazując parametr modyfikatora do elementu AndroidView:

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

Zastępowanie drawable

PlayerView używa PlayerControlView do wyświetlania elementów sterujących odtwarzaniem i paska postępu. Obiekty graficzne używane przez PlayerControlView mogą zostać zastąpione przez obiekty graficzne o tych samych nazwach zdefiniowanych w aplikacji. Aby zobaczyć listę elementów sterujących, których wygląd można zastąpić, zajrzyj do dokumentacji PlayerControlView w języku Javadoc.

Dalsze dostosowywanie

Jeśli wymagane jest dostosowanie wykraczające poza opisane powyżej, oczekujemy, że deweloperzy aplikacji wdrożą własne komponenty UI zamiast używać tych udostępnianych przez moduł UI Media3.