スタート ガイド

Transformer の使用を開始するには、次の手順を行います。

  1. Media3 Transformer をプロジェクトの依存関係として追加します。
  2. 処理するメディアと、それに適用する編集を表す EditedMediaItem を作成します。
  3. Transformer を作成し、必要な出力と、完了イベントとエラーイベントのリスナーを記述します。
  4. 編集する EditedMediaItem と出力パスを渡して、エクスポート オペレーションを開始します。エクスポート中に、現在の進行状況をクエリしたり、オペレーションをキャンセルしたりできます。
  5. エクスポートが完了したら、必要に応じて出力を処理します。たとえば、出力を別のアプリと共有したり、サーバーにアップロードしたりできます。

これらの手順の詳細については、以下をご覧ください。また、実証済みの例については、Transformer デモアプリの TransformerActivity をご覧ください。

Media3 Transformer を依存関係として追加する

Transformer の使用を開始する最も簡単な方法は、アプリ モジュールの build.gradle ファイルにライブラリの Gradle 依存関係を追加することです。

Kotlin

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

Groovy

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

ここで、1.11.1 は優先バージョンです。最新バージョンについては、リリースノートをご覧ください。

利用可能なライブラリ モジュールについて詳しくは、Google Maven AndroidX Media3 のページをご覧ください。

Java 8 のサポートを有効にする

まだ有効になっていない場合は、Transformer に依存するすべての build.gradle ファイルで Java 8 のサポートを有効にする必要があります。そのためには、android セクションに以下を追加します。

compileOptions {
  targetCompatibility JavaVersion.VERSION_1_8
}

変換を開始する

次の例では、EditedMediaItem を作成して入力ファイルの音声を削除し、Transformer インスタンスを作成して構成し、H.265/HEVC 動画をエクスポートして、結果を outputPath に出力します。

Kotlin

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)

Java

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 ビルダーに渡されたリスナーを介してアプリにイベントが通知されます。

Kotlin

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)
    }
  }

Java

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 メソッドを実装して、進行状況バーを更新できます。

Kotlin

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)
      }
    }
  }
)

Java

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 を使用してエクスポート オペレーションをキャンセルします。ハードウェア動画コーデックなどのリソースは、特にローエンド デバイスでは限られているため、出力が不要な場合はリソースを解放することが重要です。