HEVC फ़ॉर्मैट पर काम न करने वाले ऐप्लिकेशन के लिए मीडिया ट्रांसकोडिंग

Android 12 (एपीआई लेवल 31) और उसके बाद के वर्शन पर, HEVC (H.265) जैसे फ़ॉर्मैट में रिकॉर्ड किए गए वीडियो को AVC (H.264) में अपने-आप बदला जा सकता है. ऐसा तब होता है, जब वीडियो को किसी ऐसे ऐप्लिकेशन में खोला जाता है जो HEVC के साथ काम नहीं करता. इस सुविधा की मदद से, वीडियो कैप्चर करने वाले ऐप्लिकेशन, डिवाइस पर रिकॉर्ड किए गए वीडियो के लिए, स्टोरेज के हिसाब से ज़्यादा बेहतर और आधुनिक कोडिंग का इस्तेमाल कर सकते हैं. ऐसा करने पर, अन्य ऐप्लिकेशन के साथ काम करने की सुविधा पर कोई असर नहीं पड़ता.

डिवाइस पर बनाए गए कॉन्टेंट के लिए, यहां दिए गए फ़ॉर्मैट अपने-आप ट्रांसकोड हो सकते हैं:

मीडिया फ़ॉर्मैट एक्सएमएल एट्रिब्यूट MediaFormat का MIME टाइप
HEVC (H.265) HEVC मीडियाफ़ॉर्मैट.MIMETYPE_VIDEO_HEVC
एचडीआर10HDR10 MediaFeature.HdrType.HDR10
HDR10+ HDR10Plus MediaFeature.HdrType.HDR10_PLUS

Android यह मानता है कि ऐप्लिकेशन सभी मीडिया फ़ॉर्मैट के प्लेबैक के साथ काम कर सकते हैं. इसलिए, काम करने वाले मीडिया को ट्रांसकोड करने की सुविधा डिफ़ॉल्ट रूप से बंद रहती है.

ट्रांसकोडिंग का इस्तेमाल कब करना चाहिए

ट्रांसकोडिंग की प्रोसेस में काफ़ी समय लगता है. साथ ही, वीडियो फ़ाइल खोलने में भी काफ़ी देरी होती है. उदाहरण के लिए, Pixel 3 फ़ोन पर, एक मिनट की HEVC वीडियो फ़ाइल को AVC में ट्रांसकोड करने में करीब 20 सेकंड लगते हैं. इसलिए, आपको किसी वीडियो फ़ाइल को सिर्फ़ तब ट्रांसकोड करना चाहिए, जब उसे डिवाइस से भेजा जा रहा हो. उदाहरण के लिए, किसी ऐप्लिकेशन के अन्य उपयोगकर्ताओं के साथ वीडियो फ़ाइल शेयर करते समय या ऐसे क्लाउड सर्वर के साथ शेयर करते समय जो आधुनिक वीडियो फ़ॉर्मैट के साथ काम नहीं करता.

डिवाइस पर वीडियो चलाने या थंबनेल इमेज बनाने के लिए, वीडियो फ़ाइलें खोलते समय ट्रांसकोड न करें.

ट्रांसकोडिंग कॉन्फ़िगर करना

ऐप्लिकेशन, मीडिया की सुविधाओं के बारे में बताकर, ट्रांसकोडिंग के तरीके को कंट्रोल कर सकते हैं. इन सुविधाओं के बारे में बताने के दो तरीके हैं: कोड में या किसी संसाधन में.

कोड में सुविधाओं के बारे में बताना

बिल्डर का इस्तेमाल करके ApplicationMediaCapabilities ऑब्जेक्ट का इंस्टेंस बनाकर, कोड में मीडिया की सुविधाओं का एलान किया जा सकता है:

Kotlin

val mediaCapabilities = ApplicationMediaCapabilities.Builder()
    .addSupportedVideoMimeType(MediaFormat.MIMETYPE_VIDEO_HEVC)
    .addUnsupportedHdrType(MediaFeature.HdrType.HDR10)
    .addUnsupportedHdrType(MediaFeature.HdrType.HDR10_PLUS)
    .build()

Java

ApplicationMediaCapabilities mediaCapabilities = new ApplicationMediaCapabilities.Builder()
        .addSupportedVideoMimeType(MediaFormat.MIMETYPE_VIDEO_HEVC)
        .addUnsupportedHdrType(MediaFeature.HdrType.HDR10)
        .addUnsupportedHdrType(MediaFeature.HdrType.HDR10_PLUS)
        .build();

