একটি Android TV অ্যাপ কাস্ট-সক্ষম করুন

1. সংক্ষিপ্ত বিবরণ

গুগল কাস্ট লোগো

এই কোডল্যাবটি আপনাকে শেখাবে কিভাবে আপনার বিদ্যমান কাস্ট সেন্ডার অ্যাপ থেকে কাস্টিং এবং যোগাযোগ সমর্থন করার জন্য একটি বিদ্যমান Android TV অ্যাপ পরিবর্তন করতে হয়।

গুগল কাস্ট এবং কাস্ট কানেক্ট কী?

গুগল কাস্ট ব্যবহারকারীদের মোবাইল ডিভাইস থেকে টিভিতে কন্টেন্ট কাস্ট করার সুযোগ দেয়। একটি সাধারণ গুগল কাস্ট সেশনে দুটি উপাদান থাকে - একটি প্রেরক এবং একটি রিসিভার অ্যাপ্লিকেশন। প্রেরক অ্যাপ্লিকেশন, যেমন একটি মোবাইল অ্যাপ বা Youtube.com এর মতো ওয়েবসাইট, একটি কাস্ট রিসিভার অ্যাপ্লিকেশনের প্লেব্যাক শুরু করে এবং নিয়ন্ত্রণ করে। কাস্ট রিসিভার অ্যাপ্লিকেশন হল HTML 5 অ্যাপ যা Chromecast এবং Android TV ডিভাইসে চলে।

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

এই পরিকাঠামোর উপরেই Cast Connect তৈরি হয়, যেখানে আপনার Android TV অ্যাপটি রিসিভার হিসেবে কাজ করে। Cast Connect লাইব্রেরি আপনার Android TV অ্যাপটিকে বার্তা গ্রহণ করতে এবং মিডিয়া স্ট্যাটাস সম্প্রচার করতে দেয় যেন এটি একটি কাস্ট রিসিভার অ্যাপ্লিকেশন।

আমরা কী তৈরি করতে যাচ্ছি?

এই কোডল্যাবটি সম্পন্ন করার পর, আপনি একটি Android TV অ্যাপে ভিডিও কাস্ট করার জন্য Cast সেন্ডার অ্যাপ ব্যবহার করতে পারবেন। Android TV অ্যাপটি Cast প্রোটোকলের মাধ্যমেও প্রেরক অ্যাপের সাথে যোগাযোগ করতে পারে।

তুমি কি শিখবে

  • একটি নমুনা ATV অ্যাপে Cast Connect লাইব্রেরি কীভাবে যোগ করবেন।
  • কিভাবে একজন কাস্ট সেন্ডারকে সংযুক্ত করবেন এবং ATV অ্যাপ চালু করবেন।
  • কাস্ট সেন্ডার অ্যাপ থেকে ATV অ্যাপে মিডিয়া প্লেব্যাক কীভাবে শুরু করবেন।
  • ATV অ্যাপ থেকে Cast সেন্ডার অ্যাপে মিডিয়া স্ট্যাটাস কীভাবে পাঠাবেন।

তোমার যা লাগবে

2. নমুনা কোড পান

আপনি আপনার কম্পিউটারে সমস্ত নমুনা কোড ডাউনলোড করতে পারেন...

এবং ডাউনলোড করা জিপ ফাইলটি আনপ্যাক করুন।

৩. নমুনা অ্যাপটি চালান

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

ভিডিওর পূর্ণ-স্ক্রিন প্রিভিউ ওভারলে করা ভিডিও থাম্বনেইলের একটি সিরিজের ছবি (যার মধ্যে একটি হাইলাইট করা হয়েছে); উপরের ডানদিকে 'কাস্ট কানেক্ট' শব্দগুলি দেখা যাচ্ছে।

ডেভেলপার ডিভাইসগুলি নিবন্ধন করুন

অ্যাপ্লিকেশন ডেভেলপমেন্টের জন্য Cast Connect সক্ষমতা সক্ষম করার জন্য আপনাকে Cast Developer Console- এ যে Android TV ডিভাইসটি ব্যবহার করতে যাচ্ছেন তার Google Cast-এর সিরিয়াল নম্বরটি নিবন্ধন করতে হবে। আপনার Android TV-তে সেটিংস > ডিভাইস পছন্দ > Google Cast > সিরিয়াল নম্বরে গিয়ে আপনি সিরিয়াল নম্বরটি খুঁজে পেতে পারেন। মনে রাখবেন যে এটি আপনার ফিজিক্যাল ডিভাইসের সিরিয়াল নম্বর থেকে আলাদা এবং উপরে বর্ণিত পদ্ধতি থেকে এটি পেতে হবে।

