DefaultPreloadManager बनाएं और उसे कॉन्फ़िगर करें

इस पेज पर, DefaultPreloadManager बनाने का तरीका बताया गया है. यह आपकी चुनी गई रणनीति के आधार पर, आपके ऐप्लिकेशन के लिए मीडिया कॉन्टेंट को पहले से लोड करता है.

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

DefaultPreloadManager का इंस्टेंस बनाने के लिए, ये तीन चरण पूरे करें:

  • एक TargetPreloadStatusControl तय करें, जिसे प्रीलोड मैनेजर क्वेरी कर सकता है. इससे यह पता चलेगा कि मीडिया आइटम लोड करने के लिए तैयार है या नहीं और कितना लोड करना है.
  • बिल्डर बनाएं. इसका इस्तेमाल प्रीलोड मैनेजर बनाने के लिए किया जाएगा. साथ ही, इसका इस्तेमाल अपने ऐप्लिकेशन के ExoPlayer ऑब्जेक्ट बनाने के लिए भी किया जाएगा.
  • बिल्डर के build() तरीके को कॉल करके, प्रीलोड मैनेजर बनाने के लिए बिल्डर का इस्तेमाल करें.

पहले से लोड होने की सुविधा की स्थिति को टारगेट करने वाला कंट्रोल बनाना

DefaultPreloadManager.Builder बनाते समय, आपको इसे टारगेट प्रीलोड स्टेटस कंट्रोल ऑब्जेक्ट पास करना होगा. यह ऑब्जेक्ट, TargetPreloadStatusControl इंटरफ़ेस को लागू करता है. जब प्रीलोड मैनेजर, मीडिया को प्रीलोड करने की तैयारी कर रहा होता है, तब वह आपके स्टेटस कंट्रोल के getTargetPreloadStatus() तरीके को कॉल करता है. इससे यह तय किया जाता है कि किसी मीडिया आइटम के लिए कॉन्टेंट को तैयार करना है, लोड करना है या कैश मेमोरी में सेव करना है. प्रीलोडिंग, मीडिया डेटा को सीधे प्लेयर के इन-मेमोरी बफ़र में लोड करती है. इससे मीडिया डेटा तुरंत चलाने के लिए तैयार हो जाता है. वहीं, कैश मेमोरी में सेव करने की सुविधा, मीडिया डेटा को परसिस्टेंट डिस्क की कैश मेमोरी में सेव करती है, ताकि प्लेयर की मेमोरी को बचाया जा सके. स्टेटस कंट्रोल, इनमें से किसी एक स्टेटस कोड के साथ जवाब दे सकता है:

  • STAGE_SPECIFIED_RANGE_LOADED: प्रीलोड मैनेजर को, बताई गई शुरुआती पोज़िशन से और बताई गई अवधि (मिलीसेकंड में दी गई) तक के कॉन्टेंट को प्लेयर के इन-मेमोरी बफ़र में लोड करना चाहिए.
  • STAGE_SPECIFIED_RANGE_CACHED: प्रीलोड मैनेजर को, बताई गई शुरुआती पोज़िशन से लेकर बताई गई अवधि (मिलीसेकंड में दी गई है) तक के कॉन्टेंट को डिस्क की कैश मेमोरी में सेव करना चाहिए.
  • STAGE_TRACKS_SELECTED: प्रीलोड मैनेजर को कॉन्टेंट ट्रैक की जानकारी लोड और प्रोसेस करनी चाहिए. साथ ही, ट्रैक चुनने चाहिए. प्रीलोड मैनेजर को अभी कॉन्टेंट लोड करना शुरू नहीं करना चाहिए.
  • STAGE_SOURCE_PREPARED: प्रीलोड मैनेजर को कॉन्टेंट सोर्स तैयार करना चाहिए. उदाहरण के लिए, अगर कॉन्टेंट का मेटाडेटा किसी अलग मेनिफ़ेस्ट फ़ाइल में है, तो प्रीलोड मैनेजर उस मेनिफ़ेस्ट को फ़ेच और पार्स कर सकता है.
  • null: प्रीलोड मैनेजर को उस मीडिया आइटम के लिए कोई कॉन्टेंट या मेटाडेटा लोड नहीं करना चाहिए.

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

  • इंडेक्स n+1 (अगला मीडिया आइटम): डिफ़ॉल्ट शुरुआती पोज़िशन से 3000 मि॰से॰ (3 सेकंड) लोड करें
  • इंडेक्स n-1 (पिछला मीडिया आइटम): डिफ़ॉल्ट शुरुआती पोज़िशन से 1000 मि॰से॰ (एक सेकंड) लोड करें
  • रेंज n-2 से n+2 में मौजूद अन्य मीडिया आइटम: Return PreloadStatus.TRACKS_SELECTED
  • रेंज n-4 से n+4 में मौजूद अन्य मीडिया आइटम: PreloadStatus.SOURCE_PREPARED वैल्यू दिखाएं
  • अन्य सभी मीडिया आइटम के लिए, null वैल्यू दिखाएं

