मीडिया डाउनलोड किया जा रहा है

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

मीडिया डाउनलोड करने की क्लास. ऐरो के निर्देश, डेटा के फ़्लो को दिखाते हैं.

  • DownloadService: DownloadManager को रैप करता है और निर्देशों को उस पर फ़ॉरवर्ड करता है. कॉन्टेंट बनाने यह सेवा, ऐप्लिकेशन के चालू रहने के दौरान भी DownloadManager को चालू रखने की अनुमति देती है बैकग्राउंड.
  • DownloadManager: कई डाउनलोड को मैनेज करता है, उन्हें लोड (और सेव) करता है DownloadIndex से (और तक) स्थितियां, इसके आधार पर डाउनलोड को शुरू और बंद करना ज़रूरतों के हिसाब से तय किया गया है. ऐप्लिकेशन डाउनलोड करने के लिए है, तो मैनेजर आम तौर पर HttpDataSource, और उसे Cache में लिखो.
  • DownloadIndex: डाउनलोड की गई फ़ाइल की स्थिति पर बनी रहती है.

DownloadService बनाया जा रहा है

DownloadService बनाने के लिए, इसे सब-क्लास करें और ऐब्स्ट्रैक्ट तरीके:

  • getDownloadManager(): इस्तेमाल की जाने वाली DownloadManager को दिखाता है.
  • getScheduler(): एक वैकल्पिक Scheduler देता है, जो किसी सेवा का इस्तेमाल कर सकती है. ExoPlayer से ये सुविधाएं मिलती हैं:
    • PlatformScheduler, जो JobScheduler (कम से कम एपीआई 21 है) का इस्तेमाल करता है. यहां जाएं: ऐप्लिकेशन अनुमति की ज़रूरी शर्तों के लिए PlatformScheduler javadocs.
    • WorkManagerScheduler, जो WorkManager का इस्तेमाल करता है.
  • getForegroundNotification(): यह कार्रवाई करने पर दिखने वाला सूचना सेवा फ़ोरग्राउंड में चल रही है. Google Analytics 4 पर माइग्रेट करने के लिए, DownloadNotificationHelper.buildProgressNotification डिफ़ॉल्ट स्टाइल में सूचना पाएं.

आखिर में, अपनी AndroidManifest.xml फ़ाइल में सेवा तय करें:

<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC"/>
<application>
  <service android:name="com.myapp.MyDownloadService"
      android:exported="false"
      android:foregroundServiceType="dataSync">
    <!-- This is needed for Scheduler -->
    <intent-filter>
      <action android:name="androidx.media3.exoplayer.downloadService.action.RESTART"/>
      <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
  </service>
</application>

ExoPlayer में DemoDownloadService और AndroidManifest.xml को देखें डेमो ऐप पर मिल सकता है.

डाउनलोड मैनेजर बनाना

नीचे दिया गया कोड स्निपेट, DownloadManager को इंस्टैंशिएट करने का तरीका बताता है, जिसे getDownloadManager(), DownloadService में जाकर वापस कर सकता है:

Kotlin

// Note: This should be a singleton in your app.
val databaseProvider = StandaloneDatabaseProvider(context)

// A download cache should not evict media, so should use a NoopCacheEvictor.
val downloadCache = SimpleCache(downloadDirectory, NoOpCacheEvictor(), databaseProvider)

// Create a factory for reading the data from the network.
val dataSourceFactory = DefaultHttpDataSource.Factory()

// Choose an executor for downloading data. Using Runnable::run will cause each download task to
// download data on its own thread. Passing an executor that uses multiple threads will speed up
// download tasks that can be split into smaller parts for parallel execution. Applications that
// already have an executor for background downloads may wish to reuse their existing executor.
val downloadExecutor = Executor(Runnable::run)

// Create the download manager.
val downloadManager =
  DownloadManager(context, databaseProvider, downloadCache, dataSourceFactory, downloadExecutor)

// Optionally, properties can be assigned to configure the download manager.
downloadManager.requirements = requirements
downloadManager.maxParallelDownloads = 3

Java

// Note: This should be a singleton in your app.
databaseProvider = new StandaloneDatabaseProvider(context);

// A download cache should not evict media, so should use a NoopCacheEvictor.
downloadCache = new SimpleCache(downloadDirectory, new NoOpCacheEvictor(), databaseProvider);

// Create a factory for reading the data from the network.
dataSourceFactory = new DefaultHttpDataSource.Factory();

