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

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

Google Cast লোগো

এই কোডল্যাবটি আপনাকে শেখাবে কিভাবে একটি Google Cast-সক্ষম ডিভাইসে সামগ্রী কাস্ট করতে একটি বিদ্যমান Android ভিডিও অ্যাপ পরিবর্তন করতে হয়৷

Google Cast কি?

Google Cast ব্যবহারকারীদের একটি মোবাইল ডিভাইস থেকে একটি টিভিতে সামগ্রী কাস্ট করার অনুমতি দেয়৷ ব্যবহারকারীরা তখন তাদের মোবাইল ডিভাইসটিকে টিভিতে মিডিয়া প্লেব্যাকের জন্য রিমোট কন্ট্রোল হিসাবে ব্যবহার করতে পারে।

Google Cast SDK আপনাকে একটি টিভি বা সাউন্ড সিস্টেম নিয়ন্ত্রণ করতে আপনার অ্যাপ প্রসারিত করতে দেয়৷ কাস্ট SDK আপনাকে Google Cast ডিজাইন চেকলিস্টের উপর ভিত্তি করে প্রয়োজনীয় UI উপাদান যোগ করার অনুমতি দেয়।

Google Cast ডিজাইন চেকলিস্ট সমস্ত সমর্থিত প্ল্যাটফর্ম জুড়ে কাস্ট ব্যবহারকারীর অভিজ্ঞতা সহজ এবং অনুমানযোগ্য করার জন্য প্রদান করা হয়েছে৷

আমরা কি নির্মাণ করা যাচ্ছে?

আপনি যখন এই কোডল্যাবটি সম্পূর্ণ করবেন, তখন আপনার কাছে একটি Android ভিডিও অ্যাপ থাকবে যা একটি Google Cast-সক্ষম ডিভাইসে ভিডিও কাস্ট করতে সক্ষম হবে৷

আপনি কি শিখবেন

  • একটি নমুনা ভিডিও অ্যাপে কীভাবে Google Cast SDK যোগ করবেন।
  • একটি Google Cast ডিভাইস নির্বাচন করার জন্য কাস্ট বোতামটি কীভাবে যুক্ত করবেন।
  • কীভাবে একটি কাস্ট ডিভাইসের সাথে সংযোগ করবেন এবং একটি মিডিয়া রিসিভার চালু করবেন৷
  • কিভাবে একটি ভিডিও কাস্ট করতে হয়।
  • কীভাবে আপনার অ্যাপে একটি কাস্ট মিনি কন্ট্রোলার যোগ করবেন।
  • মিডিয়া বিজ্ঞপ্তি এবং লক স্ক্রিন নিয়ন্ত্রণগুলিকে কীভাবে সমর্থন করবেন।
  • কীভাবে একটি প্রসারিত নিয়ামক যুক্ত করবেন।
  • কিভাবে একটি পরিচায়ক ওভারলে প্রদান করতে হয়।
  • কাস্ট উইজেটগুলি কীভাবে কাস্টমাইজ করবেন।
  • কাস্ট কানেক্টের সাথে কীভাবে একীভূত করবেন

আপনি কি প্রয়োজন হবে

  • সর্বশেষ Android SDK
  • অ্যান্ড্রয়েড স্টুডিও সংস্করণ 3.2+
  • Android 4.1+ Jelly Bean (API লেভেল 16) সহ একটি মোবাইল ডিভাইস।
  • আপনার মোবাইল ডিভাইসকে আপনার ডেভেলপমেন্ট কম্পিউটারের সাথে সংযুক্ত করার জন্য একটি USB ডাটা কেবল।
  • একটি Google Cast ডিভাইস যেমন একটি Chromecast বা Android TV কনফিগার করা ইন্টারনেট অ্যাক্সেস সহ।
  • HDMI ইনপুট সহ একটি টিভি বা মনিটর।
  • কাস্ট কানেক্ট ইন্টিগ্রেশন পরীক্ষা করার জন্য Google TV-এর সাথে একটি Chromecast প্রয়োজন কিন্তু বাকি কোডল্যাবের জন্য ঐচ্ছিক। যদি আপনার কাছে না থাকে, তাহলে এই টিউটোরিয়ালের শেষের দিকে কাস্ট কানেক্ট সাপোর্ট যোগ করুন ধাপটি এড়িয়ে যান।

অভিজ্ঞতা

  • আপনার আগের কোটলিন এবং অ্যান্ড্রয়েড ডেভেলপমেন্ট জ্ঞান থাকতে হবে।
  • আপনার টিভি দেখার পূর্ববর্তী জ্ঞানেরও প্রয়োজন হবে :)

আপনি কিভাবে এই টিউটোরিয়াল ব্যবহার করবেন?

শুধুমাত্র মাধ্যমে এটি পড়ুন এটি পড়ুন এবং ব্যায়াম সম্পূর্ণ করুন

আপনি অ্যান্ড্রয়েড অ্যাপ তৈরি করার অভিজ্ঞতাকে কীভাবে মূল্যায়ন করবেন?

নবজাতক মধ্যবর্তী দক্ষ

আপনি টিভি দেখার সাথে আপনার অভিজ্ঞতাকে কীভাবে মূল্যায়ন করবেন?

নবজাতক মধ্যবর্তী দক্ষ

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

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

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

3. নমুনা অ্যাপ চালান

একজোড়া কম্পাসের আইকন

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

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

স্বাগতম স্ক্রিনে আমদানি প্রকল্প বা ফাইল > নতুন > আমদানি প্রকল্প... মেনু বিকল্প নির্বাচন করুন।

নির্বাচন করুন ফোল্ডার আইকন নমুনা কোড ফোল্ডার থেকে app-done ডিরেক্টরি এবং ঠিক আছে ক্লিক করুন.

ফাইল > ক্লিক করুন Android Studio 'Sync Project with Gradle' বোতাম গ্রেডল ফাইলের সাথে প্রকল্প সিঙ্ক করুন

আপনার অ্যান্ড্রয়েড ডিভাইসে USB ডিবাগিং সক্ষম করুন - Android 4.2 এবং উচ্চতর সংস্করণে, বিকাশকারী বিকল্প স্ক্রীনটি ডিফল্টরূপে লুকানো থাকে৷ এটি দৃশ্যমান করতে, সেটিংস > ফোন সম্পর্কে যান এবং বিল্ড নম্বরে সাতবার আলতো চাপুন। পূর্ববর্তী স্ক্রিনে ফিরে যান, সিস্টেম > অ্যাডভান্সড- এ যান এবং নীচের কাছে বিকাশকারী বিকল্পগুলিতে আলতো চাপুন, তারপর এটি চালু করতে USB ডিবাগিং- এ আলতো চাপুন৷

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

ভিডিও অ্যাপে কাস্ট বোতামে ক্লিক করুন এবং আপনার Google Cast ডিভাইস নির্বাচন করুন।

একটি ভিডিও নির্বাচন করুন এবং প্লে বোতামে ক্লিক করুন।

ভিডিওটি আপনার Google Cast ডিভাইসে চালানো শুরু হবে৷

