মিডিয়া প্লেব্যাক উন্নত করা: Media3-এর সাথে প্রিলোডিংয়ের সুবিধা নিয়ে আসা - পার্ট ১
৮ মিনিট লাগবে
আজকের মিডিয়া-কেন্দ্রিক অ্যাপে, মসৃণ, নিরবচ্ছিন্ন প্লেব্যাকের অভিজ্ঞতা প্রদান করা হল ব্যবহারকারীর আনন্দদায়ক অভিজ্ঞতার চাবিকাঠি। ব্যবহারকারীরা আশা করেন যে তাদের ভিডিওগুলি অবিলম্বে শুরু হবে এবং বিরতি ছাড়াই নির্বিঘ্নে চলবে।
মূল চ্যালেঞ্জ হল লেটেন্সি। সাধারণত, ব্যবহারকারী প্লেব্যাকের জন্য কোনও আইটেম বেছে নেওয়ার পরেই ভিডিও প্লেয়ার কাজ শুরু করে—কানেক্ট করা, ডাউনলোড করা, পার্স করা, বাফার করা। আজকের স্বল্প দৈর্ঘ্যের ভিডিওর ক্ষেত্রে এই প্রতিক্রিয়াশীল পদ্ধতিটি ধীরগতির। সমাধান হল প্রোঅ্যাক্টিভ হওয়া। ব্যবহারকারী এর পরে কী দেখবেন তা আমাদের অনুমান করতে হবে এবং সময়ের আগেই কন্টেন্ট রেডি রাখতে হবে। এটিই হল প্রিলোডিংয়ের মূল কথা।
প্রি-লোডিংয়ের মূল সুবিধাগুলি হল:
- 🚀 আরও দ্রুত প্লেব্যাক শুরু: ভিডিওগুলি আগে থেকেই প্রস্তুত থাকে, যার ফলে আইটেমগুলির মধ্যে দ্রুত ট্রানজিশন এবং আরও দ্রুত শুরু হয়।
- 📉 কম বাফারিং: প্রোঅ্যাক্টিভভাবে ডেটা লোড করার মাধ্যমে, প্লেব্যাক বন্ধ হয়ে যাওয়ার সম্ভাবনা অনেক কম থাকে, যেমন নেটওয়ার্কের সমস্যার কারণে।
- ✨ এর ফলে ব্যবহারকারীর অভিজ্ঞতা আরও ভালো হয়: দ্রুত শুরু হওয়া এবং কম বাফারিংয়ের ফলে ব্যবহারকারীরা আরও সাবলীল ও নির্বিঘ্ন ইন্টার্যাকশন উপভোগ করতে পারেন।
তিনটি পর্বের এই সিরিজে, আমরা Media3-এর শক্তিশালী ইউটিলিটিগুলি (প্রি)লোডিং কম্পোনেন্টের জন্য কীভাবে ব্যবহার করা যায় তা বিস্তারিতভাবে আলোচনা করব।
- পার্ট ১-এ, আমরা ফাউন্ডেশন কভার করব: Media3-তে উপলভ্য বিভিন্ন প্রিলোডিং স্ট্র্যাটেজি বোঝা, PreloadConfiguration চালু করা এবং DefaultPreloadManager সেট-আপ করা, আপনার অ্যাপকে আইটেম প্রিলোড করার সুবিধা চালু করা। এই ব্লগটি পড়া শেষ করার পরে, আপনি নিজের কনফিগার করা র্যাংকিং ও সময়সীমা অনুযায়ী মিডিয়া আইটেম প্রিলোড ও চালাতে পারবেন।
- পার্ট ২-এ, আমরা DefaultPreloadManager-এর আরও উন্নত বিষয়গুলি নিয়ে আলোচনা করব: বিশ্লেষণের জন্য লিসেনার ব্যবহার করা, স্লাইডিং উইন্ডো প্যাটার্নের মতো প্রোডাকশন-রেডি পেশাদার পদ্ধতি এবং DefaultPreloadManager ও ExoPlayer-এর কাস্টম শেয়ার করা কম্পোনেন্ট এক্সপ্লোর করা।
- ৩য় ভাগে, আমরা DefaultPreloadManager-এর মাধ্যমে ডিস্ক ক্যাশিং সম্পর্কে বিস্তারিত জানব।
প্রিলোড করার সুবিধা! 🦸♀️
প্রিলোড করার মূল ধারণাটি সহজ: আপনার প্রয়োজন হওয়ার আগেই মিডিয়া কন্টেন্ট লোড করুন। ব্যবহারকারী পরবর্তী ভিডিওতে সোয়াইপ করার সময়, ভিডিওর প্রথম অংশটি ইতিমধ্যেই ডাউনলোড হয়ে যায় এবং উপলভ্য থাকে, যা অবিলম্বে প্লেব্যাকের জন্য প্রস্তুত।
এটিকে একটি রেস্তোরাঁর মতো ভাবুন। ব্যস্ত রান্নাঘরে পেঁয়াজ কাটার জন্য অর্ডারের অপেক্ষা করা হয় না। 🧅 তারা আগে থেকেই প্রস্তুতি নিয়ে রাখেন। প্রিলোড করা হল আপনার ভিডিও প্লেয়ারের জন্য প্রস্তুতিমূলক কাজ।
চালু করা থাকলে, প্লেব্যাক বাফার পরবর্তী আইটেমে পৌঁছানোর আগে ব্যবহারকারী পরবর্তী আইটেমে স্কিপ করলে, প্রিলোডিং জয়েন লেটেন্সি কমাতে সাহায্য করতে পারে। পরবর্তী উইন্ডোর প্রথম পিরিয়ড প্রস্তুত করা হয়েছে এবং ভিডিও, অডিও ও টেক্সট স্যাম্পেল বাফার করা হয়েছে। প্রি-লোড করা সময়সীমা পরে প্লেয়ারে সারিবদ্ধ করা হয় এবং বাফার করা স্যাম্পেল সাথে সাথে উপলভ্য হয় এবং রেন্ডার করার জন্য কোডেকে ফিড করার জন্য প্রস্তুত থাকে।
Media3-তে প্রিলোড করার জন্য দুটি প্রাথমিক API আছে, প্রতিটি আলাদা ব্যবহারের ক্ষেত্রে উপযুক্ত। সঠিক API বেছে নেওয়া হল প্রথম ধাপ।
১. PreloadConfiguration-এর মাধ্যমে প্লেলিস্ট আইটেম প্রিলোড করা হচ্ছে
এটি সহজ পদ্ধতি, প্লেলিস্টের মতো লিনিয়ার, সিকোয়েন্সিয়াল মিডিয়ার ক্ষেত্রে উপযোগী যেখানে প্লেব্যাক অর্ডার অনুমান করা যায় (যেমন, পর্বের সিরিজ)। ExoPlayer-এর প্লেলিস্ট API ব্যবহার করে আপনি প্লেয়ারকে মিডিয়া আইটেমের সম্পূর্ণ তালিকা দেন এবং প্লেয়ারের জন্য PreloadConfiguration সেট করেন, তারপর এটি কনফিগার করা ক্রম অনুযায়ী পরবর্তী আইটেম অটোমেটিক প্রিলোড করে। প্লেব্যাক বাফার পরবর্তী আইটেমে ওভারল্যাপ করার আগেই ব্যবহারকারী পরবর্তী আইটেমে স্কিপ করলে, এই API জয়েন লেটেন্সি অপ্টিমাইজ করার চেষ্টা করে।
চলমান প্লেব্যাকের জন্য কোনও মিডিয়া লোড না হলে তবেই প্রিলোডিং শুরু হয়, যা এটিকে প্রাথমিক প্লেব্যাকের সাথে ব্যান্ডউইথের জন্য প্রতিযোগিতা করতে বাধা দেয়।
আপনার প্রিলোডিং প্রয়োজন কিনা সেই ব্যাপারে এখনও নিশ্চিত না হলে, এই API হল এটি ব্যবহার করে দেখার জন্য একটি দুর্দান্ত লো-লিফ্ট বিকল্প!
player.preloadConfiguration =
PreloadConfiguration(/* targetPreloadDurationUs= */ 5_000_000L)উপরের PreloadConfiguration-এর মাধ্যমে, প্লেলিস্টের পরবর্তী আইটেমের জন্য প্লেয়ার পাঁচ সেকেন্ডের মিডিয়া প্রিলোড করার চেষ্টা করে।
একবার চালু করার পরে, প্লেলিস্ট প্রিলোড করার সুবিধা বন্ধ করতে PreloadConfiguration.DEFAULT ব্যবহার করে প্লেলিস্ট প্রিলোড করার সুবিধা আবার বন্ধ করা যেতে পারে:
player.preloadConfiguration = PreloadConfiguration.DEFAULT
২. PreloadManager-এর মাধ্যমে ডায়নামিক তালিকা প্রিলোড করা
ভার্টিক্যাল ফিড বা ক্যারোজেলের মতো ডাইনামিক UI-এর ক্ষেত্রে, যেখানে ব্যবহারকারীর ইন্টার্যাকশনের মাধ্যমে "পরবর্তী" আইটেম নির্ধারণ করা হয়, সেখানে PreloadManager API উপযুক্ত। এটি Media3 ExoPlayer লাইব্রেরির মধ্যে একটি নতুন শক্তিশালী, স্বতন্ত্র কম্পোনেন্ট যা বিশেষভাবে প্রোঅ্যাক্টিভভাবে প্রিলোড করার জন্য ডিজাইন করা হয়েছে। এটি সম্ভাব্য MediaSources-এর একটি সংগ্রহ ম্যানেজ করে, ব্যবহারকারীর বর্তমান অবস্থানের নৈকট্যের উপর ভিত্তি করে সেগুলিকে অগ্রাধিকার দেয় এবং কী প্রি-লোড করতে হবে তার উপর গ্র্যানুলার নিয়ন্ত্রণ অফার করে, যা শর্ট ফর্ম ভিডিওর ডাইনামিক ফিডের মতো জটিল পরিস্থিতির জন্য উপযুক্ত।
আপনার PreloadManager সেট-আপ করা
DefaultPreloadManager হল PreloadManager-এর ক্যানোনিকাল ইমপ্লিমেন্টেশন।
DefaultPreloadManager-এর বিল্ডার DefaultPreloadManager এবং যেকোনও ExoPlayer ইনস্ট্যান্স, দুটিই তৈরি করতে পারে যা এর প্রি-লোড করা কন্টেন্ট চালাবে। DefaultPreloadManager তৈরি করতে, আপনাকে TargetPreloadStatusControl পাস করতে হবে, যা প্রিলোড ম্যানেজার কোনও আইটেমের জন্য কতটা লোড করতে হবে তা খুঁজে বের করার জন্য কোয়েরি করতে পারে। নিচের বিভাগে আমরা TargetPreloadStatusControl-এর একটি উদাহরণ ব্যাখ্যা ও সংজ্ঞায়িত করব।
val preloadManagerBuilder = DefaultPreloadManager.Builder(context, targetPreloadStatusControl) val preloadManager = val preloadManagerBuilder.build() // Build ExoPlayer with DefaultPreloadManager.Builder val player = preloadManagerBuilder.buildExoPlayer()
ExoPlayer এবং DefaultPreloadManager, দুটির জন্যই একই বিল্ডার ব্যবহার করা প্রয়োজন, যা নিশ্চিত করে যে তাদের আন্ডার-দ্য-হুড কম্পোনেন্টগুলি সঠিকভাবে শেয়ার করা হয়েছে।
আর এইটুকুই! আপনার কাছে এখন একজন ম্যানেজার আছেন যিনি নির্দেশাবলী গ্রহণ করার জন্য প্রস্তুত।
TargetPreloadStatusControl-এর মাধ্যমে সময়সীমা ও র্যাংকিং কনফিগার করা
আপনি যদি ১০ সেকেন্ডের ভিডিও প্রিলোড করতে চান, তাহলে কী হবে? আপনি ক্যারোজেলে আপনার মিডিয়া আইটেমের পজিশন প্রদান করতে পারেন এবং ব্যবহারকারী বর্তমানে যে আইটেমটি চালাচ্ছেন তার কতটা কাছাকাছি এটি রয়েছে তার উপর ভিত্তি করে DefaultPreloadManager আইটেম লোড করার ক্ষেত্রে অগ্রাধিকার দেয়।
আপনি যদি আইটেমের কত সময় প্রিলোড করতে চান তা কন্ট্রোল করতে চান, তাহলে আপনি DefaultPreloadManager.PreloadStatus-এর মাধ্যমে তা জানাতে পারেন।
যেমন,
- আইটেম ‘A’ হল সবচেয়ে বেশি অগ্রাধিকার, ৫ সেকেন্ডের ভিডিও লোড করুন।
- আইটেম ‘খ’ মাঝারি অগ্রাধিকারের, তবে আপনি যখন এটিতে পৌঁছাবেন, তখন ৩ সেকেন্ডের ভিডিও লোড করুন।
- আইটেম ‘C’-এর অগ্রাধিকার কম, শুধু ট্র্যাক লোড করুন।
- আইটেম ‘D’-এর অগ্রাধিকার আরও কম, শুধু প্রস্তুত করুন।
- অন্য কোনও আইটেম অনেক দূরে আছে, কিছু প্রিলোড করবেন না।
এই গ্র্যানুলার কন্ট্রোল আপনাকে রিসোর্স ব্যবহার অপ্টিমাইজ করতে সাহায্য করতে পারে, যা নিরবচ্ছিন্ন প্লেব্যাকের জন্য সাজেস্ট করা হয়।
import androidx.media3.exoplayer.DefaultPreloadManager.PreloadStatus
class MyTargetPreloadStatusControl(
currentPlayingIndex: Int = C.INDEX_UNSET
) : TargetPreloadStatusControl<Int,PreloadStatus> {
// The app is responsible for updating this based on UI state
override fun getTargetPreloadStatus(index: Int): PreloadStatus? {
val distance = index - currentPlayingIndex
// Adjacent items (Next): preload 5 seconds
if (distance == 1) {
// Return a PreloadStatus that is labelled by STAGE_SPECIFIED_RANGE_LOADED and suggest loading // 5000ms from the default start position
return PreloadStatus.specifiedRangeLoaded(5000L)
}
// Adjacent items (Previous): preload 3 seconds
else if (distance == -1) {
// Return a PreloadStatus that is labelled by STAGE_SPECIFIED_RANGE_LOADED //and suggest loading 3000ms from the default start position
return PreloadStatus.specifiedRangeLoaded(3000L)
}
// Items two positions away: just select tracks
else if (distance) == 2) {
// Return a PreloadStatus that is labelled by STAGE_TRACKS_SELECTED
return PreloadStatus.TRACKS_SELECTED
}
// Items four positions away: just select prepare
else if (abs(distance) <= 4) {
// Return a PreloadStatus that is labelled by STAGE_SOURCE_PREPARED
return PreloadStatus.SOURCE_PREPARED
}
// All other items are too far away
return null
}
}পরামর্শ: PreloadManager পূর্ববর্তী এবং পরবর্তী উভয় আইটেমই প্রিলোড করে রাখতে পারে, যেখানে PreloadConfiguration শুধুমাত্র পরবর্তী আইটেমগুলি দেখবে।
প্রিলোড করা আইটেম ম্যানেজ করা
আপনার ম্যানেজার তৈরি হয়ে গেলে, আপনি তাকে বলতে পারেন যে কোন বিষয়ে কাজ করতে হবে। ব্যবহারকারী ফিড স্ক্রল করার সময়, আপনি আসন্ন ভিডিওগুলি শনাক্ত করবেন এবং সেগুলি ম্যানেজারে যোগ করবেন। PreloadManager-এর সাথে ইন্টার্যাকশন হল আপনার UI এবং প্রিলোডিং ইঞ্জিনের মধ্যে একটি স্টেট-চালিত কথোপকথন।
১. মিডিয়া আইটেম যোগ করুন
আপনার ফিড পপুলেট করার সময়, কোন মিডিয়া ট্র্যাক করতে হবে তা ম্যানেজারকে জানাতে হবে। আপনি শুরু করলে, আপনি যে সম্পূর্ণ তালিকাটি প্রিলোড করতে চান তা যোগ করতে পারেন। এরপর, আপনি প্রয়োজন অনুযায়ী তালিকায় একটি করে আইটেম যোগ করতে পারবেন। প্রি-লোডিং তালিকায় কোন কোন আইটেম থাকবে তার উপর আপনার সম্পূর্ণ নিয়ন্ত্রণ রয়েছে, যার অর্থ হল ম্যানেজার থেকে কী যোগ করা এবং সরানো হবে তাও আপনাকে ম্যানেজ করতে হবে।
val initialMediaItems = pullMediaItemsFromService(/* count= */ 20)
for (index in 0 until initialMediaItems.size) {
preloadManager.add(
initialMediaItems.get(index),index)
)
}ম্যানেজার এখন ব্যাকগ্রাউন্ডে এই MediaItem-এর জন্য ডেটা ফেচ করা শুরু করবে।
যোগ করার পরে, ম্যানেজারকে তার নতুন তালিকাটি পুনরায় মূল্যায়ন করতে বলুন (ইঙ্গিত করে যে কিছু পরিবর্তন হয়েছে যেমন কোনও আইটেম যোগ করা/ সরানো, বা ব্যবহারকারী একটি নতুন আইটেম চালানোর জন্য পরিবর্তন করেছেন।)
preloadManager.invalidate()
২. আইটেম ফিরিয়ে আনা ও চালানো
এখানে মূল প্লেব্যাক লজিক আসে। ব্যবহারকারী সেই ভিডিও চালানোর সিদ্ধান্ত নিলে, আপনাকে নতুন MediaSource তৈরি করতে হবে না। পরিবর্তে, আপনি PreloadManager-কে এমন একটির জন্য জিজ্ঞাসা করুন যা এটি আগে থেকেই প্রস্তুত করেছে। আপনি MediaItem ব্যবহার করে Preload Manager থেকে MediaSource ফিরিয়ে আনতে পারবেন।
PreloadManager থেকে পাওয়া আইটেম যদি null হয়, তাহলে বুঝতে হবে যে mediaItem এখনও প্রিলোড করা হয়নি বা PreloadMamager-এ যোগ করা হয়নি, তাই আপনি সরাসরি mediaItem সেট করার বিকল্প বেছে নিয়েছেন।
// When a media item is about to display on the screen
val mediaSource = preloadManager.getMediaSource(mediaItem)
if (mediaSource!= null) {
player.setMediaSource(mediaSource)
} else {
// If mediaSource is null, that mediaItem hasn't been added yet.
// So, send it directly to the player.
player.setMediaItem(mediaItem)
}
player.prepare()
// When the media item is displaying at the center of the screen
player.play()PreloadManager থেকে পাওয়া MediaSource প্রস্তুত করার মাধ্যমে, আপনি মেমরিতে আগে থেকেই থাকা ডেটা ব্যবহার করে, প্রিলোডিং থেকে প্লেব্যাকে নির্বিঘ্নে ট্রানজিশন করতে পারবেন। এর ফলে শুরুর সময় আরও দ্রুত হয়।
৩. UI-এর সাথে বর্তমান ইন্ডেক্স সিঙ্ক করে রাখুন
আমাদের ফিড / তালিকা ডাইনামিক হতে পারে, তাই আপনার বর্তমান প্লেয়িং ইনডেক্স সম্পর্কে PreloadManager-কে জানানো গুরুত্বপূর্ণ যাতে এটি সবসময় প্রিলোড করার জন্য আপনার বর্তমান ইনডেক্সের সবচেয়ে কাছের আইটেমকে অগ্রাধিকার দিতে পারে।
preloadManager.setCurrentPlayingIndex(currentIndex) // Need to call invalidate() to update the priorities preloadManager.invalidate()
৪. কোনও আইটেম সরানো
ম্যানেজারকে দক্ষ রাখতে, আপনার এমন আইটেমগুলি সরিয়ে ফেলা উচিত যা ট্র্যাক করার আর প্রয়োজন নেই, যেমন ব্যবহারকারীর বর্তমান অবস্থান থেকে অনেক দূরে থাকা আইটেম।
// When an item is too far from the current playing index preloadManager.remove(mediaItem)
একসাথে সব আইটেম মুছে ফেলতে চাইলে, আপনি preloadManager.reset() নম্বরে কল করতে পারেন।
৫. ম্যানেজারকে রিলিজ করুন
PreloadManager-এর আর প্রয়োজন না থাকলে (যেমন, আপনার UI নষ্ট হয়ে গেলে), আপনাকে অবশ্যই এটি রিলিজ করতে হবে যাতে এর রিসোর্স ফ্রি হয়ে যায়। আপনি যেখানে প্লেয়ারের রিসোর্স রিলিজ করছেন সেখানে এটি করলে ভাল হয়। প্লেয়ারের আগে ম্যানেজার রিলিজ করার সাজেশন দেওয়া হয়, কারণ আপনার আর প্রিলোডিংয়ের প্রয়োজন না হলে প্লেয়ার চালানো চালিয়ে যেতে পারে।
// In your Activity's onDestroy() or Composable's onDispose preloadManager.release()
ডেমো টাইম
এটি লাইভ অ্যাকশনে চেক করুন 👍
নিচের ডেমোতে, আমরা ডানদিকে PreloadManager-এর প্রভাব দেখতে পাচ্ছি, যেখানে লোড টাইম কম, আর বাঁদিকে বর্তমান অভিজ্ঞতা দেখানো হয়েছে। এছাড়াও, আপনি ডেমোর জন্য কোড স্যাম্পেল দেখতে পারেন। (বোনাস: এটি প্রতিটি ভিডিওর জন্য স্টার্টআপ লেটেন্সিও দেখায়)
এর পরে কী হবে?
আর পার্ট ১ এখানেই শেষ! আপনার কাছে এখন ডায়নামিক প্রিলোডিং সিস্টেম তৈরি করার টুল আছে। ExoPlayer-এ প্লেলিস্টের পরবর্তী আইটেম প্রিলোড করতে আপনি PreloadConfiguration ব্যবহার করতে পারেন অথবা DefaultPreloadManager সেট-আপ করতে পারেন, চটপট আইটেম যোগ করতে ও সরাতে পারেন, টার্গেট প্রিলোড স্ট্যাটাস কনফিগার করতে পারেন এবং প্লেব্যাকের জন্য প্রিলোড করা কন্টেন্ট সঠিকভাবে ফিরিয়ে আনতে পারেন।
পার্ট ২-এ, আমরা DefaultPreloadManager সম্পর্কে আরও গভীরে গিয়ে আলোচনা করব। আমরা প্রিলোডিং ইভেন্ট কীভাবে শুনতে হয় তা এক্সপ্লোর করব, মেমরি সংক্রান্ত সমস্যা এড়াতে স্লাইডিং উইন্ডো ব্যবহার করার মতো পেশাদার পদ্ধতি নিয়ে আলোচনা করব এবং ExoPlayer ও DefaultPreloadManager-এর কাস্টম শেয়ার করা কম্পোনেন্টগুলি দেখব।
আপনার কি কোনও মতামত শেয়ার করার আছে? আমরা আপনার মতামত জানার জন্য অধীর আগ্রহে অপেক্ষা করছি।
সাথে থাকুন এবং আপনার অ্যাপ আরও দ্রুত করুন! 🚀
-
প্রোডাক্ট সংক্রান্ত খবরMedia3-এর মাধ্যমে মিডিয়া প্রিলোড করার বিষয়ে আমাদের তিন-পার্টের সিরিজের দ্বিতীয় ইনস্টলমেন্টে আপনাকে স্বাগত। এই সিরিজটি আপনার Android অ্যাপে অত্যন্ত প্রতিক্রিয়াশীল, কম-লেটেন্সি মিডিয়া অভিজ্ঞতা তৈরি করার প্রক্রিয়ার মাধ্যমে আপনাকে গাইড করার জন্য ডিজাইন করা হয়েছে।
Mayuri Khinvasara Khabya • ৯ মিনিট পড়া -
প্রোডাক্ট সংক্রান্ত খবরএজেন্টিক ডেভেলপমেন্টের গতি বাড়ার সাথে সাথে, Android ইঞ্জিনিয়ারিং একটি নতুন দিগন্তে পৌঁছে যাচ্ছে: সহায়ক কোড সম্পূর্ণ করা থেকে শুরু করে আপনার নির্দেশনায় এন্ড-টু-এন্ড কাজ করা এজেন্ট পর্যন্ত। আপনি যে মডেল ও এজেন্ট ব্যবহার করেন, তার উপর আপনার সম্পূর্ণ নিয়ন্ত্রণ ও নমনীয়তা থাকে।
Jason Buchel • ৩ মিনিট রিডিং -
প্রোডাক্ট সংক্রান্ত খবরআজ আমরা শেয়ার করেছি যে কীভাবে আমরা আমাদের "স্টোরের চেয়েও বেশি কিছু" ভিশনকে পরবর্তী অধ্যায়ে নিয়ে যাচ্ছি। 'অ্যাকাউন্ট' ট্যাব থেকে, এখন ২৫০ মিলিয়নেরও বেশি মাসিক অ্যাক্টিভ ব্যবহারকারীর জন্য ব্যক্তিগত হোম বেস, আমাদের ইউনিফায়েড গেমিং প্ল্যাটফর্ম ৭০০ মিলিয়নেরও বেশি গেমার প্রোফাইলকে কানেক্ট করছে, Google Play ব্যবহারকারীদের যেখানেই থাকুক না কেন তাদের সাথে কানেক্ট করছে।
Paul Feng • ৩ মিনিট রিডিং
আপনার ইনবক্সে প্রতি সপ্তাহে Android ডেভেলপমেন্ট সংক্রান্ত লেটেস্ট ইনসাইট পান।