প্রোডাক্ট সম্পর্কিত খবর

মিডিয়া প্লেব্যাক উন্নত করা: Media3-এর PreloadManager-এর খুঁটিনাটি - পর্ব ২

৯ মিনিট রিডিং
Mayuri Khinvasara Khabya-র প্রোফাইল দেখুন
Mayuri Khinvasara Khabya ডেভেলপার রিলেশন ইঞ্জিনিয়ার

Media3-এর মাধ্যমে মিডিয়া প্রি-লোডিং সংক্রান্ত তিন-পার্টের সিরিজের দ্বিতীয় পর্বে আপনাকে স্বাগত। এই সিরিজটি আপনার Android অ্যাপে অত্যন্ত রেসপন্সিভ, কম লেটেন্সি সহ মিডিয়া অভিজ্ঞতা তৈরি করার প্রসেস সম্পর্কে আপনাকে গাইড করার জন্য ডিজাইন করা হয়েছে।

  • পার্ট ১: Media3-এর মাধ্যমে প্রি-লোডিংয়ের ভূমিকা-এ প্রাথমিক বিষয়গুলি আলোচনা করা হয়েছে। আমরা সাধারণ প্লেলিস্টের জন্য PreloadConfiguration এবং ডায়নামিক ইউজার ইন্টারফেসের জন্য আরও শক্তিশালী DefaultPreloadManager-এর মধ্যে পার্থক্য এক্সপ্লোর করেছি। আপনি কীভাবে API লাইফসাইকেল প্রয়োগ করবেন তা শিখেছেন: add() ব্যবহার করে মিডিয়া যোগ করা, getMediaSource() ব্যবহার করে আগে থেকে তৈরি MediaSource পাওয়া, setCurrentPlayingIndex() ও invalidate() ব্যবহার করে অগ্রাধিকার ম্যানেজ করা এবং remove() ও release() ব্যবহার করে রিসোর্স রিলিজ করা।
  • পার্ট ২ (এই পোস্ট): এই ব্লগে, আমরা DefaultPreloadManager-এর উন্নত ক্ষমতা এক্সপ্লোর করি। আমরা PreloadManagerListener-এর মাধ্যমে কীভাবে ইনসাইট পাওয়া যায়, ExoPlayer-এর সাথে মূল কম্পোনেন্ট শেয়ার করার মতো প্রোডাকশন-রেডি পেশাদার পদ্ধতি প্রয়োগ করা যায় এবং মেমরি কার্যকরভাবে ম্যানেজ করার জন্য স্লাইডিং উইন্ডো প্যাটার্ন কীভাবে আয়ত্ত করা যায় তা কভার করি।
  • পার্ট ৩: এই সিরিজের শেষ পার্টে, পার্সিস্ট্যান্ট ডিস্ক ক্যাশের সাথে PreloadManager ইন্টিগ্রেট করার বিষয়ে বিস্তারিত আলোচনা করা হবে। এর ফলে, আপনি রিসোর্স ম্যানেজমেন্টের মাধ্যমে ডেটা ব্যবহার কমানো এবং বাধাহীন অভিজ্ঞতা প্রদান করতে পারবেন।

আপনি যদি Media3-তে প্রি-লোডিংয়ের ব্যাপারে নতুন হন, তাহলে এগিয়ে যাওয়ার আগে পার্ট ১ পড়ে নিলে ভালো হয়। যারা প্রাথমিক বিষয়গুলি পেরিয়ে আরও কিছু করতে চান, তাদের জন্য কীভাবে মিডিয়া প্লেব্যাক প্রয়োগ করার পদ্ধতি উন্নত করা যায় তা এক্সপ্লোর করা যাক।

শুনে নেওয়া: PreloadManagerListener-এর মাধ্যমে অ্যানালিটিক্স ফেচ করা

আপনি যখন প্রোডাকশনে কোনও ফিচার লঞ্চ করতে চান, তখন একজন অ্যাপ ডেভেলপার হিসেবে আপনি সেটির পেছনের অ্যানালিটিক্স বুঝতে ও ক্যাপচার করতে চান। বাস্তব জগতের পরিবেশে আপনার প্রি-লোডিং স্ট্র্যাটেজি কার্যকর হবে বলে আপনি কীভাবে নিশ্চিত হবেন? এর উত্তর দেওয়ার জন্য সাফল্যের হার, ব্যর্থতা ও পারফর্ম্যান্স সংক্রান্ত ডেটা প্রয়োজন। এই ডেটা সংগ্রহ করার প্রাথমিক মেকানিজম হল PreloadManagerListener ইন্টারফেস।