প্রসারিত নিয়ামক প্রদর্শিত হবে. আপনি প্লেব্যাক নিয়ন্ত্রণ করতে প্লে/পজ বোতাম ব্যবহার করতে পারেন।

ভিডিওর তালিকায় ফিরে যান।

একটি মিনি কন্ট্রোলার এখন স্ক্রিনের নীচে দৃশ্যমান। স্ক্রিনের নীচে প্রদর্শিত মিনি কন্ট্রোলারের সাথে 'কাস্ট ভিডিও' অ্যাপ চালানোর একটি অ্যান্ড্রয়েড ফোনের চিত্র

রিসিভারে ভিডিও পজ করতে মিনি কন্ট্রোলারের পজ বোতামে ক্লিক করুন। মিনি কন্ট্রোলারে প্লে বোতামে ক্লিক করে আবার ভিডিও চালানো চালিয়ে যান।

মোবাইল ডিভাইসের হোম বোতামে ক্লিক করুন। বিজ্ঞপ্তিগুলি টানুন এবং আপনার এখন কাস্ট সেশনের জন্য একটি বিজ্ঞপ্তি দেখতে হবে৷

আপনার ফোন লক করুন এবং আপনি যখন এটি আনলক করেন, তখন মিডিয়া প্লেব্যাক নিয়ন্ত্রণ করতে বা কাস্টিং বন্ধ করতে আপনার লক স্ক্রিনে একটি বিজ্ঞপ্তি দেখতে হবে৷

ভিডিও অ্যাপে ফিরে যান এবং Google Cast ডিভাইসে কাস্ট করা বন্ধ করতে কাস্ট বোতামে ক্লিক করুন।

সচরাচর জিজ্ঞাস্য

4. শুরু প্রকল্প প্রস্তুত করুন

'কাস্ট ভিডিও' অ্যাপ চালানোর একটি অ্যান্ড্রয়েড ফোনের চিত্র

আপনার ডাউনলোড করা স্টার্ট অ্যাপে আমাদের Google Cast এর জন্য সমর্থন যোগ করতে হবে। এখানে কিছু Google Cast পরিভাষা রয়েছে যা আমরা এই কোডল্যাবে ব্যবহার করব:

  • একটি প্রেরক অ্যাপ একটি মোবাইল ডিভাইস বা ল্যাপটপে চলে,
  • একটি রিসিভার অ্যাপ Google Cast ডিভাইসে চলে।

এখন আপনি অ্যান্ড্রয়েড স্টুডিও ব্যবহার করে স্টার্টার প্রকল্পের শীর্ষে তৈরি করতে প্রস্তুত:

  1. নির্বাচন করুন ফোল্ডার আইকন আপনার নমুনা কোড ডাউনলোড থেকে app-start ডিরেক্টরি (স্বাগত স্ক্রিনে আমদানি প্রকল্প নির্বাচন করুন বা ফাইল > নতুন > আমদানি প্রকল্প... মেনু বিকল্প)।
  2. ক্লিক করুন Android Studio 'Sync Project with Gradle' বোতাম গ্রেডল ফাইল বোতামের সাথে প্রকল্প সিঙ্ক করুন
  3. ক্লিক করুন অ্যান্ড্রয়েড স্টুডিওর রান বোতাম, একটি সবুজ ত্রিভুজ ডানদিকে নির্দেশ করে অ্যাপটি চালাতে এবং UI অন্বেষণ করতে চালান বোতাম।

অ্যাপ ডিজাইন

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

অ্যাপটিতে দুটি প্রধান ক্রিয়াকলাপ রয়েছে: VideoBrowserActivity এবং LocalPlayerActivity । Google Cast কার্যকারিতা একীভূত করার জন্য, কার্যকলাপগুলিকে AppCompatActivity বা এর অভিভাবক FragmentActivity থেকে উত্তরাধিকার সূত্রে প্রাপ্ত করতে হবে৷ এই সীমাবদ্ধতাটি বিদ্যমান যেহেতু আমাদের MediaRouteButton ( MediaRouter সমর্থন লাইব্রেরিতে সরবরাহ করা) একটি MediaRouteActionProvider হিসাবে যুক্ত করতে হবে এবং এটি শুধুমাত্র তখনই কাজ করবে যদি কার্যকলাপটি উপরে উল্লিখিত ক্লাস থেকে উত্তরাধিকারসূত্রে পাওয়া যায়। MediaRouter সমর্থন লাইব্রেরি AppCompat সমর্থন লাইব্রেরির উপর নির্ভর করে যা প্রয়োজনীয় ক্লাস প্রদান করে।

ভিডিও ব্রাউজার কার্যকলাপ

এই কার্যকলাপে একটি Fragment ( VideoBrowserFragment ) রয়েছে। এই তালিকাটি একটি ArrayAdapter ( VideoListAdapter ) দ্বারা সমর্থিত। ভিডিওগুলির তালিকা এবং তাদের সম্পর্কিত মেটাডেটা একটি JSON ফাইল হিসাবে একটি দূরবর্তী সার্ভারে হোস্ট করা হয়৷ একটি AsyncTaskLoader ( VideoItemLoader ) এই JSON নিয়ে আসে এবং MediaItem অবজেক্টের একটি তালিকা তৈরি করতে এটি প্রক্রিয়া করে।

একটি MediaItem অবজেক্ট একটি ভিডিও এবং এর সাথে সম্পর্কিত মেটাডেটা মডেল করে, যেমন এর শিরোনাম, বর্ণনা, স্ট্রীমের URL, সমর্থনকারী চিত্রগুলির জন্য URL, এবং সংশ্লিষ্ট পাঠ্য ট্র্যাক (বন্ধ ক্যাপশনের জন্য) যদি থাকে। MediaItem অবজেক্টটি ক্রিয়াকলাপের মধ্যে পাস করা হয়, তাই MediaItem এর ইউটিলিটি পদ্ধতি রয়েছে যাতে এটিকে Bundle রূপান্তর করা যায় এবং এর বিপরীতে।

যখন লোডার MediaItems এর তালিকা তৈরি করে, তখন এটি সেই তালিকাটিকে VideoListAdapter এ পাঠায় যা VideoBrowserFragment MediaItems তালিকা উপস্থাপন করে। ব্যবহারকারীকে প্রতিটি ভিডিওর জন্য একটি সংক্ষিপ্ত বিবরণ সহ ভিডিও থাম্বনেইলের একটি তালিকা উপস্থাপন করা হয়। যখন একটি আইটেম নির্বাচন করা হয়, তখন সংশ্লিষ্ট MediaItem একটি Bundle রূপান্তরিত হয় এবং LocalPlayerActivity এ পাস করা হয়।

লোকাল প্লেয়ার অ্যাক্টিভিটি

এই কার্যকলাপ একটি নির্দিষ্ট ভিডিও সম্পর্কে মেটাডেটা প্রদর্শন করে এবং ব্যবহারকারীকে মোবাইল ডিভাইসে স্থানীয়ভাবে ভিডিও চালানোর অনুমতি দেয়।

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

