মিডিয়া ডাউনলোড করা হচ্ছে

ExoPlayer অফলাইন প্লেব্যাকের জন্য মিডিয়া ডাউনলোড করার কার্যকারিতা প্রদান করে। বেশিরভাগ ব্যবহারের ক্ষেত্রে, আপনার অ্যাপ ব্যাকগ্রাউন্ডে থাকলেও ডাউনলোডগুলি চালিয়ে যাওয়া বাঞ্ছনীয়৷ এই ব্যবহারের ক্ষেত্রে, আপনার অ্যাপটিকে DownloadService সাবক্লাস করা উচিত এবং ডাউনলোডগুলি যোগ, অপসারণ এবং নিয়ন্ত্রণ করতে পরিষেবাতে কমান্ড পাঠানো উচিত। নিম্নলিখিত চিত্রটি জড়িত প্রধান শ্রেণীগুলি দেখায়।

মিডিয়া ডাউনলোড করার জন্য ক্লাস। তীর নির্দেশাবলী তথ্য প্রবাহ নির্দেশ করে.

  • DownloadService : একটি DownloadManager মোড়ানো হয় এবং এটিতে কমান্ড ফরোয়ার্ড করে। অ্যাপটি ব্যাকগ্রাউন্ডে থাকলেও পরিষেবাটি DownloadManager চলতে দেয়।
  • DownloadManager : একাধিক ডাউনলোড পরিচালনা করে, একটি DownloadIndex থেকে (এবং থেকে) তাদের অবস্থা লোড করা (এবং সঞ্চয় করা), নেটওয়ার্ক সংযোগের মতো প্রয়োজনীয়তার উপর ভিত্তি করে ডাউনলোড শুরু করা এবং বন্ধ করা ইত্যাদি। বিষয়বস্তু ডাউনলোড করতে, ম্যানেজার সাধারণত HttpDataSource থেকে ডাউনলোড করা ডেটা পড়বেন এবং এটি একটি Cache লিখবেন।
  • DownloadIndex : ডাউনলোডের অবস্থা বজায় রাখে।

একটি ডাউনলোড সার্ভিস তৈরি করা হচ্ছে

একটি DownloadService তৈরি করতে, এটিকে সাবক্লাস করুন এবং এর বিমূর্ত পদ্ধতিগুলি প্রয়োগ করুন:

  • getDownloadManager() : ব্যবহার করা DownloadManager ফেরত দেয়।
  • getScheduler() : একটি ঐচ্ছিক Scheduler প্রদান করে, যা অগ্রগতির জন্য মুলতুবি ডাউনলোডগুলির প্রয়োজনীয়তা পূরণ হলে পরিষেবাটি পুনরায় চালু করতে পারে। ExoPlayer এই বাস্তবায়ন প্রদান করে:
    • PlatformScheduler , যা JobScheduler ব্যবহার করে (ন্যূনতম API হল 21)। অ্যাপের অনুমতির প্রয়োজনীয়তার জন্য PlatformScheduler javadocs দেখুন।
    • WorkManagerScheduler , যা WorkManager ব্যবহার করে।
  • getForegroundNotification() : পরিষেবাটি যখন অগ্রভাগে চলছে তখন প্রদর্শিত হবে এমন একটি বিজ্ঞপ্তি ফেরত দেয়। আপনি ডিফল্ট স্টাইলে একটি বিজ্ঞপ্তি তৈরি করতে 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 ইনস্ট্যান্টিয়েট করতে হয়, যা আপনার DownloadService getDownloadManager() দ্বারা ফেরত দেওয়া যেতে পারে:

কোটলিন

// 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

জাভা

// 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 এ পাঠান। অভিযোজিত স্ট্রিমগুলির জন্য, একটি DownloadRequest তৈরি করতে সাহায্য করতে DownloadHelper ব্যবহার করুন ৷ নিম্নলিখিত উদাহরণটি দেখায় কিভাবে একটি ডাউনলোড অনুরোধ তৈরি করতে হয়:

কোটলিন

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

জাভা

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

এই উদাহরণে, contentId হল বিষয়বস্তুর জন্য একটি অনন্য শনাক্তকারী। সাধারণ ক্ষেত্রে, contentUri প্রায়ই contentId হিসাবে ব্যবহার করা যেতে পারে, তবে অ্যাপগুলি তাদের ব্যবহারের ক্ষেত্রে সবচেয়ে উপযুক্ত আইডি স্কিমটি ব্যবহার করতে বিনামূল্যে। DownloadRequest.Builder কিছু ঐচ্ছিক সেটার আছে। উদাহরণস্বরূপ, setKeySetId এবং setData যথাক্রমে DRM এবং কাস্টম ডেটা সেট করতে ব্যবহার করা যেতে পারে যা অ্যাপটি ডাউনলোডের সাথে সংযুক্ত করতে চায়। বিষয়বস্তুর MIME প্রকার setMimeType ব্যবহার করেও নির্দিষ্ট করা যেতে পারে, যেখানে বিষয়বস্তুর ধরন contentUri থেকে অনুমান করা যায় না এমন ক্ষেত্রে একটি ইঙ্গিত হিসাবে।

