、動画エフェクトを適用し、エクスポートを最適化します。 keywords_public: Media3、Transformer、コード変換、動画編集、トリミング、音声処理、Android メディア
形式間でトランスコードする
Transformer のビルド時に、生成する出力音声形式と動画形式を指定できます。たとえば、次のコードは、H.264/AVC 動画と AAC 音声を出力するように Transformer を構成する方法を示しています。
Kotlin
Transformer.Builder(context) .setVideoMimeType(MimeTypes.VIDEO_H264) .setAudioMimeType(MimeTypes.AUDIO_AAC) .build()
Java
new Transformer.Builder(context) .setVideoMimeType(MimeTypes.VIDEO_H264) .setAudioMimeType(MimeTypes.AUDIO_AAC) .build();
入力メディア形式がオーディオまたは動画の設定と一致する場合、Transformer は自動的に トランスムックスに切り替わります。つまり、圧縮されたサンプルを入力コンテナから出力コンテナに修正なしでコピーします。これにより、同じ形式でのデコードと再エンコードの計算コストと品質の低下を回避できます。
音声や動画を削除する
EditedMediaItem.Builder を使用して音声または動画を削除します。例:
Kotlin
EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build()
Java
new EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build();
クリップをトリミングする
入力メディア アイテムにクリッピング構成を設定することで、指定した開始タイムスタンプと終了タイムスタンプの範囲外のメディアを削除できます。たとえば、10 秒から 20 秒の間のメディアのみを含むクリップを生成するには:
Kotlin
val inputMediaItem = MediaItem.Builder() .setUri(uri) .setClippingConfiguration( MediaItem.ClippingConfiguration.Builder() .setStartPositionMs(10_000) .setEndPositionMs(20_000) .build()) .build()
Java
MediaItem inputMediaItem = new MediaItem.Builder() .setUri(uri) .setClippingConfiguration( new MediaItem.ClippingConfiguration.Builder() .setStartPositionMs(10_000) .setEndPositionMs(20_000) .build()) .build();
MP4 編集リスト
トリミングを高速化するため、Transformer は MP4 編集リストをサポートしています。これにより、動画全体を再トランスコードすることなく、より効率的な「トリミングのみ」の編集が可能になります。このメソッドでは、既存のエンコードされたサンプルと編集リスト内の「プリロール」を利用します。これにより、プレーヤーは特定のポイントから再生を開始し、不要な最初のセグメントを効果的にスキップします。
トリミングのみの編集を大幅に高速化するには、experimentalSetMp4EditListTrimEnabled(true) を呼び出します。
Kotlin
Transformer.Builder(context) .experimentalSetMp4EditListTrimEnabled(true) .build()
Java
new Transformer.Builder(context) .experimentalSetMp4EditListTrimEnabled(true) .build();
すべてのメディア プレーヤーが「プリロール」のポジションをサポートしているわけではないことに注意してください。つまり、このようなプレーヤーを使用すると、エンコードされたサンプルの絶対的な最初から再生が開始されます。別の開始点を指定する編集リスト情報があっても、それは無視されます。
トリムを最適化する
動画の先頭をトリミングする際のレイテンシを短縮するには、トリミングの最適化を有効にします。
Kotlin
Transformer.Builder(context) .experimentalSetTrimOptimizationEnabled(true) .build()
Java
new Transformer.Builder(context) .experimentalSetTrimOptimizationEnabled(true) .build();
これにより、動画のデコードと再エンコードを可能な限り少なくして、再エンコードされたデータを元の動画の残りの部分とつなぎ合わせることで、書き出しが高速化されます。この最適化は、入力ファイルの一部を新しくエンコードされた出力とステッチできることに依存しています。つまり、エンコーダの出力形式と入力形式に互換性がある必要があります。たとえば、ファイルが元々別のエンコーダ実装のデバイスで作成された場合、最適化を適用できない可能性があります。最適化を成功させるには、EncoderFactory 経由で Transformer に提供されるエンコーダのレベルとプロファイルが入力形式と互換性を持っている必要があります。
この最適化は、効果のない単一アセットの MP4 入力(no op 動画効果と 90 度で割り切れる回転を除く)でのみ機能します。最適化が失敗すると、Transformer は自動的に通常のエクスポートにフォールバックし、ExportResult.OptimizationResult で最適化の結果を報告します。
この機能の検証を行っており、今後のリリースで試験運用ではなくなる予定です。
動画の編集
EditedMediaItems には、順番に適用するオーディオ プロセッサと動画エフェクトのリストがあります。ライブラリには、一般的なユースケース向けの動画エフェクトの実装が含まれています。また、カスタム エフェクトを作成して、編集されたメディア アイテムのビルド時に渡すこともできます。
メディアをリスケールできます。これは、4K や 8K の動画など、非常に高解像度の入力に対処する際に、処理リソースや帯域幅を節約するのに役立ちます。たとえば、高さを 480 ピクセルに比例してスケーリングするには:
Kotlin
EditedMediaItem.Builder(MediaItem.fromUri(uri)) .setEffects(Effects( /* audioProcessors= */ listOf(), /* videoEffects= */ listOf(Presentation.createForHeight(480)) )).build()
Java
new EditedMediaItem.Builder(MediaItem.fromUri(uri)) .setEffects(new Effects( /* audioProcessors= */ ImmutableList.of(), /* videoEffects= */ ImmutableList.of(Presentation.createForHeight(480)))) .build();
また、指定した係数でスケーリングすることもできます(サイズを半分にするなど)。
Kotlin
val editedMediaItem = EditedMediaItem.Builder(MediaItem.fromUri(uri)) .setEffects(Effects( /* audioProcessors= */ listOf(), /* videoEffects= */ listOf( ScaleAndRotateTransformation.Builder().setScale(.5f, .5f).build()) )).build()
Java
new EditedMediaItem.Builder(MediaItem.fromUri(uri)) .setEffects(new Effects( /* audioProcessors= */ ImmutableList.of(), /* videoEffects= */ ImmutableList.of( new ScaleAndRotateTransformation.Builder().setScale(.5f, .5f).build()))) .build();
回転も同じ方法で構成できます。
Kotlin
EditedMediaItem.Builder(MediaItem.fromUri(uri)) .setEffects(Effects( /* audioProcessors= */ listOf(), /* videoEffects= */ listOf( ScaleAndRotateTransformation.Builder() .setRotationDegrees(90f) .build()) )).build()
Java
new EditedMediaItem.Builder(MediaItem.fromUri(uri)) .setEffects(new Effects( /* audioProcessors= */ ImmutableList.of(), /* videoEffects= */ ImmutableList.of( new ScaleAndRotateTransformation.Builder().setRotationDegrees(90f).build()))) .build();
カスタム動画エフェクト
Effects コンストラクタは、適用する音声効果と動画効果のリストを受け取ります。内部的には、Transformer のエフェクト フレームワークは、動画エフェクトのリストを順番に適用される GL シェーダー プログラムのシーケンスに変換します。場合によっては、エフェクト フレームワークは 1 つのシェーダー プログラムで複数のエフェクトを適用できます。たとえば、1 つのシェーダー プログラムで複数の連続した行列変換を適用できるため、効率と品質が向上します。
ExoPlayer.setVideoEffects を使用して、ExoPlayer のプレビューで動画エフェクトもサポートされています。この API の使用例については、エフェクト デモアプリをご覧ください。
デモアプリには、カスタム動画エフェクトの例が含まれています。
画像入力
Transformer は、画像を静止動画クリップとして扱うことで、画像入力をサポートします。画像を入力ソースとして構成する手順は次のとおりです。
MediaItem.Builderを使用してMediaItemを作成します。setImageDurationMsを呼び出して、出力動画での画像の表示時間を指定します。MediaItemをラップするEditedMediaItemを構築します。EditedMediaItem.Builder#setFrameRateを使用して、生成された動画ストリームのターゲット フレームレートを指定します。
次の例は、画像入力を構成して 1 秒あたり 30 フレームの 5 秒間の動画を生成する方法を示しています。
Kotlin
val imageMediaItem = MediaItem.Builder() .setUri(imageUri) .setImageDurationMs(5000) // 5 seconds .build() val editedImageItem = EditedMediaItem.Builder(imageMediaItem) .setFrameRate(30) // 30 frames per second .build()
Java
MediaItem imageMediaItem = new MediaItem.Builder() .setUri(imageUri) .setImageDurationMs(5000) // 5 seconds .build(); EditedMediaItem editedImageItem = new EditedMediaItem.Builder(imageMediaItem) .setFrameRate(30) // 30 frames per second .build();
音声編集
オーディオ エフェクトは、一連の AudioProcessor インスタンスを RAW(PCM)オーディオに適用することで実装されます。ExoPlayer は、DefaultAudioSink.Builder へのオーディオ プロセッサの受け渡しをサポートしており、オーディオ編集のプレビューが可能です。