নির্ভরতা

যেহেতু আমরা AppCompatActivity ব্যবহার করছি, তাই আমাদের AppCompat সমর্থন লাইব্রেরি প্রয়োজন। ভিডিওগুলির তালিকা পরিচালনা করার জন্য এবং তালিকার জন্য অ্যাসিঙ্ক্রোনাসভাবে ছবিগুলি পাওয়ার জন্য, আমরা ভলি লাইব্রেরি ব্যবহার করছি৷

সচরাচর জিজ্ঞাস্য

5. কাস্ট বোতাম যোগ করা হচ্ছে

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

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

নির্ভরতা

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

dependencies {
    implementation 'androidx.appcompat:appcompat:1.5.0'
    implementation 'androidx.mediarouter:mediarouter:1.3.1'
    implementation 'androidx.recyclerview:recyclerview:1.2.1'
    implementation 'com.google.android.gms:play-services-cast-framework:21.1.0'
    implementation 'com.android.volley:volley:1.2.1'
    implementation "androidx.core:core-ktx:1.8.0"
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
}

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

আরম্ভ

কাস্ট ফ্রেমওয়ার্কের একটি গ্লোবাল সিঙ্গলটন অবজেক্ট আছে, CastContext , যা সমস্ত কাস্ট ইন্টারঅ্যাকশনের সমন্বয় করে।

CastContext সিঙ্গেলটন শুরু করার জন্য প্রয়োজনীয় CastOptions সরবরাহ করতে আপনাকে অবশ্যই OptionsProvider ইন্টারফেস প্রয়োগ করতে হবে। সবচেয়ে গুরুত্বপূর্ণ বিকল্প হল রিসিভার অ্যাপ্লিকেশন আইডি, যা কাস্ট ডিভাইস আবিষ্কারের ফলাফল ফিল্টার করতে এবং কাস্ট সেশন শুরু হলে রিসিভার অ্যাপ্লিকেশন চালু করতে ব্যবহৃত হয়।

যখন আপনি আপনার নিজস্ব কাস্ট-সক্ষম অ্যাপ বিকাশ করেন, তখন আপনাকে একজন কাস্ট বিকাশকারী হিসাবে নিবন্ধন করতে হবে এবং তারপরে আপনার অ্যাপের জন্য একটি অ্যাপ্লিকেশন আইডি পেতে হবে৷ এই কোডল্যাবের জন্য, আমরা একটি নমুনা অ্যাপ আইডি ব্যবহার করব।

প্রকল্পের com.google.sample.cast.refplayer প্যাকেজে নিম্নলিখিত নতুন CastOptionsProvider.kt ফাইল যোগ করুন:

package com.google.sample.cast.refplayer

import android.content.Context
import com.google.android.gms.cast.framework.OptionsProvider
import com.google.android.gms.cast.framework.CastOptions
import com.google.android.gms.cast.framework.SessionProvider

class CastOptionsProvider : OptionsProvider {
    override fun getCastOptions(context: Context): CastOptions {
        return CastOptions.Builder()
                .setReceiverApplicationId(context.getString(R.string.app_id))
                .build()
    }

    override fun getAdditionalSessionProviders(context: Context): List<SessionProvider>? {
        return null
    }
}

এখন AndroidManifest.xml ফাইলের " application " ট্যাগের মধ্যে OptionsProvider ঘোষণা করুন:

<meta-data
    android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
    android:value="com.google.sample.cast.refplayer.CastOptionsProvider" />

VideoBrowserActivity onCreate পদ্ধতিতে অলসভাবে CastContext আরম্ভ করুন:

import com.google.android.gms.cast.framework.CastContext

private var mCastContext: CastContext? = null

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

    mCastContext = CastContext.getSharedInstance(this)
}

LocalPlayerActivity তে একই প্রারম্ভিক যুক্তি যোগ করুন।

কাস্ট বোতাম

এখন যেহেতু CastContext আরম্ভ করা হয়েছে, ব্যবহারকারীকে একটি Cast ডিভাইস নির্বাচন করার অনুমতি দেওয়ার জন্য আমাদের কাস্ট বোতামটি যোগ করতে হবে। কাস্ট বোতামটি MediaRouter সমর্থন লাইব্রেরি থেকে MediaRouteButton দ্বারা প্রয়োগ করা হয়। যেকোনো অ্যাকশন আইকনের মতো যা আপনি আপনার কার্যকলাপে যোগ করতে পারেন (একটি ActionBar বা একটি Toolbar ব্যবহার করে), আপনাকে প্রথমে আপনার মেনুতে সংশ্লিষ্ট মেনু আইটেম যোগ করতে হবে।

res/menu/browse.xml ফাইলটি সম্পাদনা করুন এবং সেটিংস আইটেমের আগে মেনুতে MediaRouteActionProvider আইটেমটি যোগ করুন:

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

কাস্ট ফ্রেমওয়ার্কে MediaRouteButton ওয়্যার আপ করতে CastButtonFactory ব্যবহার করে VideoBrowserActivity এর onCreateOptionsMenu() পদ্ধতি ওভাররাইড করুন:

import com.google.android.gms.cast.framework.CastButtonFactory

private var mediaRouteMenuItem: MenuItem? = null

override fun onCreateOptionsMenu(menu: Menu): Boolean {
     super.onCreateOptionsMenu(menu)
     menuInflater.inflate(R.menu.browse, menu)
     mediaRouteMenuItem = CastButtonFactory.setUpMediaRouteButton(getApplicationContext(), menu,
                R.id.media_route_menu_item)
     return true
}

একইভাবে LocalPlayerActivityonCreateOptionsMenu ওভাররাইড করুন।

ক্লিক করুন অ্যান্ড্রয়েড স্টুডিওর রান বোতাম, একটি সবুজ ত্রিভুজ ডানদিকে নির্দেশ করে আপনার মোবাইল ডিভাইসে অ্যাপ্লিকেশন চালানোর জন্য চালান বোতাম. আপনি অ্যাপের অ্যাকশন বারে একটি কাস্ট বোতাম দেখতে পাবেন এবং যখন আপনি এটিতে ক্লিক করবেন, এটি আপনার স্থানীয় নেটওয়ার্কে কাস্ট ডিভাইসগুলির তালিকা করবে৷ ডিভাইস আবিষ্কার CastContext দ্বারা স্বয়ংক্রিয়ভাবে পরিচালিত হয়৷ আপনার কাস্ট ডিভাইস নির্বাচন করুন এবং নমুনা রিসিভার অ্যাপটি কাস্ট ডিভাইসে লোড হবে। আপনি ব্রাউজ কার্যকলাপ এবং স্থানীয় প্লেয়ার কার্যকলাপের মধ্যে নেভিগেট করতে পারেন এবং কাস্ট বোতামের অবস্থা সিঙ্কে রাখা হয়৷

আমরা মিডিয়া প্লেব্যাকের জন্য কোনো সমর্থন যোগ করিনি, তাই আপনি এখনও কাস্ট ডিভাইসে ভিডিও চালাতে পারবেন না। সংযোগ বিচ্ছিন্ন করতে কাস্ট বোতামে ক্লিক করুন।