PreloadManagerListener দুটি গুরুত্বপূর্ণ কলব্যাক প্রদান করে যা প্রিলোডিং প্রসেস ও স্ট্যাটাস সম্পর্কে গুরুত্বপূর্ণ ইনসাইট প্রদান করে।

  • onCompleted(MediaItem mediaItem): আপনার TargetPreloadStatusControl-এ যেভাবে সংজ্ঞায়িত করা হয়েছে, সেই অনুযায়ী কোনও প্রি-লোড করার অনুরোধ সফলভাবে সম্পূর্ণ হলে এই কলব্যাকটি আহ্বান করা হয়।
  • onError(PreloadException error): এই কলব্যাক ডিবাগিং ও মনিটরিংয়ের জন্য সহায়ক হতে পারে। প্রিলোড করার প্রসেস ব্যর্থ হলে, এটি সংশ্লিষ্ট ব্যতিক্রম প্রদান করে।

নিচের উদাহরণ কোডে দেখানো হয়েছে, আপনি একটি পদ্ধতি কল করে লিসনার রেজিস্টার করতে পারবেন:

val preloadManagerListener = object : PreloadManagerListener {
    override fun onCompleted(mediaItem: MediaItem) {
        // Log success for analytics. 
        Log.d("PreloadAnalytics", "Preload completed for $mediaItem")
    }

    override fun onError( preloadError: PreloadException) {
        // Log the specific error for debugging and monitoring.
        Log.e("PreloadAnalytics", "Preload error ", preloadError)
    }
}

preloadManager.addListener(preloadManagerListener)

শ্রোতার থেকে ইনসাইট এক্সট্র্যাক্ট করা 

এইসব লিসনার কলব্যাক আপনার অ্যানালিটিক্স পাইপলাইনে হুক করা যেতে পারে। আপনার অ্যানালিটিক্স ইঞ্জিনে এইসব ইভেন্ট ফরওয়ার্ড করার মাধ্যমে, আপনি এই ধরনের গুরুত্বপূর্ণ প্রশ্নের উত্তর দিতে পারবেন:

  • আমাদের প্রি-লোড সাকসেস রেট কত? (মোট প্রি-লোড করার প্রচেষ্টার তুলনায় onCompleted ইভেন্টের অনুপাত)
  • কোন CDN বা ভিডিও ফর্ম্যাটে সবচেয়ে বেশি ত্রুটি দেখা যায়? (onError থেকে ব্যতিক্রম পার্স করে)
  • আমাদের প্রি-লোড ত্রুটির হার কত? (মোট প্রিলোড প্রচেষ্টার তুলনায় onError ইভেন্টের অনুপাত)

এই ডেটা আপনার প্রি-লোডিং স্ট্র্যাটেজি সম্পর্কে পরিমাণগত মতামত দিতে পারে, যা A/B টেস্টিং এবং ব্যবহারকারীর অভিজ্ঞতা আরও ভালো করার জন্য ডেটা-ভিত্তিক উন্নতি করতে সাহায্য করে। এই ডেটা আপনাকে বুদ্ধিদীপ্তভাবে আপনার প্রি-লোড করার সময়সীমা এবং প্রি-লোড করতে চাওয়া ভিডিওর সংখ্যা এবং বাফার অ্যালোকেট করার ব্যাপারে আরও সাহায্য করতে পারে।

ডিবাগিংয়ের বাইরে: UI ফলব্যাক করার জন্য onError ব্যবহার করা

প্রিলোড করা না গেলে, ব্যবহারকারীর জন্য আসন্ন বাফারিং ইভেন্টের একটি শক্তিশালী ইঙ্গিত পাওয়া যায়। onError কলব্যাক আপনাকে প্রতিক্রিয়া জানানোর সুযোগ দেয়। শুধু সমস্যার লগ না রেখে, আপনি UI-কে মানিয়ে নিতে পারেন। যেমন, আসন্ন ভিডিও প্রি-লোড করতে না পারলে, আপনার অ্যাপ্লিকেশন পরবর্তী সোয়াইপের জন্য অটোপ্লে বন্ধ করে দিতে পারে, যার ফলে প্লেব্যাক শুরু করার জন্য ব্যবহারকারীকে ট্যাপ করতে হবে।

