Media3 Transformer kullanarak temel bir video düzenleme uygulaması oluşturma

Jetpack Media3'teki Transformer API'leri, medya düzenleme işlemi yapmak için tasarlanmıştır. ve güvenilir olmasını sağlar. Transformer, bir dizi işlemi destekler. şunları içerir:

  • Kırpma, ölçekleme 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 biçimler işleniyor
  • Düzenlemeleri uyguladıktan sonra medya öğesini dışa aktarma

Bu sayfada, Analytics 360'taki Transformatör. Daha fazla bilgi için Media3 Transformer (Media3 Dönüştürücü).

Başlayın

Başlamak için Dönüştürücü, Efekt ve Ortak modüllerine bağımlılık ekleyin. :

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

1.4.0 yerine kitaplığını açar. Ayrıca, sürüm notları en son sürümü görebilirsiniz.

Önemli sınıflar

Sınıf Amaç
Transformer Dönüştürme işlemlerini başlatıp durdurun ve çalışan bir dönüşümde ilerleme güncellemelerini kontrol edin.
EditedMediaItem İşlenecek medya öğesini ve buna uygulanacak düzenlemeleri temsil eder.
Effects Ses ve video efektleri koleksiyonu.

Çıkışı yapılandırma

Transformer.Builder ile artık videoMimeType ve Bir dosya oluşturulmasına gerek kalmadan işlevi ayarlayarak audioMimetype dizini TransformationRequest nesne.

Biçimler arasında kod dönüştürme

Aşağıdaki kod, bir Transformer nesnesinin nasıl yapılandırılacağını gösterir H.265/AVC video ve AAC ses çıkışı:

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();

Girilen medya biçimi zaten ses için dönüştürme isteğiyle eşleşiyorsa Dönüştürücü, otomatik olarak transmuxing'e, yani giriş kapsayıcısından çıkış kapsayıcısına geçmeden önce tıklayın. Böylece işlem maliyeti ve olası kalite kaybı ve yeniden kodlamaya yönelik bir yöntemdir.

HDR modunu ayarlama

Girdi medya dosyası HDR biçimindeyse birkaç ayar arasından nasıl işlediğine dair farklı modlar vardır. Muhtemelen bu HDR_MODE_KEEP_HDR veya HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL.

HDR_MODE_KEEP_HDR HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL
Açıklama HDR verilerini koruyarak HDR çıkış biçimi, HDR giriş biçimiyle aynıdır. HDR girişi, OpenGL ton eşleyici kullanarak SDR'ye ton eşlenir. Diğer bir deyişle, çıkış biçimi SDR olacaktır.
Destek FEATURE_HdrEditing özellikli bir kodlayıcıya sahip cihazlarda 31 ve üzeri API düzeylerinde desteklenir. 29 ve üzeri API düzeylerinde desteklenir.
Hatalar Desteklenmiyorsa bunun yerine HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL kullanmayı deneyin. Desteklenmiyorsa bir ExportException hatası verir.

Gerekli kodlama özelliklerini destekleyen ve Android 13'ü çalıştıran cihazlarda (API düzeyi 33) veya sonraki sürümler, Transformer nesneleri HDR videoları düzenlemenize olanak tanır. HDR_MODE_KEEP_HDR, Composition nesnesini oluştururken varsayılan moddur. aşağıdaki kodda gösterildiği gibidir:

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, bir sesi temsil eder video öğesi kullanabilirsiniz. EditedMediaItem, yanında MediaItem toplar dönüşümlerle birlikte inceleyeceğiz.

Video kırpma

Videonun istenmeyen bölümlerini kaldırmak için özel bir başlangıç ve bitiş noktası ayarlayabilirsiniz MediaItem öğesine bir ClippingConfiguration ekleyerek konumu.

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, genel dönüşüm işlemleri için bir dizi yerleşik video efekti içerir. örneğin:

Sınıf Efekt
Presentation Medya öğesini çözünürlüğe veya en boy oranına göre ölçeklendirin
ScaleAndRotateTransformation Medya öğesini bir çarpana göre ölçeklendirin ve/veya medya öğesini döndürün
Crop Medya öğesini daha küçük veya daha büyük bir kareye göre kırpın
OverlayEffect Medya öğesinin üstüne metin veya resim yer paylaşımı ekleyin

Ses efektleri için ses efektleri için AudioProcessor ham (PCM) ses verilerini dönüştürecek örnekler. Örneğin, ChannelMixingAudioProcessor ses kanallarını miksleyin ve ölçeklendirin.

Bu efektleri kullanmak için efektin veya ses işlemcisinin bir örneğini oluşturun, uygulamak istediğiniz ses ve video efektlerini içeren Effects örneği medya öğesini ve ardından Effects nesnesini bir EditedMediaItem öğesine 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şturun

Media3'teki efektleri genişleterek özel efektler oluşturabilirsiniz örneklere göz atın. Aşağıdaki örnekte, Videoyu yakınlaştırmak ve kareyi ilk resmin üzerine getirmek için MatrixTransformation oynatmanın saniyesi:

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. İlgili içeriği oluşturmak için kullanılan Giriş çerçevelerini işlemek için queueInputFrame() yöntemi kullanılır. Örneğin, Google Cloud'un makine öğrenimi MediaPipe kullanıyorsanız bir MediaPipe FrameProcessor her kareyi bir MediaPipe grafiği üzerinden gönderin. Şurada bunun bir örneğini görebilirsiniz: Transformer demo uygulaması.

Efektleri önizle

ExoPlayer ile efektleri önizleyebilirsiniz. eklenmiş olması gerekir. Aynı Effects nesnesi olarak, EditedMediaItem için setVideoEffects() öğesini çağırın. ExoPlayer örneği.

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. Proje hedeflerinizi ExoPlayer örneğini, RenderersFactory ses oluşturucularını kullanarak ses çıkışını istediğiniz AudioSink AudioProcessor dizisi. Aşağıdaki örnekte bunu, buildAudioSink() bir DefaultRenderersFactory yöntemi.

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 için bir Transformer oluşturun ve medya öğesi oluşturabilirsiniz.

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().

İlerleme güncellemelerini kontrol edin

Transformer.start hemen geri döner ve eşzamansız olarak çalışır. Sorgulamak için bir dönüşümün mevcut ilerleme durumu, Transformer.getProgress(). Bu yöntemde ProgressHolder gerekir ve ilerleme durumu mevcutsa yani yöntem PROGRESS_STATE_AVAILABLE değerini döndürürse sağlanan ProgressHolder, ilerleme durumu yüzdesiyle güncellenecek.

İsterseniz dinleyici tamamlama veya hata etkinlikleriyle ilgili bildirim almak için Transformer adresine e-posta gönderin.