'গুগল কাস্ট' স্ক্রিন, ভার্সন নম্বর এবং সিরিয়াল নম্বর দেখানো একটি অ্যান্ড্রয়েড টিভি স্ক্রিনের ছবি

নিরাপত্তার কারণে, নিবন্ধন ছাড়া, Cast Connect শুধুমাত্র Google Play Store থেকে ইনস্টল করা অ্যাপগুলির জন্য কাজ করবে। নিবন্ধন প্রক্রিয়া শুরু করার 15 মিনিট পরে, আপনার ডিভাইসটি পুনরায় চালু করুন।

অ্যান্ড্রয়েড সেন্ডার অ্যাপটি ইনস্টল করুন

মোবাইল ডিভাইস থেকে অনুরোধ পাঠানোর পরীক্ষা করার জন্য আমরা সোর্স কোড জিপ ডাউনলোডে mobile-sender-0629.apk ফাইল হিসেবে Cast Videos নামে একটি সহজ প্রেরক অ্যাপ্লিকেশন প্রদান করেছি। আমরা APK ইনস্টল করার জন্য ADB ব্যবহার করব। যদি আপনি ইতিমধ্যেই Cast Videos এর একটি ভিন্ন সংস্করণ ইনস্টল করে থাকেন, তাহলে চালিয়ে যাওয়ার আগে ডিভাইসে থাকা সমস্ত প্রোফাইল থেকে সেই সংস্করণটি আনইনস্টল করুন।

  1. আপনার অ্যান্ড্রয়েড ফোনে ডেভেলপার অপশন এবং USB ডিবাগিং সক্ষম করুন
  2. আপনার অ্যান্ড্রয়েড ফোনটিকে আপনার ডেভেলপমেন্ট কম্পিউটারের সাথে সংযুক্ত করতে একটি USB ডেটা কেবল লাগান।
  3. আপনার অ্যান্ড্রয়েড ফোনে mobile-sender-0629.apk ইনস্টল করুন।

mobile-sender.apk ইনস্টল করার জন্য adb install কমান্ড চালানোর টার্মিনাল উইন্ডোর ছবি

  1. আপনি আপনার অ্যান্ড্রয়েড ফোনে কাস্ট ভিডিও সেন্ডার অ্যাপটি খুঁজে পেতে পারেন। কাস্ট ভিডিও প্রেরক অ্যাপ আইকন

অ্যান্ড্রয়েড ফোনের স্ক্রিনে চলমান কাস্ট ভিডিও প্রেরক অ্যাপের ছবি

Android TV অ্যাপটি ইনস্টল করুন

নিম্নলিখিত নির্দেশাবলীতে অ্যান্ড্রয়েড স্টুডিওতে সম্পূর্ণ নমুনা অ্যাপটি কীভাবে খুলবেন এবং চালাবেন তা বর্ণনা করা হয়েছে:

  1. ওয়েলকাম স্ক্রিনে ইমপোর্ট প্রজেক্ট অথবা ফাইল > নতুন > ইমপোর্ট প্রজেক্ট... মেনু অপশন নির্বাচন করুন।
  2. নির্বাচন করুন ফোল্ডার আইকন নমুনা কোড ফোল্ডার থেকে app-done ডিরেক্টরিটি খুঁজে বের করুন এবং ঠিক আছে ক্লিক করুন।
  3. ফাইল > ক্লিক করুন অ্যান্ড্রয়েড অ্যাপ স্টুডিওর গ্রেডল বোতামের সাথে সিঙ্ক প্রজেক্ট গ্রেডল ফাইলের সাথে প্রকল্প সিঙ্ক করুন
  4. আপনার Android TV ডিভাইসে ডেভেলপার অপশন এবং USB ডিবাগিং সক্ষম করুন
  5. ADB আপনার Android TV ডিভাইসের সাথে সংযোগ স্থাপন করে, ডিভাইসটি Android Studio-তে দেখানো উচিত। অ্যান্ড্রয়েড স্টুডিও টুলবারে প্রদর্শিত অ্যান্ড্রয়েড টিভি ডিভাইসের চিত্র
  6. ক্লিক করুন অ্যান্ড্রয়েড স্টুডিও রান বোতাম, ডানদিকে নির্দেশিত একটি সবুজ ত্রিভুজ রান বোতাম টিপলে, কয়েক সেকেন্ড পরে আপনি Cast Connect Codelab নামের ATV অ্যাপটি দেখতে পাবেন।