একবার তৈরি হয়ে গেলে, ডাউনলোড যোগ করার জন্য DownloadService সার্ভিসে অনুরোধ পাঠানো যেতে পারে:

কোটলিন

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

জাভা

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

এই উদাহরণে, MyDownloadService হল অ্যাপের DownloadService সাবক্লাস, এবং foreground প্যারামিটার নিয়ন্ত্রণ করে যে পরিষেবাটি অগ্রভাগে শুরু হবে কিনা। যদি আপনার অ্যাপটি ইতিমধ্যেই ফোরগ্রাউন্ডে থাকে, তাহলে foreground প্যারামিটারটি সাধারণত false সেট করা উচিত কারণ DownloadService নিজেকে অগ্রভাগে রাখবে যদি এটি নির্ধারণ করে যে এটির কাজ আছে।

ডাউনলোডগুলি সরানো হচ্ছে

DownloadService একটি রিমুভ কমান্ড পাঠিয়ে একটি ডাউনলোড সরানো যেতে পারে, যেখানে contentId অপসারণ করা ডাউনলোডকে চিহ্নিত করে:

কোটলিন

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

জাভা

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

এছাড়াও আপনি DownloadService.sendRemoveAllDownloads এর মাধ্যমে ডাউনলোড করা সমস্ত ডেটা মুছে ফেলতে পারেন।

ডাউনলোড শুরু এবং বন্ধ করা

একটি ডাউনলোড শুধুমাত্র অগ্রগতি হবে যদি চারটি শর্ত পূরণ করা হয়:

  • ডাউনলোডের কোনো থামার কারণ নেই।
  • ডাউনলোড বিরাম দেওয়া হয় না.
  • ডাউনলোড অগ্রগতির জন্য প্রয়োজনীয়তা পূরণ করা হয়. প্রয়োজনীয়তাগুলি অনুমোদিত নেটওয়ার্ক প্রকারের সীমাবদ্ধতাগুলি নির্দিষ্ট করতে পারে, সেইসাথে ডিভাইসটি নিষ্ক্রিয় বা একটি চার্জারের সাথে সংযুক্ত হওয়া উচিত কিনা৷
  • সমান্তরাল ডাউনলোডের সর্বাধিক সংখ্যা অতিক্রম করা হয় না।

এই সমস্ত শর্ত আপনার DownloadService কমান্ড পাঠিয়ে নিয়ন্ত্রণ করা যেতে পারে।

ডাউনলোড বন্ধের কারণ নির্ধারণ এবং সাফ করা

এক বা সমস্ত ডাউনলোড বন্ধ হওয়ার কারণ সেট করা সম্ভব:

কোটলিন

// 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
)

জাভা

// 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 টিকে থাকে, এবং তাই যদি আবেদন প্রক্রিয়াটি শেষ হয়ে যায় এবং পরে পুনরায় আরম্ভ করা হয়।

সমস্ত ডাউনলোড বিরাম দেওয়া এবং পুনরায় শুরু করা হচ্ছে৷

সমস্ত ডাউনলোডগুলিকে থামানো এবং নিম্নরূপ পুনরায় শুরু করা যেতে পারে:

কোটলিন

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

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

জাভা

// 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 একটি কমান্ড পাঠিয়ে গতিশীলভাবে পরিবর্তন করা যেতে পারে:

কোটলিন

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

জাভা

// 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 সম্পূর্ণ বা ব্যর্থ হওয়া সহ সমস্ত ডাউনলোডের অবস্থার জন্য জিজ্ঞাসা করা যেতে পারে। DownloadManager.getDownloadIndex() কল করে DownloadIndex পাওয়া যাবে। একটি কার্সার যা সমস্ত ডাউনলোডের উপর পুনরাবৃত্তি করে তা DownloadIndex.getDownloads() কল করে প্রাপ্ত করা যেতে পারে। বিকল্পভাবে, DownloadIndex.getDownload() কল করে একটি একক ডাউনলোডের অবস্থা জিজ্ঞাসা করা যেতে পারে।

DownloadManager এছাড়াও DownloadManager.getCurrentDownloads() প্রদান করে, যা শুধুমাত্র ডাউনলোডের বর্তমান অবস্থা (অর্থাৎ সম্পূর্ণ বা ব্যর্থ) প্রদান করে। এই পদ্ধতিটি বর্তমান ডাউনলোডের অগ্রগতি এবং স্থিতি প্রদর্শন করে এমন বিজ্ঞপ্তি এবং অন্যান্য UI উপাদানগুলি আপডেট করার জন্য উপযোগী।

ডাউনলোড শুনছি

আপনি DownloadManager একজন শ্রোতাকে যোগ করতে পারেন যাতে বর্তমান ডাউনলোডের অবস্থা পরিবর্তন হয়:

কোটলিন

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

জাভা

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

একটি নির্দিষ্ট উদাহরণের জন্য ডেমো অ্যাপের DownloadTracker ক্লাসে DownloadManagerListener দেখুন।

