MediaRouter ওভারভিউ

আপনার অ্যাপের মধ্যে MediaRouter ফ্রেমওয়ার্ক ব্যবহার করতে, আপনাকে MediaRouter অবজেক্টের ইনস্ট্যান্স পেতে হবে এবং রাউটিং ইভেন্ট শোনার জন্য MediaRouter.Callback অবজেক্ট অ্যাটাচ করতে হবে। মিডিয়া রুটের মাধ্যমে পাঠানো কন্টেন্ট রুটের সাথে যুক্ত MediaRouteProvider-এর মাধ্যমে পাস করে (কিছু বিশেষ ক্ষেত্র ছাড়া, যেমন ব্লুটুথ আউটপুট ডিভাইস)। ডিভাইসের মধ্যে কন্টেন্ট রাউট করার জন্য ব্যবহৃত ক্লাসগুলির একটি হাই-লেভেল ভিউ চিত্র ১-এ দেখানো হয়েছে।

ছবি ১. অ্যাপের মাধ্যমে ব্যবহার করা প্রধান মিডিয়া রাউটার ক্লাসের ওভারভিউ।

মনে রাখবেন: আপনার অ্যাপ যাতে Google Cast ডিভাইসে কাজ করে, তার জন্য আপনাকে Cast SDK ব্যবহার করতে হবে এবং Cast প্রেরক হিসেবে আপনার অ্যাপ তৈরি করতে হবে। সরাসরি MediaRouter ফ্রেমওয়ার্ক ব্যবহার করার পরিবর্তে Cast ডকুমেন্টেশনে দেওয়া নির্দেশাবলী অনুসরণ করুন।

মিডিয়া রুট বোতাম

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

ছবি ২. অ্যাকশন বারে মিডিয়া রুট বোতাম।

ব্যবহারকারী মিডিয়া রুট বোতামে প্রেস করলে, উপলভ্য মিডিয়া রুটগুলি একটি তালিকায় দেখা যায়, যেমনটি ছবি ৩-এ দেখানো হয়েছে।

ছবি ৩. মিডিয়া রুট বোতাম প্রেস করার পরে উপলভ্য মিডিয়া রুটের তালিকা দেখানো হয়।

মিডিয়া রুট বোতাম তৈরি করতে এইসব ধাপ অনুসরণ করুন:

  1. AppCompatActivity ব্যবহার করুন
  2. মিডিয়া রুট বোতামের মেনু আইটেম নির্ধারণ করুন
  3. MediaRouteSelector তৈরি করুন
  4. অ্যাকশন বারে মিডিয়া রুট বোতাম যোগ করুন
  5. আপনার অ্যাক্টিভিটির লাইফসাইকেলে MediaRouter.Callback পদ্ধতি তৈরি ও ম্যানেজ করুন

এই বিভাগে প্রথম চারটি ধাপের বিবরণ দেওয়া আছে। পরবর্তী বিভাগে কলব্যাক পদ্ধতি বর্ণনা করা হয়েছে।

AppCompatActivity ব্যবহার করুন

কোনও অ্যাক্টিভিটিতে মিডিয়া রাউটার ফ্রেমওয়ার্ক ব্যবহার করলে, আপনাকে AppCompatActivity থেকে অ্যাক্টিভিটি এক্সটেন্ড করতে হবে এবং androidx.appcompat.app প্যাকেজ ইমপোর্ট করতে হবে। আপনার অ্যাপ ডেভেলপমেন্ট প্রোজেক্টে androidx.appcompat:appcompat এবং androidx.mediarouter:mediarouter সাপোর্ট লাইব্রেরি যোগ করতে হবে। আপনার প্রোজেক্টে সাপোর্ট লাইব্রেরি যোগ করার বিষয়ে আরও তথ্যের জন্য, Android Jetpack ব্যবহার শুরু করা দেখুন।

সতর্কতা: মিডিয়া রাউটার ফ্রেমওয়ার্কের androidx ইমপ্লিমেন্টেশন ব্যবহার করতে ভুলবেন না। পুরনো android.media প্যাকেজ ব্যবহার করবেন না।