6. ভিডিও কন্টেন্ট কাস্টিং

'কাস্ট ভিডিও' অ্যাপ চালানোর একটি অ্যান্ড্রয়েড ফোনের চিত্র

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

কাস্টিং মিডিয়া

একটি উচ্চ স্তরে, আপনি যদি একটি কাস্ট ডিভাইসে একটি মিডিয়া চালাতে চান, তাহলে আপনাকে এই জিনিসগুলি করতে হবে:

  1. একটি MediaInfo অবজেক্ট তৈরি করুন যা একটি মিডিয়া আইটেমকে মডেল করে।
  2. কাস্ট ডিভাইসে সংযোগ করুন এবং আপনার রিসিভার অ্যাপ্লিকেশন চালু করুন৷
  3. আপনার রিসিভারে MediaInfo অবজেক্টটি লোড করুন এবং সামগ্রীটি চালান।
  4. মিডিয়া স্ট্যাটাস ট্র্যাক করুন।
  5. ব্যবহারকারীর ইন্টারঅ্যাকশনের উপর ভিত্তি করে রিসিভারে প্লেব্যাক কমান্ড পাঠান।

আমরা ইতিমধ্যে পূর্ববর্তী বিভাগে ধাপ 2 সম্পন্ন করেছি। ধাপ 3 কাস্ট ফ্রেমওয়ার্কের সাথে করা সহজ। ধাপ 1 একটি বস্তুর অন্য বস্তুর ম্যাপিং পরিমাণ; MediaInfo হল এমন কিছু যা কাস্ট ফ্রেমওয়ার্ক বোঝে এবং মিডিয়া MediaItem হল মিডিয়া আইটেমের জন্য আমাদের অ্যাপের এনক্যাপসুলেশন; আমরা সহজেই একটি MediaItem একটি MediaInfo এ ম্যাপ করতে পারি।

নমুনা অ্যাপ LocalPlayerActivity ইতিমধ্যেই এই enum ব্যবহার করে স্থানীয় বনাম রিমোট প্লেব্যাকের মধ্যে পার্থক্য করে:

private var mLocation: PlaybackLocation? = null

enum class PlaybackLocation {
    LOCAL, REMOTE
}

enum class PlaybackState {
    PLAYING, PAUSED, BUFFERING, IDLE
}

সমস্ত নমুনা প্লেয়ার লজিক ঠিক কীভাবে কাজ করে তা বোঝা আপনার জন্য এই কোডল্যাবে গুরুত্বপূর্ণ নয়। এটি বোঝা গুরুত্বপূর্ণ যে আপনার অ্যাপের মিডিয়া প্লেয়ারটিকে একইভাবে দুটি প্লেব্যাক অবস্থান সম্পর্কে সচেতন হতে পরিবর্তন করতে হবে।

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

কাস্ট সেশন পরিচালনা

কাস্ট ফ্রেমওয়ার্কের জন্য একটি কাস্ট সেশন একটি ডিভাইসের সাথে সংযোগ স্থাপন, লঞ্চ (বা যোগদান), একটি রিসিভার অ্যাপ্লিকেশনের সাথে সংযোগ এবং উপযুক্ত হলে একটি মিডিয়া নিয়ন্ত্রণ চ্যানেল শুরু করার ধাপগুলিকে একত্রিত করে৷ মিডিয়া কন্ট্রোল চ্যানেল হল কাস্ট ফ্রেমওয়ার্ক কীভাবে রিসিভার মিডিয়া প্লেয়ার থেকে বার্তা পাঠায় এবং গ্রহণ করে।

ব্যবহারকারী কাস্ট বোতাম থেকে একটি ডিভাইস নির্বাচন করলে কাস্ট সেশন স্বয়ংক্রিয়ভাবে শুরু হবে এবং ব্যবহারকারীর সংযোগ বিচ্ছিন্ন হলে স্বয়ংক্রিয়ভাবে বন্ধ হয়ে যাবে। নেটওয়ার্কিং সমস্যার কারণে রিসিভার সেশনের সাথে পুনরায় সংযোগ করাও কাস্ট SDK দ্বারা স্বয়ংক্রিয়ভাবে পরিচালনা করা হয়।

LocalPlayerActivity একটি SessionManagerListener লিসেনার যোগ করা যাক:

import com.google.android.gms.cast.framework.CastSession
import com.google.android.gms.cast.framework.SessionManagerListener
...

private var mSessionManagerListener: SessionManagerListener<CastSession>? = null
private var mCastSession: CastSession? = null
...

private fun setupCastListener() {
    mSessionManagerListener = object : SessionManagerListener<CastSession> {
        override fun onSessionEnded(session: CastSession, error: Int) {
            onApplicationDisconnected()
        }

        override fun onSessionResumed(session: CastSession, wasSuspended: Boolean) {
            onApplicationConnected(session)
        }

        override fun onSessionResumeFailed(session: CastSession, error: Int) {
            onApplicationDisconnected()
        }

        override fun onSessionStarted(session: CastSession, sessionId: String) {
            onApplicationConnected(session)
        }

        override fun onSessionStartFailed(session: CastSession, error: Int) {
            onApplicationDisconnected()
        }

        override fun onSessionStarting(session: CastSession) {}
        override fun onSessionEnding(session: CastSession) {}
        override fun onSessionResuming(session: CastSession, sessionId: String) {}
        override fun onSessionSuspended(session: CastSession, reason: Int) {}
        private fun onApplicationConnected(castSession: CastSession) {
            mCastSession = castSession
            if (null != mSelectedMedia) {
                if (mPlaybackState == PlaybackState.PLAYING) {
                    mVideoView!!.pause()
                    loadRemoteMedia(mSeekbar!!.progress, true)
                    return
                } else {
                    mPlaybackState = PlaybackState.IDLE
                    updatePlaybackLocation(PlaybackLocation.REMOTE)
                }
            }
            updatePlayButton(mPlaybackState)
            invalidateOptionsMenu()
        }

        private fun onApplicationDisconnected() {
            updatePlaybackLocation(PlaybackLocation.LOCAL)
            mPlaybackState = PlaybackState.IDLE
            mLocation = PlaybackLocation.LOCAL
            updatePlayButton(mPlaybackState)
            invalidateOptionsMenu()
       }
   }
}

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

বর্তমানে সক্রিয় সেশনটি SessionManager.getCurrentSession() হিসাবে অ্যাক্সেসযোগ্য। কাস্ট ডায়ালগগুলির সাথে ব্যবহারকারীর ইন্টারঅ্যাকশনের প্রতিক্রিয়া হিসাবে সেশনগুলি তৈরি হয় এবং স্বয়ংক্রিয়ভাবে ছিঁড়ে যায়৷

আমাদের সেশন লিসেনার নিবন্ধন করতে হবে এবং কিছু ভেরিয়েবল শুরু করতে হবে যা আমরা কার্যকলাপে ব্যবহার করব। LocalPlayerActivity onCreate পদ্ধতিতে পরিবর্তন করুন:

