Jetpack Media3 中的 Transformer API 是用於編輯媒體 兼具高效能與穩定性Transformer 支援多種作業 包括:
- 運用剪輯、縮放和旋轉等功能來修改影片
- 新增重疊和濾鏡等效果
- 正在處理特殊格式,例如 HDR 和慢動作影片
- 套用編輯後匯出媒體項目
本頁面會逐步說明 Transformer。如需詳細資訊,請參閱我們的完整指南 Media3 轉換器。
開始使用
如要開始使用,請新增 Transformer、Effect 和 Common 模組的依附元件 的重點:
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 會自動切換成「平移」,也就是 從輸入容器到輸出容器的壓縮樣本 修改內容。這樣可以避免計算費用,避免 以相同格式重新編碼和重新編碼
設定高動態範圍模式
如果輸入的媒體檔案是 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
並加入適用的轉換作業
剪輯影片
如要移除影片中不需要的部分,可以自訂開始和結束設定
將 ClippingConfiguration
加到 MediaItem
即可。
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()
方法是用於處理輸入影格。舉例來說
運用機器學習能力
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
,即可收到完成或錯誤事件的相關通知。