এছাড়াও, PreloadException ধরনের সমস্যা পরীক্ষা করে আপনি আরও বুদ্ধিদীপ্ত রিট্রাই স্ট্র্যাটেজি নির্ধারণ করতে পারবেন। সমস্যার মেসেজ বা HTTP স্ট্যাটাস কোডের ভিত্তিতে কোনও অ্যাপ ম্যানেজার থেকে ব্যর্থ সোর্স অবিলম্বে সরিয়ে দেওয়ার বিকল্প বেছে নিতে পারে। ব্যবহারকারীর অভিজ্ঞতায় লোডিং সংক্রান্ত সমস্যা যাতে না হয়, সেই জন্য UI স্ট্রিম থেকে আইটেমটি সরিয়ে দিতে হবে। এছাড়াও, আপনি PreloadException থেকে আরও বিস্তারিত ডেটা পেতে পারেন, যেমন HttpDataSourceException, যাতে সমস্যার আরও গভীরে গিয়ে তদন্ত করা যায়। ExoPlayer সংক্রান্ত সমস্যার সমাধান সম্পর্কে আরও জানুন।

বাডি সিস্টেম: ExoPlayer-এর সাথে কম্পোনেন্ট শেয়ার করা কেন প্রয়োজন?

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

এই শেয়ারিং সহজ করার জন্য DefaultPreloadManager.Builder ডিজাইন করা হয়েছে এবং এতে আপনার PreloadManager ও লিঙ্ক করা প্লেয়ার ইনস্ট্যান্স, দু'টিই ইনস্ট্যানশিয়েট করার API আছে। BandwidthMeter, LoadControl, TrackSelector, Looper-এর মতো কম্পোনেন্ট কেন শেয়ার করতে হয় তা দেখা যাক। ExoPlayer Playback-এর সাথে এইসব কম্পোনেন্ট কীভাবে ইন্টার‍্যাক্ট করে তার ভিজ্যুয়াল উপস্থাপনা চেক করুন।

preloadManager2.png

শেয়ার করা BandwidthMeter-এর সাথে ব্যান্ডউইথ সংক্রান্ত সমস্যা প্রতিরোধ করা

BandwidthMeter, ঐতিহাসিক ট্রান্সফার রেটের উপর ভিত্তি করে উপলভ্য নেটওয়ার্ক ব্যান্ডউইথের একটি আনুমানিক হিসেব প্রদান করে। PreloadManager ও প্লেয়ার আলাদা আলাদা ইনস্ট্যান্স ব্যবহার করলে, তারা একে অপরের নেটওয়ার্ক অ্যাক্টিভিটি সম্পর্কে জানতে পারে না, এর ফলে সমস্যা হতে পারে। যেমন, এমন একটি পরিস্থিতি বিবেচনা করুন যেখানে একজন ব্যবহারকারী একটি ভিডিও দেখছেন, তার নেটওয়ার্ক কানেকশন খারাপ হয়ে গেছে এবং প্রি-লোডিং MediaSource একই সাথে ভবিষ্যতের ভিডিওর জন্য একটি আগ্রাসী ডাউনলোড শুরু করে। প্রিলোড করা MediaSource-এর অ্যাক্টিভিটি অ্যাক্টিভ প্লেয়ারের প্রয়োজনীয় ব্যান্ডউইথ ব্যবহার করে, এর ফলে বর্তমান ভিডিওটি আটকে যায়। প্লেব্যাকের সময় স্টল হয়ে যাওয়া ব্যবহারকারীর অভিজ্ঞতার ক্ষেত্রে একটি বড় সমস্যা।

একটি BandwidthMeter শেয়ার করার মাধ্যমে, TrackSelector, প্রি-লোডিং বা প্লেব্যাকের সময় বর্তমান নেটওয়ার্কের অবস্থা ও বাফারের অবস্থা অনুযায়ী সবচেয়ে ভালো কোয়ালিটির ট্র্যাক বেছে নিতে পারে। এরপরে, অ্যাক্টিভ প্লেব্যাক সেশন সুরক্ষিত রাখতে এবং মসৃণ অভিজ্ঞতা নিশ্চিত করতে এটি বুদ্ধিদীপ্ত সিদ্ধান্ত নিতে পারে।

