Добавьте элементы управления воспроизведением в свое приложение

Приложению, воспроизводящему мультимедиа, требуются компоненты пользовательского интерфейса для отображения мультимедиа и управления воспроизведением. Библиотека Media3 включает модуль пользовательского интерфейса, содержащий ряд компонентов пользовательского интерфейса. Чтобы зависеть от модуля пользовательского интерфейса, добавьте следующую зависимость:

Котлин

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

классный

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

Самый важный компонент — PlayerView , представление для воспроизведения мультимедиа. PlayerView отображает видео, изображения, субтитры и обложки альбомов во время воспроизведения, а также элементы управления воспроизведением.

PlayerView имеет метод setPlayer() для подключения и отсоединения (путем передачи null ) экземпляров игрока.

Просмотр игрока

PlayerView можно использовать для воспроизведения видео, изображений и аудио. Он визуализирует видео и субтитры в случае воспроизведения видео, растровые изображения для воспроизведения изображений и может отображать изображения, включенные в качестве метаданных в аудиофайлы. Вы можете включить его в файлы макета, как и любой другой компонент пользовательского интерфейса. Например, PlayerView можно включить в следующий 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"/>

Приведенный выше фрагмент показывает, что PlayerView предоставляет несколько атрибутов. Эти атрибуты можно использовать для настройки поведения представления, а также его внешнего вида. Большинству этих атрибутов соответствуют соответствующие методы установки, которые можно использовать для настройки представления во время выполнения. В документации PlayerView эти атрибуты и методы установки перечислены более подробно.

После того как представление объявлено в файле макета, его можно просмотреть в методе onCreate действия:

Котлин

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

Ява

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

Когда проигрыватель инициализирован, его можно присоединить к представлению, вызвав setPlayer :

Котлин

// 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()

Ява

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

Выберите тип поверхности

Атрибут surface_type PlayerView позволяет вам установить тип поверхности, используемой для воспроизведения видео. Помимо значений spherical_gl_surface_view (специальное значение для воспроизведения сферического видео) и video_decoder_gl_surface_view (для рендеринга видео с использованием расширенных рендереров), допустимыми значениями являются surface_view , texture_view и none . Если представление предназначено только для воспроизведения звука, none следует использовать, чтобы избежать необходимости создания поверхности, поскольку это может оказаться дорогостоящим.

Если представление предназначено для обычного воспроизведения видео, следует использовать surface_view texture_view . SurfaceView имеет ряд преимуществ перед TextureView при воспроизведении видео:

  • Значительно более низкое энергопотребление на многих устройствах.
  • Более точная синхронизация кадров, что обеспечивает более плавное воспроизведение видео.
  • Поддержка вывода HDR-видео более высокого качества на совместимых устройствах.
  • Поддержка безопасного вывода при воспроизведении контента, защищенного DRM.
  • Возможность рендеринга видеоконтента в полном разрешении дисплея на устройствах Android TV с возможностью повышения уровня пользовательского интерфейса.

Поэтому там, где это возможно, следует отдавать предпочтение SurfaceView перед TextureView . TextureView следует использовать только в том случае, если SurfaceView не соответствует вашим потребностям. Одним из примеров является ситуация, когда требуется плавная анимация или прокрутка поверхности видео до Android 7.0 (уровень API 24), как описано в следующих примечаниях. В этом случае предпочтительнее использовать TextureView только в том случае, если SDK_INT меньше 24 (Android 7.0), а в противном случае SurfaceView .

Навигация по D-pad на Android TV

Пульт дистанционного управления Android TV оснащен крестовиной, которая отправляет команды, которые поступают в качестве ключевого события при dispatchKeyEvent(KeyEvent) вашего Activity . Их необходимо делегировать представлению игрока:

Котлин

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

Ява

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

Запрос фокуса на просмотр проигрывателя важен для навигации по элементам управления воспроизведением и пропуска рекламы. Рассмотрите возможность запроса фокуса в onCreate Activity :

Котлин

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

Ява

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

Если вы используете Compose на Android TV, вам необходимо сделать AndroidView фокусируемым и делегировать событие, передав параметр-модификатор в AndroidView соответствующим образом:

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