前回の[Android] Media3を使って.mp4の容量を減らす
にて動画ファイルの容量ダウンを図りました。
あれからライブラリが更新されたため、実装方法がちょこっと変わりました。
今回はその実装変更点の備忘録を残します。
実装
def media3_version = "1.1.1"
implementation "androidx.media3:media3-transformer:$media3_version"
implementation "androidx.media3:media3-common:$media3_version"
implementation "androidx.media3:media3-effect:$media3_version"
バージョン変更はもちろんですが、新しくmedia3-effectを追加利用します。
利用内容については後述。
suspend fun videoFileResizeByMedia3(context: Context, videoUri: Uri): Result<ExportResult, Unit> =
withContext(Dispatchers.Main) {
suspendCoroutine { continuation ->
val transformationRequest = TransformationRequest.Builder()
.setVideoMimeType(MimeTypes.VIDEO_H264).setAudioMimeType(MimeTypes.AUDIO_AAC)
.build()
val scale = ScaleAndRotateTransformation.Builder().setScale(0.67F, 0.67F).build()
val effects = Effects(
emptyList(), listOf(scale)
)
val inputMediaItem = MediaItem.fromUri(videoUri)
val editedMediaItem = EditedMediaItem.Builder(inputMediaItem).setEffects(effects)
.build()
val outputPath = context.applicationInfo.dataDir + File.separator + "sample.mp4"
val videoEncoderSettings = VideoEncoderSettings.Builder().setBitrate(2_000_000)
.build()
val encodeFactory = DefaultEncoderFactory.Builder(context)
.setRequestedVideoEncoderSettings(videoEncoderSettings).build()
val transformer = Transformer.Builder(context)
.setEncoderFactory(encodeFactory)
.setTransformationRequest(transformationRequest)
.addListener(object : Transformer.Listener {
override fun onCompleted(composition: Composition, exportResult: ExportResult) {
super.onCompleted(composition, exportResult)
continuation.resume(Ok(exportResult))
}
override fun onError(composition: Composition, exportResult: ExportResult, exportException: ExportException) {
super.onError(composition, exportResult, exportException)
continuation.resume(Err(Unit))
}
}).build()
transformer.start(editedMediaItem, outputPath)
}
}
※Kotlin-resultを用いてReturnをラップしています。今回の内容に特に関係がありませんので気にしないでください。
変わったところ
-
TransformationRequest.Builder()
.setResolutionが消滅しました。
サイズの設定はここでは行えなくなりました...。
どこで変えるかは下記のメソッドで。 -
ScaleAndRotateTransformation.Builder()
-
EditedMediaItem.Builder()
Scaleを変更することのBuilderです。
Scale~.Builder()がmedia3:media3-effectに含まれています。
その後、inputMediaItemに情報を付与したEditedMediaItemを最終的に渡します。 -
VideoEncoderSettings.Builder()
-
DefaultEncoderFactory.Builder(context)
ビットレートを設定できるエンコード設定を作成できます。
.setBitrateはお好みの値で。 -
Transformer.Builder(context)
.setEncoderFactory(encodeFactory)にて上記のエンコード設定をリクエストに設定できます。
これでビットレートを指定してエンコードできるようになりました。 -
onCompleted(composition: Composition,exportResult:ExportResult)
-
onError(composition:Composition,exportResult:ExportResult,exportException: ExportException)
前回からそうだったのですが、onTransformationCompleted/onTransformationErrorは既に非推奨であったのでこちらを使用してます。
結果の動作は前と同じです。
input:
1920*1080の1080pのMP4
総ビットレート15820kbps
58.8MB
※前回とは違う動画ファイルです。
output:
1286*724の約720pのMP4
総ビットレート2057kbps
7.6MB
かなり小さくなりました!
ビットレートを指定まで削れる喜びを感じております。
感想など
今回はビットレートを指定できることができた(前のライブラリでも本当はできた?)
ので大幅に容量を削減することができました。
人の目では画質も十分に保たれてると思います。(ただしそこは各自でビットレートを調整してください)
しかし、前回に引き続き
-
SDKの要求値は33
しかしこれは8/31にGooglePlayのアップロード要件が33を要求されるので対応しましょうといった形。 -
UnstableApiのまま
まだまだ開発中なので、またバージョンアップしたら仕様が変わることはありえます。
マイナーアップといえど、注目しておきたいです。 -
FHD, HDみたいな固定のサイズ指定ができない?
今回ビデオの高さと幅のサイズの指定が失われました。
scaleを指定して調整はできるのですが、1280/1920=0.66...なので収まりが悪くなってます...。
容量に着目だけすればビットレートさえ押さえてしまえば、高さと幅は容量サイズ的にはほぼほぼ関係ない(あまり動画関係に詳しくないので、よくわかりませんがFHDからHDにすれば差分のビットレート分は画質があげられる感じ?)
ですので、1080pのままでも良いならそのままでいいでしょう。
ですが、どうせならメジャーなサイズはバシッとライブラリ側が固定値で用意してほしいところ。
短期間でライブラリが更新されて目的に適うようになってきたので、今後のMedia3にはかなり期待しています。