ExoPlayer সাধারণত ইন্টারনেটে মিডিয়া স্ট্রিম করার জন্য ব্যবহার করা হয়। এটি এর অন্তর্নিহিত নেটওয়ার্ক সংক্রান্ত অনুরোধ করার জন্য একাধিক নেটওয়ার্ক স্ট্যাককে সমর্থন করে। নেটওয়ার্ক স্ট্যাকের আপনার পছন্দের উপর স্ট্রিমিং পারফর্ম্যান্সের ক্ষেত্রে উল্লেখযোগ্য প্রভাব পড়তে পারে।
এই পৃষ্ঠায়, আপনার পছন্দমতো নেটওয়ার্ক স্ট্যাক ব্যবহার করার জন্য কীভাবে ExoPlayer কনফিগার করতে হয় তা বলা আছে, উপলভ্য বিকল্পের তালিকা দেওয়া আছে, আপনার অ্যাপের জন্য কীভাবে নেটওয়ার্ক স্ট্যাক বেছে নিতে হয় সেই বিষয়ে কিছু নির্দেশিকা দেওয়া আছে এবং স্ট্রিম করা মিডিয়ার জন্য কীভাবে ক্যাশিং চালু করতে হয় তা ব্যাখ্যা করা আছে।
নির্দিষ্ট নেটওয়ার্ক স্ট্যাক ব্যবহার করার জন্য ExoPlayer কনফিগার করা
ExoPlayer DataSource কম্পোনেন্টের মাধ্যমে ডেটা লোড করে, যা এটি
DataSource.Factory ইনস্ট্যান্স থেকে পায়, যা অ্যাপ কোড থেকে ইনজেক্ট করা হয়।
আপনার অ্যাপকে যদি শুধুমাত্র http(s) কন্টেন্ট চালাতে হয়, তাহলে নেটওয়ার্ক
স্ট্যাক বেছে নেওয়াটা ততটাই সহজ যতটা কোনও DataSource.Factory ইনস্ট্যান্স আপডেট করা, যেগুলি আপনার
অ্যাপ ইনজেক্ট করে যাতে সেগুলি HttpDataSource.Factory-এর ইনস্ট্যান্স হয়
যা আপনি ব্যবহার করতে চান সেই নেটওয়ার্ক স্ট্যাকের সাথে সম্পর্কিত। আপনার অ্যাপকে যদি
লোকাল ফাইলের মতো http(s) নয় এমন কন্টেন্টও চালাতে হয়, তাহলে
DefaultDataSource.Factoryএগুলি ব্যবহার করুন:
Kotlin
DefaultDataSource.Factory( context, /* baseDataSourceFactory= */ PreferredHttpDataSource.Factory(context), )
জাভা
new DefaultDataSource.Factory( context, /* baseDataSourceFactory= */ new PreferredHttpDataSource.Factory(context));
এই উদাহরণে, PreferredHttpDataSource.Factory হল আপনার
পছন্দের নেটওয়ার্ক স্ট্যাকের সাথে সম্পর্কিত ফ্যাক্টরি। DefaultDataSource.Factory লেয়ারটি লোকাল ফাইলের মতো
নন-http(s) সোর্সের জন্য সহায়তা যোগ করে।
নিচের উদাহরণে দেখানো হয়েছে যে কীভাবে এমন একটি ExoPlayer তৈরি করতে হয় যা Cronet
নেটওয়ার্ক স্ট্যাক ব্যবহার করবে এবং এছাড়াও, http(s) নয় এমন কন্টেন্ট প্লেব্যাক করার সুবিধা দেবে।
Kotlin
// Given a CronetEngine and Executor, build a CronetDataSource.Factory. val cronetDataSourceFactory = CronetDataSource.Factory(cronetEngine, executor) // Wrap the CronetDataSource.Factory in a DefaultDataSource.Factory, which adds // in support for requesting data from other sources (such as files, resources, // etc). val dataSourceFactory = DefaultDataSource.Factory(context, /* baseDataSourceFactory= */ cronetDataSourceFactory) // Inject the DefaultDataSource.Factory when creating the player. val player = ExoPlayer.Builder(context) .setMediaSourceFactory( DefaultMediaSourceFactory(context).setDataSourceFactory(dataSourceFactory) ) .build()
জাভা
// Given a CronetEngine and Executor, build a CronetDataSource.Factory. CronetDataSource.Factory cronetDataSourceFactory = new CronetDataSource.Factory(cronetEngine, executor); // Wrap the CronetDataSource.Factory in a DefaultDataSource.Factory, which adds // in support for requesting data from other sources (such as files, resources, // etc). DefaultDataSource.Factory dataSourceFactory = new DefaultDataSource.Factory( context, /* baseDataSourceFactory= */ cronetDataSourceFactory); // Inject the DefaultDataSource.Factory when creating the player. ExoPlayer player = new ExoPlayer.Builder(context) .setMediaSourceFactory( new DefaultMediaSourceFactory(context).setDataSourceFactory(dataSourceFactory)) .build();
মানানসই নেটওয়ার্ক স্ট্যাক
ExoPlayer, HttpEngine, Cronet, OkHttp এবং Android-এর বিল্ট-ইন ডিফল্ট নেটওয়ার্ক স্ট্যাকের জন্য সরাসরি সহায়তা প্রদান করে। এছাড়াও, ExoPlayer-কে এক্সটেন্ড করে Android-এ কাজ করে এমন অন্যান্য নেটওয়ার্ক স্ট্যাকের সাথে কাজ করার উপযোগী করে তোলা যায়।
HttpEngine
HttpEngine
API 34 (বা S
এক্সটেনশন ৭) থেকে Android-এ সাজেস্ট করা ডিফল্ট নেটওয়ার্ক স্ট্যাক। বেশিরভাগ ক্ষেত্রে, এটি ইন্টার্নালি Cronet নেটওয়ার্ক স্ট্যাক ব্যবহার করছে,
যা QUIC প্রোটোকলের মাধ্যমে HTTP, HTTP/2 ও HTTP/3-কে সাপোর্ট করে।
ExoPlayer-এর HttpEngineDataSource.Factory-এর সাথে HttpEngine কাজ করে। নির্দিষ্ট নেটওয়ার্ক স্ট্যাক ব্যবহার করার জন্য ExoPlayer কনফিগার করা
লিঙ্কে যেভাবে বর্ণনা করা হয়েছে, সেইভাবে আপনি
এই ডেটা সোর্স ফ্যাক্টরি ইনজেক্ট করতে পারবেন।
Cronet
Cronet হল Chromium নেটওয়ার্ক স্ট্যাক যা Android অ্যাপের জন্য লাইব্রেরি হিসেবে উপলভ্য। Cronet একাধিক টেকনোলজির সুবিধা নেয় যা লেটেন্সি কমায় এবং আপনার অ্যাপকে কাজ করার জন্য প্রয়োজনীয় নেটওয়ার্ক অনুরোধের থ্রুপুট বাড়ায়, এর মধ্যে ExoPlayer-এর করা অনুরোধও অন্তর্ভুক্ত। এটি নেটিভভাবে QUIC প্রোটোকলের মাধ্যমে HTTP, HTTP/2 এবং HTTP/3-কে সাপোর্ট করে। YouTube সহ বিশ্বের সবচেয়ে বড় স্ট্রিমিং অ্যাপের কিছু অ্যাপ Cronet ব্যবহার করে।
ExoPlayer-এ এর
Cronet লাইব্রেরির মাধ্যমে Cronet কাজ করে।
এটি কীভাবে ব্যবহার করতে হয় সেই সম্পর্কে বিস্তারিত নির্দেশাবলী পেতে লাইব্রেরির README.md দেখুন। মনে রাখবেন, Cronet লাইব্রেরি তিনটি অন্তর্নিহিত Cronet
ইমপ্লিমেন্টেশন ব্যবহার করতে পারে:
- Google Play পরিষেবা: আমরা বেশিরভাগ
ক্ষেত্রে এই প্রয়োগ ব্যবহার করার জন্য সাজেস্ট করি এবং Google Play পরিষেবা উপলভ্য না থাকলে Android-এর বিল্ট-ইন নেটওয়ার্ক স্ট্যাক
(
DefaultHttpDataSource) ব্যবহার করুন। - Cronet এম্বেড করা: আপনার ব্যবহারকারীদের মধ্যে যদি বেশিরভাগই এমন মার্কেটে থাকেন যেখানে Google Play Services ব্যাপকভাবে উপলভ্য নয় অথবা আপনি যদি Cronet ইমপ্লিমেন্টেশনের ব্যবহৃত সঠিক ভার্সন নিয়ন্ত্রণ করতে চান, তাহলে এটি একটি ভাল বিকল্প হতে পারে। Cronet এম্বেডেড ব্যবহারের প্রধান অসুবিধা হল এটি আপনার অ্যাপে প্রায় ৮ এমবি যোগ করে।
- Cronet ফলব্যাক: Cronet-এর ফলব্যাক প্রয়োগ
Android-এর বিল্ট-ইন নেটওয়ার্ক স্ট্যাকের চারপাশে র্যাপার হিসেবে Cronet-এর API প্রয়োগ করে। এটি ExoPlayer-এর সাথে ব্যবহার করা উচিত নয়, কারণ Android-এর বিল্ট-ইন নেটওয়ার্ক স্ট্যাক
সরাসরি (
DefaultHttpDataSourceব্যবহার করে) ব্যবহার করা আরও বেশি কার্যকর।
OkHttp
OkHttp হল আরেকটি আধুনিক নেটওয়ার্ক স্ট্যাক যা অনেক জনপ্রিয় Android অ্যাপে ব্যাপকভাবে ব্যবহার করা হয়। এটি HTTP এবং HTTP/2-এ কাজ করে, তবে এখনও QUIC-এর মাধ্যমে HTTP/3-এ কাজ করে না।
ExoPlayer-এর
OkHttp লাইব্রেরির মাধ্যমে OkHttp কাজ করে।
এটি কীভাবে ব্যবহার করতে হয় সেই সম্পর্কে বিস্তারিত নির্দেশাবলী পেতে লাইব্রেরির README.md দেখুন। OkHttp লাইব্রেরি ব্যবহার করার সময়, নেটওয়ার্ক স্ট্যাক অ্যাপের
মধ্যে এম্বেড করা থাকে। এটি Cronet এম্বেড করা থাকার মতোই, তবে OkHttp অনেক
ছোট, এটি আপনার অ্যাপে ১MB-এর কম সাইজ যোগ করে।
Android-এর বিল্ট-ইন নেটওয়ার্ক স্ট্যাক
ExoPlayer, Android-এর বিল্ট-ইন নেটওয়ার্ক স্ট্যাকের সাথে
DefaultHttpDataSource এবং DefaultHttpDataSource.Factory ব্যবহার করা যায়, এগুলি হল
কোর ExoPlayer লাইব্রেরির অংশ।
আসল নেটওয়ার্ক স্ট্যাকের প্রয়োগ নির্ভর করে অন্তর্নিহিত ডিভাইসে চলমান সফ্টওয়্যারের উপর। বেশিরভাগ ডিভাইসে শুধুমাত্র HTTP কাজ করে (অর্থাৎ, QUIC-এর মাধ্যমে HTTP/2 ও HTTP/3 কাজ করে না)।
অন্যান্য নেটওয়ার্ক স্ট্যাক
এছাড়াও, অ্যাপ ExoPlayer-এর সাথে অন্যান্য নেটওয়ার্ক স্ট্যাক ইন্টিগ্রেট করতে পারে।
এটি করতে, একটি HttpDataSource প্রয়োগ করুন যা সংশ্লিষ্ট HttpDataSource.Factory-এর সাথে
নেটওয়ার্ক স্ট্যাককে র্যাপ করে। এটি কীভাবে করতে হয় তার ভালো উদাহরণ হল ExoPlayer-এর Cronet এবং
OkHttp লাইব্রেরি।
সম্পূর্ণ Java নেটওয়ার্ক স্ট্যাকের সাথে ইন্টিগ্রেট করার সময়, আপনার HttpDataSource প্রয়োগ
সঠিকভাবে কাজ করছে কিনা তা চেক করতে একটি
DataSourceContractTest প্রয়োগ করা ভাল। OkHttp লাইব্রেরিতে OkHttpDataSourceContractTest হল
এটি কীভাবে করতে হয় তার একটি ভাল উদাহরণ।
নেটওয়ার্ক স্ট্যাক বেছে নেওয়া
নিচের টেবিলে ExoPlayer-এর সাথে কাজ করে এমন নেটওয়ার্ক স্ট্যাকের সুবিধা ও অসুবিধাগুলি সংক্ষেপে তুলে ধরা হয়েছে।
| নেটওয়ার্ক স্ট্যাক | প্রোটোকল | APK সাইজের প্রভাব | নোট |
|---|---|---|---|
| HttpEngine | HTTP HTTP/2 HTTP/3 ওভার QUIC |
কোনওটিই নয় | শুধুমাত্র API 34 বা S এক্সটেনশন 7-এ উপলভ্য |
| Cronet (Google Play পরিষেবা) | HTTP HTTP/2 HTTP/3 ওভার QUIC |
ছোট (<১০০কেবি) |
Google Play পরিষেবা থাকতে হবে। Cronet ভার্সন অটোমেটিক আপডেট হয়েছে |
| Cronet (এম্বেড করা) | HTTP HTTP/2 HTTP/3 ওভার QUIC |
বড় (~৮ এমবি) |
অ্যাপ ডেভেলপার দ্বারা নিয়ন্ত্রিত Cronet ভার্সন |
| Cronet (ফলব্যাক) | HTTP (ডিভাইস অনুযায়ী আলাদা হয়) |
ছোট (<১০০কেবি) |
ExoPlayer-এর জন্য সাজেস্ট করা হয় না |
| OkHttp | HTTP HTTP/2 |
ছোট (<১এমবি) |
|
| বিল্ট-ইন নেটওয়ার্ক স্ট্যাক | HTTP (ডিভাইস অনুযায়ী আলাদা হয়) |
কোনওটিই নয় | ডিভাইস অনুযায়ী প্রয়োগ আলাদা আলাদা হয় |
QUIC প্রোটোকলের মাধ্যমে HTTP/2 ও HTTP/3, মিডিয়া স্ট্রিমিং পারফর্ম্যান্স উল্লেখযোগ্যভাবে উন্নত করতে পারে। বিশেষ করে, কন্টেন্ট ডিস্ট্রিবিউশন নেটওয়ার্ক (CDN) ব্যবহার করে ডিস্ট্রিবিউট করা অ্যাডাপ্টিভ মিডিয়া স্ট্রিম করার সময়, এমন কিছু ক্ষেত্রে এই প্রোটোকল ব্যবহার করা যেতে পারে যেখানে CDN আরও বেশি দক্ষতার সাথে কাজ করতে পারে। এই কারণে, QUIC-এর মাধ্যমে HTTP/2 ও HTTP/3 উভয় প্রোটোকলের জন্য HttpEngine ও Cronet-এর সহায়তা (এবং HTTP/2-এর জন্য OkHttp-এর সহায়তা), Android-এর বিল্ট-ইন নেটওয়ার্ক স্ট্যাক ব্যবহার করার তুলনায় একটি বড় সুবিধা, তবে কন্টেন্ট হোস্ট করা সার্ভারকেও এইসব প্রোটোকল মেনে চলতে হবে।
আলাদাভাবে মিডিয়া স্ট্রিমিংয়ের কথা বিবেচনা করলে, আমরা Google Play Services-এর দেওয়া HttpEngine বা
Cronet ব্যবহার করার সাজেশন দিই। Google Play Services উপলভ্য না থাকলে DefaultHttpDataSource
এগুলি ব্যবহার করা যায়। এই সাজেশনটি বেশিরভাগ ডিভাইসে QUIC-এর মাধ্যমে HTTP/2 ও HTTP/3 ব্যবহার করার সুবিধা চালু করা এবং
APK সাইজ উল্লেখযোগ্যভাবে বৃদ্ধি না করার মধ্যে একটি ভালো
ভারসাম্য বজায় রাখে। এই সাজেশনের কিছু
ব্যতিক্রম আছে। যেসব ক্ষেত্রে Google Play পরিষেবা আপনার অ্যাপ রান করা ডিভাইসের
একটি উল্লেখযোগ্য অংশে উপলভ্য নাও থাকতে পারে,
সেখানে Cronet Embedded বা OkHttp ব্যবহার করা আরও উপযুক্ত হতে পারে। APK সাইজ যদি খুব গুরুত্বপূর্ণ বিষয় হয় অথবা মিডিয়া
স্ট্রিমিং যদি আপনার অ্যাপের কার্যকারিতার একটি ছোট অংশ হয়, তাহলে বিল্ট-ইন
নেটওয়ার্ক স্ট্যাক ব্যবহার করা যেতে পারে।
শুধু মিডিয়া নয়, আপনার অ্যাপের করা সমস্ত নেটওয়ার্কিংয়ের জন্য একটি নেটওয়ার্ক স্ট্যাক বেছে নেওয়া সাধারণত ভাল আইডিয়া। এটি রিসোর্সকে (যেমন সকেট) দক্ষতার সাথে পুল করতে এবং ExoPlayer ও অন্যান্য অ্যাপ কম্পোনেন্টের মধ্যে শেয়ার করতে দেয়।
কারণ, আপনার অ্যাপকে সম্ভবত মিডিয়া প্লেব্যাকের সাথে সম্পর্কিত নয় এমন নেটওয়ার্কিং পারফর্ম করতে হবে। তাই, নেটওয়ার্ক স্ট্যাক বেছে নেওয়ার সময়, মিডিয়া স্ট্রিমিংয়ের জন্য উপরে দেওয়া আমাদের সাজেশন, নেটওয়ার্কিং পারফর্ম করে এমন অন্য কম্পোনেন্ট সংক্রান্ত প্রয়োজনীয়তা এবং আপনার অ্যাপের জন্য সেগুলির আপেক্ষিক গুরুত্ব বিবেচনা করতে হবে।
মিডিয়া ক্যাশে করা
নেটওয়ার্ক থেকে একই বাইট বারবার লোড করা এড়াতে, ExoPlayer ডিস্কে লোড করা বাইট ক্যাশে করার সুবিধা দেয়। বর্তমান মিডিয়াতে ফিরে যেতে বা একই আইটেম আবার চালাতে চাইলে এটি কাজে লাগে।
ক্যাশিংয়ের জন্য একটি ডেডিকেটেড ক্যাশে
ডাইরেক্টরি ও CacheDataSource.Factory-এর দিকে পয়েন্ট করা SimpleCache ইনস্ট্যান্স প্রয়োজন:
Kotlin
// Note: This should be a singleton in your app. val databaseProvider = StandaloneDatabaseProvider(context) // An on-the-fly cache should evict media when reaching a maximum disk space limit. val cache = SimpleCache(downloadDirectory, LeastRecentlyUsedCacheEvictor(maxBytes), databaseProvider) // Configure the DataSource.Factory with the cache and factory for the desired HTTP stack. val cacheDataSourceFactory = CacheDataSource.Factory().setCache(cache).setUpstreamDataSourceFactory(httpDataSourceFactory) // Inject the DefaultDataSource.Factory when creating the player. val player = ExoPlayer.Builder(context) .setMediaSourceFactory( DefaultMediaSourceFactory(context).setDataSourceFactory(cacheDataSourceFactory) ) .build()
জাভা
// Note: This should be a singleton in your app. DatabaseProvider databaseProvider = new StandaloneDatabaseProvider(context); // An on-the-fly cache should evict media when reaching a maximum disk space limit. Cache cache = new SimpleCache( downloadDirectory, new LeastRecentlyUsedCacheEvictor(maxBytes), databaseProvider); // Configure the DataSource.Factory with the cache and factory for the desired HTTP stack. DataSource.Factory cacheDataSourceFactory = new CacheDataSource.Factory() .setCache(cache) .setUpstreamDataSourceFactory(httpDataSourceFactory); // Inject the DefaultDataSource.Factory when creating the player. ExoPlayer player = new ExoPlayer.Builder(context) .setMediaSourceFactory( new DefaultMediaSourceFactory(context).setDataSourceFactory(cacheDataSourceFactory)) .build();