চলো ATV অ্যাপের মাধ্যমে Cast Connect খেলি

  1. অ্যান্ড্রয়েড টিভি হোম স্ক্রিনে যান।
  2. আপনার অ্যান্ড্রয়েড ফোন থেকে কাস্ট ভিডিও সেন্ডার অ্যাপটি খুলুন। কাস্ট বোতামে ক্লিক করুন। কাস্ট বোতাম আইকন এবং আপনার ATV ডিভাইসটি নির্বাচন করুন।
  3. আপনার ATV তে Cast Connect Codelab ATV অ্যাপটি চালু হবে এবং আপনার প্রেরকের Cast বোতামটি নির্দেশ করবে যে এটি সংযুক্ত আছে। উল্টানো রঙের কাস্ট বোতাম আইকন .
  4. ATV অ্যাপ থেকে একটি ভিডিও নির্বাচন করুন এবং ভিডিওটি আপনার ATV তে চলতে শুরু করবে।
  5. আপনার মোবাইল ফোনে, আপনার সেন্ডার অ্যাপের নীচে একটি মিনি কন্ট্রোলার এখন দৃশ্যমান। প্লেব্যাক নিয়ন্ত্রণ করতে আপনি প্লে/পজ বোতাম ব্যবহার করতে পারেন।
  6. মোবাইল ফোন থেকে একটি ভিডিও নির্বাচন করুন এবং চালান। ভিডিওটি আপনার ATV তে চালানো শুরু হবে এবং প্রসারিত কন্ট্রোলারটি আপনার মোবাইল প্রেরকে প্রদর্শিত হবে।
  7. আপনার ফোনটি লক করুন এবং যখন আপনি এটি আনলক করবেন, তখন মিডিয়া প্লেব্যাক নিয়ন্ত্রণ করতে বা কাস্টিং বন্ধ করতে লক স্ক্রিনে একটি বিজ্ঞপ্তি দেখতে পাবেন।

একটি অ্যান্ড্রয়েড ফোনের স্ক্রিনের একটি অংশের ছবি যেখানে মিনিপ্লেয়ার ভিডিও চালাচ্ছে

৪. শুরুর প্রকল্পটি প্রস্তুত করুন

এখন যেহেতু আমরা সম্পূর্ণ অ্যাপটির Cast Connect ইন্টিগ্রেশন যাচাই করেছি, তাই আপনার ডাউনলোড করা স্টার্ট অ্যাপটিতে Cast Connect এর জন্য সমর্থন যোগ করতে হবে। এখন আপনি Android Studio ব্যবহার করে স্টার্টার প্রজেক্টের উপরে তৈরি করতে প্রস্তুত:

  1. ওয়েলকাম স্ক্রিনে ইমপোর্ট প্রজেক্ট অথবা ফাইল > নতুন > ইমপোর্ট প্রজেক্ট... মেনু অপশন নির্বাচন করুন।
  2. নির্বাচন করুন ফোল্ডার আইকন নমুনা কোড ফোল্ডার থেকে app-start ডিরেক্টরিটি খুঁজে বের করুন এবং ঠিক আছে ক্লিক করুন।
  3. ফাইল > ক্লিক করুন অ্যান্ড্রয়েড স্টুডিওর গ্রেডল বোতামের সাথে সিঙ্ক প্রকল্প গ্রেডল ফাইলের সাথে প্রকল্প সিঙ্ক করুন
  4. ATV ডিভাইস নির্বাচন করুন এবং ক্লিক করুন অ্যান্ড্রয়েড স্টুডিওর রান বোতাম, ডানদিকে নির্দেশিত একটি সবুজ ত্রিভুজ অ্যাপটি চালাতে এবং UI অন্বেষণ করতে রান বোতামটি টিপুন। নির্বাচিত অ্যান্ড্রয়েড টিভি ডিভাইসটি দেখানো অ্যান্ড্রয়েড স্টুডিও টুলবার

ভিডিওর পূর্ণ-স্ক্রিন প্রিভিউ ওভারলে করা ভিডিও থাম্বনেইলের একটি সিরিজের ছবি (যার মধ্যে একটি হাইলাইট করা হয়েছে); উপরের ডানদিকে 'কাস্ট কানেক্ট' শব্দগুলি দেখা যাচ্ছে।

অ্যাপ ডিজাইন

এই অ্যাপটি ব্যবহারকারীদের ব্রাউজ করার জন্য ভিডিওগুলির একটি তালিকা প্রদান করে। ব্যবহারকারীরা অ্যান্ড্রয়েড টিভিতে চালানোর জন্য একটি ভিডিও নির্বাচন করতে পারেন। অ্যাপটিতে দুটি প্রধান কার্যকলাপ রয়েছে: MainActivity এবং PlaybackActivity

