समस्या का हल


"क्लियरटेक्स्ट एचटीटीपी ट्रैफ़िक की अनुमति नहीं है" गड़बड़ियों को ठीक करना

यह गड़बड़ी तब होती है, जब आपका ऐप्लिकेशन cleartext एचटीटीपी ट्रैफ़िक (यानी कि https:// के बजाय http://) का अनुरोध करता है. ऐसा तब होता है, जब नेटवर्क सिक्योरिटी कॉन्फ़िगरेशन इसकी अनुमति नहीं देता. अगर आपका ऐप्लिकेशन, Android 9 (एपीआई लेवल 28) या इसके बाद के वर्शन को टारगेट करता है, तो डिफ़ॉल्ट कॉन्फ़िगरेशन के तहत, क्लियरटेक्स्ट एचटीटीपी ट्रैफ़िक बंद हो जाता है.

अगर आपके ऐप्लिकेशन को क्लियरटेक्स्ट एचटीटीपी ट्रैफ़िक के साथ काम करना है, तो आपको ऐसे नेटवर्क सिक्योरिटी कॉन्फ़िगरेशन का इस्तेमाल करना होगा जो इसकी अनुमति देता हो. ज़्यादा जानकारी के लिए, Android का नेटवर्क सुरक्षा से जुड़ा दस्तावेज़ देखें. सभी क्लियरटेक्स्ट एचटीटीपी ट्रैफ़िक को चालू करने के लिए, अपने ऐप्लिकेशन के AndroidManifest.xml के application एलिमेंट में android:usesCleartextTraffic="true" जोड़ें.

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

"SSLHandshakeException", "CertPathValidatorException", और "ERR_CERT_AUTHORITY_INVALID" गड़बड़ियों को ठीक करना

SSLHandshakeException, CertPathValidatorException, और ERR_CERT_AUTHORITY_INVALID, ये सभी सर्वर के एसएसएल सर्टिफ़िकेट से जुड़ी समस्या के बारे में बताते हैं. ये गड़बड़ियां, ExoPlayer से जुड़ी नहीं हैं. ज़्यादा जानकारी के लिए, Android का एसएसएल दस्तावेज़ देखें.

कुछ मीडिया फ़ाइलों को स्किप क्यों नहीं किया जा सकता?

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

अगर आपको मीडिया में आगे-पीछे जाने की सुविधा चाहिए, लेकिन आपके पास ऐसा मीडिया है जिसमें यह सुविधा नहीं है, तो हमारा सुझाव है कि आप अपने कॉन्टेंट को किसी ऐसे कंटेनर फ़ॉर्मैट में बदलें जो इस सुविधा के लिए ज़्यादा सही हो. MP3, ADTS, और AMR फ़ाइलों के लिए, फ़ाइल में एक जैसा बिटरेट होने पर, फ़ाइल में आगे-पीछे जाने की सुविधा भी चालू की जा सकती है. इसके बारे में यहां बताया गया है.

कुछ MP3 फ़ाइलों में, आगे-पीछे करने की सुविधा ठीक से काम क्यों नहीं करती?

वेरिएबल बिटरेट (वीबीआर) वाली MP3 फ़ाइलें, उन इस्तेमाल के उदाहरणों के लिए सही नहीं होती हैं जिनमें सटीक सीकिंग की ज़रूरत होती है. ऐसा इन दो वजहों से हो सकता है:

  1. वीडियो के किसी भी हिस्से पर जाने की सुविधा के लिए, कंटेनर फ़ॉर्मैट को हेडर में सटीक टाइम-टू-बाइट मैपिंग देनी चाहिए. इस मैपिंग की मदद से, कोई खिलाड़ी वीडियो में किसी खास जगह पर जाने के लिए अनुरोध किए गए समय को उससे जुड़े बाइट ऑफ़सेट पर मैप कर सकता है. साथ ही, उस ऑफ़सेट से मीडिया का अनुरोध करना, उसे पार्स करना, और उसे चलाना शुरू कर सकता है. MP3 फ़ाइलों में इस मैपिंग के बारे में बताने के लिए उपलब्ध हेडर (जैसे कि XING हेडर) अक्सर सटीक नहीं होते.
  2. जिन कंटेनर फ़ॉर्मैट में टाइम-टू-बाइट मैपिंग सटीक नहीं होती या बिलकुल नहीं होती, उनमें भी सटीक सीक किया जा सकता है. हालांकि, इसके लिए ज़रूरी है कि कंटेनर में स्ट्रीम के ऐब्सलूट सैंपल टाइमस्टैंप शामिल हों. इस मामले में, प्लेयर, सीक करने के समय को बाइट ऑफ़सेट के सबसे सही अनुमान पर मैप कर सकता है. साथ ही, उस ऑफ़सेट से मीडिया का अनुरोध करना शुरू कर सकता है. इसके बाद, पहले ऐब्सलूट सैंपल टाइमस्टैंप को पार्स कर सकता है. इसके अलावा, सही सैंपल मिलने तक मीडिया में गाइडेड बाइनरी सर्च को असरदार तरीके से लागू कर सकता है. माफ़ करें, MP3 फ़ाइल में स्ट्रीम में मौजूद हर सैंपल के लिए टाइमस्टैंप नहीं होता. इसलिए, इस तरीके का इस्तेमाल नहीं किया जा सकता.

इन वजहों से, वीबीआर MP3 फ़ाइल में सटीक तरीके से खोजने का सिर्फ़ एक तरीका है. इसके लिए, पूरी फ़ाइल को स्कैन करना होगा. साथ ही, प्लेयर में टाइम-टू-बाइट मैपिंग को मैन्युअल तरीके से बनाना होगा. इस रणनीति को FLAG_ENABLE_INDEX_SEEKING का इस्तेमाल करके चालू किया जा सकता है. इसे setMp3ExtractorFlags का इस्तेमाल करके DefaultExtractorsFactory पर सेट किया जा सकता है. ध्यान दें कि यह बड़ी MP3 फ़ाइलों के लिए अच्छी तरह से काम नहीं करता. खास तौर पर, अगर उपयोगकर्ता स्ट्रीम को चलाने के कुछ ही समय बाद, उसे आखिर के आस-पास ले जाने की कोशिश करता है. इसके लिए, प्लेयर को तब तक इंतज़ार करना पड़ता है, जब तक पूरी स्ट्रीम डाउनलोड और इंडेक्स नहीं हो जाती. इस मामले में, हमने ExoPlayer में सटीक जानकारी के बजाय तेज़ी से जानकारी देने को प्राथमिकता दी है. इसलिए, FLAG_ENABLE_INDEX_SEEKING डिफ़ॉल्ट रूप से बंद है.

अगर आपके पास मीडिया को कंट्रोल करने का विकल्प है, तो हमारा सुझाव है कि आप MP4 जैसे ज़्यादा सही कंटेनर फ़ॉर्मैट का इस्तेमाल करें. हमें ऐसे किसी भी इस्तेमाल के बारे में जानकारी नहीं है जहां MP3, मीडिया फ़ॉर्मैट का सबसे अच्छा विकल्प हो.

मेरे वीडियो में आगे-पीछे करने की सुविधा धीरे क्यों काम कर रही है?

जब प्लेयर किसी वीडियो में नई पोज़िशन पर जाता है, तो उसे दो काम करने होते हैं:

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

(1) की वजह से होने वाली देरी को कम करने के लिए, प्लेयर की मेमोरी में बफ़र किए गए डेटा की मात्रा को बढ़ाया जा सकता है. इसके अलावा, डेटा को डिस्क में पहले से ही कैश मेमोरी में सेव किया जा सकता है.

ExoPlayer.setSeekParameters का इस्तेमाल करके, वीडियो में सटीक जगह पर जाने की सुविधा को कम करके (2) की वजह से होने वाली देरी को कम किया जा सकता है. इसके अलावा, वीडियो को फिर से एन्कोड करके, ज़्यादा बार I-फ़्रेम का इस्तेमाल किया जा सकता है. हालांकि, इससे आउटपुट फ़ाइल का साइज़ बढ़ जाएगा.

कुछ MPEG-TS फ़ाइलें क्यों नहीं चलती हैं?

कुछ MPEG-TS फ़ाइलों में, ऐक्सेस यूनिट डेलिमिटर (एयूडी) नहीं होते हैं. डिफ़ॉल्ट रूप से, ExoPlayer फ़्रेम की सीमाओं का पता लगाने के लिए, एयूडी पर निर्भर करता है. इसी तरह, कुछ MPEG-TS फ़ाइलों में आईडीआर कीफ़्रेम नहीं होते हैं. डिफ़ॉल्ट रूप से, ExoPlayer सिर्फ़ इन कीफ़्रेम को ध्यान में रखता है.

अगर ExoPlayer को ऐसी MPEG-TS फ़ाइल चलाने के लिए कहा जाता है जिसमें AUD या आईडीआर कीफ़्रेम नहीं हैं, तो वह बफ़रिंग की स्थिति में अटक जाएगा. अगर आपको ऐसी फ़ाइलें चलानी हैं, तो FLAG_DETECT_ACCESS_UNITS और FLAG_ALLOW_NON_IDR_KEYFRAMES का इस्तेमाल करें. इन फ़्लैग को DefaultExtractorsFactory पर setTsExtractorFlags का इस्तेमाल करके या DefaultHlsExtractorFactory पर कंस्ट्रक्टर का इस्तेमाल करके सेट किया जा सकता है. FLAG_DETECT_ACCESS_UNITS का इस्तेमाल करने से, एयूडी पर आधारित फ़्रेम बाउंड्री का पता लगाने के मुकाबले, कंप्यूटेशनल तौर पर ज़्यादा खर्च होता है. इसके अलावा, इसका कोई और साइड इफ़ेक्ट नहीं होता. FLAG_ALLOW_NON_IDR_KEYFRAMES का इस्तेमाल करने पर, कुछ MPEG-TS फ़ाइलें चलाने के दौरान, वीडियो के शुरू होने पर और वीडियो को आगे-पीछे करने के तुरंत बाद, कुछ समय के लिए विज़ुअल में गड़बड़ी हो सकती है.

कुछ MPEG-TS फ़ाइलों में सबटाइटल क्यों नहीं मिलते?

कुछ MPEG-TS फ़ाइलों में CEA-608 ट्रैक शामिल होते हैं, लेकिन उन्हें कंटेनर मेटाडेटा में शामिल नहीं किया जाता. इसलिए, ExoPlayer उनका पता नहीं लगा पाता. DefaultExtractorsFactory को सबटाइटल के फ़ॉर्मैट की सूची देकर, किसी भी सबटाइटल ट्रैक को मैन्युअल तरीके से तय किया जा सकता है. इसमें ऐक्सेसिबिलिटी चैनल भी शामिल हैं. इनका इस्तेमाल MPEG-TS स्ट्रीम में सबटाइटल ट्रैक की पहचान करने के लिए किया जा सकता है:

Kotlin

val extractorsFactory =
  DefaultExtractorsFactory()
    .setTsSubtitleFormats(
      listOf(
        Format.Builder()
          .setSampleMimeType(MimeTypes.APPLICATION_CEA608)
          .setAccessibilityChannel(accessibilityChannel)
          // Set other subtitle format info, such as language.
          .build()
      )
    )
val player: Player =
  ExoPlayer.Builder(context, DefaultMediaSourceFactory(context, extractorsFactory)).build()

Java

DefaultExtractorsFactory extractorsFactory =
    new DefaultExtractorsFactory()
        .setTsSubtitleFormats(
            ImmutableList.of(
                new Format.Builder()
                    .setSampleMimeType(MimeTypes.APPLICATION_CEA608)
                    .setAccessibilityChannel(accessibilityChannel)
                    // Set other subtitle format info, such as language.
                    .build()));
Player player =
    new ExoPlayer.Builder(context, new DefaultMediaSourceFactory(context, extractorsFactory))
        .build();

कुछ MP4/FMP4 फ़ाइलें सही तरीके से क्यों नहीं चलती हैं?

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

अगर आपको दिख रहा है कि मीडिया का कुछ हिस्सा अचानक गायब हो गया है या दोहराया गया है, तो Mp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS या FragmentedMp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS सेट करके देखें. इससे एक्सट्रैक्टर, बदलाव की सूचियों को पूरी तरह से अनदेखा कर देगा. इन्हें setMp4ExtractorFlags या setFragmentedMp4ExtractorFlags का इस्तेमाल करके, DefaultExtractorsFactory पर सेट किया जा सकता है.

कुछ स्ट्रीम, एचटीटीपी रिस्पॉन्स कोड 301 या 302 के साथ क्यों फ़ेल हो जाती हैं?

एचटीटीपी रिस्पॉन्स कोड 301 और 302, दोनों रीडायरेक्ट करने के बारे में बताते हैं. कम शब्दों में जानकारी Wikipedia पर देखी जा सकती है. जब ExoPlayer कोई अनुरोध करता है और उसे 301 या 302 स्टेटस कोड वाला जवाब मिलता है, तो आम तौर पर वह रीडायरेक्ट किए गए यूआरएल पर चला जाता है और वीडियो को सामान्य तरीके से चलाना शुरू कर देता है. हालांकि, क्रॉस-प्रोटोकॉल रीडायरेक्ट के मामले में ऐसा डिफ़ॉल्ट रूप से नहीं होता. क्रॉस-प्रोटोकॉल रीडायरेक्ट, एचटीटीपीएस से एचटीटीपी या इसके उलट (या कम सामान्य तौर पर, प्रोटोकॉल के किसी अन्य पेयर के बीच) रीडायरेक्ट करता है. wget कमांड लाइन टूल का इस्तेमाल करके, यह पता लगाया जा सकता है कि किसी यूआरएल की वजह से क्रॉस-प्रोटोकॉल रीडायरेक्ट होता है या नहीं. इसके लिए, यह तरीका अपनाएं:

wget "https://yourserver.example.com/test.mp3" 2>&1  | grep Location

आउटपुट कुछ ऐसा दिखना चाहिए:

Location: https://secondserver.example.net/test.mp3 [following]
Location: http://thirdserver.example.org/test.mp3 [following]

इस उदाहरण में, दो रीडायरेक्ट हैं. पहला रीडायरेक्ट https://yourserver.example.com/test.mp3 से https://secondserver.example.net/test.mp3 पर किया गया है. दोनों एचटीटीपीएस हैं. इसलिए, यह क्रॉस-प्रोटोकॉल रीडायरेक्ट नहीं है. दूसरा रीडायरेक्ट, https://secondserver.example.net/test.mp3 से http://thirdserver.example.org/test.mp3 पर किया गया है. यह एचटीटीपीएस से एचटीटीपी पर रीडायरेक्ट करता है. इसलिए, यह क्रॉस-प्रोटोकॉल रीडायरेक्ट है. ExoPlayer, अपने डिफ़ॉल्ट कॉन्फ़िगरेशन में इस रीडायरेक्ट को फ़ॉलो नहीं करेगा. इसका मतलब है कि वीडियो नहीं चलेगा.

अगर आपको ऐसा करना है, तो अपने ऐप्लिकेशन में इस्तेमाल किए गए DefaultHttpDataSource.Factory इंस्टेंस को इंस्टैंटिएट करते समय, ExoPlayer को क्रॉस-प्रोटोकॉल रीडायरेक्ट को फ़ॉलो करने के लिए कॉन्फ़िगर किया जा सकता है. नेटवर्क स्टैक को चुनने और कॉन्फ़िगर करने के बारे में जानने के लिए, यहां जाएं.

कुछ स्ट्रीम में UnrecognizedInputFormatException की समस्या क्यों आती है?

यह सवाल, इस तरह की वीडियो चलाने में आने वाली समस्याओं से जुड़ा है:

UnrecognizedInputFormatException: None of the available extractors
(MatroskaExtractor, FragmentedMp4Extractor, ...) could read the stream.

इस गड़बड़ी की दो वजहें हो सकती हैं. इस समस्या की सबसे आम वजह यह है कि DASH (mpd), HLS (m3u8) या SmoothStreaming (ism, isml) कॉन्टेंट चलाने की कोशिश की जा रही है, लेकिन प्लेयर उसे प्रोग्रेसिव स्ट्रीम के तौर पर चलाने की कोशिश कर रहा है. इस तरह की स्ट्रीम चलाने के लिए, आपको ExoPlayer मॉड्यूल पर निर्भर रहना होगा. अगर स्ट्रीम यूआरआई, स्टैंडर्ड फ़ाइल एक्सटेंशन पर खत्म नहीं होता है, तो स्ट्रीम का टाइप साफ़ तौर पर बताने के लिए, MediaItem.Builder के setMimeType को MimeTypes.APPLICATION_MPD, MimeTypes.APPLICATION_M3U8 या MimeTypes.APPLICATION_SS भी पास किया जा सकता है.

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

कुछ डिवाइसों पर setPlaybackParameters ठीक से काम क्यों नहीं करता?

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

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

"Player is accessed on the wrong thread" गड़बड़ियों का क्या मतलब है?

शुरू करने से जुड़े पेज पर, थ्रेडिंग के बारे में जानकारी देखें.

मैं "Unexpected status line: ICY 200 OK" समस्या को कैसे ठीक करूं?

यह समस्या तब हो सकती है, जब सर्वर के जवाब में एचटीटीपी के मुताबिक स्टेटस लाइन के बजाय, आईसीवाई स्टेटस लाइन शामिल हो. आईसीवाई स्टेटस लाइनें अब काम नहीं करती हैं और इनका इस्तेमाल नहीं किया जाना चाहिए. इसलिए, अगर आपके पास सर्वर को कंट्रोल करने का ऐक्सेस है, तो आपको इसे अपडेट करना चाहिए, ताकि एचटीटीपी के मुताबिक रिस्पॉन्स मिल सके. अगर ऐसा नहीं किया जा सकता, तो ExoPlayer OkHttp लाइब्रेरी का इस्तेमाल करने से समस्या हल हो जाएगी. ऐसा इसलिए, क्योंकि यह ICY स्टेटस लाइन को सही तरीके से हैंडल कर सकती है.

मैं यह क्वेरी कैसे करूं कि स्ट्रीम की जा रही वीडियो लाइव स्ट्रीम है या नहीं?

खिलाड़ी के isCurrentWindowLive तरीके के बारे में क्वेरी की जा सकती है. इसके अलावा, isCurrentWindowDynamic पर जाकर यह देखा जा सकता है कि विंडो डाइनैमिक है या नहीं. इसका मतलब है कि समय के साथ-साथ विंडो अपडेट हो रही है या नहीं.

ऐप्लिकेशन को बैकग्राउंड में ले जाने पर भी ऑडियो कैसे चलता रहे?

यह पक्का करने के लिए कि ऐप्लिकेशन बैकग्राउंड में चलने पर भी ऑडियो चलता रहे, यह तरीका अपनाएं:

  1. आपके पास चालू फ़ोरग्राउंड सेवा होनी चाहिए. इससे सिस्टम को संसाधन खाली करने के लिए, आपकी प्रोसेस को बंद करने से रोका जाता है.
  2. आपके पास WifiLock और WakeLock होना चाहिए. इनसे यह पक्का होता है कि सिस्टम, वाई-फ़ाई रेडियो और सीपीयू को चालू रखे. ExoPlayer का इस्तेमाल करके, ऐसा आसानी से किया जा सकता है. इसके लिए, setWakeMode को कॉल करें. इससे ज़रूरी लॉक सही समय पर अपने-आप मिल जाएंगे और रिलीज़ हो जाएंगे.

यह ज़रूरी है कि ऑडियो बंद होने के तुरंत बाद, आप लॉक हटा दें (अगर setWakeMode का इस्तेमाल नहीं किया जा रहा है) और सेवा को बंद कर दें.

ExoPlayer मेरे कॉन्टेंट के साथ काम करता है, लेकिन ExoPlayer Cast लाइब्रेरी क्यों नहीं करती?

ऐसा हो सकता है कि जिस कॉन्टेंट को चलाने की कोशिश की जा रही है वह सीओआरएस की सुविधा के साथ काम न करता हो. Cast framework को कॉन्टेंट चलाने के लिए, सीओआरएस की सुविधा चालू करनी होती है.

कॉन्टेंट क्यों नहीं चलता, लेकिन कोई गड़बड़ी नहीं दिखती?

ऐसा हो सकता है कि जिस डिवाइस पर कॉन्टेंट चलाया जा रहा है उस पर मीडिया सैंपल का कोई खास फ़ॉर्मैट काम न करे. इसकी पुष्टि आसानी से की जा सकती है. इसके लिए, अपने प्लेयर में EventLogger को श्रोता के तौर पर जोड़ें. इसके बाद, Logcat में इस तरह की लाइन ढूंढें:

[ ] Track:x, id=x, mimeType=mime/type, ... , supported=NO_UNSUPPORTED_TYPE

NO_UNSUPPORTED_TYPE का मतलब है कि डिवाइस, mimeType में बताए गए मीडिया सैंपल फ़ॉर्मैट को डिकोड नहीं कर पा रहा है. सपोर्ट किए गए सैंपल फ़ॉर्मैट के बारे में जानने के लिए, Android मीडिया फ़ॉर्मैट का दस्तावेज़ देखें. प्लेबैक के लिए, लोड की जा सकने वाली और इस्तेमाल की जा सकने वाली डीकोडिंग लाइब्रेरी कैसे मिलेगी? यह जानकारी भी आपके काम आ सकती है.

मैं प्लेबैक के लिए, डीकोडिंग लाइब्रेरी को लोड करके उसका इस्तेमाल कैसे करूं?

  • ज़्यादातर डिकोडर लाइब्रेरी में, डिपेंडेंसी को बनाने और उनकी जांच करने के लिए मैन्युअल तरीके से किए जाने वाले चरण होते हैं. इसलिए, पक्का करें कि आपने संबंधित लाइब्रेरी के README में दिए गए चरणों का पालन किया हो. उदाहरण के लिए, ExoPlayer FFmpeg लाइब्रेरी के लिए, libraries/decoder_ffmpeg/README.md में दिए गए निर्देशों का पालन करना ज़रूरी है. साथ ही, आपको उन सभी फ़ॉर्मैट के लिए डिकोडर चालू करने के लिए कॉन्फ़िगरेशन फ़्लैग पास करने होंगे जिन्हें आपको चलाना है.
  • जिन लाइब्रेरी में नेटिव कोड होता है उनके लिए, पक्का करें कि README में बताए गए Android NDK के सही वर्शन का इस्तेमाल किया जा रहा हो. साथ ही, कॉन्फ़िगरेशन और बिल्डिंग के दौरान दिखने वाली किसी भी गड़बड़ी पर ध्यान दें. README में दिए गए निर्देशों का पालन करने के बाद, आपको हर सपोर्ट किए गए आर्किटेक्चर के लिए, लाइब्रेरी के पाथ की libs सबडायरेक्ट्री में .so फ़ाइलें दिखनी चाहिए.
  • डेमो ऐप्लिकेशन में लाइब्रेरी का इस्तेमाल करके, प्लेबैक की सुविधा आज़माने के लिए, बंडल किए गए डीकोडर चालू करना लेख पढ़ें. अपने ऐप्लिकेशन में लाइब्रेरी का इस्तेमाल करने के निर्देशों के लिए, लाइब्रेरी का README देखें.
  • अगर DefaultRenderersFactory का इस्तेमाल किया जा रहा है, तो डिकोडर लोड होने पर आपको Logcat में "Loaded FfmpegAudioRenderer" जैसी जानकारी वाला लॉग दिखेगा. अगर यह मौजूद नहीं है, तो पक्का करें कि ऐप्लिकेशन में डिकोडिंग लाइब्रेरी की निर्भरता हो.
  • अगर आपको Logcat में LibraryLoader से चेतावनी वाले लॉग दिखते हैं, तो इसका मतलब है कि लाइब्रेरी का नेटिव कॉम्पोनेंट लोड नहीं हो सका. ऐसा होने पर, पक्का करें कि आपने लाइब्रेरी के README में दिए गए चरणों का सही तरीके से पालन किया हो. साथ ही, निर्देशों का पालन करते समय कोई गड़बड़ी न हुई हो.

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

क्या ExoPlayer की मदद से, YouTube वीडियो सीधे चलाए जा सकते हैं?

नहीं, ExoPlayer, YouTube से वीडियो नहीं चला सकता. जैसे, इस फ़ॉर्मैट के यूआरएल https://www.youtube.com/watch?v=.... इसके बजाय, आपको YouTube IFrame Player API का इस्तेमाल करना चाहिए. यह Android पर YouTube वीडियो चलाने का आधिकारिक तरीका है.

वीडियो रुक-रुक कर चल रहा है

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

अगर आपको Android 6.0 (एपीआई लेवल 23) से लेकर Android 11 (एपीआई लेवल 30) तक के किसी वर्शन पर चलने वाले डिवाइस पर वीडियो रुक-रुककर चलने की समस्या आ रही है, तो एसिंक्रोनस बफ़र क्यूइंग की सुविधा चालू करें. खास तौर पर, यह समस्या DRM से सुरक्षित या ज़्यादा फ़्रेम रेट वाला कॉन्टेंट चलाने पर आती है.

एपीआई लिंट की ऐसी गड़बड़ियां जो ठीक नहीं हुईं

Media3, एपीआई के सबसेट के लिए बाइनरी फ़ाइल के साथ काम करने की सुविधा की गारंटी देता है. जिन हिस्सों में बाइनरी कंपैटिबिलिटी की गारंटी नहीं दी जाती है उन्हें @UnstableApi के तौर पर मार्क किया जाता है. इस अंतर को साफ़ तौर पर समझाने के लिए, अस्थिर एपीआई सिंबल के इस्तेमाल से लिंट की गड़बड़ी जनरेट होती है. ऐसा तब तक होता है, जब तक उन्हें @OptIn के साथ एनोटेट नहीं किया जाता.

@UnstableApi एनोटेशन से, किसी एपीआई की क्वालिटी या परफ़ॉर्मेंस के बारे में कुछ भी पता नहीं चलता. इससे सिर्फ़ यह पता चलता है कि यह "एपीआई-फ़्रीज़" नहीं है.

एपीआई लिंट की ऐसी गड़बड़ियों को ठीक करने के लिए, आपके पास दो विकल्प हैं जो समय-समय पर बदलती रहती हैं:

  • ऐसे स्टेबल एपीआई का इस्तेमाल करें जिससे एक जैसा नतीजा मिले.
  • अस्थिर एपीआई का इस्तेमाल जारी रखें और @OptIn का इस्तेमाल करके, उसके इस्तेमाल के बारे में एनोटेट करें. इसके बारे में बाद में बताया गया है.
@OptIn एनोटेशन जोड़ना

Android Studio, एनोटेशन जोड़ने में आपकी मदद कर सकता है:

स्क्रीनशॉट: ऑप्ट-इन एनोटेशन जोड़ने का तरीका
दूसरी इमेज: Android Studio की मदद से @androidx.annotations.OptIn एनोटेशन जोड़ना.

Kotlin में, इस्तेमाल की गई कुछ साइटों को मैन्युअल तरीके से भी एनोटेट किया जा सकता है:

import androidx.annotation.OptIn
import androidx.media3.common.util.UnstableApi

@OptIn(UnstableApi::class)
fun functionUsingUnstableApi() { ... }

साथ ही, Java में भी:

import androidx.annotation.OptIn;
import androidx.media3.common.util.UnstableApi;

@OptIn(markerClass = UnstableApi.class)
private void methodUsingUnstableApis() { ... }

package-info.java फ़ाइल जोड़कर, पूरे पैकेज के लिए ऑप्ट-इन किया जा सकता है:

@OptIn(markerClass = UnstableApi.class)
package name.of.your.package;

import androidx.annotation.OptIn;
import androidx.media3.common.util.UnstableApi;

lint.xml फ़ाइल में लिंट की किसी खास गड़बड़ी को छिपाकर, पूरे प्रोजेक्ट के लिए ऑप्ट-इन किया जा सकता है:

 <?xml version="1.0" encoding="utf-8"?>
 <lint>
   <issue id="UnsafeOptInUsageError">
     <option name="opt-in" value="androidx.media3.common.util.UnstableApi" />
   </issue>
 </lint>

इसमें kotlin.OptIn एनोटेशन भी है, जिसका इस्तेमाल नहीं किया जाना चाहिए. androidx.annotation.OptIn एनोटेशन का इस्तेमाल करना ज़रूरी है.