preloadManagerBuilder.setBandwidthMeter(customBandwidthMeter)

ExoPlayer-এর শেয়ার করা LoadControl, TrackSelector, Renderer কম্পোনেন্ট ব্যবহার করে ধারাবাহিকতা নিশ্চিত করা

  • LoadControl: এই কম্পোনেন্ট বাফারিং নীতি নির্ধারণ করে, যেমন প্লেব্যাক শুরু করার আগে কত ডেটা বাফার করতে হবে এবং কখন আরও ডেটা লোড করা শুরু বা বন্ধ করতে হবে। LoadControl শেয়ার করার ফলে, প্লেয়ার ও PreloadManager-এর মেমরি ব্যবহারকে একটি কো-অর্ডিনেটেড বাফারিং স্ট্র্যাটেজি নির্দেশিত করে। এটি প্রি-লোড করা ও অ্যাক্টিভভাবে চালানো মিডিয়া, দু'টির ক্ষেত্রেই প্রযোজ্য। এর ফলে রিসোর্স সংক্রান্ত বিরোধ এড়ানো যায়। কন্টেন্ট ধারাবাহিকতা বজায় রাখতে, কতগুলি আইটেম কত সময়ের জন্য প্রি-লোড করছেন, সেই অনুযায়ী আপনাকে বুদ্ধি করে বাফার সাইজ বরাদ্দ করতে হবে। প্রতিযোগিতার সময়, প্লেয়ার স্ক্রিনে দেখানো বর্তমান আইটেম চালানোর ব্যাপারে অগ্রাধিকার দেবে। শেয়ার করা LoadControl-এর মাধ্যমে, প্লেব্যাকের জন্য লোডিং সম্পূর্ণ না হওয়া পর্যন্ত প্রিলোড ম্যানেজার প্রিলোড করা চালিয়ে যাবে, যতক্ষণ না প্রিলোডিংয়ের জন্য বরাদ্দ করা টার্গেট বাফার বাইট সর্বোচ্চ সীমায় পৌঁছে যায়।

মনে রাখবেন: Media3 (1.8)-এর লেটেস্ট ভার্সনে LoadControl শেয়ার করার ফলে, এর Allocator যে PreloadManager ও প্লেয়ারের সাথে সঠিকভাবে শেয়ার করা যাবে তা নিশ্চিত করা হয়। প্রিলোডিং কার্যকরভাবে কন্ট্রোল করার জন্য LoadControl ব্যবহার করা হল এমন একটি ফিচার যা আসন্ন Media3 1.9 রিলিজে উপলভ্য হবে।

preloadManagerBuilder.setLoadControl(customLoadControl)

  • TrackSelector: কোন ট্র্যাক (যেমন, নির্দিষ্ট রেজোলিউশনের ভিডিও, নির্দিষ্ট ভাষায় অডিও) লোড ও চালানো হবে তা বেছে নেওয়ার দায়িত্ব এই কম্পোনেন্টের। শেয়ার করার ফলে, প্রি-লোডিংয়ের সময় বেছে নেওয়া ট্র্যাকগুলিই প্লেয়ার ব্যবহার করবে। এর ফলে, এমন পরিস্থিতি এড়ানো যায় যেখানে একটি ৪৮০p ভিডিও ট্র্যাক প্রি-লোড করা হয়, কিন্তু প্লেব্যাক করার সময় প্লেয়ারটি অবিলম্বে সেটি বাতিল করে দেয় এবং ৭২০p ট্র্যাক ফেচ করে।< br /> প্রি-লোড ম্যানেজারকে প্লেয়ারের সাথে TrackSelector-এর একই ইনস্ট্যান্স শেয়ার করা উচিত নয়। পরিবর্তে, তাদের আলাদা TrackSelector ইনস্ট্যান্স ব্যবহার করা উচিত, তবে একই ইমপ্লিমেন্টেশন। এই কারণেই আমরা DefaultPreloadManager.Builder-এ TrackSelector-এর পরিবর্তে TrackSelectorFactory সেট করি।