প্রধান কার্যকলাপ

এই কার্যকলাপে একটি Fragment ( MainFragment ) রয়েছে। ভিডিওর তালিকা এবং তাদের সাথে সম্পর্কিত মেটাডেটা MovieList ক্লাসে কনফিগার করা হয় এবং setupMovies() পদ্ধতিটি Movie অবজেক্টের একটি তালিকা তৈরি করতে ব্যবহৃত হয়।

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

যখন একটি আইটেম নির্বাচন করা হয়, তখন সংশ্লিষ্ট Movie অবজেক্টটি PlaybackActivity তে পাস করা হয়।

প্লেব্যাক অ্যাক্টিভিটি

এই কার্যকলাপে একটি ফ্র্যাগমেন্ট ( PlaybackVideoFragment ) রয়েছে যা ExoPlayer সহ একটি VideoView , কিছু মিডিয়া নিয়ন্ত্রণ এবং নির্বাচিত ভিডিওর বিবরণ দেখানোর জন্য একটি টেক্সট এরিয়া হোস্ট করে এবং ব্যবহারকারীকে Android TV তে ভিডিওটি চালানোর অনুমতি দেয়। ব্যবহারকারী ভিডিওগুলি চালানো/বিরতি দিতে বা প্লেব্যাক খুঁজতে রিমোট কন্ট্রোল ব্যবহার করতে পারেন।

কাস্ট কানেক্টের পূর্বশর্ত

কাস্ট কানেক্ট গুগল প্লে সার্ভিসের নতুন সংস্করণ ব্যবহার করে যার জন্য অ্যান্ড্রয়েডএক্স নেমস্পেস ব্যবহার করার জন্য আপনার এটিভি অ্যাপটি আপডেট করা প্রয়োজন।

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

৫. কাস্ট সাপোর্ট কনফিগার করা

নির্ভরতা

প্রয়োজনীয় লাইব্রেরি নির্ভরতা অন্তর্ভুক্ত করতে অ্যাপ build.gradle ফাইলটি আপডেট করুন:

dependencies {
    ....

    // Cast Connect libraries
    implementation 'com.google.android.gms:play-services-cast-tv:20.0.0'
    implementation 'com.google.android.gms:play-services-cast:21.1.0'
}

ত্রুটি ছাড়াই প্রকল্পটি তৈরি হয়েছে তা নিশ্চিত করতে প্রকল্পটি সিঙ্ক করুন।

আরম্ভকরণ

CastReceiverContext হল একটি সিঙ্গেলটন অবজেক্ট যা সমস্ত Cast ইন্টারঅ্যাকশন সমন্বয় করে। CastReceiverContext শুরু করার সময় CastReceiverOptions প্রদান করতে আপনাকে ReceiverOptionsProvider ইন্টারফেসটি বাস্তবায়ন করতে হবে।

CastReceiverOptionsProvider.kt ফাইল তৈরি করুন এবং প্রকল্পে নিম্নলিখিত ক্লাসটি যোগ করুন:

package com.google.sample.cast.castconnect

import android.content.Context
import com.google.android.gms.cast.tv.ReceiverOptionsProvider
import com.google.android.gms.cast.tv.CastReceiverOptions

class CastReceiverOptionsProvider : ReceiverOptionsProvider {
    override fun getOptions(context: Context): CastReceiverOptions {
        return CastReceiverOptions.Builder(context)
                .setStatusText("Cast Connect Codelab")
                .build()
    }
}

তারপর AndroidManifest.xml ফাইলের <application> ট্যাগের মধ্যে রিসিভার অপশন প্রোভাইডার নির্দিষ্ট করুন:

<application>
  ...
  <meta-data
    android:name="com.google.android.gms.cast.tv.RECEIVER_OPTIONS_PROVIDER_CLASS_NAME"
    android:value="com.google.sample.cast.castconnect.CastReceiverOptionsProvider" />
</application>

আপনার Cast প্রেরকের কাছ থেকে আপনার ATV অ্যাপের সাথে সংযোগ স্থাপন করতে, আপনি যে অ্যাক্টিভিটি চালু করতে চান তা নির্বাচন করুন। এই কোডল্যাবে, যখন একটি Cast সেশন শুরু হবে তখন আমরা অ্যাপটির MainActivity চালু করব। AndroidManifest.xml ফাইলে, MainActivity এ লঞ্চ ইন্টেন্ট ফিল্টার যোগ করুন।