import com.google.android.gms.cast.framework.CastContext
...

private var mCastContext: CastContext? = null
...

override fun onCreate(savedInstanceState: Bundle?) {
    ...
    mCastContext = CastContext.getSharedInstance(this)
    mCastSession = mCastContext!!.sessionManager.currentCastSession
    setupCastListener()
    ...
    loadViews()
    ...
    val bundle = intent.extras
    if (bundle != null) {
        ....
        if (shouldStartPlayback) {
              ....

        } else {
            if (mCastSession != null && mCastSession!!.isConnected()) {
                updatePlaybackLocation(PlaybackLocation.REMOTE)
            } else {
                updatePlaybackLocation(PlaybackLocation.LOCAL)
            }
            mPlaybackState = PlaybackState.IDLE
            updatePlayButton(mPlaybackState)
        }
    }
    ...
}

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

Cast SDK-এ, RemoteMediaClient রিসিভারে রিমোট মিডিয়া প্লেব্যাক পরিচালনার জন্য সুবিধাজনক API-এর একটি সেট প্রদান করে। মিডিয়া প্লেব্যাক সমর্থন করে এমন একটি CastSession এর জন্য, SDK দ্বারা RemoteMediaClient এর একটি উদাহরণ স্বয়ংক্রিয়ভাবে তৈরি হবে৷ CastSession উদাহরণে getRemoteMediaClient() পদ্ধতিতে কল করে এটি অ্যাক্সেস করা যেতে পারে। রিসিভারে বর্তমানে নির্বাচিত ভিডিও লোড করতে LocalPlayerActivity তে নিম্নলিখিত পদ্ধতিগুলি যোগ করুন:

import com.google.android.gms.cast.framework.media.RemoteMediaClient
import com.google.android.gms.cast.MediaInfo
import com.google.android.gms.cast.MediaLoadOptions
import com.google.android.gms.cast.MediaMetadata
import com.google.android.gms.common.images.WebImage
import com.google.android.gms.cast.MediaLoadRequestData

private fun loadRemoteMedia(position: Int, autoPlay: Boolean) {
    if (mCastSession == null) {
        return
    }
    val remoteMediaClient = mCastSession!!.remoteMediaClient ?: return
    remoteMediaClient.load( MediaLoadRequestData.Builder()
                .setMediaInfo(buildMediaInfo())
                .setAutoplay(autoPlay)
                .setCurrentTime(position.toLong()).build())
}

private fun buildMediaInfo(): MediaInfo? {
    val movieMetadata = MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE)
    mSelectedMedia?.studio?.let { movieMetadata.putString(MediaMetadata.KEY_SUBTITLE, it) }
    mSelectedMedia?.title?.let { movieMetadata.putString(MediaMetadata.KEY_TITLE, it) }
    movieMetadata.addImage(WebImage(Uri.parse(mSelectedMedia!!.getImage(0))))
    movieMetadata.addImage(WebImage(Uri.parse(mSelectedMedia!!.getImage(1))))
    return mSelectedMedia!!.url?.let {
        MediaInfo.Builder(it)
            .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
            .setContentType("videos/mp4")
            .setMetadata(movieMetadata)
            .setStreamDuration((mSelectedMedia!!.duration * 1000).toLong())
            .build()
    }
}

এখন দূরবর্তী প্লেব্যাক সমর্থন করতে কাস্ট সেশন লজিক ব্যবহার করতে বিদ্যমান বিভিন্ন পদ্ধতি আপডেট করুন:

private fun play(position: Int) {
    startControllersTimer()
    when (mLocation) {
        PlaybackLocation.LOCAL -> {
            mVideoView!!.seekTo(position)
            mVideoView!!.start()
        }
        PlaybackLocation.REMOTE -> {
            mPlaybackState = PlaybackState.BUFFERING
            updatePlayButton(mPlaybackState)
            //seek to a new position within the current media item's new position 
            //which is in milliseconds from the beginning of the stream
            mCastSession!!.remoteMediaClient?.seek(position.toLong())
        }
        else -> {}
    }
    restartTrickplayTimer()
}
private fun togglePlayback() {
    ...
    PlaybackState.IDLE -> when (mLocation) {
        ...
        PlaybackLocation.REMOTE -> {
            if (mCastSession != null && mCastSession!!.isConnected) {
                loadRemoteMedia(mSeekbar!!.progress, true)
            }
        }
        else -> {}
    }
    ...
}
override fun onPause() {
    ...
    mCastContext!!.sessionManager.removeSessionManagerListener(
                mSessionManagerListener!!, CastSession::class.java)
}
override fun onResume() {
    Log.d(TAG, "onResume() was called")
    mCastContext!!.sessionManager.addSessionManagerListener(
            mSessionManagerListener!!, CastSession::class.java)
    if (mCastSession != null && mCastSession!!.isConnected) {
        updatePlaybackLocation(PlaybackLocation.REMOTE)
    } else {
        updatePlaybackLocation(PlaybackLocation.LOCAL)
    }
    super.onResume()
}

updatePlayButton পদ্ধতির জন্য, isConnected ভেরিয়েবলের মান পরিবর্তন করুন:

private fun updatePlayButton(state: PlaybackState?) {
    ...
    val isConnected = (mCastSession != null
                && (mCastSession!!.isConnected || mCastSession!!.isConnecting))
    ...
}

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

7. মিনি কন্ট্রোলার

কাস্ট ডিজাইন চেকলিস্টের প্রয়োজন যে সমস্ত কাস্ট অ্যাপ একটি মিনি কন্ট্রোলার প্রদান করে যা ব্যবহারকারী যখন বর্তমান সামগ্রী পৃষ্ঠা থেকে দূরে নেভিগেট করে তখন প্রদর্শিত হয়৷ মিনি কন্ট্রোলার তাত্ক্ষণিক অ্যাক্সেস এবং বর্তমান কাস্ট সেশনের জন্য একটি দৃশ্যমান অনুস্মারক প্রদান করে৷

কাস্ট ভিডিও অ্যাপে মিনিপ্লেয়ার দেখানো Android ফোনের নীচের অংশের চিত্র

কাস্ট SDK একটি কাস্টম ভিউ প্রদান করে, MiniControllerFragment , যা আপনি মিনি কন্ট্রোলার দেখাতে চান এমন কার্যকলাপের অ্যাপ লেআউট ফাইলে যোগ করা যেতে পারে।

res/layout/player_activity.xml এবং res/layout/video_browser.xml উভয়ের নীচে নিম্নলিখিত খণ্ড সংজ্ঞা যোগ করুন:

<fragment
    android:id="@+id/castMiniController"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:visibility="gone"
    class="com.google.android.gms.cast.framework.media.widget.MiniControllerFragment"/>

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

8. বিজ্ঞপ্তি এবং লক স্ক্রীন

Google Cast ডিজাইন চেকলিস্টের জন্য একটি প্রেরক অ্যাপের প্রয়োজন একটি বিজ্ঞপ্তি এবং লক স্ক্রীন থেকে মিডিয়া নিয়ন্ত্রণগুলি কার্যকর করার জন্য৷

