Новости о продуктах

Что нового в Media3 1.9.0

Время на чтение: 6 минут
Посмотреть профиль Кристины Симаковой
Kristina Simakova Менеджер по разработке

Вышла версия Media3 1.9.0 Помимо обычных исправлений ошибок и улучшений производительности, последняя версия также содержит четыре новых или в значительной степени переписанных модуля:

  • media3-inspector – извлечение метаданных и кадров вне воспроизведения.
  • media3-ui-compose-material3 – создайте базовый интерфейс медиапроигрывателя на основе Material 3 и Compose всего за несколько шагов.
  • media3-cast – автоматическая обработка переходов между Cast и локальным воспроизведением
  • media3-decoder-av1 – стабильное воспроизведение AV1 с помощью переписанного декодера расширения на основе библиотеки dav1d.

Мы также улучшили кеширование и управление памятью в PreloadManager и упростили работу с ExoPlayer, Transformer и MediaSession.

В этом выпуске также впервые предоставляется экспериментальный доступ к CompositionPlayer для предварительного просмотра изменений медиафайлов.  


Ниже вы найдете подробную информацию. Как обычно, полный список изменений приведен в примечаниях к выпуску.

Извлечение метаданных и кадров вне воспроизведения

Во многих случаях вам может потребоваться проверить медиаконтент, не запуская воспроизведение. Например, вы можете определить, какие форматы он содержит, какова его продолжительность, или получить значки.

Новый модуль media3-inspector объединяет все утилиты для проверки медиафайлов без воспроизведения:

  • MetadataRetriever для считывания продолжительности, формата и статических метаданных из MediaItem.
  • FrameExtractor, чтобы получить кадры или значки из объекта.
  • MediaExtractorCompat, который заменяет класс MediaExtractor платформы Android и позволяет получать подробную информацию о фрагментах в файле.

MetadataRetriever и FrameExtractor следуют простому шаблону AutoCloseable. Подробную информацию вы найдете в новом руководстве.

suspend fun extractThumbnail(mediaItem: MediaItem) {

  FrameExtractor.Builder(context, mediaItem).build().use {

    val thumbnail = frameExtractor.getThumbnail().await()

  } 

}

Создайте базовый пользовательский интерфейс Material3 Compose Media всего за несколько шагов.

В предыдущих выпусках мы начали предоставлять код коннектора между элементами пользовательского интерфейса Compose и вашим экземпляром Player. В Media3 1.9.0 мы добавили новый модуль media3-ui-compose-material3 с полностью стилизованными кнопками и элементами контента Material3. Они позволяют создать пользовательский интерфейс медиа всего за несколько шагов, обеспечивая при этом полную гибкость в настройке собственного стиля. Если вы хотите создать собственный стиль интерфейса, вы можете использовать стандартные блоки, которые отвечают за всю логику обновления и подключения, поэтому вам нужно сосредоточиться только на разработке элемента интерфейса. Ознакомьтесь с расширенным руководством по модулям Compose UI.

Мы также работаем над другими компонентами Compose, такими как встроенная панель перемотки, полная замена PlayerView, а также интеграция субтитров и рекламы.

@Composable
fun SimplePlayerUI(player: Player, modifier: Modifier = Modifier) {
  Column(modifier) {
    ContentFrame(player)  // Video surface and shutter logic
    Row (Modifier.align(Alignment.CenterHorizontally)) {                 
      SeekBackButton(player)   // Simple controls
      PlayPauseButton(player)
      SeekForwardButton(player)
    }
  }
}

 

image.png

Простой интерфейс проигрывателя Compose с готовыми элементами

Автоматически обрабатывать переходы между Cast и локальным воспроизведением

Класс CastPlayer в модуле media3-cast был переписан, чтобы автоматически обрабатывать переходы между локальным воспроизведением (например, с помощью ExoPlayer) и удаленным воспроизведением Cast.

При настройке MediaSession просто создайте CastPlayer вокруг ExoPlayer и добавьте MediaRouteButton в интерфейс.

// MediaSession setup with CastPlayer 