<activity android:name=".MainActivity">
  ...
  <intent-filter>
    <action android:name="com.google.android.gms.cast.tv.action.LAUNCH" />
    <category android:name="android.intent.category.DEFAULT" />
  </intent-filter>
</activity>

কাস্ট রিসিভার প্রসঙ্গ জীবনচক্র

আপনার অ্যাপটি চালু হওয়ার সাথে সাথে CastReceiverContext শুরু করা উচিত এবং যখন আপনার অ্যাপটি ব্যাকগ্রাউন্ডে সরানো হয় তখন CastReceiverContext বন্ধ করা উচিত। আমরা আপনাকে androidx.lifecycle লাইব্রেরি থেকে LifecycleObserver ব্যবহার করে CastReceiverContext.start() এবং CastReceiverContext.stop() কলিং পরিচালনা করার পরামর্শ দিচ্ছি।

MyApplication.kt ফাইলটি খুলুন, অ্যাপ্লিকেশনের onCreate পদ্ধতিতে initInstance() কল করে কাস্ট কনটেক্সটটি ইনিশিয়ালাইজ করুন। AppLifeCycleObserver ক্লাসে অ্যাপ্লিকেশনটি পুনরায় শুরু হলে start() CastReceiverContext এবং অ্যাপ্লিকেশনটি পজ করা হলে stop() করুন:

package com.google.sample.cast.castconnect

import com.google.android.gms.cast.tv.CastReceiverContext
...

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        CastReceiverContext.initInstance(this)
        ProcessLifecycleOwner.get().lifecycle.addObserver(AppLifecycleObserver())
    }

    class AppLifecycleObserver : DefaultLifecycleObserver {
        override fun onResume(owner: LifecycleOwner) {
            Log.d(LOG_TAG, "onResume")
            CastReceiverContext.getInstance().start()
        }

        override fun onPause(owner: LifecycleOwner) {
            Log.d(LOG_TAG, "onPause")
            CastReceiverContext.getInstance().stop()
        }
    }
}

মিডিয়া ম্যানেজারের সাথে মিডিয়াসেশন সংযোগ করা হচ্ছে

MediaManager হল CastReceiverContext singleton-এর একটি সম্পত্তি, এটি মিডিয়া স্ট্যাটাস পরিচালনা করে, লোড ইনটেন্ট পরিচালনা করে, প্রেরকদের কাছ থেকে মিডিয়া নেমস্পেস বার্তাগুলিকে মিডিয়া কমান্ডে অনুবাদ করে এবং মিডিয়া স্ট্যাটাস প্রেরকদের কাছে ফেরত পাঠায়।

যখন আপনি একটি MediaSession তৈরি করেন, তখন আপনাকে বর্তমান MediaSession টোকেনটি MediaManager কে প্রদান করতে হবে যাতে এটি জানতে পারে কোথায় কমান্ড পাঠাতে হবে এবং মিডিয়া প্লেব্যাক অবস্থা পুনরুদ্ধার করতে হবে। PlaybackVideoFragment.kt ফাইলে, MediaManager এ টোকেন সেট করার আগে নিশ্চিত করুন যে MediaSession শুরু হয়েছে।

import com.google.android.gms.cast.tv.CastReceiverContext
import com.google.android.gms.cast.tv.media.MediaManager
...

class PlaybackVideoFragment : VideoSupportFragment() {
    private var castReceiverContext: CastReceiverContext? = null
    ...

    private fun initializePlayer() {
        if (mPlayer == null) {
            ...
            mMediaSession = MediaSessionCompat(getContext(), LOG_TAG)
            ...
            castReceiverContext = CastReceiverContext.getInstance()
            if (castReceiverContext != null) {
                val mediaManager: MediaManager = castReceiverContext!!.getMediaManager()
                mediaManager.setSessionCompatToken(mMediaSession!!.getSessionToken())
            }

        }
    }
}

নিষ্ক্রিয় প্লেব্যাকের কারণে যখন আপনি আপনার MediaSession রিলিজ করেন, তখন আপনার MediaManager এ একটি null টোকেন সেট করা উচিত:

private fun releasePlayer() {
    mMediaSession?.release()
    castReceiverContext?.mediaManager?.setSessionCompatToken(null)
    ...
}

আসুন নমুনা অ্যাপটি চালাই।