class MyTargetPreloadStatusControl(var currentPlayingIndex: Int = 0) :
  TargetPreloadStatusControl<Int, DefaultPreloadManager.PreloadStatus> {

  override fun getTargetPreloadStatus(index: Int): DefaultPreloadManager.PreloadStatus {
    if (index - currentPlayingIndex == 1) { // next track
      // return a PreloadStatus that is labelled by STAGE_SPECIFIED_RANGE_LOADED and
      // suggest loading 3000ms from the default start position
      return DefaultPreloadManager.PreloadStatus.specifiedRangeLoaded(3000L)
    } else if (index - currentPlayingIndex == -1) { // previous track
      // return a PreloadStatus that is labelled by STAGE_SPECIFIED_RANGE_LOADED and
      // suggest loading 3000ms from the default start position
      return DefaultPreloadManager.PreloadStatus.specifiedRangeLoaded(3000L)
    } else if (abs(index - currentPlayingIndex) == 2) {
      // return a PreloadStatus that is labelled by STAGE_TRACKS_SELECTED
      return DefaultPreloadManager.PreloadStatus.PRELOAD_STATUS_TRACKS_SELECTED
    } else if (abs(index - currentPlayingIndex) <= 4) {
      // return a PreloadStatus that is labelled by STAGE_SOURCE_PREPARED
      return DefaultPreloadManager.PreloadStatus.PRELOAD_STATUS_SOURCE_PREPARED
    }
    return DefaultPreloadManager.PreloadStatus.PRELOAD_STATUS_NOT_PRELOADED
  }
}

कोड के बारे में अहम बातें

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

प्रीलोड मैनेजर बनाना

प्रीलोड मैनेजर बनाने के लिए, आपको DefaultPreloadManager.Builder की ज़रूरत होगी. इस बिल्डर को मौजूदा कॉन्टेक्स्ट और ऐप्लिकेशन के टारगेट प्रीलोड स्टेटस कंट्रोल के साथ कॉन्फ़िगर किया जाता है. सभी डिफ़ॉल्ट कॉन्फ़िगरेशन के साथ प्रीलोड मैनेजर बनाया जा सकता है.

val targetPreloadStatusControl = MyTargetPreloadStatusControl()
val preloadManagerBuilder = DefaultPreloadManager.Builder(context, targetPreloadStatusControl)
val preloadManager = preloadManagerBuilder.build()

बिल्डर, सेटर के तरीके भी उपलब्ध कराता है. इनका इस्तेमाल, प्रीलोड मैनेजर के कस्टम कॉम्पोनेंट सेट करने के लिए किया जा सकता है.

उदाहरण के लिए, DefaultPreloadManager में सभी प्रीलोडिंग मीडिया सोर्स के लिए, टारगेट टोटल बफ़र बाइट को पसंद के मुताबिक बनाया जा सकता है. इससे, प्रीलोड किया गया डेटा उस सीमा से ज़्यादा नहीं होगा. setPlayerTargetBufferBytes(String, int) का इस्तेमाल करके, उस सीमा को कॉन्फ़िगर किया जा सकता है. इसके लिए, प्लेयर के नाम "preload" के साथ कस्टम DefaultLoadControl.Builder का इस्तेमाल करें. साथ ही, उस इंस्टेंस को प्रीलोड मैनेजर बिल्डर को पास करें:

val targetPreloadStatusControl = MyTargetPreloadStatusControl()
val preloadManagerBuilder = DefaultPreloadManager.Builder(context, targetPreloadStatusControl)

preloadManagerBuilder.setLoadControl(
  DefaultLoadControl.Builder()
    .setPlayerTargetBufferBytes("preload", 128 * 1024 * 1024) // 128 MiB
    .build()
)
val preloadManager = preloadManagerBuilder.build()

बिल्डर के सेटर तरीके, पसंद के मुताबिक बनाने के लिए ज़रूरी नहीं होते. हालांकि, अगर आपको किसी मीडिया आइटम को डिस्क में कैश मेमोरी में सेव करना है, तो आपको बिल्डर को Cache के साथ कॉन्फ़िगर करना होगा. इसके लिए, setCache() को कॉल करें. अगर कोई कैश मेमोरी कॉन्फ़िगर नहीं की गई है, तो मीडिया आइटम को कैश मेमोरी में सेव करने की कोशिश करने पर IllegalStateException दिखेगा.

प्रीलोड किए गए मीडिया आइटम को चलाने के लिए, ExoPlayer बनाएं

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

// Direct creation
val exoPlayer = preloadManagerBuilder.buildExoPlayer()

// Creation with custom playback specific configurations
val skipSilenceExoPlayerBuilder = ExoPlayer.Builder(context).setSkipSilenceEnabled(true)
val skipSilenceExoPlayer = preloadManagerBuilder.buildExoPlayer(skipSilenceExoPlayerBuilder)