বিজ্ঞপ্তি এলাকায় মিডিয়া নিয়ন্ত্রণ দেখানো একটি Android ফোনের চিত্র

কাস্ট SDK প্রেরক অ্যাপকে বিজ্ঞপ্তি এবং লক স্ক্রীনের জন্য মিডিয়া নিয়ন্ত্রণ তৈরি করতে সাহায্য করার জন্য একটি MediaNotificationService প্রদান করে। পরিষেবাটি স্বয়ংক্রিয়ভাবে গ্রেডল দ্বারা আপনার অ্যাপের ম্যানিফেস্টে একত্রিত হয়৷

প্রেরক কাস্ট করার সময় MediaNotificationService ব্যাকগ্রাউন্ডে চলবে এবং বর্তমান কাস্টিং আইটেম, একটি প্লে/পজ বোতাম এবং একটি স্টপ বোতাম সম্পর্কে একটি চিত্র থাম্বনেল এবং মেটাডেটা সহ একটি বিজ্ঞপ্তি দেখাবে৷

CastContext আরম্ভ করার সময় বিজ্ঞপ্তি এবং লক স্ক্রীন নিয়ন্ত্রণগুলি CastOptions দিয়ে সক্ষম করা যেতে পারে৷ বিজ্ঞপ্তি এবং লক স্ক্রীনের জন্য মিডিয়া নিয়ন্ত্রণগুলি ডিফল্টরূপে চালু থাকে৷ যতক্ষণ নোটিফিকেশন চালু থাকে ততক্ষণ লক স্ক্রিন বৈশিষ্ট্যটি চালু থাকে।

CastOptionsProvider সম্পাদনা করুন এবং এই কোডের সাথে মেলে getCastOptions বাস্তবায়ন পরিবর্তন করুন:

import com.google.android.gms.cast.framework.media.CastMediaOptions
import com.google.android.gms.cast.framework.media.NotificationOptions

override fun getCastOptions(context: Context): CastOptions {
   val notificationOptions = NotificationOptions.Builder()
            .setTargetActivityClassName(VideoBrowserActivity::class.java.name)
            .build()
    val mediaOptions = CastMediaOptions.Builder()
            .setNotificationOptions(notificationOptions)
            .build()
   return CastOptions.Builder()
                .setReceiverApplicationId(context.getString(R.string.app_id))
                .setCastMediaOptions(mediaOptions)
                .build()
}

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

লক স্ক্রিনে মিডিয়া নিয়ন্ত্রণ দেখানো একটি Android ফোনের চিত্র

9. পরিচায়ক ওভারলে

Google Cast ডিজাইন চেকলিস্টের জন্য একটি প্রেরক অ্যাপের প্রয়োজন যাতে বিদ্যমান ব্যবহারকারীদের সাথে কাস্ট বোতামটি পরিচয় করিয়ে দিতে পারে যাতে প্রেরক অ্যাপটি এখন কাস্টিং সমর্থন করে এবং Google Cast এ নতুন ব্যবহারকারীদের সাহায্য করে।

কাস্ট ভিডিও অ্যান্ড্রয়েড অ্যাপে কাস্ট বোতামের চারপাশে সূচনামূলক কাস্ট ওভারলে দেখানো চিত্র

কাস্ট SDK একটি কাস্টম ভিউ প্রদান করে, IntroductoryOverlay , যা ব্যবহারকারীদের কাছে প্রথম দেখানো হলে কাস্ট বোতামটি হাইলাইট করতে ব্যবহার করা যেতে পারে। VideoBrowserActivity তে নিম্নলিখিত কোড যোগ করুন:

import com.google.android.gms.cast.framework.IntroductoryOverlay
import android.os.Looper

private var mIntroductoryOverlay: IntroductoryOverlay? = null

private fun showIntroductoryOverlay() {
    mIntroductoryOverlay?.remove()
    if (mediaRouteMenuItem?.isVisible == true) {
       Looper.myLooper().run {
           mIntroductoryOverlay = com.google.android.gms.cast.framework.IntroductoryOverlay.Builder(
                    this@VideoBrowserActivity, mediaRouteMenuItem!!)
                   .setTitleText("Introducing Cast")
                   .setSingleTime()
                   .setOnOverlayDismissedListener(
                           object : IntroductoryOverlay.OnOverlayDismissedListener {
                               override fun onOverlayDismissed() {
                                   mIntroductoryOverlay = null
                               }
                          })
                   .build()
          mIntroductoryOverlay!!.show()
        }
    }
}

এখন, একটি CastStateListener যোগ করুন এবং onCreate পদ্ধতি পরিবর্তন করে একটি কাস্ট ডিভাইস উপলব্ধ হলে showIntroductoryOverlay পদ্ধতিতে কল করুন এবং নিম্নলিখিতগুলির সাথে মেলানোর জন্য onResume এবং onPause পদ্ধতিগুলিকে ওভাররাইড করুন:

import com.google.android.gms.cast.framework.CastState
import com.google.android.gms.cast.framework.CastStateListener

private var mCastStateListener: CastStateListener? = null

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.video_browser)
    setupActionBar()
    mCastStateListener = object : CastStateListener {
            override fun onCastStateChanged(newState: Int) {
                if (newState != CastState.NO_DEVICES_AVAILABLE) {
                    showIntroductoryOverlay()
                }
            }
        }
    mCastContext = CastContext.getSharedInstance(this)
}

override fun onResume() {
    super.onResume()
    mCastContext?.addCastStateListener(mCastStateListener!!)
}

override fun onPause() {
    super.onPause()
    mCastContext?.removeCastStateListener(mCastStateListener!!)
}

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

10. প্রসারিত নিয়ামক

Google Cast ডিজাইন চেকলিস্টের জন্য একটি প্রেরক অ্যাপ প্রয়োজন যাতে মিডিয়া কাস্ট করা হয় তার জন্য প্রসারিত কন্ট্রোলার প্রদান করে৷ প্রসারিত কন্ট্রোলারটি মিনি কন্ট্রোলারের একটি পূর্ণ স্ক্রীন সংস্করণ।

একটি অ্যান্ড্রয়েড ফোনে বাজানো একটি ভিডিওর দৃষ্টান্ত যেখানে প্রসারিত কন্ট্রোলার ওভারলে করছে৷

কাস্ট SDK প্রসারিত কন্ট্রোলারের জন্য একটি উইজেট প্রদান করে যাকে বলা হয় ExpandedControllerActivity । এটি একটি বিমূর্ত শ্রেণী যা আপনাকে একটি কাস্ট বোতাম যোগ করতে সাবক্লাস করতে হবে।

প্রথমত, একটি নতুন মেনু রিসোর্স ফাইল তৈরি করুন, যাকে বলা হয় expanded_controller.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>

com.google.sample.cast.refplayer প্যাকেজে একটি নতুন প্যাকেজ expandedcontrols তৈরি করুন৷ এরপর, com.google.sample.cast.refplayer.expandedcontrols প্যাকেজে ExpandedControlsActivity.kt নামে একটি নতুন ফাইল তৈরি করুন।

