ट्रांसफ़र्मेशन

Jetpack Media3 Transformer की मदद से, Android पर मीडिया ऐसेट में बदलाव किया जा सकता है, उन्हें बदला जा सकता है, और एक्सपोर्ट किया जा सकता है. इस पेज पर, मुख्य ट्रांसफ़ॉर्मेशन को कॉन्फ़िगर करने का तरीका बताया गया है:

  • ट्रांसकोडिंग और ट्रांसमक्सिंग: ऑडियो और वीडियो फ़ॉर्मैट बदलें या कंटेनर के सैंपल कॉपी करके (ट्रांसमक्सिंग) फिर से एन्कोड करने की प्रोसेस को बायपास करें.
  • ट्रैक हटाना: मीडिया से ऑडियो या वीडियो ट्रैक हटाना.
  • ट्रिम करना और ऑप्टिमाइज़ करना: टाइमस्टैंप के हिसाब से मीडिया को क्लिप करें. साथ ही, MP4 फ़ाइल में बदलाव करने की सूचियों और ट्रिम ऑप्टिमाइज़ेशन का इस्तेमाल करके, फ़ाइलों को तेज़ी से एक्सपोर्ट करें.
  • वीडियो इफ़ेक्ट: वीडियो को स्केल करें, घुमाएं या कस्टम OpenGL शेडर इफ़ेक्ट लागू करें. इन्हें ExoPlayer में भी देखा जा सकता है.
  • इमेज इनपुट: स्टैटिक इमेज को अपनी पसंद के मुताबिक अवधि और फ़्रेम रेट वाली वीडियो क्लिप में बदलें.
  • ऑडियो प्रोसेसिंग: रॉ ऑडियो में बदलाव करने के लिए, AudioProcessor इंस्टेंस को चेन करें.

फ़ॉर्मैट के बीच ट्रांसकोड करना

Transformer बनाते समय, आउटपुट ऑडियो और वीडियो के फ़ॉर्मैट तय किए जा सकते हैं. उदाहरण के लिए, यहां दिए गए कोड से पता चलता है कि H.264/AVC वीडियो और AAC ऑडियो आउटपुट करने के लिए, Transformer को कैसे कॉन्फ़िगर करें:

Kotlin

Transformer.Builder(context)
  .setVideoMimeType(MimeTypes.VIDEO_H264)
  .setAudioMimeType(MimeTypes.AUDIO_AAC)
  .build()

Java

new Transformer.Builder(context)
    .setVideoMimeType(MimeTypes.VIDEO_H264)
    .setAudioMimeType(MimeTypes.AUDIO_AAC)
    .build();

अगर इनपुट मीडिया फ़ॉर्मैट, ऑडियो या वीडियो के कॉन्फ़िगरेशन से पहले से ही मेल खाता है, तो ट्रांसफ़ॉर्मर अपने-आप ट्रांसमक्सिंग पर स्विच हो जाता है. इसका मतलब है कि यह कंप्रेस किए गए सैंपल को इनपुट कंटेनर से आउटपुट कंटेनर में बिना किसी बदलाव के कॉपी करता है. इससे एक ही फ़ॉर्मैट में डिकोड और फिर से एन्कोड करने की कंप्यूटेशनल लागत और क्वालिटी में संभावित गिरावट से बचा जा सकता है.

ऑडियो या वीडियो हटाना

EditedMediaItem.Builder का इस्तेमाल करके ऑडियो या वीडियो हटाएं. उदाहरण के लिए:

Kotlin

EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build()

Java

new EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build();

किसी क्लिप में काट-छांट करना

इनपुट मीडिया आइटम पर क्लिप करने का कॉन्फ़िगरेशन सेट करके, शुरू और खत्म होने के टाइमस्टैंप के बाहर मौजूद किसी भी मीडिया को हटाया जा सकता है. उदाहरण के लिए, अगर आपको 10 सेकंड से 20 सेकंड के बीच के मीडिया का इस्तेमाल करके क्लिप बनानी है, तो यह तरीका अपनाएं:

Kotlin

val inputMediaItem =
  MediaItem.Builder()
    .setUri(uri)
    .setClippingConfiguration(
      MediaItem.ClippingConfiguration.Builder()
        .setStartPositionMs(10_000)
        .setEndPositionMs(20_000)
        .build()
    )
    .build()

Java

MediaItem inputMediaItem =
    new MediaItem.Builder()
        .setUri(uri)
        .setClippingConfiguration(
            new MediaItem.ClippingConfiguration.Builder()
                .setStartPositionMs(10_000)
                .setEndPositionMs(20_000)
                .build())
        .build();

MP4 फ़ाइलों में बदलाव करने की सूचियां

वीडियो को जल्दी ट्रिम करने के लिए, Transformer में MP4 फ़ाइल की एडिट लिस्ट का इस्तेमाल किया जा सकता है. इससे पूरे वीडियो को फिर से ट्रांसकोड किए बिना, सिर्फ़ "ट्रिम करने" से जुड़े बदलाव ज़्यादा आसानी से किए जा सकते हैं. इस तरीके में, पहले से एन्कोड किए गए सैंपल और एडिट लिस्ट में "प्री-रोल" का इस्तेमाल किया जाता है. इससे प्लेयर को किसी खास पॉइंट से वीडियो चलाना शुरू करने का निर्देश मिलता है. इससे शुरुआती अवांछित सेगमेंट को स्किप किया जा सकता है.

सिर्फ़ ट्रिम करने से जुड़े बदलावों को तेज़ी से करने के लिए, experimentalSetMp4EditListTrimEnabled(true) कॉल करें.

Kotlin

Transformer.Builder(context).experimentalSetMp4EditListTrimEnabled(true).build()

Java

new Transformer.Builder(context).experimentalSetMp4EditListTrimEnabled(true).build();
ध्यान दें कि सभी मीडिया प्लेयर, "प्री-रोल" विज्ञापन दिखाने की सुविधा नहीं देते. इसका मतलब है कि इस तरह के प्लेयर का इस्तेमाल करने पर, फ़ाइल कोडिंग किए गए सैंपल की शुरुआत से प्ले होना शुरू हो जाएगी. भले ही, एडिट लिस्ट की जानकारी में कोई दूसरा शुरुआती पॉइंट बताया गया हो.

ट्रिम को ऑप्टिमाइज़ करना

वीडियो की शुरुआत में काट-छांट करने में लगने वाला समय कम करने के लिए, काट-छांट करने की सुविधा को ऑप्टिमाइज़ करें.

Kotlin

Transformer.Builder(context).experimentalSetTrimOptimizationEnabled(true).build()

Java

new Transformer.Builder(context).experimentalSetTrimOptimizationEnabled(true).build();

इससे एक्सपोर्ट की प्रोसेस तेज़ हो जाती है. ऐसा इसलिए होता है, क्योंकि वीडियो के सिर्फ़ उतने हिस्से को डिकोड और फिर से एन्कोड किया जाता है जितना ज़रूरी होता है. इसके बाद, फिर से एन्कोड किए गए डेटा को वीडियो के बाकी हिस्से के साथ जोड़ दिया जाता है. ऑप्टिमाइज़ेशन के लिए, इनपुट फ़ाइल के कुछ हिस्से को नए तरीके से कोड किए गए आउटपुट के साथ जोड़ना ज़रूरी होता है. इसका मतलब है कि एनकोडर के आउटपुट फ़ॉर्मैट और इनपुट फ़ॉर्मैट का एक जैसा होना ज़रूरी है. इसलिए, उदाहरण के लिए, अगर फ़ाइल को किसी ऐसे डिवाइस पर बनाया गया था जिसमें एन्कोडर को अलग तरीके से लागू किया गया था, तो हो सकता है कि फ़ाइल को ऑप्टिमाइज़ न किया जा सके. ऑप्टिमाइज़ेशन के लिए, यह ज़रूरी है कि EncoderFactory के ज़रिए Transformer को दिए गए एनकोडर का लेवल और प्रोफ़ाइल, इनपुट फ़ॉर्मैट के साथ काम करती हो.