একটি xml ফাইল তৈরি করুন যা মিডিয়া রুট বোতামের জন্য একটি মেনু আইটেমকে সংজ্ঞায়িত করে। আইটেমের অ্যাকশন MediaRouteActionProvider ক্লাস হতে হবে। এখানে একটি উদাহরণ ফাইল দেওয়া হল:

// myMediaRouteButtonMenuItem.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      >

    <item android:id="@+id/media_route_menu_item"
        android:title="@string/media_route_menu_title"
        app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider"
        app:showAsAction="always"
    />
</menu>

MediaRouteSelector তৈরি করুন

মিডিয়া রুট বোতাম মেনুতে যে রুটগুলি দেখা যায় সেগুলি MediaRouteSelector দ্বারা নির্ধারিত হয়। AppCompatActivity থেকে আপনার অ্যাক্টিভিটি এক্সটেন্ড করুন এবং অ্যাক্টিভিটি তৈরি করার সময় onCreate() পদ্ধতি থেকে MediaRouteSelector.Builder কল করে সিলেক্টর তৈরি করুন, যেমনটি নিম্নলিখিত কোড স্যাম্পেলে দেখানো হয়েছে। মনে রাখবেন, সিলেক্টর ক্লাস ভেরিয়েবেলে সেভ করা হয় এবং অনুমোদিত রুটের ধরন MediaControlIntent অবজেক্ট যোগ করার মাধ্যমে নির্দিষ্ট করা হয়:

Kotlin

class MediaRouterPlaybackActivity : AppCompatActivity() {

    private var mSelector: MediaRouteSelector? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Create a route selector for the type of routes your app supports.
        mSelector = MediaRouteSelector.Builder()
                // These are the framework-supported intents
                .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
                .build()
    }
}

জাভা

public class MediaRouterPlaybackActivity extends AppCompatActivity {
    private MediaRouteSelector mSelector;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Create a route selector for the type of routes your app supports.
        mSelector = new MediaRouteSelector.Builder()
                // These are the framework-supported intents
                .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
                .build();
    }
}

বেশিরভাগ অ্যাপ্লিকেশনের জন্য, শুধুমাত্র CATEGORY_REMOTE_PLAYBACK রুট টাইপ প্রয়োজন। এই ধরনের রুট, আপনার অ্যাপ চালানো ডিভাইসকে রিমোট কন্ট্রোল হিসেবে বিবেচনা করে। কানেক্ট করা রিসিভার ডিভাইস সব কন্টেন্ট ডেটা রিট্রিভাল, ডিকোডিং ও প্লেব্যাক ম্যানেজ করে। Google Cast সাপোর্ট করে এমন অ্যাপ, যেমন Chromecast, এইভাবে কাজ করে।

কিছু প্রস্তুতকারক "সেকেন্ডারি আউটপুট" নামক একটি বিশেষ রাউটিং বিকল্পের সুবিধা প্রদান করে। এই রাউটিংয়ের মাধ্যমে, আপনার মিডিয়া অ্যাপ, বেছে নেওয়া রিমোট রিসিভার ডিভাইসের স্ক্রিন এবং/অথবা স্পিকারে সরাসরি ভিডিও বা মিউজিক রিট্রিভ, রেন্ডার ও স্ট্রিম করে। ওয়্যারলেস-চালিত মিউজিক সিস্টেম বা ভিডিও ডিসপ্লেতে কন্টেন্ট পাঠাতে সেকেন্ডারি আউটপুট ব্যবহার করুন। এইসব ডিভাইস খোঁজা ও বেছে নেওয়ার সুবিধা চালু করতে, আপনাকে MediaRouteSelector-এ CATEGORY_LIVE_AUDIO বা CATEGORY_LIVE_VIDEO কন্ট্রোল ক্যাটেগরি যোগ করতে হবে। এছাড়াও, আপনাকে নিজের Presentation ডায়ালগ তৈরি ও ম্যানেজ করতে হবে।

অ্যাকশন বারে মিডিয়া রুট বোতাম যোগ করুন

মিডিয়া রুট মেনু ও MediaRouteSelector সংজ্ঞায়িত করার মাধ্যমে, আপনি এখন কোনও অ্যাক্টিভিটিতে মিডিয়া রুট বোতাম যোগ করতে পারবেন। বিকল্পের মেনু যোগ করতে আপনার প্রতিটি অ্যাক্টিভিটির জন্য onCreateOptionsMenu() পদ্ধতি ওভাররাইড করুন।