val exoPlayer = ExoPlayer.Builder(context).build()

val castPlayer = CastPlayer.Builder(context).setLocalPlayer(exoPlayer).build()

val session = MediaSession.Builder(context, castPlayer).build()

// MediaRouteButton in UI 

@Composable fun UIWithMediaRouteButton() {

  MediaRouteButton()

}
image.png

Новая интеграция CastPlayer в демоприложении сеанса Media3

Стабильное воспроизведение AV1 с переписанным расширением на основе dav1d.

В версии 1.9.0 полностью переписан модуль расширения AV1 на основе популярной библиотеки dav1d.

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

Интегрируйте кеширование и управление памятью в PreloadManager

Мы также улучшили PreloadManager. Он уже позволял предварительно загружать медиаконтент в память вне воспроизведения, а затем при необходимости легко передавать его проигрывателю. Хотя это и было довольно эффективно, все равно нужно было следить за тем, чтобы не превысить лимиты памяти, случайно загрузив слишком много данных. Поэтому в Media3 1.9.0 мы добавили две функции, которые упрощают и стабилизируют этот процесс:

  1. Поддержка кеширования. Теперь при определении того, насколько далеко вперед нужно выполнять предварительную загрузку, вы можете выбрать PreloadStatus.specifiedRangeCached(0, 5000) в качестве целевого состояния для предварительно загруженных элементов. В результате указанный диапазон будет добавлен в кеш на диске, а не загружен в память. Это позволяет выполнять предзагрузку гораздо большего количества объектов, поскольку те, которые находятся дальше от текущего, больше не занимают память. Обратите внимание, что для этого необходимо задать Cache в DefaultPreloadManager.Builder.
  2. Автоматическое управление памятью. Мы также обновили интерфейс LoadControl, чтобы улучшить обработку предварительной загрузки. Теперь вы можете установить явный верхний предел памяти для всех предварительно загруженных элементов в памяти. По умолчанию это значение равно 144 МБ, но вы можете изменить его в DefaultLoadControl.Builder. Когда лимит будет достигнут, DefaultPreloadManager автоматически прекратит предзагрузку и при необходимости освободит память, удалив объекты с более низким приоритетом.

Используйте новые упрощенные режимы работы по умолчанию в ExoPlayer

Как всегда, мы также добавили множество дополнительных улучшений в ExoPlayer. Вот лишь некоторые из них:

  • Включение и отключение звука. Метод setVolume уже существовал, но теперь мы добавили удобные методы mute и unmute, позволяющие легко восстановить предыдущую громкость, не отслеживая ее самостоятельно.
  • Обнаружение зависания проигрывателя. В редких случаях проигрыватель может зависнуть в состоянии буферизации или воспроизведения, например из-за проблем с кодеком или неправильной конфигурации. Пользователи будут недовольны, но вы не увидите эти проблемы в аналитике. Чтобы сделать это более очевидным, проигрыватель теперь сообщает о StuckPlayerException, когда обнаруживает зависание.
  • Запрет блокировки по умолчанию. Ранее управление запретом блокировки было необязательным, из-за чего в редких случаях прогресс воспроизведения в фоновом режиме мог задерживаться. Теперь эта функция включена по умолчанию, поэтому вы можете удалить весь код, который вручную управляет запретом блокировки во время воспроизведения.
  • Упрощенная настройка логики кнопки субтитров. Изменить TrackSelectionParameters, чтобы включить или отключить субтитры, было на удивление сложно, поэтому мы добавили для этого случая простое логическое значение selectTextByDefault.

Упростите настройки кнопок мультимедиа в MediaSession

До сих пор, чтобы определить, какие кнопки должны показываться на панели уведомлений мультимедиа в Android Auto или Wear OS, нужно было задавать специальные команды и кнопки, даже если вы просто хотели запустить стандартный метод проигрывателя.

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

session.setMediaButtonPreferences(listOf(
    CommandButton.Builder(CommandButton.ICON_FAST_FORWARD) // choose an icon
      .setDisplayName(R.string.skip_forward)
      .setPlayerCommand(Player.COMMAND_SEEK_FORWARD) // choose an action 
      .build()
))
image.png

