Jetpack Media3'teki Transformer API'leri, medya düzenlemeyi performanslı ve güvenilir hale getirmek için tasarlanmıştır. Transformer, aşağıdakiler de dahil olmak üzere çeşitli işlemleri destekler:
- Kırpma, ölçeklendirme ve döndürme yoluyla videoyu değiştirme
- Yer paylaşımı ve filtre gibi efektler ekleme
- HDR ve ağır çekim video gibi özel formatları işleme
- Düzenlemeler uygulandıktan sonra medya öğesini dışa aktarma
Bu sayfada, Transformer'ın kapsadığı temel kullanım alanlarından bazıları açıklanmaktadır. Daha fazla bilgi için Media3 Transformer ile ilgili tam kılavuzlarımıza göz atabilirsiniz.
Başlayın
Başlamak için Jetpack Media3'ün Transformer, Effect ve Common modüllerine bağımlılık ekleyin:
Kotlin
implementation("androidx.media3:media3-transformer:1.11.1")
implementation("androidx.media3:media3-effect:1.11.1")
implementation("androidx.media3:media3-common:1.11.1")
Modern
implementation "androidx.media3:media3-transformer:1.11.1"
implementation "androidx.media3:media3-effect:1.11.1"
implementation "androidx.media3:media3-common:1.11.1"
1.11.1 ifadesini kitaplığın tercih ettiğiniz sürümüyle değiştirdiğinizden emin olun. En yeni sürümü görmek için sürüm notlarına göz atabilirsiniz.
Önemli sınıflar
| Sınıf | Amaç |
|---|---|
Transformer |
Dönüşümleri başlatıp durdurma ve devam eden bir dönüşümle ilgili ilerleme güncellemelerini kontrol etme |
EditedMediaItem |
İşlenecek bir medya öğesini ve bu öğeye uygulanacak düzenlemeleri temsil eder. |
Effects |
Ses ve video efektleri koleksiyonu. |
Çıkışı yapılandırma
Transformer.Builder ile artık TransformationRequest nesnesi oluşturmanıza gerek kalmadan işlevi ayarlayarak videoMimeType ve audioMimetype değerlerini doğrudan belirtebilirsiniz.
Biçimler arasında kod dönüştürme
Aşağıdaki kodda, H.265/AVC video ve AAC ses çıkışı için Transformer nesnesinin nasıl yapılandırılacağı gösterilmektedir:
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();
Giriş medya biçimi, ses veya video için dönüşüm isteğiyle zaten eşleşiyorsa Transformer otomatik olarak transmuxing'e geçer. Yani sıkıştırılmış örnekleri giriş kapsayıcısından çıkış kapsayıcısına değişiklik yapmadan kopyalar. Bu sayede, aynı biçimde kod çözme ve yeniden kodlama işleminin hesaplama maliyeti ve olası kalite kaybı önlenir.
HDR modunu ayarlama
Giriş medya dosyası HDR biçimindeyse Transformer'ın HDR bilgilerini nasıl işleyeceğiyle ilgili birkaç farklı mod arasından seçim yapabilirsiniz. HDR_MODE_KEEP_HDR veya HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL kullanmanız önerilir.
HDR_MODE_KEEP_HDR |
HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL |
|
|---|---|---|
| Açıklama | HDR verilerini koruyun. Bu, HDR çıkış biçiminin HDR giriş biçimiyle aynı olduğu anlamına gelir. | OpenGL ton eşleyici kullanarak HDR girişini SDR'ye ton eşleme. Bu durumda çıkış biçimi SDR olur. |
| Destek | FEATURE_HdrEditing özelliğine sahip bir kodlayıcı içeren cihazlar için API düzeyi 31 ve sonraki sürümlerde desteklenir. |
API düzeyi 29 ve üzeri sürümlerde desteklenir. |
| Hatalar | Desteklenmiyorsa bunun yerine HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL kullanmaya çalışır. |
Desteklenmiyorsa ExportException hatası verir. |
Gerekli kodlama özelliklerini destekleyen ve Android 13 (API düzeyi 33) veya sonraki sürümleri çalıştıran cihazlarda Transformer nesneleri, HDR videoları düzenlemenize olanak tanır.
Aşağıdaki kodda gösterildiği gibi, Composition nesnesi oluşturulurken varsayılan mod HDR_MODE_KEEP_HDR'dir:
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();
Medya öğesi hazırlama
MediaItem, uygulamanızdaki bir ses veya video öğesini temsil eder. EditedMediaItem, bir MediaItem ve buna uygulanacak dönüşümleri toplar.
Videoyu kırpma
Videonun istenmeyen kısımlarını kaldırmak için MediaItem öğesine ClippingConfiguration ekleyerek özel başlangıç ve bitiş konumları ayarlayabilirsiniz.
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();
Yerleşik efektleri kullanma
Media3, yaygın dönüşümler için çeşitli yerleşik video efektleri içerir. Örneğin:
| Sınıf | Efekt |
|---|---|
Presentation |
Medya öğesini çözünürlüğe veya en-boy oranına göre ölçeklendirme |
ScaleAndRotateTransformation |
Medya öğesini bir çarpanla ölçeklendirme ve/veya medya öğesini döndürme |
Crop |
Medya öğesini daha küçük veya daha büyük bir çerçeveye kırpma |
OverlayEffect |
Medya öğesinin üzerine metin veya resim yer paylaşımı ekleme |
Ses efektleri için ham (PCM) ses verilerini dönüştürecek bir AudioProcessor örneği dizisi ekleyebilirsiniz. Örneğin, ses kanallarını karıştırmak ve ölçeklendirmek için ChannelMixingAudioProcessor kullanabilirsiniz.
Bu efektleri kullanmak için efekt veya ses işlemcisinin bir örneğini oluşturun, medya öğesine uygulamak istediğiniz ses ve video efektleriyle bir Effects örneği oluşturun, ardından Effects nesnesini bir EditedMediaItem nesnesine ekleyin.
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();
Özel efektler oluşturma
Media3'te bulunan efektleri genişleterek kullanım alanlarınıza özel efektler oluşturabilirsiniz. Aşağıdaki örnekte, videoyu oynatmanın ilk saniyesinde kareyi dolduracak şekilde yakınlaştırmak için MatrixTransformation alt sınıfını kullanın:
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();
Bir efektin davranışını daha fazla özelleştirmek için GlShaderProgram uygulayın.
Giriş karelerini işlemek için queueInputFrame() yöntemi kullanılır. Örneğin, MediaPipe'ın makine öğrenimi özelliklerinden yararlanmak için her kareyi bir MediaPipe grafiği üzerinden göndermek üzere MediaPipe FrameProcessor kullanabilirsiniz. Transformer demo uygulamasında bunun bir örneğini görebilirsiniz.
Efektleri önizleme
ExoPlayer ile, dışa aktarma işlemine başlamadan önce bir medya öğesine eklenen efektleri önizleyebilirsiniz. EditedMediaItem için kullandığınız Effect nesnelerini kullanarak ExoPlayer örneğinizde setVideoEffects() yöntemini çağırın.
Kotlin
val player = ExoPlayer.Builder(context)
.build()
.also { exoPlayer ->
exoPlayer.setMediaItem(inputMediaItem)
exoPlayer.setVideoEffects(listOf(zoomEffect))
exoPlayer.prepare()
}
Java
ExoPlayer player = new ExoPlayer.Builder(context).build();
player.setMediaItem(inputMediaItem);
player.setVideoEffects(ImmutableList.of(zoomEffect));
player.prepare();
ExoPlayer ile ses efektlerini de önizleyebilirsiniz. ExoPlayer örneğinizi oluştururken oynatıcının ses oluşturucularını, AudioProcessor dizinizi kullanan bir AudioSink'ye ses çıkışı verecek şekilde yapılandıran özel bir RenderersFactory iletin. Aşağıdaki örnekte, bir DefaultRenderersFactory öğesinin buildAudioSink() yöntemini geçersiz kılarak bunu yapıyoruz.
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();
Dönüşüm başlatma
Son olarak, düzenlemelerinizi uygulamak ve ortaya çıkan medya öğesini dışa aktarmaya başlamak için bir Transformer oluşturun.
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);
Benzer şekilde, gerekirse dışa aktarma işlemini Transformer.cancel() ile iptal edebilirsiniz.
İlerleme güncellemelerini kontrol etme
Transformer.start hemen döndürülür ve eşzamansız olarak çalışır. Bir dönüşümün mevcut ilerleme durumunu sorgulamak için Transformer.getProgress() yöntemini çağırın. Bu yöntem bir ProgressHolder alır ve ilerleme durumu mevcutsa (yani yöntem PROGRESS_STATE_AVAILABLE değerini döndürürse) sağlanan ProgressHolder, mevcut ilerleme yüzdesiyle güncellenir.
Tamamlanma veya hata etkinlikleri hakkında bildirim almak için Transformer nesnenize bir dinleyici de ekleyebilirsiniz.