Kotlin

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    super.onCreateOptionsMenu(menu)

    // Inflate the menu and configure the media router action provider.
    menuInflater.inflate(R.menu.sample_media_router_menu, menu)

    // Attach the MediaRouteSelector to the menu item
    val mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item)
    val mediaRouteActionProvider =
            MenuItemCompat.getActionProvider(mediaRouteMenuItem) as MediaRouteActionProvider

    // Attach the MediaRouteSelector that you built in onCreate()
    selector?.also(mediaRouteActionProvider::setRouteSelector)

    // Return true to show the menu.
    return true
}

জাভা

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);

    // Inflate the menu and configure the media router action provider.
    getMenuInflater().inflate(R.menu.sample_media_router_menu, menu);

    // Attach the MediaRouteSelector to the menu item
    MenuItem mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item);
    MediaRouteActionProvider mediaRouteActionProvider =
            (MediaRouteActionProvider)MenuItemCompat.getActionProvider(
            mediaRouteMenuItem);
    // Attach the MediaRouteSelector that you built in onCreate()
    mediaRouteActionProvider.setRouteSelector(selector);

    // Return true to show the menu.
    return true;
}

আপনার অ্যাপে অ্যাকশন বার প্রয়োগ করা সম্পর্কে আরও তথ্য পেতে, অ্যাকশন বার ডেভেলপার নির্দেশিকা দেখুন।

এছাড়াও, আপনি যেকোনও ভিউতে MediaRouteButton হিসেবে মিডিয়া রুট বোতাম যোগ করতে পারবেন। setRouteSelector() পদ্ধতি ব্যবহার করে আপনাকে অবশ্যই বোতামে MediaRouteSelector অ্যাটাচ করতে হবে। আপনার অ্যাপ্লিকেশনে মিডিয়া রুট বোতাম যোগ করার নির্দেশিকা পেতে Google Cast ডিজাইন চেকলিস্ট দেখুন।

MediaRouter কলব্যাক

একই ডিভাইসে চলা সব অ্যাপ একটিই MediaRouter ইনস্ট্যান্স ও তার রুট শেয়ার করে (অ্যাপের MediaRouteSelector-এর মাধ্যমে প্রতিটি অ্যাপের জন্য ফিল্টার করা)। প্রতিটি অ্যাক্টিভিটি MediaRouter.Callback পদ্ধতির নিজস্ব প্রয়োগ ব্যবহার করে MediaRouter-এর সাথে যোগাযোগ করে। ব্যবহারকারী কোনও রুট বেছে নিলে, পরিবর্তন করলে বা ডিসকানেক্ট করলে, MediaRouter কলব্যাক মেথড কল করে।

কলব্যাকে একাধিক পদ্ধতি আছে যা আপনি ওভাররাইড করে রাউটিং ইভেন্ট সম্পর্কে তথ্য পেতে পারেন। কমপক্ষে, আপনার MediaRouter.Callback ক্লাসের ইমপ্লিমেন্টেশন onRouteSelected() এবং onRouteUnselected() ওভাররাইড করা উচিত।

যেহেতু MediaRouter একটি শেয়ার করা রিসোর্স, তাই আপনার অ্যাপকে সাধারণ অ্যাক্টিভিটি লাইফসাইকেল কলব্যাকের উত্তরে MediaRouter কলব্যাক ম্যানেজ করতে হবে:

  • অ্যাক্টিভিটি তৈরি করা হলে (onCreate(Bundle)) MediaRouter-এর একটি পয়েন্টার নিন এবং অ্যাপের লাইফটাইমের জন্য এটি ধরে রাখুন।
  • অ্যাক্টিভিটি দৃশ্যমান হলে (onStart()) MediaRouter-এ কলব্যাক অ্যাটাচ করুন এবং এটি লুকানো থাকলে (onStop()) ডিটাচ করুন।