यह ऑप्टिमाइज़ेशन सिर्फ़ एक ऐसेट वाले MP4 इनपुट के साथ काम करता है जिसमें कोई इफ़ेक्ट न हो. हालांकि, इसमें नो-ऑप वीडियो इफ़ेक्ट और 90 डिग्री से भाग देने पर पूरी तरह से विभाजित होने वाले रोटेशन शामिल किए जा सकते हैं. अगर ऑप्टिमाइज़ेशन पूरा नहीं होता है, तो Transformer अपने-आप सामान्य एक्सपोर्ट पर वापस आ जाता है. साथ ही, ExportResult.OptimizationResult में ऑप्टिमाइज़ेशन के नतीजे की जानकारी देता है.

हम इस सुविधा की पुष्टि कर रहे हैं. हमें उम्मीद है कि आने वाले समय में, यह सुविधा एक्सपेरिमेंट के तौर पर उपलब्ध नहीं होगी.

वीडियो में बदलाव करने की सुविधा

EditedMediaItems में ऑडियो प्रोसेसर और वीडियो इफ़ेक्ट की सूचियां होती हैं, जिन्हें क्रम से लागू किया जा सकता है. लाइब्रेरी में, सामान्य इस्तेमाल के उदाहरणों के लिए वीडियो इफ़ेक्ट लागू करने की सुविधा शामिल होती है. इसके अलावा, आपके पास पसंद के मुताबिक इफ़ेक्ट लिखने और उन्हें मीडिया आइटम में बदलाव करते समय पास करने का विकल्प होता है.

मीडिया को फिर से स्केल किया जा सकता है. इससे, 4K या 8K वीडियो जैसे बहुत ज़्यादा हाई रिज़ॉल्यूशन वाले इनपुट को प्रोसेस करने के लिए, संसाधनों या बैंडविड्थ को बचाया जा सकता है. उदाहरण के लिए, ऊंचाई को 480 पिक्सल के हिसाब से स्केल करने के लिए:

Kotlin

EditedMediaItem.Builder(MediaItem.fromUri(uri))
  .setEffects(
    Effects(
      /* audioProcessors= */ listOf(),
      /* videoEffects= */ listOf(Presentation.createForHeight(480)),
    )
  )
  .build()

Java

new EditedMediaItem.Builder(MediaItem.fromUri(uri))
    .setEffects(
        new Effects(
            /* audioProcessors= */ ImmutableList.of(),
            /* videoEffects= */ ImmutableList.of(Presentation.createForHeight(480))))
    .build();

इसके अलावा, किसी दिए गए फ़ैक्टर के हिसाब से भी स्केल किया जा सकता है. उदाहरण के लिए, साइज़ को आधा करने के लिए:

Kotlin

val editedMediaItem =
  EditedMediaItem.Builder(MediaItem.fromUri(uri))
    .setEffects(
      Effects(
        /* audioProcessors= */ listOf(),
        /* videoEffects= */ listOf(
          ScaleAndRotateTransformation.Builder().setScale(.5f, .5f).build()
        ),
      )
    )
    .build()

Java

new EditedMediaItem.Builder(MediaItem.fromUri(uri))
    .setEffects(
        new Effects(
            /* audioProcessors= */ ImmutableList.of(),
            /* videoEffects= */ ImmutableList.of(
                new ScaleAndRotateTransformation.Builder().setScale(.5f, .5f).build())))
    .build();

रोटेशन को इसी तरह कॉन्फ़िगर किया जा सकता है:

Kotlin

EditedMediaItem.Builder(MediaItem.fromUri(uri))
  .setEffects(
    Effects(
      /* audioProcessors= */ listOf(),
      /* videoEffects= */ listOf(
        ScaleAndRotateTransformation.Builder().setRotationDegrees(90f).build()
      ),
    )
  )
  .build()