preloadManagerBuilder.setTrackSelectorFactory(customTrackSelectorFactory)

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

preloadManagerBuilder.setRenderersFactory(customRenderersFactory)

আরও Exoplayer কম্পোনেন্ট সম্পর্কে পড়ুন।

গোল্ডেন রুল: সবকটি কন্ট্রোল করার জন্য একটি সাধারণ প্লেব্যাক লুপার

প্লেয়ার তৈরি করার সময় Looper পাস করার মাধ্যমে, ExoPlayer ইনস্ট্যান্স যে থ্রেডে অ্যাক্সেস করা যাবে তা স্পষ্টভাবে নির্দিষ্ট করা যেতে পারে। যে থ্রেড থেকে প্লেয়ার অ্যাক্সেস করতে হবে তার লুপার Player.getApplicationLooper ব্যবহার করে কোয়েরি করা যেতে পারে। প্লেয়ার ও PreloadManager-এর মধ্যে শেয়ার করা Looper বজায় রাখার মাধ্যমে, এটি নিশ্চিত করা হয় যে এইসব শেয়ার করা মিডিয়া অবজেক্টের সব অপারেশন একটি থ্রেডের মেসেজ কোয়ের মধ্যে সিরিয়ালাইজ করা হয়। এর ফলে কনকারেন্সি সংক্রান্ত বাগ কমে যেতে পারে।

লোড বা প্রি-লোড করার জন্য মিডিয়া সোর্সের সাথে PreloadManager ও প্লেয়ারের মধ্যে হওয়া সব ইন্টার‍্যাকশন একই প্লেব্যাক থ্রেডে হতে হবে। থ্রেড সুরক্ষিত রাখার জন্য Looper শেয়ার করা আবশ্যক এবং সেই কারণে PreloadManager ও প্লেয়ারের মধ্যে PlaybackLooper শেয়ার করতে হবে।

ব্যাকগ্রাউন্ডে PreloadManager একটি স্টেটফুল MediaSource অবজেক্ট প্রস্তুত করে। আপনার UI কোড player.setMediaSource(mediaSource) কল করলে, আপনি প্লেয়ারে প্রি-লোডিং MediaSource থেকে এই জটিল, স্টেটফুল অবজেক্টের হ্যান্ডঅফ পারফর্ম করছেন। এই পরিস্থিতিতে, সম্পূর্ণ PreloadMediaSource ম্যানেজার থেকে প্লেয়ারে সরানো হয়। এইসব ইন্টার‍্যাকশন ও হ্যান্ড-অফ একই PlaybackLooper-এ হতে হবে।

PreloadManager ও ExoPlayer আলাদা আলাদা থ্রেডে কাজ করলে, রেস কন্ডিশন হতে পারে। প্লেয়ারের থ্রেড ঠিক সেই মুহূর্তে MediaSource-এর ইন্টার্নাল স্টেট (যেমন, বাফারে নতুন ডেটা লেখা) থেকে রিড করার চেষ্টা করছে, যখন PreloadManager-এর থ্রেড সেটি পরিবর্তন করতে পারে। এর ফলে অপ্রত্যাশিত আচরণ, IllegalStateException হয় যা ডিবাগ করা কঠিন।

preloadManagerBuilder.setPreloadLooper(playbackLooper)

আসুন দেখা যাক, কীভাবে আপনি সেট-আপের মধ্যেই ExoPlayer ও DefaultPreloadManager-এর মধ্যে উপরের সবকটি কম্পোনেন্ট শেয়ার করতে পারবেন।

val preloadManagerBuilder =
DefaultPreloadManager.Builder(context, targetPreloadStatusControl)

// Optional - Share components between ExoPlayer and DefaultPreloadManager
preloadManagerBuilder
     .setBandwidthMeter(customBandwidthMeter)
     .setLoadControl(customLoadControl)
     .setMediaSourceFactory(customMediaSourceFactory)
     .setTrackSelectorFactory(customTrackSelectorFactory)
     .setRenderersFactory(customRenderersFactory)
     .setPreloadLooper(playbackLooper)

val preloadManager = val preloadManagerBuilder.build()

