মিডিয়া অ্যাপের সাথে কানেক্ট করার দুটি উপায় আছে:
MediaControllerMediaBrowser
MediaController
মিডিয়া কন্ট্রোলার মিডিয়া সেশনের সাথে ইন্টার্যাক্ট করে মিডিয়া অ্যাপের প্লেব্যাক কোয়েরি ও কন্ট্রোল করে। Media3-তে, MediaController API Player
ইন্টারফেস প্রয়োগ করে। মিডিয়া কন্ট্রোলার ব্যবহার করে এমন ক্লায়েন্ট অ্যাপের উদাহরণ:
- Android সিস্টেম মিডিয়া কন্ট্রোল
- Android Wear OS কম্প্যানিয়ন অ্যাপ
- Android Auto ও Automotive OS
- Google Assistant-এর মতো ভয়েস অ্যাসিস্ট্যান্ট
- মিডিয়া কন্ট্রোলার টেস্ট অ্যাপ
মিডিয়া অ্যাপের মধ্যেও মিডিয়া কন্ট্রোলার উপযোগী হতে পারে, যেমন প্লেয়ার ও মিডিয়া সেশন যদি Service-এ থাকে, যা UI সহ Activity বা Fragment থেকে আলাদা।
MediaController তৈরি করুন
MediaController তৈরি করতে, সংশ্লিষ্ট MediaSession-এর জন্য SessionToken তৈরি করে
শুরু করুন। আপনার Activity-এর onStart() পদ্ধতি বা
Fragment এর জন্য একটি ভালো জায়গা হতে পারে।
Kotlin
val sessionToken = SessionToken(context, ComponentName(context, PlaybackService::class.java))
জাভা
SessionToken sessionToken = new SessionToken(context, new ComponentName(context, PlaybackService.class));
এই SessionToken ব্যবহার করে MediaController তৈরি করলে, কন্ট্রোলারটি প্রদত্ত সেশনের সাথে কানেক্ট হয়ে যায়। এটি অ্যাসিঙ্ক্রোনাসভাবে ঘটে, তাই আপনাকে
ফলাফলের জন্য অপেক্ষা করতে হবে এবং উপলভ্য হলে এটি ব্যবহার করতে হবে।
Kotlin
val controllerFuture = MediaController.Builder(context, sessionToken).buildAsync() controllerFuture.addListener( { // MediaController is available here with controllerFuture.get() }, MoreExecutors.directExecutor(), )
জাভা
ListenableFuture<MediaController> controllerFuture = new MediaController.Builder(context, sessionToken).buildAsync(); controllerFuture.addListener( () -> { // MediaController is available here with controllerFuture.get() }, MoreExecutors.directExecutor());
MediaController ব্যবহার করুন
MediaController, Player ইন্টারফেস প্রয়োগ করে, তাই আপনি কানেক্ট করা MediaSession-এর প্লেব্যাক নিয়ন্ত্রণ করতে
ইন্টারফেসে নির্ধারিত কমান্ড ব্যবহার করতে পারবেন।
অর্থাৎ, MediaController-এ play() কল করলে কানেক্ট করা MediaSession-এ কমান্ড পাঠানো হবে,
যা পরে তার অন্তর্নিহিত Player-এ কমান্ড ডেলিগেট করবে।
Player স্ট্যাটাসে পরিবর্তন শোনার জন্য আপনি কন্ট্রোলারে Player.Listener যোগ করতে পারেন। Player.Listener ব্যবহার করার ব্যাপারে আরও জানতে প্লেয়ার ইভেন্ট সংক্রান্ত নির্দেশিকা দেখুন।
MediaController.Listener ইন্টারফেস ইভেন্টের জন্য অতিরিক্ত কলব্যাক এবং কানেক্ট করা MediaSession থেকে কাস্টম কমান্ড সংজ্ঞায়িত করে। উদাহরণ হল
onCustomCommand() সেশন কাস্টম কমান্ড পাঠালে,
onAvailableSessionCommandsChanged() সেশন উপলভ্য সেশন কমান্ড পরিবর্তন করলে
অথবা onDisconnected() সেশন থেকে কন্ট্রোলার ডিসকানেক্ট
হয়ে গেলে।
Builder-এর সাহায্যে কন্ট্রোলার তৈরি করার সময় MediaController.Listener সেট করা যেতে পারে:
Kotlin
val controllerFuture = MediaController.Builder(context, sessionToken) .setListener( object : MediaController.Listener { override fun onCustomCommand( controller: MediaController, command: SessionCommand, args: Bundle, ): ListenableFuture<SessionResult> { // Handle custom command. return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS)) } override fun onDisconnected(controller: MediaController) { // Handle disconnection. } } ) .buildAsync()
জাভা
ListenableFuture<MediaController> controllerFuture = new MediaController.Builder(context, sessionToken) .setListener( new MediaController.Listener() { @Override public ListenableFuture<SessionResult> onCustomCommand( MediaController controller, SessionCommand command, Bundle args) { // Handle custom command. return Futures.immediateFuture(new SessionResult(SessionResult.RESULT_SUCCESS)); } @Override public void onDisconnected(MediaController controller) { // Handle disconnection. } }) .buildAsync();
অন্যান্য কম্পোনেন্টের মতো, MediaController-এর আর প্রয়োজন না থাকলে, সেটি রিলিজ করতে ভুলবেন না, যেমন Activity বা Fragment-এর onStop() মেথডে।
Kotlin
MediaController.releaseFuture(controllerFuture)
জাভা
MediaController.releaseFuture(controllerFuture);
কন্ট্রোলার রিলিজ করে দিলেও সেশনে পাঠানো সব পেন্ডিং কমান্ড ডেলিভার করা হবে এবং এইসব কমান্ড ম্যানেজ করা হয়ে গেলে অথবা টাইম-আউট পিরিয়ড শেষ হয়ে গেলে, যেটি আগে হবে, তারপরেই সেশন সার্ভিস থেকে আনবাইন্ড করা হবে।
MediaBrowser
MediaBrowser, MediaController-এর অফার করা ক্ষমতার উপর ভিত্তি করে তৈরি করা হয়, যাতে মিডিয়া অ্যাপের MediaLibraryService-এর অফার করা মিডিয়া লাইব্রেরি ব্রাউজ করার সুবিধা চালু করা যায়।
MediaBrowser তৈরি করুন
Kotlin
val browserFuture = MediaBrowser.Builder(context, sessionToken).buildAsync() browserFuture.addListener( { // MediaBrowser is available here with browserFuture.get() }, MoreExecutors.directExecutor(), )
জাভা
ListenableFuture<MediaBrowser> browserFuture = new MediaBrowser.Builder(context, sessionToken).buildAsync(); browserFuture.addListener( () -> { // MediaBrowser is available here with browserFuture.get() }, MoreExecutors.directExecutor());
MediaBrowser ব্যবহার করুন
মিডিয়া অ্যাপের কন্টেন্ট লাইব্রেরি ব্রাউজ করা শুরু করতে, প্রথমে getLibraryRoot()-এর মাধ্যমে রুট নোড
পুনরুদ্ধার করুন:
Kotlin
// Get the library root to start browsing the library tree. val rootFuture = mediaBrowser.getLibraryRoot(/* params= */ null) rootFuture.addListener( { // Root node MediaItem is available here with rootFuture.get().value }, MoreExecutors.directExecutor(), )
জাভা
// Get the library root to start browsing the library tree. ListenableFuture<LibraryResult<MediaItem>> rootFuture = mediaBrowser.getLibraryRoot(/* params= */ null); rootFuture.addListener( () -> { // Root node MediaItem is available here with rootFuture.get().value }, MoreExecutors.directExecutor());
তারপর আপনি getChildren()-এর মাধ্যমে লাইব্রেরিতে MediaItem-এর চাইল্ড আইটেম ফিরিয়ে এনে মিডিয়া লাইব্রেরিতে নেভিগেট করতে পারবেন। যেমন, রুট নোড MediaItem-এর চিলড্রেন
ফিরে পেতে:
Kotlin
// Get the library root to start browsing the library tree. val childrenFuture = mediaBrowser.getChildren(rootMediaItem.mediaId, 0, Int.MAX_VALUE, null) childrenFuture.addListener( { // List of children MediaItem nodes is available here with // childrenFuture.get().value }, MoreExecutors.directExecutor(), )
জাভা
ListenableFuture<LibraryResult<ImmutableList<MediaItem>>> childrenFuture = mediaBrowser.getChildren(rootMediaItem.mediaId, 0, Integer.MAX_VALUE, null); childrenFuture.addListener( () -> { // List of children MediaItem nodes is available here with // childrenFuture.get().value }, MoreExecutors.directExecutor());
অন্য মিডিয়া অ্যাপের জন্য প্লেব্যাক কন্ট্রোল দেখান
অন্য মিডিয়া অ্যাপের জন্য বোতাম সহ UI কন্ট্রোল দেখানোর সময়, সেই অ্যাপের ঘোষিত মিডিয়া বোতাম সংক্রান্ত পছন্দ অনুসরণ করা গুরুত্বপূর্ণ।
আপনার UI-এর সীমাবদ্ধতা ও প্রয়োজনীয়তার সাথে অ্যাপের পছন্দ সংক্রান্ত সমস্যার সমাধান করতে, CommandButton.DisplayConstraints ব্যবহার করুন। আপনার UI-এর সীমা ও বিধিনিষেধ আপনি নির্ধারণ করতে পারেন এবং resolve() পদ্ধতি
আইকন, পজিশন ও অভিপ্রেত অ্যাকশন সহ দেখানোর জন্য বোতামের একটি নির্দিষ্ট তালিকা
প্রদান করে। ব্যবহারকারী এইসব বোতামের কোনও একটিতে ক্লিক করলে, আপনি
CommandButton.executeAction ব্যবহার করে মিডিয়া অ্যাপে সংশ্লিষ্ট অ্যাকশন ট্রিগার করতে
পারবেন।
Kotlin
// Get media button preferences from media app val mediaButtonPreferences = controller.getMediaButtonPreferences() // Declare constraints of UI (example: limit overflow button to one) val displayConstraints = DisplayConstraints.Builder().setMaxButtonsForSlot(CommandButton.SLOT_OVERFLOW, 1).build() // Resolve media app preferences with constraints val resolvedButtons = displayConstraints.resolve(mediaButtonPreferences, controller) // Display buttons in UI for (button in resolvedButtons) { generateUiButton( uiPosition = button.slots[0], icon = getIconRes(button.icon), onClick = { button.executeAction(controller) }, ) }
জাভা
// Get media button preferences from media app List<CommandButton> mediaButtonPreferences = controller.getMediaButtonPreferences(); // Declare constraints of UI (example: limit overflow button to one) DisplayConstraints displayConstraints = new DisplayConstraints.Builder() .setMaxButtonsForSlot(CommandButton.SLOT_OVERFLOW, 1) .build(); // Resolve media app preferences with constraints List<CommandButton> resolvedButtons = displayConstraints.resolve(mediaButtonPreferences, controller); // Display buttons in UI for (CommandButton button : resolvedButtons) { generateUiButton( /* uiPosition= */ button.slots.get(0), /* icon= */ getIconRes(button.icon), /* onClick= */ () -> button.executeAction(controller)); }