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
সাধারণ ব্যবহার এই পদক্ষেপগুলি অনুসরণ করে:
-
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);
- ঐচ্ছিকভাবে,
getMappedTrackInfo
এবংgetTrackSelections
ব্যবহার করে ডিফল্ট নির্বাচিত ট্র্যাকগুলি পরিদর্শন করুন এবংclearTrackSelections
,replaceTrackSelections
এবংaddTrackSelection
ব্যবহার করে সমন্বয় করুন। -
getDownloadRequest
কল করে নির্বাচিত ট্র্যাকগুলির জন্য একটিDownloadRequest
তৈরি করুন। উপরে বর্ণিত, ডাউনলোড যোগ করার জন্য অনুরোধটি আপনারDownloadService
পাঠানো যেতে পারে। -
release()
ব্যবহার করে সাহায্যকারীকে ছেড়ে দিন।
ডাউনলোড করা অভিযোজিত বিষয়বস্তুর প্লেব্যাকের জন্য প্লেয়ার কনফিগার করা এবং সংশ্লিষ্ট MediaItem
পাস করা প্রয়োজন, যেমন উপরে বর্ণিত হয়েছে।
MediaItem
তৈরি করার সময়, MediaItem.localConfiguration.streamKeys
অবশ্যই DownloadRequest
সাথে মেলে যাতে প্লেয়ার শুধুমাত্র ডাউনলোড করা ট্র্যাকের উপসেটগুলি চালানোর চেষ্টা করে৷ MediaItem
তৈরি করতে Download.request.toMediaItem
এবং DownloadRequest.toMediaItem
ব্যবহার করা আপনার জন্য এটির যত্ন নেবে৷