নিম্নলিখিত কোড স্যাম্পেল থেকে আপনি জানতে পারবেন যে কীভাবে কলব্যাক অবজেক্ট তৈরি ও সেভ করতে হয়, কীভাবে MediaRouter-এর ইনস্ট্যান্স পেতে হয় এবং কীভাবে কলব্যাক ম্যানেজ করতে হয়। onStart()-এ কলব্যাক অ্যাটাচ করার সময় CALLBACK_FLAG_REQUEST_DISCOVERY ফ্ল্যাগ ব্যবহারের বিষয়টি লক্ষ্য করুন। এটি আপনার MediaRouteSelector-কে মিডিয়া রুট বোতামের উপলভ্য রুটের তালিকা রিফ্রেশ করার অনুমতি দেয়।

Kotlin

class MediaRouterPlaybackActivity : AppCompatActivity() {

    private var mediaRouter: MediaRouter? = null
    private var mSelector: MediaRouteSelector? = null

    // Variables to hold the currently selected route and its playback client
    private var mRoute: MediaRouter.RouteInfo? = null
    private var remotePlaybackClient: RemotePlaybackClient? = null

    // Define the Callback object and its methods, save the object in a class variable
    private val mediaRouterCallback = object : MediaRouter.Callback() {

        override fun onRouteSelected(router: MediaRouter, route: MediaRouter.RouteInfo) {
            Log.d(TAG, "onRouteSelected: route=$route")
            if (route.supportsControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) {
                // Stop local playback (if necessary)
                // ...

                // Save the new route
                mRoute = route

                // Attach a new playback client
                remotePlaybackClient =
                    RemotePlaybackClient(this@MediaRouterPlaybackActivity, mRoute)

                // Start remote playback (if necessary)
                // ...
            }
        }

        override fun onRouteUnselected(
                router: MediaRouter,
                route: MediaRouter.RouteInfo,
                reason: Int
        ) {
            Log.d(TAG, "onRouteUnselected: route=$route")
            if (route.supportsControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) {

                // Changed route: tear down previous client
                mRoute?.also {
                    remotePlaybackClient?.release()
                    remotePlaybackClient = null
                }

                // Save the new route
                mRoute = route

                when (reason) {
                    MediaRouter.UNSELECT_REASON_ROUTE_CHANGED -> {
                        // Resume local playback (if necessary)
                        // ...
                    }
                }
            }
        }
    }


    // Retain a pointer to the MediaRouter
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Get the media router service.
        mediaRouter = MediaRouter.getInstance(this)
        ...
    }

    // Use this callback to run your MediaRouteSelector to generate the
    // list of available media routes
    override fun onStart() {
        mSelector?.also { selector ->
            mediaRouter?.addCallback(selector, mediaRouterCallback,
                    MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY)
        }
        super.onStart()
    }

    // Remove the selector on stop to tell the media router that it no longer
    // needs to discover routes for your app.
    override fun onStop() {
        mediaRouter?.removeCallback(mediaRouterCallback)
        super.onStop()
    }
    ...
}

জাভা

public class MediaRouterPlaybackActivity extends AppCompatActivity {
    private MediaRouter mediaRouter;
    private MediaRouteSelector mSelector;

    // Variables to hold the currently selected route and its playback client
    private MediaRouter.RouteInfo mRoute;
    private RemotePlaybackClient remotePlaybackClient;

    // Define the Callback object and its methods, save the object in a class variable
    private final MediaRouter.Callback mediaRouterCallback =
            new MediaRouter.Callback() {

        @Override
        public void onRouteSelected(MediaRouter router, RouteInfo route) {
            Log.d(TAG, "onRouteSelected: route=" + route);

            if (route.supportsControlCategory(
                MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)){
                // Stop local playback (if necessary)
                // ...

                // Save the new route
                mRoute = route;

                // Attach a new playback client
                remotePlaybackClient = new RemotePlaybackClient(this, mRoute);

                // Start remote playback (if necessary)
                // ...
            }
        }

        @Override
        public void onRouteUnselected(MediaRouter router, RouteInfo route, int reason) {
            Log.d(TAG, "onRouteUnselected: route=" + route);

            if (route.supportsControlCategory(
                MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)){

                // Changed route: tear down previous client
                if (mRoute != null && remotePlaybackClient != null) {
                    remotePlaybackClient.release();
                    remotePlaybackClient = null;
                }

                // Save the new route
                mRoute = route;

                if (reason != MediaRouter.UNSELECT_REASON_ROUTE_CHANGED) {
                    // Resume local playback  (if necessary)
                    // ...
                }
            }
        }
    }