ডাউনলোড করা সামগ্রী বাজানো হচ্ছে

ডাউনলোড করা বিষয়বস্তু প্লে করা অনলাইন বিষয়বস্তু খেলার অনুরূপ, যে ডেটা নেটওয়ার্কের পরিবর্তে ডাউনলোড Cache থেকে পড়া হয়।

ডাউনলোড করা বিষয়বস্তু চালানোর জন্য, ডাউনলোডের জন্য ব্যবহৃত একই Cache উদাহরণ ব্যবহার করে একটি CacheDataSource.Factory তৈরি করুন এবং প্লেয়ার তৈরি করার সময় এটিকে DefaultMediaSourceFactory এ ইনজেক্ট করুন:

কোটলিন

// 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()

জাভা

// 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 পাস করার মতোই সহজ। Download.request.toMediaItem ব্যবহার করে একটি Download থেকে বা সরাসরি DownloadRequest.toMediaItem ব্যবহার করে একটি DownloadRequest থেকে একটি MediaItem পাওয়া যেতে পারে।

মিডিয়াসোর্স কনফিগারেশন

পূর্ববর্তী উদাহরণটি সমস্ত MediaItem এর প্লেব্যাকের জন্য ডাউনলোড ক্যাশে উপলব্ধ করে। আপনি পৃথক MediaSource দৃষ্টান্তগুলির জন্য ডাউনলোড ক্যাশে উপলব্ধ করতে পারেন, যা সরাসরি প্লেয়ারে প্রেরণ করা যেতে পারে:

কোটলিন

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

জাভা

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

অ্যাডাপটিভ স্ট্রিম ডাউনলোড এবং প্লে করা হচ্ছে

অভিযোজিত স্ট্রীম (যেমন ড্যাশ, স্মুথস্ট্রিমিং এবং এইচএলএস) সাধারণত একাধিক মিডিয়া ট্র্যাক ধারণ করে। প্রায়শই একাধিক ট্র্যাক থাকে যেগুলিতে একই বিষয়বস্তু বিভিন্ন গুণাবলীতে থাকে (যেমন SD, HD এবং 4K ভিডিও ট্র্যাক)। একই ধরণের একাধিক ট্র্যাক থাকতে পারে যাতে বিভিন্ন বিষয়বস্তু থাকে (যেমন বিভিন্ন ভাষায় একাধিক অডিও ট্র্যাক)।

স্ট্রিমিং প্লেব্যাকের জন্য, কোন ট্র্যাকগুলি চালানো হবে তা চয়ন করতে একটি ট্র্যাক নির্বাচক ব্যবহার করা যেতে পারে। একইভাবে, ডাউনলোড করার জন্য, কোন ট্র্যাক ডাউনলোড করা হবে তা চয়ন করতে একটি DownloadHelper ব্যবহার করা যেতে পারে। একটি DownloadHelper সাধারণ ব্যবহার এই পদক্ষেপগুলি অনুসরণ করে:

  1. DownloadHelper.forMediaItem পদ্ধতিগুলির একটি ব্যবহার করে একটি DownloadHelper তৈরি করুন৷ সাহায্যকারী প্রস্তুত করুন এবং কলব্যাকের জন্য অপেক্ষা করুন।

    কোটলিন

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

    জাভা

    DownloadHelper downloadHelper =
       DownloadHelper.forMediaItem(
           context,
           MediaItem.fromUri(contentUri),
           new DefaultRenderersFactory(context),
           dataSourceFactory);
    downloadHelper.prepare(callback);
    
  2. ঐচ্ছিকভাবে, getMappedTrackInfo এবং getTrackSelections ব্যবহার করে ডিফল্ট নির্বাচিত ট্র্যাকগুলি পরিদর্শন করুন এবং clearTrackSelections , replaceTrackSelections এবং addTrackSelection ব্যবহার করে সমন্বয় করুন।
  3. getDownloadRequest কল করে নির্বাচিত ট্র্যাকগুলির জন্য একটি DownloadRequest তৈরি করুন। উপরে বর্ণিত, ডাউনলোড যোগ করার জন্য অনুরোধটি আপনার DownloadService পাঠানো যেতে পারে।
  4. release() ব্যবহার করে সাহায্যকারীকে ছেড়ে দিন।

ডাউনলোড করা অভিযোজিত বিষয়বস্তুর প্লেব্যাকের জন্য প্লেয়ার কনফিগার করা এবং সংশ্লিষ্ট MediaItem পাস করা প্রয়োজন, যেমন উপরে বর্ণিত হয়েছে।

MediaItem তৈরি করার সময়, MediaItem.localConfiguration.streamKeys অবশ্যই DownloadRequest সাথে মেলে যাতে প্লেয়ার শুধুমাত্র ডাউনলোড করা ট্র্যাকের উপসেটগুলি চালানোর চেষ্টা করে৷ MediaItem তৈরি করতে Download.request.toMediaItem এবং DownloadRequest.toMediaItem ব্যবহার করা আপনার জন্য এটির যত্ন নেবে৷