मीडिया कॉन्टेंट को ऐक्सेस करने के लिए, इस ऑब्जेक्ट का इस्तेमाल इन तरीकों से करें ContentResolver#openTypedAssetFileDescriptor():

Kotlin

val providerOptions = Bundle().apply {
    putParcelable(MediaStore.EXTRA_MEDIA_CAPABILITIES, mediaCapabilities)
}
contentResolver.openTypedAssetFileDescriptor(mediaUri, mediaMimeType, providerOptions)
    .use { fileDescriptor ->
        // Content will be transcoded based on values defined in the
        // ApplicationMediaCapabilities provided.
    }

Java

Bundle providerOptions = new Bundle();
providerOptions.putParcelable(MediaStore.EXTRA_MEDIA_CAPABILITIES, mediaCapabilities);
try (AssetFileDescriptor fileDescriptor =  contentResolver.openTypedAssetFileDescriptor(mediaUri, mediaMimeType, providerOptions)) {
    // Content will be transcoded based on values defined in the
    // ApplicationMediaCapabilities provided.
}

इस तरीके से, खास कोड पाथ के लिए ज़्यादा कंट्रोल मिलता है. जैसे, सिर्फ़ डिवाइस से वीडियो फ़ाइल ट्रांसफ़र करते समय ट्रांसकोडिंग को चालू करना. इसे नीचे बताए गए तरीके के मुकाबले प्राथमिकता दी जाती है.

किसी संसाधन में क्षमताओं के बारे में बताना

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

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

इस तरीके का इस्तेमाल करने के लिए, media_capabilities.xml रिसॉर्स फ़ाइल बनाएं:

<?xml version="1.0" encoding="utf-8"?>
<media-capabilities xmlns:android="http://schemas.android.com/apk/res/android">
    <format android:name="HEVC" supported="true"/>
    <format android:name="HDR10" supported="false"/>
    <format android:name="HDR10Plus" supported="false"/>
</media-capabilities>

इस उदाहरण में, डिवाइस पर रिकॉर्ड किए गए एचडीआर वीडियो को एवीसी एसडीआर (स्टैंडर्ड डाइनैमिक रेंज) वीडियो में आसानी से ट्रांसकोड किया जाता है, जबकि एचईवीसी वीडियो को नहीं.

मीडिया की सुविधाओं वाली फ़ाइल का रेफ़रंस जोड़ने के लिए, application टैग में property टैग का इस्तेमाल करें. अपनी AndroidManifest.xml फ़ाइल में इन प्रॉपर्टी को जोड़ें:

<property
    android:name="android.media.PROPERTY_MEDIA_CAPABILITIES"
    android:resource="@xml/media_capabilities" />

वीडियो फ़ाइल खोलने के लिए, किसी दूसरे ऐप्लिकेशन की मीडिया सुविधाओं का इस्तेमाल करना

अगर आपका ऐप्लिकेशन किसी दूसरे ऐप्लिकेशन के साथ वीडियो फ़ाइल शेयर करता है, तो हो सकता है कि वीडियो फ़ाइल को ट्रांसकोड करना पड़े. इसके बाद ही, उसे पाने वाला ऐप्लिकेशन उसे खोल पाएगा.

इस मामले को ठीक करने के लिए, openTypedAssetFileDescriptor का इस्तेमाल करके कोई वीडियो फ़ाइल खोलें और फ़ाइल पाने वाले ऐप्लिकेशन का यूआईडी डालें. यूआईडी पाने के लिए, Binder.getCallingUid का इस्तेमाल करें. इसके बाद, प्लैटफ़ॉर्म, वीडियो फ़ाइल को ट्रांसकोड करना है या नहीं, यह तय करने के लिए, वीडियो पाने वाले ऐप्लिकेशन की मीडिया सुविधाओं का इस्तेमाल करता है.

Kotlin

val providerOptions = Bundle().apply {
    putParcelable(MediaStore.EXTRA_MEDIA_CAPABILITIES_UID, Binder.getCallingUid())
}
contentResolver.openTypedAssetFileDescriptor(mediaUri, mediaMimeType, providerOptions)
    .use { fileDescriptor ->
        // Content will be transcoded based on the media capabilities of the
        // calling app.
    }

Java

Bundle providerOptions = new Bundle();
providerOptions.putParcelable(MediaStore.EXTRA_MEDIA_CAPABILITIES_UID, Binder.getCallingUid());
try (AssetFileDescriptor fileDescriptor =  contentResolver.openTypedAssetFileDescriptor(mediaUri, mediaMimeType, providerOptions)) {
    // Content will be transcoded based on the media capabilities of the
    // calling app.
}

