Jetpack Media3'teki Transformer API'leri, medya düzenlemeyi performanslı ve güvenilir hale getirmek için tasarlanmıştır. Dönüştürücü, aşağıdakiler dahil olmak üzere çeşitli işlemleri destekler:
- Kırpma, ölçeklendirme ve döndürme işlemleriyle videoyu değiştirme
- Yer paylaşımı ve filtre gibi efektler ekleme
- HDR ve ağır çekim video gibi özel biçimleri işleme
- Düzenlemeler uygulandıktan sonra medya öğesini dışa aktarma
Bu sayfada, Transformer'ın kapsadığı bazı önemli 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:
implementation "androidx.media3:media3-transformer:1.5.0" implementation "androidx.media3:media3-effect:1.5.0" implementation "androidx.media3:media3-common:1.5.0"
1.5.0
değerini, kitaplığın tercih ettiğiniz sürümüyle değiştirdiğinizden emin olun. En son sürümü görmek için sürüm notlarına bakabilirsiniz.
Önemli sınıflar
Sınıf | Amaç |
---|---|
Transformer |
Dönüşümleri başlatıp durdurabilir ve çalışan bir dönüşümdeki ilerleme güncellemelerini kontrol edebilirsiniz. |
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şturmak zorunda kalmadan işlevi ayarlayarak videoMimeType
ve audioMimetype
dizinlerini belirtebilirsiniz.
Biçim dönüştürme
Aşağıdaki kodda, H.265/AVC video ve AAC ses çıkışı için bir 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 Dönüştürücü otomatik olarak transmuxing'e (sıkıştırılmış örnekleri giriş kapsayıcısından çıkış kapsayıcısına değişiklik yapmadan kopyalama) geçer. 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 işleme şekliyle ilgili birkaç farklı mod arasından seçim yapabilirsiniz. Muhtemelen HDR_MODE_KEEP_HDR
veya HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL
'yi kullanmak istersiniz.
HDR_MODE_KEEP_HDR |
HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL |
|
---|---|---|
Açıklama | HDR verilerini koruyun. Yani HDR çıkış biçimi, HDR giriş biçimiyle aynıdır. | OpenGL ton eşleyicisi kullanarak HDR girişini SDR olarak ton eşleyin. 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 sonraki sürümlerde desteklenir. |
Hatalar | Desteklenmiyorsa bunun yerine HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL kullanmaya çalışır. |
Desteklenmiyorsa ExportException hatası oluşturur. |
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.
HDR_MODE_KEEP_HDR
, aşağıdaki kodda gösterildiği gibi Composition
nesnesi oluşturulurken varsayılan moddur:
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
, MediaItem
ile birlikte ona uygulanacak dönüşümleri toplar.
Video kırpma
Videonun istenmeyen bölümlerini kaldırmak için MediaItem
alanına ClippingConfiguration
ekleyerek özel başlangıç ve bitiş konumları belirleyebilirsiniz.
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
sırası ekleyebilirsiniz. Örneğin, ses kanallarını karıştırmak ve ölçeklendirmek için ChannelMixingAudioProcessor
kullanabilirsiniz.
Bu efektleri kullanmak için efektin veya ses işleyicinin 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
'a 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'e dahil edilen efektleri genişleterek kullanım alanlarınıza özel özel efektler oluşturabilirsiniz. Aşağıdaki örnekte, oynatmanın ilk saniyesinde videoyu yakınlaştırarak çerçeveyi doldurmak için alt sınıf MatrixTransformation
'ü 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 da özelleştirmek için GlShaderProgram
uygulayın. queueInputFrame()
yöntemi, giriş çerçevelerini işlemek için kullanılır. Örneğin, MediaPipe'in makine öğrenimi özelliklerinden yararlanmak için her kareyi bir MediaPipe grafiği üzerinden göndermek üzere bir MediaPipe FrameProcessor
kullanabilirsiniz. Bunun bir örneğini Transformer demo uygulamasında bulabilirsiniz.
Efektleri önizleme
ExoPlayer ile, dışa aktarma işlemini başlatmadan önce bir medya öğesine eklenen efektleri önizleyebilirsiniz. EditedMediaItem
ile aynı Effects
nesnesini kullanarak ExoPlayer örneğinizde setVideoEffects()
'yi çağırın.
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();
Ses efektlerini ExoPlayer ile de önizleyebilirsiniz. ExoPlayer
örneğinizi oluştururken, oynatıcının ses oluşturma araçlarını AudioProcessor
sıranızı kullanan bir AudioSink
'ye ses çıkışı verecek şekilde yapılandıran özel bir RenderersFactory
iletin. Aşağıdaki örnekte, bunu bir DefaultRenderersFactory
sınıfının buildAudioSink()
yöntemini geçersiz kılarak 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 oluşturulan 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 Transformer.cancel()
simgesini kullanarak dışa aktarma işlemini iptal edebilirsiniz.
İlerleme durumu güncellemelerini kontrol etme
Transformer.start
hemen döndürülür ve asynkron olarak çalışır. Bir dönüşümün mevcut ilerleme durumunu sorgulamak için Transformer.getProgress()
işlevini çağırın.
Bu yöntem bir ProgressHolder
alır ve ilerleme durumu mevcutsa yani yöntem PROGRESS_STATE_AVAILABLE
döndürürse sağlanan ProgressHolder
geçerli ilerleme yüzdesiyle güncellenir.
Tamamlanma veya hata etkinlikleri hakkında bildirim almak için Transformer
öğenize bir dinleyici de ekleyebilirsiniz.