ক্লিক করুন অ্যান্ড্রয়েড স্টুডিওর রান বোতাম, ডানদিকে নির্দেশিত একটি সবুজ ত্রিভুজ আপনার ATV ডিভাইসে অ্যাপটি স্থাপন করতে Run বোতামটি ব্যবহার করুন, অ্যাপটি বন্ধ করুন এবং ATV হোম স্ক্রিনে ফিরে যান। আপনার প্রেরকের কাছ থেকে, Cast বোতামে ক্লিক করুন। কাস্ট বোতাম আইকন এবং আপনার ATV ডিভাইসটি নির্বাচন করুন। আপনি দেখতে পাবেন ATV ডিভাইসে ATV অ্যাপটি চালু হয়েছে এবং Cast বোতামের অবস্থা সংযুক্ত হয়েছে।

৬. মিডিয়া লোড হচ্ছে

ডেভেলপার কনসোলে আপনার দ্বারা সংজ্ঞায়িত প্যাকেজ নামের একটি ইন্টেন্টের মাধ্যমে লোড কমান্ডটি পাঠানো হয়। এই ইন্টেন্টটি গ্রহণকারী টার্গেট অ্যাক্টিভিটি নির্দিষ্ট করার জন্য আপনাকে আপনার অ্যান্ড্রয়েড টিভি অ্যাপে নিম্নলিখিত পূর্বনির্ধারিত ইন্টেন্ট ফিল্টারটি যুক্ত করতে হবে। AndroidManifest.xml ফাইলে, PlayerActivity তে লোড ইন্টেন্ট ফিল্টারটি যুক্ত করুন:

<activity android:name="com.google.sample.cast.castconnect.PlaybackActivity"
          android:launchMode="singleTask"
          android:exported="true">
  <intent-filter>
     <action android:name="com.google.android.gms.cast.tv.action.LOAD"/>
     <category android:name="android.intent.category.DEFAULT" />
  </intent-filter>
</activity>

অ্যান্ড্রয়েড টিভিতে লোড অনুরোধ পরিচালনা করা

এখন যেহেতু কার্যকলাপটি লোড অনুরোধ সম্বলিত এই অভিপ্রায়টি গ্রহণ করার জন্য কনফিগার করা হয়েছে, আমাদের এটি পরিচালনা করতে হবে।

অ্যাক্টিভিটি শুরু হওয়ার সময় অ্যাপটি processIntent নামে একটি প্রাইভেট মেথড কল করে। এই মেথডটিতে ইনকামিং ইন্টেন্ট প্রসেস করার লজিক থাকে। লোড রিকোয়েস্ট পরিচালনা করার জন্য আমরা এই মেথডটি পরিবর্তন করব এবং MediaManager ইনস্ট্যান্সের onNewIntent মেথডটি কল করে আরও প্রসেস করার জন্য ইন্টেন্টটি পাঠাব। যদি MediaManager সনাক্ত করে যে ইন্টেন্টটি একটি লোড রিকোয়েস্ট, তাহলে এটি ইন্টেন্ট থেকে MediaLoadRequestData অবজেক্টটি বের করে MediaLoadCommandCallback.onLoad() ব্যবহার করে। লোড রিকোয়েস্ট ধারণকারী ইন্টেন্ট পরিচালনা করার জন্য PlaybackVideoFragment.kt ফাইলে processIntent মেথডটি পরিবর্তন করুন:

fun processIntent(intent: Intent?) {
    val mediaManager: MediaManager = CastReceiverContext.getInstance().getMediaManager()
    // Pass intent to Cast SDK
    if (mediaManager.onNewIntent(intent)) {
        return
    }

    // Clears all overrides in the modifier.
    mediaManager.getMediaStatusModifier().clear()

    // If the SDK doesn't recognize the intent, handle the intent with your own logic.
    ...
}

এরপর আমরা MediaLoadCommandCallback অ্যাবস্ট্রাক্ট ক্লাসটি প্রসারিত করব যা MediaManager দ্বারা ডাকা onLoad() পদ্ধতিটিকে ওভাররাইড করবে। এই পদ্ধতিটি লোড অনুরোধের ডেটা গ্রহণ করে এবং এটিকে একটি Movie অবজেক্টে রূপান্তর করে। একবার রূপান্তরিত হয়ে গেলে, স্থানীয় প্লেয়ার দ্বারা মুভিটি চালানো হয়। এরপর MediaManager MediaLoadRequest দিয়ে আপডেট করা হয় এবং সংযুক্ত প্রেরকদের কাছে MediaStatus সম্প্রচার করে। PlaybackVideoFragment.kt ফাইলে MyMediaLoadCommandCallback নামে একটি নেস্টেড প্রাইভেট ক্লাস তৈরি করুন:

