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()
Java
Transformer transformer = new Transformer.Builder(context) .setVideoMimeType(MimeTypes.VIDEO_H265) .setAudioMimeType(MimeTypes.AUDIO_AAC) .build();
入力メディア形式が音声の変換リクエストとすでに一致している場合 Transformer は、Transmuxing(変換、 圧縮されたサンプルが入力コンテナから出力コンテナに あります。これにより、モデルの計算コストや品質の低下を 再エンコードを行います。
HDR モードを設定する
入力メディア ファイルが HDR 形式の場合、数種類から選択できます
Transformer による 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()
Java
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()
Java
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
のインスタンス
次に、Effects
オブジェクトを EditedMediaItem
に追加します。
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()
Java
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()
Java
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()
メソッドは入力フレームを処理するために使用されます。たとえば、
Google Cloud の ML 機能を
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() }
Java
ExoPlayer player = new ExoPlayer.builder(context).build(); player.setMediaItem(inputMediaItem); player.setVideoEffects(effects); exoPlayer.prepare();
ExoPlayer でオーディオ エフェクトをプレビューすることもできます。カスタムモデルを構築する際は、
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()
Java
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)
Java
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
に送信して、完了またはエラーイベントに関する通知を受け取ります。