시작하기

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.5.0")
implementation("androidx.media3:media3-effect:1.5.0")
implementation("androidx.media3:media3-common:1.5.0")

Groovy

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

여기서 1.5.0은 원하는 버전입니다. 최신 버전은 출시 노트에서 확인할 수 있습니다.

사용 가능한 라이브러리 모듈에 관한 자세한 내용은 Google Maven AndroidX Media3 페이지를 참고하세요.

Java 8 지원 사용 설정

아직 사용 설정하지 않은 경우 android 섹션에 다음을 추가하여 Transformer에 종속된 모든 build.gradle 파일에서 Java 8 지원을 사용 설정해야 합니다.

compileOptions {
  targetCompatibility JavaVersion.VERSION_1_8
}

변환 시작

다음은 입력 파일의 오디오를 삭제하는 EditedMediaItem를 만든 다음 H.265/HEVC 동영상을 내보내도록 Transformer 인스턴스를 만들고 구성하여 결과를 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)

자바

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는 백그라운드에서 작업을 실행하고 애플리케이션 스레드에서 리스너 메서드 호출을 게시합니다.

이벤트 리슨

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

자바

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

자바

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를 사용하여 내보내기 작업을 취소합니다. 하드웨어 동영상 코덱과 같은 리소스는 특히 저가형 기기에서 제한적이므로 출력이 필요하지 않은 경우 리소스를 확보하기 위해 이렇게 하는 것이 중요합니다.