import com.google.android.gms.cast.MediaLoadRequestData
import com.google.android.gms.cast.MediaInfo
import com.google.android.gms.cast.MediaMetadata
import com.google.android.gms.cast.MediaError
import com.google.android.gms.cast.tv.media.MediaException
import com.google.android.gms.cast.tv.media.MediaCommandCallback
import com.google.android.gms.cast.tv.media.QueueUpdateRequestData
import com.google.android.gms.cast.tv.media.MediaLoadCommandCallback
import com.google.android.gms.tasks.Task
import com.google.android.gms.tasks.Tasks
import android.widget.Toast
...

private inner class MyMediaLoadCommandCallback :  MediaLoadCommandCallback() {
    override fun onLoad(
        senderId: String?, mediaLoadRequestData: MediaLoadRequestData): Task<MediaLoadRequestData> {
        Toast.makeText(activity, "onLoad()", Toast.LENGTH_SHORT).show()
        return if (mediaLoadRequestData == null) {
            // Throw MediaException to indicate load failure.
            Tasks.forException(MediaException(
                MediaError.Builder()
                    .setDetailedErrorCode(MediaError.DetailedErrorCode.LOAD_FAILED)
                    .setReason(MediaError.ERROR_REASON_INVALID_REQUEST)
                    .build()))
        } else Tasks.call {
            play(convertLoadRequestToMovie(mediaLoadRequestData)!!)
            // Update media metadata and state
            val mediaManager = castReceiverContext!!.mediaManager
            mediaManager.setDataFromLoad(mediaLoadRequestData)
            mediaLoadRequestData
        }
    }
}

private fun convertLoadRequestToMovie(mediaLoadRequestData: MediaLoadRequestData?): Movie? {
    if (mediaLoadRequestData == null) {
        return null
    }
    val mediaInfo: MediaInfo = mediaLoadRequestData.getMediaInfo() ?: return null
    var videoUrl: String = mediaInfo.getContentId()
    if (mediaInfo.getContentUrl() != null) {
        videoUrl = mediaInfo.getContentUrl()
    }
    val metadata: MediaMetadata = mediaInfo.getMetadata()
    val movie = Movie()
    movie.videoUrl = videoUrl
    movie.title = metadata?.getString(MediaMetadata.KEY_TITLE)
    movie.description = metadata?.getString(MediaMetadata.KEY_SUBTITLE)
    if(metadata?.hasImages() == true) {
        movie.cardImageUrl = metadata.images[0].url.toString()
    }
    return movie
}

এখন যেহেতু কলব্যাক সংজ্ঞায়িত করা হয়েছে, আমাদের এটি MediaManager এ নিবন্ধন করতে হবে। MediaManager.onNewIntent() কল করার আগে কলব্যাকটি নিবন্ধিত হতে হবে। প্লেয়ারটি শুরু করার সময় setMediaLoadCommandCallback যোগ করুন:

private fun initializePlayer() {
    if (mPlayer == null) {
        ...
        mMediaSession = MediaSessionCompat(getContext(), LOG_TAG)
        ...
        castReceiverContext = CastReceiverContext.getInstance()
        if (castReceiverContext != null) {
            val mediaManager: MediaManager = castReceiverContext.getMediaManager()
            mediaManager.setSessionCompatToken(mMediaSession.getSessionToken())
            mediaManager.setMediaLoadCommandCallback(MyMediaLoadCommandCallback())
        }
    }
}

আসুন নমুনা অ্যাপটি চালাই।

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

৭. কাস্ট কন্ট্রোল কমান্ড সমর্থন করা

বর্তমান অ্যাপ্লিকেশনটি এখন মিডিয়া সেশনের সাথে সামঞ্জস্যপূর্ণ মৌলিক কমান্ডগুলিকে সমর্থন করে, যেমন প্লে, পজ এবং সিক। তবে, কিছু কাস্ট কন্ট্রোল কমান্ড রয়েছে যা মিডিয়া সেশনে উপলব্ধ নয়। কাস্ট কন্ট্রোল কমান্ডগুলিকে সমর্থন করার জন্য আপনাকে একটি MediaCommandCallback নিবন্ধন করতে হবে।

প্লেয়ারটি শুরু করার সময় setMediaCommandCallback ব্যবহার করে MediaManager ইনস্ট্যান্সে MyMediaCommandCallback যোগ করুন:

private fun initializePlayer() {
    ...
    castReceiverContext = CastReceiverContext.getInstance()
    if (castReceiverContext != null) {
        val mediaManager = castReceiverContext!!.mediaManager
        ...
        mediaManager.setMediaCommandCallback(MyMediaCommandCallback())
    }
}

