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

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

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

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

গুগল কাস্ট কী?

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

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

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

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

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

তুমি কি শিখবে

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

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

  • সর্বশেষ অ্যান্ড্রয়েড এসডিকে
  • অ্যান্ড্রয়েড স্টুডিও সংস্করণ 3.2+
  • অ্যান্ড্রয়েড ৪.১+ জেলি বিন (এপিআই লেভেল ১৬) সহ একটি মোবাইল ডিভাইস।
  • আপনার মোবাইল ডিভাইসটিকে আপনার ডেভেলপমেন্ট কম্পিউটারের সাথে সংযুক্ত করার জন্য একটি USB ডেটা কেবল।
  • ইন্টারনেট অ্যাক্সেস সহ কনফিগার করা Chromecast বা Android TV এর মতো একটি Google Cast ডিভাইস।
  • HDMI ইনপুট সহ একটি টিভি বা মনিটর।
  • Cast Connect ইন্টিগ্রেশন পরীক্ষা করার জন্য Google TV সহ একটি Chromecast প্রয়োজন, তবে বাকি কোডল্যাবের জন্য এটি ঐচ্ছিক। যদি আপনার কাছে এটি না থাকে, তাহলে এই টিউটোরিয়ালের শেষে "Add Cast Connect Support" ধাপটি এড়িয়ে যেতে দ্বিধা করবেন না।

অভিজ্ঞতা

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

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

শুধু পুরোটা পড়ুন এটি পড়ুন এবং অনুশীলনগুলি সম্পূর্ণ করুন।

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

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

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

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

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

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

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

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

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

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

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

ওয়েলকাম স্ক্রিনে ইমপোর্ট প্রজেক্ট অথবা ফাইল > নতুন > ইমপোর্ট প্রজেক্ট... মেনু অপশন নির্বাচন করুন।

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

ফাইল > ক্লিক করুন অ্যান্ড্রয়েড স্টুডিও 'গ্রেডলের সাথে প্রকল্প সিঙ্ক করুন' বোতাম গ্রেডল ফাইলের সাথে প্রকল্প সিঙ্ক করুন

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

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

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

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

ভিডিওটি আপনার Google Cast ডিভাইসে চলতে শুরু করবে।

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

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

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

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

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

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

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

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

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

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

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

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

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

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

অ্যাপ ডিজাইন

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

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

ভিডিও ব্রাউজার অ্যাক্টিভিটি

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

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

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

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

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

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

নির্ভরতা

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

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

৫. কাস্ট বোতাম যোগ করা

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

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

নির্ভরতা

প্রয়োজনীয় লাইব্রেরি নির্ভরতা অন্তর্ভুক্ত করতে অ্যাপ 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 ইন্টারফেসটি বাস্তবায়ন করতে হবে। সবচেয়ে গুরুত্বপূর্ণ বিকল্প হল রিসিভার অ্যাপ্লিকেশন আইডি, যা Cast ডিভাইস আবিষ্কারের ফলাফল ফিল্টার করতে এবং Cast সেশন শুরু হলে রিসিভার অ্যাপ্লিকেশন চালু করতে ব্যবহৃত হয়।

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

প্রকল্পের 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 ডিভাইস নির্বাচন করার অনুমতি দেওয়ার জন্য আমাদের Cast বোতামটি যুক্ত করতে হবে। 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"/>

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

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
}

LocalPlayerActivity তে onCreateOptionsMenu একইভাবে ওভাররাইড করুন।

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

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

৬. ভিডিও কন্টেন্ট কাস্ট করা

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

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

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

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

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

আমরা পূর্ববর্তী বিভাগে ধাপ ২ ইতিমধ্যেই সম্পন্ন করেছি। ধাপ ৩ কাস্ট ফ্রেমওয়ার্কের সাথে করা সহজ। ধাপ ১ হল একটি বস্তুর সাথে অন্য বস্তুর ম্যাপিং করা; MediaInfo হল এমন কিছু যা Cast ফ্রেমওয়ার্ক বোঝে এবং 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 কার্যকলাপে, আমরা যখন Cast ডিভাইস থেকে সংযুক্ত বা সংযোগ বিচ্ছিন্ন হয়ে যাই তখন আমাদের অবহিত করতে আগ্রহী, যাতে আমরা স্থানীয় প্লেয়ারে স্যুইচ করতে পারি। মনে রাখবেন যে সংযোগটি কেবল আপনার মোবাইল ডিভাইসে চলমান অ্যাপ্লিকেশনের উদাহরণের মাধ্যমেই ব্যাহত হতে পারে না, বরং এটি আপনার (অথবা অন্য কোনও) অ্যাপ্লিকেশনের অন্য একটি উদাহরণের মাধ্যমেও ব্যাহত হতে পারে যা অন্য কোনও মোবাইল ডিভাইসে চলছে।

বর্তমানে সক্রিয় সেশনটি 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))
    ...
}

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

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

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

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

কাস্ট 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"/>

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

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

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

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

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

প্রেরক যখন কাস্ট করবেন তখন 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()
}

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

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

৯. ভূমিকা ওভারলে

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

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

Cast SDK একটি কাস্টম ভিউ প্রদান করে, IntroductoryOverlay , যা ব্যবহারকারীদের প্রথম দেখানোর সময় Cast বোতামটি হাইলাইট করতে ব্যবহার করা যেতে পারে। 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 যোগ করুন এবং যখন একটি Cast ডিভাইস উপলব্ধ থাকে তখন showIntroductoryOverlay পদ্ধতিটি কল করুন, onCreate পদ্ধতিটি পরিবর্তন করে এবং নিম্নলিখিতগুলির সাথে মিল করার জন্য 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!!)
}

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

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

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

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

Cast SDK এক্সপেন্ডেড কন্ট্রোলারের জন্য একটি উইজেট প্রদান করে যার নাম ExpandedControllerActivity । এটি একটি অ্যাবস্ট্রাক্ট ক্লাস যা আপনাকে Cast বোতাম যোগ করার জন্য সাবক্লাস করতে হবে।

প্রথমত, একটি নতুন মেনু রিসোর্স ফাইল তৈরি করুন, যার নাম expanded_controller.xml , যাতে প্রসারিত কন্ট্রোলারটি Cast বোতামটি প্রদান করতে পারে:

<?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 সম্পাদনা করুন এবং NotificationOptions এবং CastMediaOptions পরিবর্তন করে লক্ষ্য কার্যকলাপটি ExpandedControlsActivity তে সেট করুন:

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())
}

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

১১. কাস্ট কানেক্ট সাপোর্ট যোগ করুন

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

নির্ভরতা

দ্রষ্টব্য: Cast Connect বাস্তবায়নের জন্য, play-services-cast-framework 19.0.0 বা তার বেশি হতে হবে।

লঞ্চ অপশন

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

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 অ্যাপে পাঠানো হবে না।

Launch Credentials সেট করার জন্য 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 এখন স্বয়ংক্রিয়ভাবে বর্তমান সেশনের জন্য কোন শংসাপত্র ব্যবহার করবে তা পরিচালনা করবে।

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

গুগল টিভির মাধ্যমে Chromecast-এ Android TV APK ইনস্টল করার ধাপ

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

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

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

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>

১৩. অভিনন্দন

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

আরও বিস্তারিত জানার জন্য, অ্যান্ড্রয়েড সেন্ডার ডেভেলপার গাইড দেখুন।