পরামর্শ: আপনি যদি ExoPlayer-এ DefaultLoadControl ইত্যাদির মতো ডিফল্ট কম্পোনেন্ট ব্যবহার করেন, তাহলে আপনাকে DefaultPreloadManager-এর সাথে সেগুলি স্পষ্টভাবে শেয়ার করতে হবে না। আপনি DefaultPreloadManager.Builder-এর buildExoPlayer-এর মাধ্যমে আপনার ExoPlayer ইনস্ট্যান্স তৈরি করলে, ডিফল্ট কনফিগারেশনের সাথে ডিফল্ট প্রয়োগ ব্যবহার করলে, এইসব কম্পোনেন্ট অটোমেটিক একে অপরের সাথে রেফারেন্স করা হয়। তবে, আপনি কাস্টম কম্পোনেন্ট বা কাস্টম কনফিগারেশন ব্যবহার করলে, উপরে উল্লেখ করা API-এর মাধ্যমে DefaultPreloadManager-কে সেই সম্পর্কে স্পষ্টভাবে জানাতে হবে।

প্রোডাকশন-রেডি প্রি-লোডিং: স্লাইডিং উইন্ডো প্যাটার্ন

ডায়নামিক ফিডে, ব্যবহারকারী কার্যত অসীম সংখ্যক কন্টেন্ট স্ক্রল করে দেখতে পারেন। আপনি যদি সংশ্লিষ্ট সরানোর কৌশল ছাড়াই DefaultPreloadManager-এ ক্রমাগত ভিডিও যোগ করেন, তাহলে অনিবার্যভাবে OutOfMemoryError হবে। প্রতিটি প্রি-লোডেড MediaSource একটি SampleQueue ধরে রাখে, যা মেমরি বাফার বরাদ্দ করে। এগুলি জমা হতে থাকলে, অ্যাপ্লিকেশনের হিপ স্পেস শেষ হয়ে যেতে পারে। এর সমাধান হল একটি অ্যালগরিদম, যার সাথে আপনি হয়ত আগেই পরিচিত, এটিকে স্লাইডিং উইন্ডো বলা হয়। স্লাইডিং উইন্ডো প্যাটার্ন মেমরিতে আইটেমের একটি ছোট, ম্যানেজ করা যায় এমন সেট বজায় রাখে যা ফিডে ব্যবহারকারীর বর্তমান পজিশনের সাথে লজিক্যালি অ্যাডেজেন্ট। ব্যবহারকারী স্ক্রল করার সাথে সাথে, ম্যানেজ করা আইটেমের এই "উইন্ডো" তাদের সাথে স্লাইড করে, নতুন আইটেম যোগ করে যা এখন দেখা যাচ্ছে এবং সেইসব আইটেম সরিয়ে দেয় যা এখন আর দেখা যাচ্ছে না।

slidingwindow.png

স্লাইডিং উইন্ডো প্যাটার্ন প্রয়োগ করা

এটি বোঝা গুরুত্বপূর্ণ যে PreloadManager কোনও বিল্ট-ইন setWindowSize() পদ্ধতি প্রদান করে না। স্লাইডিং উইন্ডো হল একটি ডিজাইন প্যাটার্ন যা আপনাকে, ডেভেলপারকে, আদিম add() এবং remove() পদ্ধতি ব্যবহার করে প্রয়োগ করার জন্য দায়ী। আপনার অ্যাপ্লিকেশন লজিককে অবশ্যই স্ক্রল বা পৃষ্ঠা পরিবর্তনের মতো UI ইভেন্টকে এইসব API কলের সাথে কানেক্ট করতে হবে। এর জন্য কোড রেফারেন্স চাইলে, আমাদের socialite স্যাম্পেলে এই স্লাইডিং উইন্ডো প্যাটার্ন প্রয়োগ করা আছে, এতে PreloadManagerWrapper-ও আছে যা স্লাইডিং উইন্ডোকে অনুকরণ করে।

ব্যবহারকারীর দেখার তালিকায় আইটেমটি আর শীঘ্রই দেখা যাবে না বলে মনে হলে, আপনার ইমপ্লিমেন্টেশনে preloadManager.remove(mediaItem) যোগ করতে ভুলবেন না। ব্যবহারকারীর কাছাকাছি নেই এমন আইটেম সরিয়ে দিতে না পারলে, প্রিলোডিং প্রয়োগ করার ক্ষেত্রে মেমরি সংক্রান্ত সমস্যার মূল কারণ এটিই। remove() কল নিশ্চিত করে যে রিসোর্স রিলিজ করা হয়েছে যা আপনার অ্যাপের মেমরি ব্যবহারকে সীমিত এবং স্থিতিশীল রাখতে সাহায্য করে।