পদ্ধতিগুলিকে ওভাররাইড করার জন্য MyMediaCommandCallback ক্লাস তৈরি করুন, যেমন onQueueUpdate() যা কাস্ট নিয়ন্ত্রণ কমান্ডগুলিকে সমর্থন করে:

private inner class MyMediaCommandCallback : MediaCommandCallback() {
    override fun onQueueUpdate(
        senderId: String?,
        queueUpdateRequestData: QueueUpdateRequestData
    ): Task<Void> {
        Toast.makeText(getActivity(), "onQueueUpdate()", Toast.LENGTH_SHORT).show()
        // Queue Prev / Next
        if (queueUpdateRequestData.getJump() != null) {
            Toast.makeText(
                getActivity(),
                "onQueueUpdate(): Jump = " + queueUpdateRequestData.getJump(),
                Toast.LENGTH_SHORT
            ).show()
        }
        return super.onQueueUpdate(senderId, queueUpdateRequestData)
    }
}

৮. মিডিয়া স্ট্যাটাস নিয়ে কাজ করা

মিডিয়া স্ট্যাটাস পরিবর্তন করা হচ্ছে

Cast Connect মিডিয়া সেশন থেকে বেস মিডিয়া স্ট্যাটাস পায়। উন্নত বৈশিষ্ট্যগুলি সমর্থন করার জন্য, আপনার Android TV অ্যাপটি MediaStatusModifier এর মাধ্যমে অতিরিক্ত স্ট্যাটাস বৈশিষ্ট্যগুলি নির্দিষ্ট এবং ওভাররাইড করতে পারে। MediaStatusModifier সর্বদা আপনার CastReceiverContext এ সেট করা MediaSession এ কাজ করবে।

উদাহরণস্বরূপ, onLoad কলব্যাক ট্রিগার হলে setMediaCommandSupported নির্দিষ্ট করতে:

import com.google.android.gms.cast.MediaStatus
...
private class MyMediaLoadCommandCallback : MediaLoadCommandCallback() {
    fun onLoad(
        senderId: String?,
        mediaLoadRequestData: MediaLoadRequestData
    ): Task<MediaLoadRequestData> {
        Toast.makeText(getActivity(), "onLoad()", Toast.LENGTH_SHORT).show()
        ...
        return Tasks.call({
            play(convertLoadRequestToMovie(mediaLoadRequestData)!!)
            ...
            // Use MediaStatusModifier to provide additional information for Cast senders.
            mediaManager.getMediaStatusModifier()
                .setMediaCommandSupported(MediaStatus.COMMAND_QUEUE_NEXT, true)
                .setIsPlayingAd(false)
            mediaManager.broadcastMediaStatus()
            // Return the resolved MediaLoadRequestData to indicate load success.
            mediaLoadRequestData
        })
    }
}

পাঠানোর আগে মিডিয়াস্ট্যাটাস আটকানো

ওয়েব রিসিভার SDK এর MessageInterceptor এর মতো, আপনি আপনার MediaManager এ একটি MediaStatusWriter নির্দিষ্ট করতে পারেন যাতে সংযুক্ত প্রেরকদের কাছে সম্প্রচার করার আগে আপনার MediaStatus এ অতিরিক্ত পরিবর্তন করা যায়।

উদাহরণস্বরূপ, মোবাইল প্রেরকদের কাছে পাঠানোর আগে আপনি MediaStatus এ কাস্টম ডেটা সেট করতে পারেন:

import com.google.android.gms.cast.tv.media.MediaManager.MediaStatusInterceptor
import com.google.android.gms.cast.tv.media.MediaStatusWriter
import org.json.JSONObject
import org.json.JSONException
...

private fun initializePlayer() {
    if (mPlayer == null) {
        ...
        if (castReceiverContext != null) {
            ...
            val mediaManager: MediaManager = castReceiverContext.getMediaManager()
            ...
            // Use MediaStatusInterceptor to process the MediaStatus before sending out.
            mediaManager.setMediaStatusInterceptor(
                MediaStatusInterceptor { mediaStatusWriter: MediaStatusWriter ->
                    try {
                        mediaStatusWriter.setCustomData(JSONObject("{myData: 'CustomData'}"))
                    } catch (e: JSONException) {
                        Log.e(LOG_TAG,e.message,e);
                    }
            })
        }
    }
}        

৯. অভিনন্দন

এখন তুমি জানো কিভাবে Cast Connect Library ব্যবহার করে একটি Android TV অ্যাপ Cast-সক্ষম করতে হয়।

আরও বিস্তারিত জানার জন্য ডেভেলপার গাইডটি দেখুন: /cast/docs/android_tv_receiver