FFmpeg開發筆記(五十七)使用Media3的Transformer加工影片檔案

aqi00發表於2024-10-16
繼音影片播放器ExoPlayer之後,谷歌又推出了音影片轉換器Transformer,要在音影片加工領域施展拳腳。根據Android開發者官網介紹:Jetpack Media3是Android媒體庫的新家,可讓App呈現豐富的視聽體驗。Media3提供了一個簡單的架構,能夠基於裝置功能開展自定義與可靠性最佳化,可以解決媒體部分的碎片化問題。

Transformer作為Media3架構中的轉換元件,可以用於編輯加工音影片,包括在不同格式之間轉換編碼與修改媒體內容,例如從較長的影片剪輯片段、或者應用自定義的濾鏡效果,以及其他音影片編輯操作等等。
谷歌官方也提供了Transformer的程式碼應用例子,示例原始碼的託管地址為https://github.com/androidx/media/tree/release/demos,託管頁面開啟之後訪問transformer目錄,即可找到Transformer元件的實際運用模組程式碼。
因為Transformer被Media3囊括在內,所以它對執行環境要求頗高,具體環境要求參見之前的文章《使用Media3的Exoplayer播放網路影片》。準備好了開發環境之後,再按照以下描述引入Media3的ExoPlayer庫,詳細步驟說明如下。

一、修改模組的build.gradle

在build.gradle的dependencies節點內部補充下面的導包語句,把Transformer用到的相關庫都加進來。

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

二、活動頁面程式碼增加Transformer的處理程式碼

首先建立音影片的時間處理效果,比如下面程式碼構建了一個剪輯影片片段的媒體專案,準備把影片檔案的第10秒到第20秒單獨剪輯出來。

MediaItem.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(mVideoUri)
    .setClippingConfiguration(clippingConfiguration)
    .build();

接著建立音影片的空間處理效果,包括旋轉、縮放影片畫面等等,並對上一步的媒體專案運用指定的空間效果。建立程式碼如下:

ScaleAndRotateTransformation rotateEffect =
  new ScaleAndRotateTransformation.Builder()
    //.setRotationDegrees(90f)
    .setScale(0.5f, 0.5f)
    .build();
Effects effects = new Effects(
    ImmutableList.of(),
    ImmutableList.of(rotateEffect)
);
EditedMediaItem editedMediaItem =
  new EditedMediaItem.Builder(mediaItem)
    .setEffects(effects)
    .build();

然後按照以下程式碼構建轉換器物件,指定輸出影片格式為H265,輸出音訊格式為AAC,並且監聽轉換操作的結束事件和失敗事件。構建程式碼如下:

Transformer transformer = new Transformer.Builder(this)
    .setVideoMimeType(MimeTypes.VIDEO_H265)
    .setAudioMimeType(MimeTypes.AUDIO_AAC)
    .addListener(new Transformer.Listener() {
        @Override
        public void onCompleted(Composition composition, ExportResult exportResult) {
            Toast.makeText(mContext, "轉換成功", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onError(Composition composition, ExportResult exportResult, ExportException exportException) {
            Toast.makeText(mContext, "轉換失敗", Toast.LENGTH_SHORT).show();
            Log.d(TAG, "exportException: "+exportException.toString());
        }
    })
    .build();

最後填寫輸出檔案的儲存路徑,呼叫轉換器物件的start方法,開始執行音影片轉換動作。轉換程式碼如下:

String outputPath = mPath + DateUtil.getNowDateTime() + ".mp4";
transformer.start(editedMediaItem, outputPath);

編譯執行App,即可在真機上選取影片檔案並執行對應的編輯加工操作。

更多詳細的FFmpeg開發知識參見《FFmpeg開發實戰:從零基礎到短影片上線》一書。

相關文章