// Choose an executor for downloading data. Using Runnable::run will cause each download task to
// download data on its own thread. Passing an executor that uses multiple threads will speed up
// download tasks that can be split into smaller parts for parallel execution. Applications that
// already have an executor for background downloads may wish to reuse their existing executor.
Executor downloadExecutor = Runnable::run;

// Create the download manager.
downloadManager =
    new DownloadManager(
        context, databaseProvider, downloadCache, dataSourceFactory, downloadExecutor);

// Optionally, setters can be called to configure the download manager.
downloadManager.setRequirements(requirements);
downloadManager.setMaxParallelDownloads(3);

अच्छे उदाहरण के लिए, डेमो ऐप्लिकेशन में DemoUtil पर जाएं.

डाउनलोड जोड़ना

डाउनलोड करने के लिए, DownloadRequest बनाएं और उसे अपने DownloadService. एडेप्टिव स्ट्रीम के लिए, का इस्तेमाल करें DownloadHelper DownloadRequest बनाएं. नीचे दिए गए उदाहरण में, डाउनलोड का अनुरोध करने का तरीका बताया गया है:

Kotlin

val downloadRequest = DownloadRequest.Builder(contentId, contentUri).build()

Java

DownloadRequest downloadRequest = new DownloadRequest.Builder(contentId, contentUri).build();

इस उदाहरण में, contentId, कॉन्टेंट के लिए एक यूनीक आइडेंटिफ़ायर है. आसान मामलों में, contentUri का इस्तेमाल अक्सर contentId के तौर पर किया जा सकता है. हालांकि, ऐप्लिकेशन बिना किसी शुल्क के इस्तेमाल किए जा सकते हैं उनके इस्तेमाल के उदाहरण के लिए, कोई भी आईडी स्कीम सबसे सही होती है. DownloadRequest.Builder में यह भी है कुछ वैकल्पिक सेटर. उदाहरण के लिए, setKeySetId और setData का इस्तेमाल इन कामों के लिए किया जा सकता है वह DRM और कस्टम डेटा सेट करें जिसे ऐप्लिकेशन डाउनलोड के साथ संबद्ध करना चाहता है, क्रम से. कॉन्टेंट के MIME टाइप को setMimeType का इस्तेमाल करके भी बताया जा सकता है, का इस्तेमाल उन मामलों में किया जाता है जहां contentUri से कॉन्टेंट टाइप का अनुमान नहीं लगाया जा सकता.

बनाने के बाद, DownloadService को अनुरोध भेजा जा सकता है, ताकि डाउनलोड:

Kotlin

DownloadService.sendAddDownload(
  context,
  MyDownloadService::class.java,
  downloadRequest,
  /* foreground= */ false
)

Java

DownloadService.sendAddDownload(
    context, MyDownloadService.class, downloadRequest, /* foreground= */ false);

इस उदाहरण में, MyDownloadService ऐप्लिकेशन की DownloadService सब-क्लास है, और foreground पैरामीटर से यह कंट्रोल होता है कि सेवा यहां शुरू होगी या नहीं होता है. अगर आपका ऐप्लिकेशन पहले से ही फ़ोरग्राउंड में है, तो foreground आम तौर पर, पैरामीटर false पर सेट होना चाहिए, क्योंकि DownloadService अगर उसे लगता है कि उसे कुछ काम करना है, तो वह खुद को फ़ोरग्राउंड में रख सकता है.

डाउनलोड की गई फ़ाइलें हटाई जा रही हैं

DownloadService को निकालें आदेश भेजकर किसी डाउनलोड को निकाला जा सकता है, जहां contentId निकाले जाने वाले डाउनलोड की पहचान करता है:

Kotlin

DownloadService.sendRemoveDownload(
  context,
  MyDownloadService::class.java,
  contentId,
  /* foreground= */ false
)

Java

DownloadService.sendRemoveDownload(
    context, MyDownloadService.class, contentId, /* foreground= */ false);

आप चाहें, तो इसका इस्तेमाल करके, डाउनलोड किए गए सभी डेटा को हटाया जा सकता है DownloadService.sendRemoveAllDownloads.

डाउनलोड शुरू और बंद करना

डाउनलोड सिर्फ़ तब ही होगा, जब ये चार शर्तें पूरी होंगी:

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

इन सभी शर्तों को अपने DownloadService.

डाउनलोड रोकने की वजहें सेट करना और मिटाना