TargetPreloadStatusControl-এর মাধ্যমে শ্রেণীবদ্ধ প্রিলোডিং স্ট্র্যাটেজি ফাইন-টিউন করা

কী কী প্রিলোড করতে হবে (আমাদের উইন্ডোতে থাকা আইটেম) তা আমরা নির্ধারণ করেছি, এখন প্রতিটি আইটেমের জন্য কতখানি প্রিলোড করতে হবে সেই বিষয়ে একটি সুনির্দিষ্ট স্ট্র্যাটেজি প্রয়োগ করতে পারি। পার্ট ১-এ TargetPreloadStatusControl সেট-আপের মাধ্যমে কীভাবে এই গ্র্যানুলারিটি অর্জন করা যায় তা আমরা আগেই দেখেছি।

মনে রাখবেন, +/- ১ পজিশনে থাকা আইটেম +/- ৪ পজিশনে থাকা আইটেমের তুলনায় বেশিবার প্লে হওয়ার সম্ভাবনা থাকে। ব্যবহারকারী পরবর্তীকালে যেসব আইটেম দেখতে পারেন সেগুলিতে আপনি আরও বেশি রিসোর্স (নেটওয়ার্ক, CPU, মেমরি) বরাদ্দ করতে পারেন। এটি নৈকট্যের উপর ভিত্তি করে একটি "প্রিলোডিং" কৌশল তৈরি করে, যা অবিলম্বে প্লেব্যাককে কার্যকর রিসোর্স ব্যবহারের সাথে ব্যালেন্স করার মূল চাবিকাঠি।

আপনার প্রি-লোড করার সময়সীমা সংক্রান্ত স্ট্র্যাটেজি ঠিক করতে, আগের বিভাগে আলোচনা করা PreloadManagerListener-এর মাধ্যমে অ্যানালিটিক্স ডেটা ব্যবহার করতে পারেন।

উপসংহার ও পরবর্তী ধাপ

Media3-এর DefaultPreloadManager ব্যবহার করে দ্রুত, স্থিতিশীল ও রিসোর্স-দক্ষ মিডিয়া ফিড তৈরি করার জন্য আপনি এখন উন্নত জ্ঞান অর্জন করেছেন।

গুরুত্বপূর্ণ বিষয়গুলি রিক্যাপ করা যাক:

  • অ্যানালিটিক্স ইনসাইট সংগ্রহ করতে এবং শক্তিশালী সমস্যা সমাধান প্রয়োগ করতে PreloadManagerListener ব্যবহার করুন।
  • গুরুত্বপূর্ণ কম্পোনেন্ট শেয়ার করা হচ্ছে কিনা তা নিশ্চিত করতে, আপনার ম্যানেজার ও প্লেয়ার ইনস্ট্যান্স তৈরি করার জন্য সবসময় একটি DefaultPreloadManager.Builder ব্যবহার করুন।
  • OutOfMemoryError এড়াতে add() এবং remove() কল অ্যাক্টিভভাবে ম্যানেজ করার মাধ্যমে স্লাইডিং উইন্ডো প্যাটার্ন প্রয়োগ করুন।
  • পারফর্ম্যান্স ও রিসোর্স ব্যবহারের মধ্যে ভারসাম্য বজায় রাখতে স্মার্ট, টিয়ার-ভিত্তিক প্রি-লোডিং স্ট্র্যাটেজি তৈরি করতে TargetPreloadStatusControl ব্যবহার করুন।

পার্ট ৩-এ এর পরে কী আছে: প্রিলোড করা মিডিয়া সহ ক্যাশিং

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

শেয়ার করার জন্য আপনার কোনও মতামত আছে? আপনার মতামত জানার জন্য আমরা উদগ্রীব।

সাথে থাকুন এবং আপনার ভিডিও প্লেব্যাক আরও দ্রুত করুন! 🚀

এর লেখা:
পড়া চালিয়ে যান