अलग-अलग फ़ॉर्मैट में ट्रांसकोड करना
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( 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
का इस्तेमाल करें. इस एपीआई का इस्तेमाल करने का तरीका जानने के लिए, इफ़ेक्ट डेमो ऐप्लिकेशन देखें.
डेमो ऐप्लिकेशन में, पसंद के मुताबिक वीडियो इफ़ेक्ट के उदाहरण शामिल हैं.
ऑडियो में बदलाव करना
ऑडियो इफ़ेक्ट लागू करने के लिए, रॉ (पीसीएम) ऑडियो पर AudioProcessor
इंस्टेंस का क्रम लागू किया जाता है. ExoPlayer, ऑडियो प्रोसेसर को DefaultAudioSink.Builder
में पास करने की सुविधा देता है. इससे ऑडियो में किए गए बदलावों की झलक देखी जा सकती है.