মিডিয়ারাউটার ওভারভিউ

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

চিত্র 1. অ্যাপস দ্বারা ব্যবহৃত মূল মিডিয়া রাউটার ক্লাসের ওভারভিউ।

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

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

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

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

যখন ব্যবহারকারী মিডিয়া রুট বোতাম টিপে, উপলব্ধ মিডিয়া রুটগুলি চিত্র 3 এ দেখানো একটি তালিকায় উপস্থিত হয়।

চিত্র 3. উপলব্ধ মিডিয়া রুটের একটি তালিকা, মিডিয়া রুট বোতাম টিপানোর পরে দেখানো হয়েছে।

একটি মিডিয়া রুট বোতাম তৈরি করতে এই পদক্ষেপগুলি অনুসরণ করুন:

  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 অবজেক্ট যোগ করে নির্দিষ্ট করা হয়েছে:

কোটলিন

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() পদ্ধতি ওভাররাইড করুন।

কোটলিন

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 দৃষ্টান্ত এবং এর রুটগুলি ভাগ করে (অ্যাপের MediaRouteSelector দ্বারা অ্যাপ প্রতি ফিল্টার করা)। প্রতিটি কার্যকলাপ MediaRouter এর সাথে যোগাযোগ করে MediaRouter.Callback পদ্ধতির নিজস্ব বাস্তবায়ন ব্যবহার করে। যখনই ব্যবহারকারী একটি রুট নির্বাচন, পরিবর্তন বা সংযোগ বিচ্ছিন্ন করে তখন MediaRouter কলব্যাক পদ্ধতিগুলিকে কল করে৷

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

যেহেতু MediaRouter একটি শেয়ার্ড রিসোর্স, আপনার অ্যাপটিকে তার MediaRouter কলব্যাকগুলিকে স্বাভাবিক কার্যকলাপের লাইফসাইকেল কলব্যাকের প্রতিক্রিয়া হিসাবে পরিচালনা করতে হবে:

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

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

কোটলিন

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 ক্লাস প্লেব্যাক এবং মিডিয়া সারির পরিচালনার জন্য একাধিক মিডিয়া আইটেমের সারি সারি সমর্থন করে।

নমুনা কোড

অ্যান্ড্রয়েড বেসিকমিডিয়ারাউটার এবং মিডিয়ারাউটার নমুনাগুলি মিডিয়ারাউটার API-এর ব্যবহার আরও প্রদর্শন করে।