एक या सभी डाउनलोड को रोकने की वजह सेट की जा सकती है:

Kotlin

// Set the stop reason for a single download.
DownloadService.sendSetStopReason(
  context,
  MyDownloadService::class.java,
  contentId,
  stopReason,
  /* foreground= */ false
)

// Clear the stop reason for a single download.
DownloadService.sendSetStopReason(
  context,
  MyDownloadService::class.java,
  contentId,
  Download.STOP_REASON_NONE,
  /* foreground= */ false
)

Java

// Set the stop reason for a single download.
DownloadService.sendSetStopReason(
    context, MyDownloadService.class, contentId, stopReason, /* foreground= */ false);

// Clear the stop reason for a single download.
DownloadService.sendSetStopReason(
    context,
    MyDownloadService.class,
    contentId,
    Download.STOP_REASON_NONE,
    /* foreground= */ false);

stopReason कोई भी गैर-शून्य मान हो सकता है (Download.STOP_REASON_NONE = 0 है एक विशेष वैल्यू होती है, जिसका मतलब है कि डाउनलोड रोका नहीं जाता). ऐसे ऐप्लिकेशन जिनमें ये चीज़ें हैं डाउनलोड रोकने की कई वजहों से, ट्रैक करने के लिए अलग-अलग वैल्यू इस्तेमाल की जा सकती हैं डाउनलोड बंद क्यों हो जाती है. सभी के लिए, बंद होने की वजह सेट करना और मिटाना डाउनलोड, किसी सुविधा के रुकने की वजह सेट और मिटाने की तरह ही काम करता है एक बार डाउनलोड किया जा सकता है. हालांकि, contentId को null पर सेट किया जाना चाहिए.

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

सभी डाउनलोड को रोकना और फिर से शुरू करना

डाउनलोड किए जाने वाले सभी वीडियो को इस तरह से रोका और फिर से शुरू किया जा सकता है:

Kotlin

// Pause all downloads.
DownloadService.sendPauseDownloads(
  context,
  MyDownloadService::class.java,
  /* foreground= */ false
)

// Resume all downloads.
DownloadService.sendResumeDownloads(
  context,
  MyDownloadService::class.java,
  /* foreground= */ false
)

Java

// Pause all downloads.
DownloadService.sendPauseDownloads(context, MyDownloadService.class, /* foreground= */ false);

// Resume all downloads.
DownloadService.sendResumeDownloads(context, MyDownloadService.class, /* foreground= */ false);

डाउनलोड रोकने पर, वे Download.STATE_QUEUED की स्थिति में रहेंगे. बंद करने की वजहें सेट करने के उलट, यह तरीका किसी भी स्थिति में लागू नहीं होता बदलाव. इससे सिर्फ़ DownloadManager के रनटाइम की स्थिति पर असर पड़ता है.

डाउनलोड को प्रोसेस करने के लिए ज़रूरी शर्तें सेट करना

Requirements का इस्तेमाल उन पाबंदियों के बारे में बताने के लिए किया जा सकता है जिन्हें पूरा करना ज़रूरी है डाउनलोड करें. कॉल करके ज़रूरी शर्तें तय की जा सकती हैं DownloadManager बनाते समय DownloadManager.setRequirements(), जैसा कि ऊपर उदाहरण दिया गया है. कोई निर्देश भेजकर, उन्हें डाइनैमिक तौर पर भी बदला जा सकता है DownloadService में:

Kotlin

// Set the download requirements.
DownloadService.sendSetRequirements(
  context, MyDownloadService::class.java, requirements, /* foreground= */ false)

Java

// Set the download requirements.
DownloadService.sendSetRequirements(
  context,
  MyDownloadService.class,
  requirements,
  /* foreground= */ false);

ज़रूरी शर्तें पूरी न होने की वजह से डाउनलोड नहीं हो सकता Download.STATE_QUEUED की स्थिति में होगा. 'नहीं मिला' के तौर पर क्वेरी कर सकते हैं DownloadManager.getNotMetRequirements() की ज़रूरी शर्तें.

समांतर डाउनलोड की अधिकतम संख्या सेट करना

कॉल करके पैरलल डाउनलोड की अधिकतम संख्या सेट की जा सकती है DownloadManager.setMaxParallelDownloads(). आम तौर पर, ऐसा तब किया जाता है, जब DownloadManager बनाकर, जैसा कि ऊपर उदाहरण में बताया गया है.