package com.google.sample.cast.refplayer.expandedcontrols

import android.view.Menu
import com.google.android.gms.cast.framework.media.widget.ExpandedControllerActivity
import com.google.sample.cast.refplayer.R
import com.google.android.gms.cast.framework.CastButtonFactory

class ExpandedControlsActivity : ExpandedControllerActivity() {
    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        super.onCreateOptionsMenu(menu)
        menuInflater.inflate(R.menu.expanded_controller, menu)
        CastButtonFactory.setUpMediaRouteButton(this, menu, R.id.media_route_menu_item)
        return true
    }
}

এখন OPTIONS_PROVIDER_CLASS_NAME এর উপরে থাকা application ট্যাগের মধ্যে AndroidManifest.xmlExpandedControlsActivity ঘোষণা করুন:

<application>
    ...
    <activity
        android:name="com.google.sample.cast.refplayer.expandedcontrols.ExpandedControlsActivity"
        android:label="@string/app_name"
        android:launchMode="singleTask"
        android:theme="@style/Theme.CastVideosDark"
        android:screenOrientation="portrait"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
        </intent-filter>
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.google.sample.cast.refplayer.VideoBrowserActivity"/>
    </activity>
    ...
</application>

CastOptionsProvider এডিট করুন এবং টার্গেট অ্যাক্টিভিটি কে ExpandedControlsActivity এ সেট করতে NotificationOptions এবং CastMediaOptions পরিবর্তন করুন:

import com.google.sample.cast.refplayer.expandedcontrols.ExpandedControlsActivity

override fun getCastOptions(context: Context): CastOptions {
    val notificationOptions = NotificationOptions.Builder()
            .setTargetActivityClassName(ExpandedControlsActivity::class.java.name)
            .build()
    val mediaOptions = CastMediaOptions.Builder()
            .setNotificationOptions(notificationOptions)
            .setExpandedControllerActivityClassName(ExpandedControlsActivity::class.java.name)
            .build()
    return CastOptions.Builder()
            .setReceiverApplicationId(context.getString(R.string.app_id))
            .setCastMediaOptions(mediaOptions)
            .build()
}

যখন রিমোট মিডিয়া লোড হয় তখন ExpandedControlsActivity প্রদর্শন করতে LocalPlayerActivity loadRemoteMedia পদ্ধতি আপডেট করুন:

import com.google.sample.cast.refplayer.expandedcontrols.ExpandedControlsActivity

private fun loadRemoteMedia(position: Int, autoPlay: Boolean) {
    if (mCastSession == null) {
        return
    }
    val remoteMediaClient = mCastSession!!.remoteMediaClient ?: return
    remoteMediaClient.registerCallback(object : RemoteMediaClient.Callback() {
        override fun onStatusUpdated() {
            val intent = Intent(this@LocalPlayerActivity, ExpandedControlsActivity::class.java)
            startActivity(intent)
            remoteMediaClient.unregisterCallback(this)
        }
    })
    remoteMediaClient.load(MediaLoadRequestData.Builder()
                .setMediaInfo(buildMediaInfo())
                .setAutoplay(autoPlay)
                .setCurrentTime(position.toLong()).build())
}

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

11. কাস্ট কানেক্ট সমর্থন যোগ করুন

কাস্ট কানেক্ট লাইব্রেরি বিদ্যমান প্রেরক অ্যাপ্লিকেশনগুলিকে কাস্ট প্রোটোকলের মাধ্যমে Android TV অ্যাপ্লিকেশনগুলির সাথে যোগাযোগ করার অনুমতি দেয়৷ কাস্ট কানেক্ট কাস্ট পরিকাঠামোর উপরে তৈরি করে, আপনার Android TV অ্যাপ রিসিভার হিসেবে কাজ করে।

নির্ভরতা

দ্রষ্টব্য: কাস্ট কানেক্ট বাস্তবায়নের জন্য, play-services-cast-framework 19.0.0 বা উচ্চতর হতে হবে।

লঞ্চ অপশন

Android TV অ্যাপ্লিকেশানটি চালু করার জন্য, যাকে Android রিসিভারও বলা হয়, আমাদের LaunchOptions অবজেক্টে setAndroidReceiverCompatible পতাকাটিকে সত্য হিসাবে সেট করতে হবে। এই LaunchOptions অবজেক্ট নির্দেশ করে যে কীভাবে রিসিভার চালু করা হয় এবং CastOptionsProvider ক্লাসের দ্বারা ফেরত দেওয়া CastOptions এ পাঠানো হয়। উপরে উল্লিখিত পতাকাটিকে false সেট করা, কাস্ট ডেভেলপার কনসোলে সংজ্ঞায়িত অ্যাপ আইডির জন্য ওয়েব রিসিভার চালু করবে।

CastOptionsProvider.kt ফাইলে getCastOptions পদ্ধতিতে নিম্নলিখিত যোগ করুন:

import com.google.android.gms.cast.LaunchOptions
...
val launchOptions = LaunchOptions.Builder()
            .setAndroidReceiverCompatible(true)
            .build()
return new CastOptions.Builder()
        .setLaunchOptions(launchOptions)
        ...
        .build()

লঞ্চ শংসাপত্র সেট করুন

প্রেরকের পক্ষ থেকে, আপনি সেশনে কে যোগ দিচ্ছেন তা প্রতিনিধিত্ব করতে CredentialsData নির্দিষ্ট করতে পারেন। credentials হল একটি স্ট্রিং যা ব্যবহারকারী-সংজ্ঞায়িত হতে পারে, যতক্ষণ না আপনার ATV অ্যাপ এটি বুঝতে পারে। CredentialsData শুধুমাত্র লঞ্চ বা যোগদানের সময় আপনার Android TV অ্যাপে পাঠানো হয়। আপনি সংযুক্ত থাকাকালীন এটি আবার সেট করলে, এটি আপনার Android TV অ্যাপে পাঠানো হবে না।

লঞ্চ শংসাপত্রগুলি সেট করার জন্য CredentialsData সংজ্ঞায়িত করা এবং LaunchOptions অবজেক্টে পাস করা দরকার৷ আপনার CastOptionsProvider.kt ফাইলে getCastOptions পদ্ধতিতে নিম্নলিখিত কোড যোগ করুন:

import com.google.android.gms.cast.CredentialsData
...

val credentialsData = CredentialsData.Builder()
        .setCredentials("{\"userId\": \"abc\"}")
        .build()
val launchOptions = LaunchOptions.Builder()
       ...
       .setCredentialsData(credentialsData)
       .build()

LoadRequest এ শংসাপত্র সেট করুন

যদি আপনার ওয়েব রিসিভার অ্যাপ এবং আপনার অ্যান্ড্রয়েড টিভি অ্যাপ credentials ভিন্নভাবে পরিচালনা করে, তাহলে আপনাকে প্রতিটির জন্য পৃথক credentials সংজ্ঞায়িত করতে হতে পারে। এটির যত্ন নেওয়ার জন্য, loadRemoteMedia ফাংশনের অধীনে আপনার LocalPlayerActivity.kt ফাইলে নিম্নলিখিত কোড যোগ করুন:

