Начало работы

Начало работы с Transformer состоит из следующих шагов:

  1. Добавьте Media3 Transformer в качестве зависимости в ваш проект.
  2. Создайте EditedMediaItem , представляющий медиаданные для обработки и изменения, применяемые к ним.
  3. Создайте Transformer , описывающий требуемый вывод и прослушиватель событий завершения и ошибок.
  4. Запустите операцию экспорта, передав EditedMediaItem для редактирования и выходной путь. Во время экспорта вы можете запросить текущий прогресс или отменить операцию.
  5. Когда экспорт завершится, обработайте вывод по мере необходимости. Например, вы можете поделиться выводом с другим приложением или загрузить его на сервер.

Продолжайте читать, чтобы узнать больше об этих шагах, а для полного примера смотрите TransformerActivity в демонстрационном приложении Transformer .

Добавить Media3 Transformer как зависимость

Самый простой способ начать использовать Transformer — добавить зависимости Gradle от библиотеки в файле build.gradle вашего модуля приложения:

Котлин

implementation("androidx.media3:media3-transformer:1.7.1")
implementation("androidx.media3:media3-effect:1.7.1")
implementation("androidx.media3:media3-common:1.7.1")

Круто

implementation "androidx.media3:media3-transformer:1.7.1"
implementation "androidx.media3:media3-effect:1.7.1"
implementation "androidx.media3:media3-common:1.7.1"

где 1.7.1 — ваша предпочтительная версия. Последнюю версию можно найти, прочитав заметки о выпуске .

Более подробную информацию о доступных модулях библиотеки можно найти на странице Google Maven AndroidX Media3 .

Включить поддержку Java 8

Если поддержка Java 8 еще не включена, вам необходимо включить ее во всех файлах build.gradle , которые зависят от Transformer, добавив следующее в раздел android :

compileOptions {
  targetCompatibility JavaVersion.VERSION_1_8
}

Начать трансформацию

Ниже приведен пример создания EditedMediaItem для удаления звука из входного файла, а затем создания и настройки экземпляра Transformer для экспорта видео H.265/HEVC и вывода результата в outputPath .

Котлин

val inputMediaItem = MediaItem.fromUri("path_to_input_file")
val editedMediaItem =
    EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build()
val transformer = Transformer.Builder(context)
    .setVideoMimeType(MimeTypes.VIDEO_H265)
    .addListener(transformerListener)
    .build()
transformer.start(editedMediaItem, outputPath)

Ява

MediaItem inputMediaItem = MediaItem.fromUri("path_to_input_file");
EditedMediaItem editedMediaItem =
    new EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build();
Transformer transformer =
    new Transformer.Builder(context)
        .setVideoMimeType(MimeTypes.VIDEO_H265)
        .addListener(transformerListener)
        .build();
transformer.start(editedMediaItem, outputPath);

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

Вы можете последовательно выполнять несколько операций экспорта на одном и том же экземпляре Transformer , но одновременный экспорт с одним и тем же экземпляром не поддерживается.

Примечание о потоке

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

Слушать события

Метод start асинхронный. Он немедленно возвращает значение, и приложение уведомляется о событиях через слушателя, переданного в Transformer builder.

Котлин

val transformerListener: Transformer.Listener =
    object : Transformer.Listener {
  override fun onCompleted(composition: Composition, result: ExportResult) {
    playOutput()
  }

  override fun onError(composition: Composition, result: ExportResult,
                       exception: ExportException) {
    displayError(exception)
  }
}

Ява

Transformer.Listener transformerListener =
    new Transformer.Listener() {
      @Override
      public void onCompleted(Composition composition, ExportResult result) {
        playOutput();
      }

      @Override
      public void onError(Composition composition, ExportResult result,
          ExportException exception) {
        displayError(exception);
      }
    };

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

Получайте обновления о ходе работ

Вызовите Transformer.getProgress для запроса текущего прогресса преобразования. Возвращаемое значение указывает состояние прогресса. Если состояние прогресса — PROGRESS_STATE_AVAILABLE , то предоставленный ProgressHolder обновляется текущим процентом прогресса. В следующем примере показано, как периодически запрашивать прогресс преобразования, где метод updateProgressInUi может быть реализован для обновления индикатора прогресса.

Котлин

transformer.start(inputMediaItem, outputPath)
val progressHolder = ProgressHolder()
mainHandler.post(
    object : Runnable {
      override fun run() {
        val progressState: @ProgressState Int = transformer.getProgress(progressHolder)
        updateProgressInUi(progressState, progressHolder)
        if (progressState != Transformer.PROGRESS_STATE_NOT_STARTED) {
          mainHandler.postDelayed(/* r= */this,  /* delayMillis= */500)
        }
      }
    }
)

Ява

transformer.start(inputMediaItem, outputPath);
ProgressHolder progressHolder = new ProgressHolder();
mainHandler.post(
    new Runnable() {
      @Override
      public void run() {
        @Transformer.ProgressState int progressState = transformer.getProgress(progressHolder);
        updateProgressInUi(progressState, progressHolder);
        if (progressState != PROGRESS_STATE_NOT_STARTED) {
          mainHandler.postDelayed(/* r= */ this, /* delayMillis= */ 500);
        }
      }
    });

Отменить преобразование

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