Java

new EditedMediaItem.Builder(MediaItem.fromUri(uri))
    .setEffects(
        new Effects(
            /* audioProcessors= */ ImmutableList.of(),
            /* videoEffects= */ ImmutableList.of(
                new ScaleAndRotateTransformation.Builder().setRotationDegrees(90f).build())))
    .build();

कस्टम वीडियो इफ़ेक्ट

Effects कंस्ट्रक्टर, लागू करने के लिए ऑडियो और वीडियो इफ़ेक्ट की सूची स्वीकार करता है. Transformer का इफ़ेक्ट फ़्रेमवर्क, वीडियो इफ़ेक्ट की सूची को GL शेडर प्रोग्राम के क्रम में बदलता है. इन प्रोग्राम को क्रम से लागू किया जाता है. कुछ मामलों में, इफ़ेक्ट फ़्रेमवर्क एक ही शेडर प्रोग्राम की मदद से कई इफ़ेक्ट लागू कर सकता है. उदाहरण के लिए, एक शेडर प्रोग्राम, मैट्रिक्स के कई लगातार ट्रांसफ़ॉर्मेशन लागू कर सकता है. इससे परफ़ॉर्मेंस और क्वालिटी बेहतर होती है.

ExoPlayer में वीडियो इफ़ेक्ट की झलक देखने की सुविधा भी उपलब्ध है. इसके लिए, ExoPlayer.setVideoEffects का इस्तेमाल करें. इस एपीआई को इस्तेमाल करने का तरीका जानने के लिए, इफ़ेक्ट डेमो ऐप्लिकेशन देखें.

डेमो ऐप्लिकेशन में, पसंद के मुताबिक वीडियो इफ़ेक्ट के उदाहरण शामिल हैं.

इमेज इनपुट

Transformer, इमेज को स्टैटिक वीडियो क्लिप के तौर पर इस्तेमाल करता है. किसी इमेज को इनपुट सोर्स के तौर पर कॉन्फ़िगर करने के लिए, यह तरीका अपनाएं:

  • MediaItem.Builder का इस्तेमाल करके MediaItem बनाएं. setImageDurationMs को कॉल करके, आउटपुट वीडियो में इमेज दिखने की अवधि तय करें.

  • MediaItem को रैप करने वाला EditedMediaItem बनाएं. EditedMediaItem.Builder#setFrameRate का इस्तेमाल करके, जनरेट की गई वीडियो स्ट्रीम के लिए टारगेट फ़्रेम रेट तय करें.

यहां दिए गए उदाहरण में, 30 फ़्रेम प्रति सेकंड की दर से पांच सेकंड का वीडियो जनरेट करने के लिए, इमेज इनपुट को कॉन्फ़िगर करने का तरीका बताया गया है:

Kotlin

val imageMediaItem =
  MediaItem.Builder()
    .setUri(imageUri)
    .setImageDurationMs(5000) // 5 seconds
    .build()

val editedImageItem =
  EditedMediaItem.Builder(imageMediaItem)
    .setFrameRate(30) // 30 frames per second
    .build()

Java

MediaItem imageMediaItem =
    new MediaItem.Builder()
        .setUri(imageUri)
        .setImageDurationMs(5000) // 5 seconds
        .build();
new EditedMediaItem.Builder(imageMediaItem)
    .setFrameRate(30) // 30 frames per second
    .build();

ऑडियो में बदलाव करना

ऑडियो इफ़ेक्ट लागू करने के लिए, रॉ (पीसीएम) ऑडियो पर AudioProcessor इंस्टेंस का क्रम लागू किया जाता है. ExoPlayer, ऑडियो प्रोसेसर को DefaultAudioSink.Builder में पास करने की सुविधा देता है. इससे ऑडियो में किए गए बदलावों की झलक देखी जा सकती है.