시작하기

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

Groovy

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

여기서 1.10.0은 선호하는 버전입니다. 최신 버전은 출시 노트를 참고하여 확인할 수 있습니다.

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

Java 8 지원 사용 설정

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

compileOptions {
  targetCompatibility JavaVersion.VERSION_1_8
}

변환 시작

다음은 입력 파일의 오디오를 삭제하는 EditedMediaItem을 만든 다음 H.265/HEVC 동영상을 내보내고 결과를 outputPath에 출력하도록 Transformer 인스턴스를 만들고 구성하는 예입니다.

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 인스턴스는 단일 애플리케이션 스레드에서 액세스해야 하며 리스너 메서드는 동일한 스레드에서 호출됩니다. 대부분의 경우 애플리케이션 스레드는 애플리케이션의 기본 스레드일 수 있습니다. 내부적으로 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을 사용하여 내보내기 작업을 취소합니다. 하드웨어 동영상 코덱과 같은 리소스는 특히 저가형 기기에서 제한되므로 출력이 필요하지 않은 경우 리소스를 확보하기 위해 이 작업을 실행하는 것이 중요합니다.