Настройки кнопок управления медиаконтентом с кнопкой перемотки вперед

CompositionPlayer для предварительного просмотра в реальном времени

В версии 1.9.0 представлен CompositionPlayer с новой аннотацией @ExperimentalApi. Аннотация указывает, что функция доступна для экспериментов, но все ещё находится в разработке. 

CompositionPlayer – это новый компонент в API редактирования Media3, предназначенный для предварительного просмотра изменений медиафайлов в реальном времени. CompositionPlayer основан на знакомом интерфейсе Media3 Player и позволяет пользователям увидеть изменения, прежде чем экспортировать видео. Он использует тот же объект Composition, который вы передаете в Transformer для экспорта, что упрощает процесс редактирования за счет унификации модели данных для предварительного просмотра и экспорта.

Рекомендуем начать использовать CompositionPlayer и поделиться своим мнением. Следите за публикациями и обновлениями документации, чтобы узнать больше.

InAppMuxer как мультиплексор по умолчанию в Transformer

Теперь Transformer использует InAppMp4Muxer в качестве мультиплексора по умолчанию для записи файлов медиаконтейнеров. Внутренне InAppMp4Muxer зависит от модуля Media3 Muxer, обеспечивающего согласованное поведение во всех версиях API. 

Обратите внимание, что хотя Transformer больше не использует MediaMuxer платформы Android по умолчанию, вы по-прежнему можете предоставить FrameworkMuxer.Factory через setMuxerFactory, если это необходимо для вашего случая использования.

Новые API для регулировки скорости

В версии 1.9.0 упрощены API для изменения скорости воспроизведения при редактировании медиаконтента. Мы добавили новые методы непосредственно в EditedMediaItem.Builder, чтобы управлять скоростью. Это сделало API более интуитивно понятным. Теперь вы можете изменить скорость клипа, вызвав setSpeed(SpeedProvider provider) для EditedMediaItem.Builder:

val speedProvider = object : SpeedProvider {
    override fun getSpeed(presentationTimeUs: Long): Float {
        return speed
    }

    override fun getNextSpeedChangeTimeUs(timeUs: Long): Long {
        return C.TIME_UNSET
    }
}

EditedMediaItem speedEffectItem = EditedMediaItem.Builder(mediaItem)
    .setSpeed(speedProvider)
    .build()

Этот новый подход заменяет предыдущий метод использования Effects#createExperimentalSpeedChangingEffects(), который мы прекратили поддерживать и удалим в будущем выпуске.

Типы дорожек для EditedMediaItemSequence

В версии 1.9.0 EditedMediaItemSequence требует указывать типы дорожек, которые должны быть в выходном файле, при создании последовательности. Это изменение обеспечивает более явную и надежную обработку дорожек во всей композиции. 

Для этого используется новый конструктор EditedMediaItemSequence.Builder, который принимает набор типов треков (например, C.TRACK_TYPE_AUDIO, C.TRACK_TYPE_VIDEO).

Чтобы упростить создание, мы добавили новые статические методы:

  • EditedMediaItemSequence.withAudioFrom(List<EditedMediaItem>)
  • EditedMediaItemSequence.withVideoFrom(List<EditedMediaItem>)
  • EditedMediaItemSequence.withAudioAndVideoFrom(List<EditedMediaItem>)

Рекомендуем перейти на новый конструктор или удобные методы, чтобы определения последовательностей были более понятными и надежными.

Пример создания последовательности, состоящей только из видео:

EditedMediaItemSequence videoOnlySequence =
    EditedMediaItemSequence.Builder(setOf(C.TRACK_TYPE_VIDEO))
        .addItem(editedMediaItem)
        .build()

Если вы столкнетесь с ошибками или у вас возникнут вопросы или запросы на добавление функций, свяжитесь с нами через систему отслеживания ошибок Media3. Мы с нетерпением ждем ваших отзывов!

Автор:
Продолжить чтение