उदाहरण के तौर पर दी गई स्थितियां

नीचे दिए गए डायग्राम में, इस्तेमाल के दो सामान्य उदाहरण दिखाए गए हैं. दोनों ही मामलों में, ओरिजनल वीडियो को HEVC फ़ॉर्मैट में सेव किया जाता है और वीडियो शेयर करने वाला ऐप्लिकेशन, HEVC फ़ॉर्मैट के साथ काम नहीं करता.

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

दूसरा उदाहरण. वीडियो शेयर करने वाले ऐप्लिकेशन से ट्रांसकोडिंग शुरू होती है. दूसरा उदाहरण वीडियो कैप्चर करने वाला ऐप्लिकेशन, MediaStore यूआरआई का इस्तेमाल करके, वीडियो शेयर करने वाले ऐप्लिकेशन के साथ वीडियो शेयर करता है. वीडियो शेयर करने वाला ऐप्लिकेशन, openTypedAssetFileDescriptor का इस्तेमाल करके वीडियो फ़ाइल को खोलता है. साथ ही, यह बताता है कि यह मीडिया की सुविधाओं में HEVC के साथ काम नहीं करता. इससे ट्रांसकोडिंग की प्रोसेस शुरू हो जाती है. प्रोसेस पूरी होने के बाद, फ़ाइल को क्लाउड में मौजूद सर्वर पर अपलोड कर दिया जाता है.

ऐसे फ़ॉर्मैट जिनके बारे में जानकारी नहीं दी गई है

काम करने वाले मीडिया को ट्रांसकोड करने की सुविधा, उन सभी फ़ॉर्मैट के लिए चालू होती है जिनके लिए यह सुविधा काम नहीं करती. साथ ही, यह उन सभी फ़ॉर्मैट के लिए बंद होती है जिनके लिए यह सुविधा काम करती है. जिन फ़ॉर्मैट के लिए एलान नहीं किया गया है उनके लिए, प्लैटफ़ॉर्म यह तय करता है कि उन्हें ट्रांसकोड करना है या नहीं. Android 12 में, एलान न किए गए सभी फ़ॉर्मैट के लिए ट्रांसकोडिंग की सुविधा बंद है. आने वाले समय में नए फ़ॉर्मैट के लिए, यह व्यवहार बदल सकता है.

डेवलपर के लिए सेटिंग और टूल

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

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

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

  • मान लें कि ऐप्लिकेशन मॉडर्न फ़ॉर्मैट के साथ काम करते हैं इस सेटिंग से यह कंट्रोल किया जाता है कि जब ऐप्लिकेशन ऐसे फ़ॉर्मैट को चलाने की कोशिश करे जिसे तय न किया गया हो. ऐसा तब होता है, जब मेनिफ़ेस्ट में यह जानकारी न दी गई हो कि ऐप्लिकेशन किसी खास फ़ॉर्मैट के साथ काम करता है या नहीं या Google ने ऐप्लिकेशन को सर्वर-साइड के ज़रिए वीडियो को ज़बरदस्ती ट्रांसकोड करने की सूची में नहीं जोड़ा हो. सेटिंग चालू होने पर, ऐप्लिकेशन वीडियो को ट्रांसकोड नहीं करता. सेटिंग बंद होने पर, ऐप्लिकेशन वीडियो को ट्रांसकोड करता है. यह विकल्प डिफ़ॉल्ट रूप से चालू होता है.

  • ट्रांसकोडिंग की सूचनाएं दिखाएं यह सुविधा चालू होने पर, जब ट्रांसकोडिंग शुरू होती है, तब ऐप्लिकेशन काम न करने वाली मीडिया फ़ाइल को पढ़कर, ट्रांसकोडिंग की स्थिति की सूचना दिखाता है. यह विकल्प डिफ़ॉल्ट रूप से चालू होता है.

  • ट्रांसकोडिंग कैश मेमोरी बंद करें अगर यह सेटिंग चालू है, तो ट्रांसकोडिंग की ज़रूरत वाले ऐप्लिकेशन, ट्रांसकोडिंग कैश मेमोरी का इस्तेमाल नहीं करते. डेवलपमेंट के दौरान, यह सुविधा किसी ऐसी मीडिया फ़ाइल पर ट्रांसकोडिंग को आसानी से ट्रिगर करने में मददगार हो सकती है जिस पर यह सुविधा काम नहीं करती. हालांकि, इससे डिवाइस की परफ़ॉर्मेंस खराब हो सकती है. यह विकल्प डिफ़ॉल्ट रूप से बंद होता है.