    // Retain a pointer to the MediaRouter
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Get the media router service.
        mediaRouter = MediaRouter.getInstance(this);
        ...
    }

    // Use this callback to run your MediaRouteSelector to generate the list of available media routes
    @Override
    public void onStart() {
        mediaRouter.addCallback(mSelector, mediaRouterCallback,
                MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
        super.onStart();
    }

    // Remove the selector on stop to tell the media router that it no longer
    // needs to discover routes for your app.
    @Override
    public void onStop() {
        mediaRouter.removeCallback(mediaRouterCallback);
        super.onStop();
    }
    ...
}

এছাড়াও, মিডিয়া রাউটার ফ্রেমওয়ার্ক একটি MediaRouteDiscoveryFragment ক্লাস প্রদান করে, যা কোনও অ্যাক্টিভিটির জন্য কলব্যাক যোগ করা ও সরিয়ে দেওয়ার বিষয়টি ম্যানেজ করে।

মনে রাখবেন: আপনি যদি মিউজিক প্লেব্যাক অ্যাপ তৈরি করেন এবং অ্যাপটি ব্যাকগ্রাউন্ডে থাকাকালীন মিউজিক চালাতে চান, তাহলে আপনাকে প্লেব্যাকের জন্য একটি Service তৈরি করতে হবে এবং পরিষেবার লাইফসাইকেল কলব্যাক থেকে মিডিয়া রাউটার ফ্রেমওয়ার্ক কল করতে হবে।

রিমোট প্লেব্যাক রুট কন্ট্রোল করা হচ্ছে

আপনি রিমোট প্লেব্যাক রুট বেছে নিলে, আপনার অ্যাপ রিমোট কন্ট্রোল হিসেবে কাজ করে। রুটের অন্য প্রান্তে থাকা ডিভাইসটি সব কন্টেন্ট ডেটা রিট্রিভাল, ডিকোডিং এবং প্লেব্যাক ফাংশন ম্যানেজ করে। আপনার অ্যাপের UI-তে থাকা কন্ট্রোল, RemotePlaybackClient অবজেক্ট ব্যবহার করে রিসিভার ডিভাইসের সাথে যোগাযোগ করে।

RemotePlaybackClient ক্লাস কন্টেন্ট প্লেব্যাক ম্যানেজ করার জন্য অতিরিক্ত পদ্ধতি প্রদান করে। RemotePlaybackClient ক্লাস থেকে প্লেব্যাকের কয়েকটি গুরুত্বপূর্ণ পদ্ধতি এখানে দেওয়া হল:

  • play() — Uri-এর মাধ্যমে নির্দিষ্ট করা কোনও মিডিয়া ফাইল চালান।
  • pause() — বর্তমানে চলছে এমন মিডিয়া ট্র্যাক পজ করুন।
  • resume() — পজ কমান্ডের পরে বর্তমান ট্র্যাক চালানো চালিয়ে যান।
  • seek() — বর্তমান ট্র্যাকের নির্দিষ্ট পজিশনে যান।
  • release() — আপনার অ্যাপ থেকে রিমোট প্লেব্যাক ডিভাইসের কানেকশন বন্ধ করুন।

আপনার অ্যাপে দেওয়া প্লেব্যাক কন্ট্রোলে অ্যাকশন অ্যাটাচ করতে আপনি এইসব পদ্ধতি ব্যবহার করতে পারবেন। এইসব পদ্ধতির বেশিরভাগই আপনাকে কলব্যাক অবজেক্ট যোগ করার অনুমতি দেয় যাতে আপনি প্লেব্যাক টাস্ক বা কন্ট্রোল অনুরোধের প্রোগ্রেস মনিটর করতে পারেন।

এছাড়াও, RemotePlaybackClient ক্লাস, প্লেব্যাকের জন্য একাধিক মিডিয়া আইটেম কিউতে যোগ করা এবং মিডিয়া কিউ ম্যানেজ করার সুবিধা প্রদান করে।

নমুনা কোড

Android BasicMediaRouter এবং MediaRouter স্যাম্পেল MediaRouter API-এর ব্যবহার আরও ভালভাবে দেখায়।