जब कोई डाउनलोड आगे नहीं बढ़ सकता, क्योंकि साथ-साथ डाउनलोड की जाने वाली फ़ाइलों की ज़्यादा से ज़्यादा संख्या है पहले से प्रगति पर हैं, यह Download.STATE_QUEUED स्थिति में होगा.

डाउनलोड की क्वेरी की जा रही है

सभी की स्थिति के लिए, DownloadManager के DownloadIndex से क्वेरी की जा सकती है इसमें वे डाउनलोड भी शामिल हैं जो पूरे हो चुके हैं या पूरे नहीं हो पाए हैं. DownloadIndex इसे DownloadManager.getDownloadIndex() पर कॉल करके पाया जा सकता है. उस कर्सर को डाउनलोड की गई फ़ाइलों को डाउनलोड करने के लिए, DownloadIndex.getDownloads(). इसके अलावा, सिंगल डाउनलोड की स्थिति DownloadIndex.getDownload() पर कॉल करके पूछताछ की जा सकती है.

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

डाउनलोड किए गए गानों को सुना जा रहा है

आपके पास DownloadManager को सुनने के लिए, लिसनर जोड़ने का विकल्प है, ताकि आपको पता चल सके कि हाल ही में क्या हुआ है डाउनलोड की स्थिति:

Kotlin

downloadManager.addListener(
  object : DownloadManager.Listener { // Override methods of interest here.
  }
)

Java

downloadManager.addListener(
    new DownloadManager.Listener() {
      // Override methods of interest here.
    });

इसके लिए डेमो ऐप्लिकेशन की DownloadTracker क्लास में DownloadManagerListener को देखें का एक अच्छा उदाहरण है.

डाउनलोड किया गया कॉन्टेंट चलाया जा रहा है

डाउनलोड किया गया कॉन्टेंट चलाना, ऑनलाइन कॉन्टेंट चलाने जैसा ही है. हालांकि, डेटा को नेटवर्क के बजाय, डाउनलोड Cache से पढ़ा जाता है.

डाउनलोड किया गया कॉन्टेंट चलाने के लिए, उसका इस्तेमाल करके CacheDataSource.Factory बनाएं Cache इंस्टेंस जिसका इस्तेमाल डाउनलोड करने के लिए किया गया था और इसे इंजेक्ट करें प्लेयर बनाते समय DefaultMediaSourceFactory:

Kotlin

// Create a read-only cache data source factory using the download cache.
val cacheDataSourceFactory: DataSource.Factory =
  CacheDataSource.Factory()
    .setCache(downloadCache)
    .setUpstreamDataSourceFactory(httpDataSourceFactory)
    .setCacheWriteDataSinkFactory(null) // Disable writing.

val player =
  ExoPlayer.Builder(context)
    .setMediaSourceFactory(
      DefaultMediaSourceFactory(context).setDataSourceFactory(cacheDataSourceFactory)
    )
    .build()

Java

// Create a read-only cache data source factory using the download cache.
DataSource.Factory cacheDataSourceFactory =
    new CacheDataSource.Factory()
        .setCache(downloadCache)
        .setUpstreamDataSourceFactory(httpDataSourceFactory)
        .setCacheWriteDataSinkFactory(null); // Disable writing.

ExoPlayer player =
    new ExoPlayer.Builder(context)
        .setMediaSourceFactory(
            new DefaultMediaSourceFactory(context).setDataSourceFactory(cacheDataSourceFactory))
        .build();

अगर उसी प्लेयर इंस्टेंस का इस्तेमाल, डाउनलोड नहीं किया गया कॉन्टेंट चलाने के लिए भी किया जाएगा तो CacheDataSource.Factory को रीड-ओनली के तौर पर कॉन्फ़िगर किया जाना चाहिए, ताकि डाउनलोड करने का भी ध्यान रखें.

प्लेयर के CacheDataSource.Factory के साथ कॉन्फ़िगर होने के बाद, यह काम करेगा वीडियो डाउनलोड करने के लिए, उनके पास डाउनलोड किए गए वीडियो का ऐक्सेस हो. तब कोई डाउनलोड चलाया जाता है इससे, खिलाड़ी को ज़रूरी MediaItem पास करना आसान हो जाता है. MediaItem Download.request.toMediaItem का इस्तेमाल करके, Download से हासिल किया जा सकता है या DownloadRequest.toMediaItem का इस्तेमाल करके, सीधे DownloadRequest से.

MediaSource कॉन्फ़िगरेशन

