使用入门

开始使用 Transformer 包括以下步骤:

  1. 在项目中添加 Media3 Transformer 作为依赖项。
  2. 构建一个 EditedMediaItem,用于表示要处理的媒体以及要对其应用的编辑。
  3. 构建 Transformer,描述所需的输出以及用于完成和错误事件的监听器。
  4. 启动导出操作,传入要修改的 EditedMediaItem 和输出路径。在导出期间,您可以查询当前进度或取消操作。
  5. 导出完成后,根据需要处理输出。例如,您可以将输出内容分享到其他应用或将其上传到服务器。

请继续阅读,详细了解这些步骤,并参阅转换器演示应用中的 TransformerActivity,查看完整示例。

添加 Media3 Transformer 作为依赖项

开始使用 Transformer 的最简单方法是在应用模块的 build.gradle 文件中添加对该库的 Gradle 依赖项:

Kotlin

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

Groovy

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 支持

如果尚未启用,您需要在所有依赖于 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 取消导出操作。硬件视频编解码器等资源是有限的,尤其是在低端设备上,因此如果不需要输出,请务必这样做以释放资源。