remoteMediaClient.load(MediaLoadRequestData.Builder()
       ...
       .setCredentials("user-credentials")
       .setAtvCredentials("atv-user-credentials")
       .build())

আপনার প্রেরক যে রিসিভার অ্যাপে কাস্ট করছেন তার উপর নির্ভর করে, SDK এখন স্বয়ংক্রিয়ভাবে বর্তমান সেশনের জন্য কোন শংসাপত্রগুলি ব্যবহার করবে তা পরিচালনা করবে।

কাস্ট কানেক্ট পরীক্ষা করা হচ্ছে

Google TV-এর সাথে Chromecast-এ Android TV APK ইনস্টল করার ধাপ

  1. আপনার অ্যান্ড্রয়েড টিভি ডিভাইসের আইপি ঠিকানা খুঁজুন। সাধারণত, এটি সেটিংস > নেটওয়ার্ক এবং ইন্টারনেট > (আপনার ডিভাইসের সাথে সংযুক্ত নেটওয়ার্কের নাম) এর অধীনে উপলব্ধ। ডানদিকে এটি নেটওয়ার্কে বিশদ এবং আপনার ডিভাইসের আইপি দেখাবে।
  2. টার্মিনাল ব্যবহার করে ADB এর মাধ্যমে সংযোগ করতে আপনার ডিভাইসের IP ঠিকানা ব্যবহার করুন:
$ adb connect <device_ip_address>:5555
  1. আপনার টার্মিনাল উইন্ডো থেকে, আপনি এই কোডল্যাবের শুরুতে ডাউনলোড করেছেন এমন কোডল্যাব নমুনার জন্য শীর্ষ স্তরের ফোল্ডারে নেভিগেট করুন। উদাহরণ স্বরূপ:
$ cd Desktop/android_codelab_src
  1. এই ফোল্ডারে থাকা .apk ফাইলটি আপনার অ্যান্ড্রয়েড টিভিতে চালিয়ে ইনস্টল করুন:
$ adb -s <device_ip_address>:5555 install android-tv-app.apk
  1. আপনি এখন আপনার Android TV ডিভাইসে আপনার অ্যাপস মেনুতে কাস্ট ভিডিও নামে একটি অ্যাপ দেখতে সক্ষম হবেন।
  2. আপনার অ্যান্ড্রয়েড স্টুডিও প্রজেক্টে ফিরে যান এবং আপনার শারীরিক মোবাইল ডিভাইসে প্রেরক অ্যাপটি ইনস্টল ও চালাতে রান বোতামে ক্লিক করুন। উপরের ডানদিকের কোণায়, কাস্ট আইকনে ক্লিক করুন এবং উপলব্ধ বিকল্পগুলি থেকে আপনার Android TV ডিভাইসটি নির্বাচন করুন৷ আপনি এখন আপনার অ্যান্ড্রয়েড টিভি ডিভাইসে চালু হওয়া অ্যান্ড্রয়েড টিভি অ্যাপটি দেখতে পাবেন এবং একটি ভিডিও চালানো আপনাকে আপনার অ্যান্ড্রয়েড টিভি রিমোট ব্যবহার করে ভিডিও প্লেব্যাক নিয়ন্ত্রণ করতে সক্ষম করবে।

12. কাস্ট উইজেট কাস্টমাইজ করুন

আপনি কাস্ট উইজেটগুলি কাস্টমাইজ করতে পারেন রঙ সেট করে, বোতামগুলিকে স্টাইল করে, পাঠ্য এবং থাম্বনেইলের উপস্থিতি, এবং প্রদর্শনের জন্য বোতামের প্রকারগুলি বেছে নিয়ে৷

res/values/styles_castvideo.xml আপডেট করুন

<style name="Theme.CastVideosTheme" parent="Theme.AppCompat.Light.NoActionBar">
    ...
    <item name="mediaRouteTheme">@style/CustomMediaRouterTheme</item>
    <item name="castIntroOverlayStyle">@style/CustomCastIntroOverlay</item>
    <item name="castMiniControllerStyle">@style/CustomCastMiniController</item>
    <item name="castExpandedControllerStyle">@style/CustomCastExpandedController</item>
    <item name="castExpandedControllerToolbarStyle">
        @style/ThemeOverlay.AppCompat.ActionBar
    </item>
    ...
</style>

নিম্নলিখিত কাস্টম থিম ঘোষণা করুন:

<!-- Customize Cast Button -->
<style name="CustomMediaRouterTheme" parent="Theme.MediaRouter">
    <item name="mediaRouteButtonStyle">@style/CustomMediaRouteButtonStyle</item>
</style>
<style name="CustomMediaRouteButtonStyle" parent="Widget.MediaRouter.Light.MediaRouteButton">
    <item name="mediaRouteButtonTint">#EEFF41</item>
</style>

<!-- Customize Introductory Overlay -->
<style name="CustomCastIntroOverlay" parent="CastIntroOverlay">
    <item name="castButtonTextAppearance">@style/TextAppearance.CustomCastIntroOverlay.Button</item>
    <item name="castTitleTextAppearance">@style/TextAppearance.CustomCastIntroOverlay.Title</item>
</style>
<style name="TextAppearance.CustomCastIntroOverlay.Button" parent="android:style/TextAppearance">
    <item name="android:textColor">#FFFFFF</item>
</style>
<style name="TextAppearance.CustomCastIntroOverlay.Title" parent="android:style/TextAppearance.Large">
    <item name="android:textColor">#FFFFFF</item>
</style>

<!-- Customize Mini Controller -->
<style name="CustomCastMiniController" parent="CastMiniController">
    <item name="castShowImageThumbnail">true</item>
    <item name="castTitleTextAppearance">@style/TextAppearance.AppCompat.Subhead</item>
    <item name="castSubtitleTextAppearance">@style/TextAppearance.AppCompat.Caption</item>
    <item name="castBackground">@color/accent</item>
    <item name="castProgressBarColor">@color/orange</item>
</style>

<!-- Customize Expanded Controller -->
<style name="CustomCastExpandedController" parent="CastExpandedController">
    <item name="castButtonColor">#FFFFFF</item>
    <item name="castPlayButtonDrawable">@drawable/cast_ic_expanded_controller_play</item>
    <item name="castPauseButtonDrawable">@drawable/cast_ic_expanded_controller_pause</item>
    <item name="castStopButtonDrawable">@drawable/cast_ic_expanded_controller_stop</item>
</style>

13. অভিনন্দন

আপনি এখন জানেন কিভাবে Android এ Cast SDK উইজেট ব্যবহার করে একটি ভিডিও অ্যাপ কাস্ট-সক্ষম করতে হয়।

আরও বিশদ বিবরণের জন্য, অ্যান্ড্রয়েড প্রেরক বিকাশকারী নির্দেশিকা দেখুন।