पहले दिए गए उदाहरण में, डाउनलोड की गई कैश मेमोरी को सभी के लिए उपलब्ध कराया जा सकता है MediaItem. आप डाउनलोड कैश मेमोरी को इनके लिए भी उपलब्ध करा सकते हैं: अलग-अलग MediaSource इंस्टेंस, जिन्हें सीधे प्लेयर को भेजा जा सकता है:

Kotlin

val mediaSource =
  ProgressiveMediaSource.Factory(cacheDataSourceFactory)
    .createMediaSource(MediaItem.fromUri(contentUri))
player.setMediaSource(mediaSource)
player.prepare()

Java

ProgressiveMediaSource mediaSource =
    new ProgressiveMediaSource.Factory(cacheDataSourceFactory)
        .createMediaSource(MediaItem.fromUri(contentUri));
player.setMediaSource(mediaSource);
player.prepare();

अडैप्टिव स्ट्रीम डाउनलोड करना और चलाना

अडैप्टिव स्ट्रीम (उदाहरण के लिए, डैश, स्मूदस्ट्रीमिंग, और एचएलएस) में आम तौर पर, कई अन्य मीडिया ट्रैक. अक्सर ऐसे कई ट्रैक होते हैं जिनमें एक जैसा कॉन्टेंट होता है अलग-अलग क्वालिटी के वीडियो (जैसे कि एसडी, एचडी, और 4K वीडियो ट्रैक). ऐसे लोग भी हो सकते हैं अलग-अलग कॉन्टेंट वाले एक ही टाइप के एक से ज़्यादा ट्रैक (उदाहरण के लिए, एक से ज़्यादा अलग-अलग भाषाओं में ऑडियो ट्रैक इस्तेमाल करता है).

प्लेबैक स्ट्रीमिंग के लिए, ट्रैक सिलेक्टर का इस्तेमाल करके यह चुना जा सकता है कि ट्रैक चलाए जाते हैं. इसी तरह, डाउनलोड करने के लिए, DownloadHelper का इस्तेमाल इन कामों के लिए किया जा सकता है चुनें कि कौनसे ट्रैक डाउनलोड किए जाएं. आम तौर पर, DownloadHelper का इस्तेमाल यह तरीका अपनाएं:

  1. DownloadHelper.forMediaItem में से किसी एक का इस्तेमाल करके DownloadHelper बनाएं तरीकों का इस्तेमाल करना होगा. हेल्पर को तैयार करें और कॉलबैक का इंतज़ार करें.

    Kotlin

    val downloadHelper =
     DownloadHelper.forMediaItem(
       context,
       MediaItem.fromUri(contentUri),
       DefaultRenderersFactory(context),
       dataSourceFactory
     )
    downloadHelper.prepare(callback)
    

    Java

    DownloadHelper downloadHelper =
       DownloadHelper.forMediaItem(
           context,
           MediaItem.fromUri(contentUri),
           new DefaultRenderersFactory(context),
           dataSourceFactory);
    downloadHelper.prepare(callback);
    
  2. इसके अलावा, getMappedTrackInfo का इस्तेमाल करके डिफ़ॉल्ट तौर पर चुने गए ट्रैक की जांच करें और getTrackSelections, और clearTrackSelections का इस्तेमाल करके बदलाव करें, replaceTrackSelections और addTrackSelection.
  3. कॉल करके चुने गए ट्रैक के लिए DownloadRequest बनाएं getDownloadRequest. अपने DownloadService को यह अनुरोध भेजा जा सकता है जैसा कि ऊपर बताया गया है, डाउनलोड जोड़ें.
  4. release() का इस्तेमाल करके, हेल्पर को छोड़ें.

ज़रूरत के हिसाब से डाउनलोड किए गए कॉन्टेंट को चलाने के लिए, प्लेयर को कॉन्फ़िगर करना और संबंधित MediaItem को पास करना होगा, जैसा कि ऊपर बताया गया है.

MediaItem बनाते समय, MediaItem.localConfiguration.streamKeys यह होना चाहिए DownloadRequest में दी गई जानकारी से मेल खाने के लिए सेट करें, ताकि खिलाड़ी सिर्फ़ डाउनलोड किए गए ट्रैक के सबसेट को चलाना. इसका इस्तेमाल किया जा रहा है Download.request.toMediaItem और DownloadRequest.toMediaItem MediaItem आपके लिए इसका ध्यान रखेगा.