Jetpack Media3의 Transformer API는 미디어 편집 높은 성능을 발휘하고 있습니다 Transformer는 다양한 연산을 지원하며 포함:
- 자르기, 크기 조정, 회전을 통해 동영상 수정하기
- 오버레이 및 필터와 같은 효과 추가
- HDR, 슬로 모션 동영상과 같은 특수 형식 처리
- 수정사항을 적용한 후 미디어 항목 내보내기
이 페이지에서는 Transformer입니다. 자세한 내용은 Media3 Transformer:
시작하기
시작하려면 Transformer, Effect, Common 모듈에 종속 항목을 추가하세요. Jetpack Media3:
implementation "androidx.media3:media3-transformer:1.4.1" implementation "androidx.media3:media3-effect:1.4.1" implementation "androidx.media3:media3-common:1.4.1"
1.4.1
를 원하는 버전의
있습니다. 자세한 내용은
출시 노트
최신 버전을 확인하세요.
중요 클래스
클래스 | 목적 |
---|---|
Transformer |
변환을 시작 및 중지하고 실행 중인 변환의 진행 상황 업데이트를 확인합니다. |
EditedMediaItem |
처리할 미디어 항목과 적용할 수정사항을 나타냅니다. |
Effects |
오디오 및 동영상 효과 컬렉션입니다. |
출력 구성
이제 Transformer.Builder
를 사용하여 videoMimeType
및
함수를 설정하여 audioMimetype
디렉터리로 이동합니다.
TransformationRequest
객체.
형식 간 트랜스코딩
다음 코드는 Transformer
객체를 다음과 같이 구성하는 방법을 보여줍니다.
출력 H.265/AVC 동영상 및 AAC 오디오:
Kotlin
val transformer = Transformer.Builder(context) .setVideoMimeType(MimeTypes.VIDEO_H265) .setAudioMimeType(MimeTypes.AUDIO_AAC) .build()
자바
Transformer transformer = new Transformer.Builder(context) .setVideoMimeType(MimeTypes.VIDEO_H265) .setAudioMimeType(MimeTypes.AUDIO_AAC) .build();
입력 미디어 형식이 이미 오디오 변환 요청과 일치하는 경우 Transformer는 transmuxing으로 자동 전환되어 압축된 샘플을 입력 컨테이너에서 출력 컨테이너로 있습니다. 이를 통해 시스템의 전산 비용과 잠재적 품질 손실을 디코딩 및 다시 인코딩하는 데 사용됩니다.
HDR 모드 설정
입력 미디어 파일이 HDR 형식인 경우 몇 가지
HDR 정보를 처리하는 방법에 관한 다양한 모드를 제공합니다. 여러분은 아마도
HDR_MODE_KEEP_HDR
또는
HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL
HDR_MODE_KEEP_HDR |
HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL |
|
---|---|---|
설명 | HDR 데이터를 보존합니다. 즉, HDR 출력 형식이 HDR 입력 형식과 동일합니다. | OpenGL 톤 매퍼를 사용하여 HDR 입력을 SDR로 톤매핑합니다. 즉, 출력 형식이 SDR이 됩니다. |
지원 | FEATURE_HdrEditing 기능이 있는 인코더가 포함된 기기의 경우 API 수준 31 이상에서 지원됩니다. |
API 수준 29 이상에서 지원됩니다. |
오류 | 지원되지 않는 경우 대신 HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL 를 사용하려고 시도합니다. |
지원되지 않으면 ExportException 이 발생합니다. |
필수 인코딩 기능을 지원하고 Android 13을 실행하는 기기
(API 수준 33) 이상에서는 Transformer
객체를 사용하여 HDR 동영상을 수정할 수 있습니다.
HDR_MODE_KEEP_HDR
는 Composition
객체를 빌드할 때의 기본 모드입니다.
다음과 같습니다.
Kotlin
val composition = Composition.Builder( ImmutableList.of(videoSequence)) .setHdrMode(HDR_MODE_KEEP_HDR) .build()
자바
Composition composition = new Composition.Builder( ImmutableList.of(videoSequence)) .setHdrMode(Composition.HDR_MODE_KEEP_HDR) .build();
미디어 항목 준비
MediaItem
는 오디오를 나타냅니다.
동영상 항목을 만들 수 있습니다. EditedMediaItem
이(가) MediaItem
을(를) 수집합니다.
적용할 변환과 함께 표시됩니다.
동영상 자르기
동영상에서 원하지 않는 부분을 삭제하려면 맞춤 시작 및 종료 시간을 설정하세요.
MediaItem
에 ClippingConfiguration
를 추가하여 위치를 조정합니다.
Kotlin
val clippingConfiguration = MediaItem.ClippingConfiguration.Builder() .setStartPositionMs(10_000) // start at 10 seconds .setEndPositionMs(20_000) // end at 20 seconds .build() val mediaItem = MediaItem.Builder() .setUri(videoUri) .setClippingConfiguration(clippingConfiguration) .build()
자바
ClippingConfiguration clippingConfiguration = new MediaItem.ClippingConfiguration.Builder() .setStartPositionMs(10_000) // start at 10 seconds .setEndPositionMs(20_000) // end at 20 seconds .build(); MediaItem mediaItem = new MediaItem.Builder() .setUri(videoUri) .setClippingConfiguration(clippingConfiguration) .build();
내장 효과 사용
Media3에는 일반적인 변환을 위한 여러 동영상 효과가 내장되어 있습니다. 예를 들면 다음과 같습니다.
클래스 | 결과 |
---|---|
Presentation |
해상도 또는 가로세로 비율에 따라 미디어 항목 크기 조정 |
ScaleAndRotateTransformation |
승수로 미디어 항목 크기 조정 또는 미디어 항목 회전 |
Crop |
미디어 항목을 더 작거나 큰 프레임으로 자릅니다. |
OverlayEffect |
미디어 항목 위에 텍스트 또는 이미지 오버레이를 추가합니다. |
오디오 효과에 사용할 오디오 효과음을
AudioProcessor
드림
원시 (PCM) 오디오 데이터를 변환하는 인스턴스입니다. 예를 들어
ChannelMixingAudioProcessor
오디오 채널을 믹싱하고
스케일링할 수 있습니다
이러한 효과를 사용하려면 효과 또는 오디오 프로세서의 인스턴스를 만들고
적용하려는 오디오 및 동영상 효과가 있는 Effects
의 인스턴스
미디어 항목을 클릭한 다음 EditedMediaItem
에 Effects
객체를 추가합니다.
Kotlin
val channelMixingProcessor = ChannelMixingAudioProcessor() val rotateEffect = ScaleAndRotateTransformation.Builder().setRotationDegrees(60f).build() val cropEffect = Crop(-0.5f, 0.5f, -0.5f, 0.5f) val effects = Effects(listOf(channelMixingProcessor), listOf(rotateEffect, cropEffect)) val editedMediaItem = EditedMediaItem.Builder(mediaItem) .setEffects(effects) .build()
자바
ChannelMixingAudioProcessor channelMixingProcessor = new ChannelMixingAudioProcessor(); ScaleAndRotateTransformation rotateEffect = new ScaleAndRotateTransformation.Builder() .setRotationDegrees(60f) .build(); Crop cropEffect = new Crop(-0.5f, 0.5f, -0.5f, 0.5f); Effects effects = new Effects( ImmutableList.of(channelMixingProcessor), ImmutableList.of(rotateEffect, cropEffect) ); EditedMediaItem editedMediaItem = new EditedMediaItem.Builder(mediaItem) .setEffects(effects) .build();
맞춤 효과 만들기
Media3에 포함된 효과를 확장하여 맞춤 효과를 만들 수 있습니다.
맞춤설정할 수 있습니다 다음 예에서는 서브클래스를 사용합니다.
MatrixTransformation
: 동영상이 첫 번째 구간에서 프레임을 채우도록 확대/축소
재생 시간(초):
Kotlin
val zoomEffect = MatrixTransformation { presentationTimeUs -> val transformationMatrix = Matrix() // Set the scaling factor based on the playback position val scale = min(1f, presentationTimeUs / 1_000f) transformationMatrix.postScale(/* x */ scale, /* y */ scale) transformationMatrix } val editedMediaItem = EditedMediaItem.Builder(inputMediaItem) .setEffects(Effects(listOf(), listOf(zoomEffect)) .build()
자바
MatrixTransformation zoomEffect = presentationTimeUs -> { Matrix transformationMatrix = new Matrix(); // Set the scaling factor based on the playback position float scale = min(1f, presentationTimeUs / 1_000f); transformationMatrix.postScale(/* x */ scale, /* y */ scale); return transformationMatrix; }; EditedMediaItem editedMediaItem = new EditedMediaItem.Builder(inputMediaItem) .setEffects(new Effects(ImmutableList.of(), ImmutableList.of(zoomEffect))) .build();
효과의 동작을 추가로 맞춤설정하려면 다음을 구현합니다.
GlShaderProgram
이
queueInputFrame()
메서드는 입력 프레임을 처리하는 데 사용됩니다. 예를 들어
머신러닝 기능을 활용하여
MediaPipe에는
MediaPipe FrameProcessor
MediaPipe 그래프를 통해 각 프레임을 전송합니다. 이에 대한 예는
Transformer 데모 앱
효과 미리보기
ExoPlayer를 사용하면 효과를 미리 볼 수 있습니다.
미디어 항목에 추가되었습니다. 같은
Effects
객체의 경우 EditedMediaItem
의 경우 기기에서 setVideoEffects()
를 호출합니다.
ExoPlayer 인스턴스
Kotlin
val player = ExoPlayer.builder(context) .build() .also { exoPlayer -> exoPlayer.setMediaItem(inputMediaItem) exoPlayer.setVideoEffects(effects) exoPlayer.prepare() }
자바
ExoPlayer player = new ExoPlayer.builder(context).build(); player.setMediaItem(inputMediaItem); player.setVideoEffects(effects); exoPlayer.prepare();
ExoPlayer로 오디오 효과를 미리 볼 수도 있습니다. GCP 리소스를
ExoPlayer
인스턴스는RenderersFactory
오디오 렌더러를 추가하여 AudioSink
AudioProcessor
시퀀스. 아래 예에서는
DefaultRenderersFactory
의 buildAudioSink()
메서드
Kotlin
val player = ExoPlayer.Builder(context, object : DefaultRenderersFactory(context) { override fun buildAudioSink( context: Context, enableFloatOutput: Boolean, enableAudioTrackPlaybackParams: Boolean, enableOffload: Boolean ): AudioSink? { return DefaultAudioSink.Builder(context) .setEnableFloatOutput(enableFloatOutput) .setEnableAudioTrackPlaybackParams(enableAudioTrackPlaybackParams) .setOffloadMode(if (enableOffload) { DefaultAudioSink.OFFLOAD_MODE_ENABLED_GAPLESS_REQUIRED } else { DefaultAudioSink.OFFLOAD_MODE_DISABLED }) .setAudioProcessors(arrayOf(channelMixingProcessor)) .build() } }).build()
자바
ExoPlayer player = new ExoPlayer.Builder(context, new DefaultRenderersFactory(context) { @Nullable @Override protected AudioSink buildAudioSink( Context context, boolean enableFloatOutput, boolean enableAudioTrackPlaybackParams, boolean enableOffload ) { return new DefaultAudioSink.Builder(context) .setEnableFloatOutput(enableFloatOutput) .setEnableAudioTrackPlaybackParams(enableAudioTrackPlaybackParams) .setOffloadMode( enableOffload ? DefaultAudioSink.OFFLOAD_MODE_ENABLED_GAPLESS_REQUIRED : DefaultAudioSink.OFFLOAD_MODE_DISABLED) .setAudioProcessors(new AudioProcessor[]{channelMixingProcessor}) .build(); } }).build();
혁신 시작
마지막으로 Transformer
를 만들어 수정사항을 적용하고 내보내기를 시작합니다.
결과 미디어 항목입니다.
Kotlin
val transformer = Transformer.Builder(context) .addListener(listener) .build() transformer.start(editedMediaItem, outputPath)
자바
Transformer transformer = new Transformer.Builder(context) .addListener(listener) .build(); transformer.start(editedMediaItem, outputPath);
필요한 경우
Transformer.cancel()
진행 상황 업데이트 확인
Transformer.start
는 즉시 반환되고 비동기식으로 실행됩니다. 쿼리하려면
변환의 현재 진행 상황, 호출
Transformer.getProgress()
이 메서드는 ProgressHolder
를 사용하며, 진행 상태를 사용할 수 있는 경우
즉, 메서드가 PROGRESS_STATE_AVAILABLE
를 반환하면 제공된
ProgressHolder
앱이 현재 진행률로 업데이트됩니다.
또한
리스너
Transformer
에 전달하여 완료 또는 오류 이벤트에 대한 알림을 받습니다.