আপনার কাস্টম ওয়েব রিসিভারে মূল ফিচার যোগ করা

এই পৃষ্ঠায় কাস্টম ওয়েব রিসিভার অ্যাপের জন্য উপলভ্য ফিচারের কোড স্নিপেট ও বিবরণ দেওয়া আছে।

  1. একটি cast-media-player এলিমেন্ট যা ওয়েব রিসিভারের সাথে দেওয়া বিল্ট-ইন প্লেয়ার UI-কে দেখায়।
  2. cast-media-player এলিমেন্টের জন্য কাস্টম CSS-এর মতো স্টাইলিং, যার মাধ্যমে background-image, splash-image ও font-family-এর মতো বিভিন্ন UI এলিমেন্ট স্টাইল করা যায়।
  3. Web Receiver ফ্রেমওয়ার্ক লোড করার জন্য একটি স্ক্রিপ্ট এলিমেন্ট।
  4. মেসেজ ইন্টারসেপ্ট করা ও ইভেন্ট ম্যানেজ করার জন্য JavaScript কোড।
  5. অটোপ্লে করার জন্য সারিতে যোগ করুন।
  6. প্লেব্যাক কনফিগার করার বিকল্প।
  7. ওয়েব রিসিভার কন্টেক্সট সেট করার বিকল্প।
  8. Web Receiver অ্যাপে কাজ করে এমন কমান্ড সেট করার বিকল্প।
  9. Web Receiver অ্যাপ্লিকেশন চালু করার জন্য জাভাস্ক্রিপ্ট কল।

অ্যাপ্লিকেশন কনফিগারেশন ও বিকল্প

অ্যাপ্লিকেশন কনফিগার করা

CastReceiverContext হল ডেভেলপারদের কাছে এক্সপোজ করা সবচেয়ে বাইরের ক্লাস এবং এটি আন্ডারলাইং লাইব্রেরি লোড করা ম্যানেজ করে এবং Web Receiver SDK-এর ইনিশিয়ালাইজেশন হ্যান্ডেল করে। SDK এমন API প্রদান করে যা অ্যাপ্লিকেশন ডেভেলপারদের CastReceiverOptions-এর মাধ্যমে SDK কনফিগার করতে দেয়। প্রতিটি অ্যাপ্লিকেশন লঞ্চে এইসব কনফিগারেশন একবার করে মূল্যায়ন করা হয় এবং start-এ কল করার সময় ঐচ্ছিক প্যারামিটার সেট করলে SDK-কে এগুলি পাস করা হয়।

নিচের উদাহরণে দেখানো হয়েছে কীভাবে কোনও প্রেরকের কানেকশন এখনও অ্যাক্টিভ আছে কিনা তা শনাক্ত করার জন্য ডিফল্ট আচরণ ওভাররাইড করতে হয়। Web Receiver যদি কোনও প্রেরকের সাথে maxInactivity সেকেন্ড ধরে যোগাযোগ করতে না পারে, তাহলে একটি SENDER_DISCONNECTED ইভেন্ট ডিসপ্যাচ করা হয়। নিচের কনফিগারেশন এই টাইমআউট ওভাররাইড করে। সমস্যা ডিবাগ করার সময় এটি কাজে লাগতে পারে, কারণ IDLE স্ট্যাটাসে কোনও কানেক্ট করা প্রেরক না থাকলে এটি ওয়েব রিসিভার অ্যাপকে Chrome রিমোট ডিবাগার সেশন বন্ধ করা থেকে আটকায়।

const context = cast.framework.CastReceiverContext.getInstance();
const options = new cast.framework.CastReceiverOptions();
options.maxInactivity = 3600; // Development only
context.start(options);

প্লেয়ার কনফিগার করা

কন্টেন্ট লোড করার সময়, Web Receiver SDK, cast.framework.PlaybackConfig ব্যবহার করে DRM তথ্য, আবার চেষ্টা করার কনফিগারেশন এবং অনুরোধ হ্যান্ডলারের মতো প্লেব্যাক ভেরিয়েবল কনফিগার করার উপায় প্রদান করে। এই তথ্য PlayerManager দ্বারা ম্যানেজ করা হয় এবং প্লেয়ার তৈরি করার সময় এটি মূল্যায়ন করা হয়। Web Receiver SDK-তে প্রতিবার নতুন লোড পাস করা হলে প্লেয়ার তৈরি হয়। প্লেয়ার তৈরি করার পরে PlaybackConfig-এ করা পরিবর্তন পরবর্তী কন্টেন্ট লোড করার সময় মূল্যায়ন করা হয়। PlaybackConfig পরিবর্তন করার জন্য SDK নিম্নলিখিত পদ্ধতি প্রদান করে।

  • CastReceiverOptions.playbackConfig শুরু করার সময় ডিফল্ট কনফিগারেশন বিকল্প ওভাররাইড করতে CastReceiverContext।
  • PlayerManager.getPlaybackConfig() বর্তমান কনফিগারেশন পেতে।
  • PlayerManager.setPlaybackConfig() বর্তমান কনফিগারেশন ওভাররাইড করতে। পরবর্তী সব লোডের ক্ষেত্রে এই সেটিং প্রয়োগ করা হয় অথবা এটি আবার ওভাররাইড না করা পর্যন্ত প্রয়োগ করা হয়।
  • PlayerManager.setMediaPlaybackInfoHandler() বর্তমান কনফিগারেশনের উপরে লোড করা মিডিয়া আইটেমের জন্য অতিরিক্ত কনফিগারেশন প্রয়োগ করতে। প্লেয়ার তৈরি হওয়ার ঠিক আগে হ্যান্ডলারকে কল করা হয়। এখানে করা পরিবর্তন স্থায়ী নয় এবং getPlaybackConfig()-এ করা কোয়েরিতে অন্তর্ভুক্ত করা হয় না। পরবর্তী মিডিয়া আইটেম লোড করা হলে, এই হ্যান্ডলার আবার কল করা হয়।

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

const playbackConfig = new cast.framework.PlaybackConfig();
playbackConfig.manifestRequestHandler = requestInfo => {
  requestInfo.withCredentials = true;
};
context.start({playbackConfig: playbackConfig});

PlayerManager-এ দেওয়া গেটার ও সেটার ব্যবহার করে কীভাবে PlaybackConfig ওভাররাইড করতে হয় তা নিচের উদাহরণে দেখানো হল। এই সেটিং প্লেয়ারকে কনফিগার করে যাতে ১টি সেগমেন্ট লোড হওয়ার পরে কন্টেন্ট প্লেব্যাক আবার চালু করা যায়।

const playerManager =
    cast.framework.CastReceiverContext.getInstance().getPlayerManager();
const playbackConfig = (Object.assign(
            new cast.framework.PlaybackConfig(), playerManager.getPlaybackConfig()));
playbackConfig.autoResumeNumberOfSegments = 1;
playerManager.setPlaybackConfig(playbackConfig);

নিচের উদাহরণে দেখানো হয়েছে যে কীভাবে মিডিয়া প্লেব্যাক ইনফো হ্যান্ডলার ব্যবহার করে নির্দিষ্ট লোড অনুরোধের জন্য PlaybackConfig ওভাররাইড করতে হয়। হ্যান্ডলার, বর্তমান আইটেমের contentId থেকে licenseUrl পাওয়ার জন্য অ্যাপ্লিকেশনের প্রয়োগ করা getLicenseUrlForMedia পদ্ধতিকে কল করে।

playerManager.setMediaPlaybackInfoHandler((loadRequestData, playbackConfig) => {
  const mediaInformation = loadRequestData.media;
  playbackConfig.licenseUrl = getLicenseUrlForMedia(mediaInformation.contentId);

  return playbackConfig;
});

ইভেন্ট লিসনার

Web Receiver SDK আপনার Web Receiver অ্যাপকে প্লেয়ার ইভেন্ট ম্যানেজ করতে দেয়। ইভেন্ট লিসনার cast.framework.events.EventType প্যারামিটার (বা এই প্যারামিটারগুলির একটি অ্যারে) নেয় যা ইভেন্ট(গুলি) নির্দিষ্ট করে যা লিসনারকে ট্রিগার করবে। ডিবাগিংয়ের জন্য উপযোগী cast.framework.events.EventType-এর আগে থেকে কনফিগার করা অ্যারে cast.framework.events.category-এ পাওয়া যাবে। ইভেন্ট প্যারামিটার, ইভেন্ট সম্পর্কে অতিরিক্ত তথ্য প্রদান করে।

যেমন, আপনি যদি জানতে চান যে কখন mediaStatus পরিবর্তন ব্রডকাস্ট করা হচ্ছে, তাহলে ইভেন্ট ম্যানেজ করতে আপনি নিম্নলিখিত লজিক ব্যবহার করতে পারেন:

const playerManager =
    cast.framework.CastReceiverContext.getInstance().getPlayerManager();
playerManager.addEventListener(
    cast.framework.events.EventType.MEDIA_STATUS, (event) => {
      // Write your own event handling code, for example
      // using the event.mediaStatus value
});

মেসেজ ইন্টারসেপশন

Web Receiver SDK আপনার Web Receiver অ্যাপকে মেসেজ ইন্টারসেপ্ট করতে এবং সেই মেসেজে কাস্টম কোড এক্সিকিউট করতে দেয়। মেসেজ ইন্টারসেপ্টর একটি cast.framework.messages.MessageType প্যারামিটার নেয় যা কোন ধরনের মেসেজ ইন্টারসেপ্ট করা উচিত তা নির্দিষ্ট করে।

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

যেমন, আপনি যদি লোড অনুরোধ ডেটা পরিবর্তন করতে চান, তাহলে এটি ইন্টারসেপ্ট ও পরিবর্তন করতে নিম্নলিখিত লজিক ব্যবহার করতে পারেন:

const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD, loadRequestData => {
      const error = new cast.framework.messages.ErrorData(
                      cast.framework.messages.ErrorType.LOAD_FAILED);
      if (!loadRequestData.media) {
        error.reason = cast.framework.messages.ErrorReason.INVALID_PARAM;
        return error;
      }

      if (!loadRequestData.media.entity) {
        return loadRequestData;
      }

      return thirdparty.fetchAssetAndAuth(loadRequestData.media.entity,
                                          loadRequestData.credentials)
        .then(asset => {
          if (!asset) {
            throw cast.framework.messages.ErrorReason.INVALID_REQUEST;
          }

          loadRequestData.media.contentUrl = asset.url;
          loadRequestData.media.metadata = asset.metadata;
          loadRequestData.media.tracks = asset.tracks;
          return loadRequestData;
        }).catch(reason => {
          error.reason = reason; // cast.framework.messages.ErrorReason
          return error;
        });
    });

context.start();

সমস্যা ম্যানেজ করা

মেসেজ ইন্টারসেপ্টরে সমস্যা হলে, আপনার ওয়েব রিসিভার অ্যাপের উপযুক্ত cast.framework.messages.ErrorType এবং cast.framework.messages.ErrorReason রিটার্ন করা উচিত।

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD, loadRequestData => {
      const error = new cast.framework.messages.ErrorData(
                      cast.framework.messages.ErrorType.LOAD_CANCELLED);
      if (!loadRequestData.media) {
        error.reason = cast.framework.messages.ErrorReason.INVALID_PARAM;
        return error;
      }

      ...

      return fetchAssetAndAuth(loadRequestData.media.entity,
                               loadRequestData.credentials)
        .then(asset => {
          ...
          return loadRequestData;
        }).catch(reason => {
          error.reason = reason; // cast.framework.messages.ErrorReason
          return error;
        });
    });

মেসেজ ইন্টারসেপশন বনাম ইভেন্ট লিসনার

মেসেজ ইন্টারসেপশন ও ইভেন্ট লিসেনারের মধ্যে কিছু মূল পার্থক্য নিচে দেওয়া হল:

  • ইভেন্ট লিসনার আপনাকে অনুরোধের ডেটা পরিবর্তন করতে দেয় না।
  • অ্যানালিটিক্স বা কাস্টম ফাংশন ট্রিগার করার জন্য ইভেন্ট লিসনার সবচেয়ে ভালভাবে ব্যবহার করা হয়।
playerManager.addEventListener(cast.framework.events.category.CORE,
    event => {
        console.log(event);
    });
  • মেসেজ ইন্টারসেপশন আপনাকে কোনও মেসেজ শুনতে, ইন্টারসেপ্ট করতে এবং অনুরোধের ডেটা নিজেই পরিবর্তন করতে দেয়।
  • অনুরোধের ডেটার ক্ষেত্রে কাস্টম লজিক ম্যানেজ করার জন্য মেসেজ ইন্টারসেপশন সবচেয়ে ভালভাবে ব্যবহার করা হয়।

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

MediaInformation cast.framework.messages.MessageType.LOAD মেসেজে মিডিয়া লোড করার জন্য অসংখ্য প্রপার্টি প্রদান করে, যার মধ্যে entity, contentUrl ও contentId অন্তর্ভুক্ত।

  • entity প্রপার্টিটি আপনার প্রেরক এবং প্রাপক অ্যাপ, উভয়ের ক্ষেত্রেই ব্যবহার করার জন্য সাজেস্ট করা হয়েছে। প্রপার্টি হল একটি ডিপ লিঙ্ক URL যা প্লেলিস্ট বা মিডিয়া কন্টেন্ট হতে পারে। আপনার অ্যাপ্লিকেশনকে এই URL পার্স করতে হবে এবং অন্য দুটি ফিল্ডের মধ্যে অন্তত একটি পূরণ করতে হবে।
  • contentUrl প্লেয়ারটি কন্টেন্ট লোড করার জন্য যে চালানোর উপযুক্ত URL ব্যবহার করবে, এটি তার সাথে সম্পর্কিত। যেমন, এই URL একটি DASH ম্যানিফেস্টের দিকে পয়েন্ট করতে পারে।
  • contentId কোনও চালানো যায় এমন কন্টেন্টের URL (contentUrl প্রপার্টির মতো) অথবা লোড করা হচ্ছে এমন কন্টেন্ট বা প্লেলিস্টের অনন্য শনাক্তকারী হতে পারে। এই প্রপার্টিকে শনাক্তকারী হিসেবে ব্যবহার করলে, আপনার অ্যাপ্লিকেশনকে contentUrl-এ একটি প্লেযোগ্য URL পূরণ করতে হবে।

সাজেশন হল, আসল আইডি বা মূল প্যারামিটার স্টোর করতে entity ব্যবহার করুন এবং মিডিয়ার URL-এর জন্য contentUrl ব্যবহার করুন। এর একটি উদাহরণ নিচে দেওয়া স্নিপেটে দেখানো হয়েছে, যেখানে LOAD অনুরোধে entity আছে এবং খেলার উপযুক্ত contentUrl পাওয়া গেছে:

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD, loadRequestData => {
      ...

      if (!loadRequestData.media.entity) {
        // Copy the value from contentId for legacy reasons if needed
        loadRequestData.media.entity = loadRequestData.media.contentId;
      }

      return thirdparty.fetchAssetAndAuth(loadRequestData.media.entity,
                                          loadRequestData.credentials)
        .then(asset => {
          loadRequestData.media.contentUrl = asset.url;
          ...
          return loadRequestData;
        });
    });

ডিভাইসের কেপেবিলিটি

getDeviceCapabilities পদ্ধতিটি কানেক্ট করা কাস্ট ডিভাইস এবং এর সাথে অ্যাটাচ করা ভিডিও বা অডিও ডিভাইসের তথ্য প্রদান করে। getDeviceCapabilities পদ্ধতি Google Assistant, ব্লুটুথ এবং কানেক্ট করা ডিসপ্লে ও অডিও ডিভাইসের জন্য সহায়তা সংক্রান্ত তথ্য প্রদান করে।

এই পদ্ধতিটি একটি অবজেক্ট রিটার্ন করে যা আপনি নির্দিষ্ট করা এনামগুলির মধ্যে একটি পাস করে কোয়েরি করতে পারেন যাতে সেই এনামের জন্য ডিভাইসের ক্ষমতা পাওয়া যায়। enum-গুলি cast.framework.system.DeviceCapabilities-এ সংজ্ঞায়িত করা আছে।

এই উদাহরণে চেক করা হয় যে Web Receiver ডিভাইসটি IS_HDR_SUPPORTED ও IS_DV_SUPPORTED কী ব্যবহার করে HDR ও DolbyVision (DV) চালাতে পারে কিনা, যথাক্রমে।

const context = cast.framework.CastReceiverContext.getInstance();
context.addEventListener(cast.framework.system.EventType.READY, () => {
  const deviceCapabilities = context.getDeviceCapabilities();
  if (deviceCapabilities &&
      deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_HDR_SUPPORTED]) {
    // Write your own event handling code, for example
    // using the deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_HDR_SUPPORTED] value
  }
  if (deviceCapabilities &&
      deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_DV_SUPPORTED]) {
    // Write your own event handling code, for example
    // using the deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_DV_SUPPORTED] value
  }
});
context.start();

ব্যবহারকারীর ইন্টার‍্যাকশন ম্যানেজ করা

একজন ব্যবহারকারী প্রেরক অ্যাপ্লিকেশনের (ওয়েব, Android এবং iOS), অ্যাসিস্ট্যান্ট-চালু থাকা ডিভাইসে ভয়েস কমান্ড, স্মার্ট ডিসপ্লেতে টাচ কন্ট্রোল এবং Android TV ডিভাইসে রিমোট কন্ট্রোলের মাধ্যমে আপনার ওয়েব রিসিভার অ্যাপ্লিকেশনের সাথে ইন্টার‍্যাক্ট করতে পারেন। Cast SDK বিভিন্ন API প্রদান করে যাতে Web Receiver অ্যাপ এইসব ইন্টার‍্যাকশন ম্যানেজ করতে পারে, ব্যবহারকারীর অ্যাকশন স্টেট-এর মাধ্যমে অ্যাপ্লিকেশন UI আপডেট করতে পারে এবং বিকল্প হিসেবে ব্যাকএন্ড পরিষেবা আপডেট করার জন্য পরিবর্তনগুলি পাঠাতে পারে।

কাজ করে এমন মিডিয়া কমান্ড

UI কন্ট্রোল স্টেটগুলি iOS ও Android প্রেরকের এক্সপ্যান্ড করা কন্ট্রোলার, রিসিভার ও রিমোট কন্ট্রোল অ্যাপ যা টাচ ডিভাইসে চলে এবং Android TV ডিভাইসে রিসিভার অ্যাপের MediaStatus.supportedMediaCommands দ্বারা পরিচালিত হয়। কোনও প্রপার্টিতে নির্দিষ্ট বিটওয়াইজ Command চালু করা থাকলে, সেই অ্যাকশনের সাথে সম্পর্কিত বোতামগুলি চালু করা হয়। ভ্যালু সেট করা না থাকলে, বোতামটি বন্ধ থাকে। এইসব ভ্যালু ওয়েব রিসিভারে পরিবর্তন করা যেতে পারে:

  1. নির্দিষ্ট Commands সেট করতে PlayerManager.setSupportedMediaCommands ব্যবহার করা
  2. addSupportedMediaCommands ব্যবহার করে নতুন কমান্ড যোগ করা হচ্ছে
  3. removeSupportedMediaCommands ব্যবহার করে আগে থেকে থাকা কমান্ড সরানো হচ্ছে।
playerManager.setSupportedMediaCommands(cast.framework.messages.Command.SEEK |
  cast.framework.messages.Command.PAUSE);

প্রাপক আপডেট করা MediaStatus তৈরি করলে, এতে supportedMediaCommands প্রপার্টির পরিবর্তন অন্তর্ভুক্ত থাকবে। স্ট্যাটাস ব্রডকাস্ট করা হলে, কানেক্ট করা প্রেরক অ্যাপগুলি সেই অনুযায়ী তাদের UI-তে বোতাম আপডেট করবে।

কাজ করে এমন মিডিয়া কমান্ড ও টাচ ডিভাইস সম্পর্কে আরও জানতে Accessing UI controls নির্দেশিকা দেখুন।

ব্যবহারকারীর অ্যাকশন স্টেট ম্যানেজ করা হচ্ছে

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

  • কোনও মিডিয়া আইটেম লোড করার সময় ব্যবহারকারীর পছন্দ অনুযায়ী MediaInformation userActionStates সেট করুন।
  • USER_ACTION মেসেজ ইন্টারসেপ্ট করে অনুরোধ করা অ্যাকশন নির্ধারণ করে।
  • UI আপডেট করতে MediaInformation UserActionState আপডেট করুন।

নিম্নলিখিত স্নিপেট LOAD অনুরোধ ইন্টারসেপ্ট করে এবং LoadRequestData-এর MediaInformation পপুলেট করে। এই ক্ষেত্রে, লোড করা হচ্ছে এমন কন্টেন্ট ব্যবহারকারী পছন্দ করেন।

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD, (loadRequestData) => {
      const userActionLike = new cast.framework.messages.UserActionState(
          cast.framework.messages.UserAction.LIKE);
      loadRequestData.media.userActionStates = [userActionLike];

      return loadRequestData;
    });

নিম্নলিখিত স্নিপেট USER_ACTION মেসেজ ইন্টারসেপ্ট করে এবং অনুরোধ করা পরিবর্তনের সাথে ব্যাকএন্ড কল করার বিষয়টি ম্যানেজ করে। তারপরে এটি প্রাপকের ডিভাইসে UserActionState আপডেট করার জন্য কল করে।

playerManager.setMessageInterceptor(cast.framework.messages.MessageType.USER_ACTION,
  (userActionRequestData) => {
    // Obtain the media information of the current content to associate the action to.
    let mediaInfo = playerManager.getMediaInformation();

    // If there is no media info return an error and ignore the request.
    if (!mediaInfo) {
        console.error('Not playing media, user action is not supported');
        return new cast.framework.messages.ErrorData(messages.ErrorType.BAD_REQUEST);
    }

    // Reach out to backend services to store user action modifications. See sample below.
    return sendUserAction(userActionRequestData, mediaInfo)

    // Upon response from the backend, update the client's UserActionState.
    .then(backendResponse => updateUserActionStates(backendResponse))

    // If any errors occurred in the backend return them to the cast receiver.
    .catch((error) => {
      console.error(error);
      return error;
    });
});

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

function sendUserAction(userActionRequestData, mediaInfo) {
  return new Promise((resolve, reject) => {
    switch (userActionRequestData.userAction) {
      // Handle user action changes supported by the backend.
      case cast.framework.messages.UserAction.LIKE:
      case cast.framework.messages.UserAction.DISLIKE:
      case cast.framework.messages.UserAction.FOLLOW:
      case cast.framework.messages.UserAction.UNFOLLOW:
      case cast.framework.messages.UserAction.FLAG:
      case cast.framework.messages.UserAction.SKIP_AD:
        let backendResponse = {userActionRequestData: userActionRequestData, mediaInfo: mediaInfo};
        setTimeout(() => {resolve(backendResponse)}, 1000);
        break;
      // Reject all other user action changes.
      default:
        reject(
          new cast.framework.messages.ErrorData(cast.framework.messages.ErrorType.INVALID_REQUEST));
    }
  });
}

নিচের স্নিপেটটি UserActionRequestData নেয় এবং MediaInformation থেকে UserActionState যোগ করে বা সরিয়ে দেয়। MediaInformation-এর UserActionState আপডেট করলে, অনুরোধ করা অ্যাকশনের সাথে সম্পর্কিত বোতামের স্ট্যাটাস পরিবর্তিত হয়। এই পরিবর্তন স্মার্ট ডিসপ্লে কন্ট্রোল UI, রিমোট কন্ট্রোল অ্যাপ এবং Android TV UI-তে দেখা যায়। এছাড়াও, iOS এবং Android প্রেরকদের জন্য এক্সপ্যান্ড করা কন্ট্রোলারের UI আপডেট করতে, এটি আউটগোয়িং MediaStatus মেসেজের মাধ্যমে ব্রডকাস্ট করা হয়।

function updateUserActionStates(backendResponse) {
  // Unwrap the backend response.
  let mediaInfo = backendResponse.mediaInfo;
  let userActionRequestData = backendResponse.userActionRequestData;

  // If the current item playing has changed, don't update the UserActionState for the current item.
  if (playerManager.getMediaInformation().entity !== mediaInfo.entity) {
    return;
  }

  // Check for existing userActionStates in the MediaInformation.
  // If none, initialize a new array to populate states with.
  let userActionStates = mediaInfo.userActionStates || [];

  // Locate the index of the UserActionState that will be updated in the userActionStates array.
  let index = userActionStates.findIndex((currUserActionState) => {
    return currUserActionState.userAction == userActionRequestData.userAction;
  });

  if (userActionRequestData.clear) {
    // Remove the user action state from the array if cleared.
    if (index >= 0) {
      userActionStates.splice(index, 1);
    }
    else {
      console.warn("Could not find UserActionState to remove in MediaInformation");
    }
  } else {
    // Add the UserActionState to the array if enabled.
    userActionStates.push(
      new cast.framework.messages.UserActionState(userActionRequestData.userAction));
  }

  // Update the UserActionState array and set the new MediaInformation
  mediaInfo.userActionStates = userActionStates;
  playerManager.setMediaInformation(mediaInfo, true);
  return;
}

ভয়েস কমান্ড

অ্যাসিস্ট্যান্ট চালু থাকা ডিভাইসের জন্য Web Receiver SDK-তে বর্তমানে নিম্নলিখিত মিডিয়া কমান্ড কাজ করে। এইসব কমান্ডের ডিফল্ট প্রয়োগ cast.framework.PlayerManager-এ পাওয়া যায়।

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

ভয়েসের মাধ্যমে কাজ করে এমন মিডিয়া কমান্ড

অ্যাসিস্ট্যান্ট চালু থাকা ডিভাইসে ভয়েস কমান্ডের মাধ্যমে মিডিয়া কমান্ড ট্রিগার হওয়া আটকাতে, আপনাকে প্রথমে কাজ করে এমন মিডিয়া কমান্ড সেট করতে হবে যা আপনি সাপোর্ট করতে চান। তারপরে, আপনাকে অবশ্যই CastReceiverOptions.enforceSupportedCommands প্রপার্টি চালু করে সেইসব কমান্ড প্রয়োগ করতে হবে। Cast SDK প্রেরক এবং টাচ-চালিত ডিভাইসের UI পরিবর্তন করে এইসব কনফিগারেশন দেখানো হবে। ফ্ল্যাগ চালু না থাকলে, ইনকামিং ভয়েস কমান্ড কাজ করবে।

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

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

const context = cast.framework.CastReceiverContext.getInstance();

context.start({
  enforceSupportedCommands: true,
  supportedCommands: cast.framework.messages.Command.PAUSE
});

আপনি সীমাবদ্ধ করতে চান এমন প্রতিটি কমান্ডের জন্য আলাদা আলাদা লজিক প্রয়োগ করতে পারবেন। enforceSupportedCommands ফ্ল্যাগ সরিয়ে দিন এবং আপনি যে কমান্ড সীমাবদ্ধ করতে চান সেটির জন্য ইনকামিং মেসেজ ইন্টারসেপ্ট করতে পারেন। এখানে আমরা SDK-এর মাধ্যমে প্রদান করা অনুরোধ ইন্টারসেপ্ট করি যাতে SEEK অ্যাসিস্ট্যান্ট চালু থাকা ডিভাইসে ইস্যু করা কমান্ড আপনার Web Receiver অ্যাপ্লিকেশনে কোনও সিক ট্রিগার না করে।

আপনার অ্যাপ্লিকেশনে কাজ করে না এমন মিডিয়া কমান্ডের জন্য, উপযুক্ত ভুল হওয়ার কারণ রিটার্ন করুন, যেমন NOT_SUPPORTED।

playerManager.setMessageInterceptor(cast.framework.messages.MessageType.SEEK,
  seekData => {
    // Block seeking if the SEEK supported media command is disabled
    if (!(playerManager.getSupportedMediaCommands() & cast.framework.messages.Command.SEEK)) {
      let e = new cast.framework.messages.ErrorData(cast.framework.messages.ErrorType
      .INVALID_REQUEST);
      e.reason = cast.framework.messages.ErrorReason.NOT_SUPPORTED;
      return e;
    }

    return seekData;
  });

ভয়েস অ্যাক্টিভিটি থেকে ব্যাকগ্রাউন্ডিং

Assistant-এর অ্যাক্টিভিটির কারণে Cast প্ল্যাটফর্ম আপনার অ্যাপ্লিকেশনের সাউন্ড ব্যাকগ্রাউন্ডে চালালে, যেমন ব্যবহারকারীর স্পিচ শোনা বা উত্তর দেওয়া, অ্যাক্টিভিটি FocusState শুরু হলে ওয়েব রিসিভার অ্যাপ্লিকেশনে NOT_IN_FOCUS মেসেজ পাঠানো হয়। অ্যাক্টিভিটি শেষ হলে IN_FOCUS সহ আরেকটি মেসেজ পাঠানো হয়। আপনার অ্যাপ্লিকেশন ও চালানো মিডিয়ার উপর নির্ভর করে, আপনি হয়ত FocusState NOT_IN_FOCUS থাকাকালীন মেসেজ ইন্টারসেপ্ট করে মিডিয়া পজ করতে চান FOCUS_STATE টাইপ করুন।

যেমন, Assistant কোনও ব্যবহারকারীর প্রশ্নের উত্তর দিলে, অডিওবুক প্লেব্যাক পজ করা হলে তা ব্যবহারকারীর জন্য ভাল অভিজ্ঞতা হয়।

playerManager.setMessageInterceptor(cast.framework.messages.MessageType.FOCUS_STATE,
  focusStateRequestData => {
    // Pause content when the app is out of focus. Resume when focus is restored.
    if (focusStateRequestData.state == cast.framework.messages.FocusState.NOT_IN_FOCUS) {
      playerManager.pause();
    } else {
      playerManager.play();
    }

    return focusStateRequestData;
  });

ভয়েস-নির্দিষ্ট ক্যাপশন ভাষা

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

যেমন, "Ok Google, ক্যাপশন চালু করো" কমান্ডের জন্য isSuggestedLanguage-এর মান true সেট করা হয়েছে, কারণ কমান্ডটি যে ভাষায় বলা হয়েছে তা থেকে ভাষাটি অনুমান করা হয়েছে। যদি ভাষাটি স্পষ্টভাবে অনুরোধ করা হয়, যেমন "OK Google, ইংরেজি ক্যাপশন চালু করো", তাহলে isSuggestedLanguage-এর মান false হিসেবে সেট করা হয়।

মেটাডেটা ও ভয়েস কাস্টিং

ডিফল্ট হিসেবে ওয়েব রিসিভার ভয়েস কমান্ড ম্যানেজ করলেও, আপনার কন্টেন্টের মেটাডেটা সম্পূর্ণ ও সঠিক কিনা তা আপনাকে নিশ্চিত করতে হবে। এটি নিশ্চিত করে যে ভয়েস কমান্ড Assistant-এর মাধ্যমে সঠিকভাবে ম্যানেজ করা হয় এবং মেটাডেটা Google Home অ্যাপের মতো নতুন ধরনের ইন্টারফেস এবং Google Home Hub-এর মতো স্মার্ট ডিসপ্লেতে সঠিকভাবে দেখানো হয়।

স্ট্রিম ট্রান্সফার

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

স্ট্রিম ট্রান্সফারের জন্য ইভেন্ট ফ্লো হল:

  1. সোর্স ডিভাইসে:
    1. মিডিয়া বন্ধ হয়ে যায়।
    2. বর্তমান মিডিয়া স্ট্যাটাস সেভ করার জন্য ওয়েব রিসিভার অ্যাপ্লিকেশন একটি কমান্ড পায়।
    3. Web Receiver অ্যাপ্লিকেশন বন্ধ হয়ে যায়।
  2. গন্তব্য ডিভাইসে:
    1. Web Receiver অ্যাপ্লিকেশন লোড করা হয়।
    2. সেভ করা মিডিয়ার স্টেট ফিরিয়ে আনার জন্য Web Receiver অ্যাপ্লিকেশন একটি কমান্ড পায়।
    3. মিডিয়া আবার চলতে শুরু করে।

মিডিয়া স্ট্যাটাসের এলিমেন্টের মধ্যে এগুলি পড়ে:

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

স্ট্রিম ট্রান্সফার চালু করা

আপনার ওয়েব রিসিভারের জন্য স্ট্রিম ট্রান্সফার প্রয়োগ করতে:

  1. STREAM_TRANSFER কমান্ড ব্যবহার করে supportedMediaCommands আপডেট করুন:
    playerManager.addSupportedMediaCommands(
    cast.framework.messages.Command.STREAM_TRANSFER, true);
  2. সেশন স্টেট-এ বর্ণিত SESSION_STATE এবং RESUME_SESSION মেসেজ ইন্টারসেপ্টরকে ঐচ্ছিকভাবে ওভাররাইড করুন। সেশন স্ন্যাপশটের অংশ হিসেবে কাস্টম ডেটা সেভ করার প্রয়োজন হলে তবেই এগুলি ওভাররাইড করুন। অন্যথায়, সেশন স্টেট সেভ করার জন্য ডিফল্ট ইমপ্লিমেন্টেশন স্ট্রিম ট্রান্সফারকে সাপোর্ট করবে।

সেশন স্টেট সংরক্ষণ করা হচ্ছে

বর্তমান মিডিয়া স্ট্যাটাসের স্ন্যাপশট নিয়ে, স্ট্যাটাসকে লোড অনুরোধে পরিবর্তন করে এবং লোড অনুরোধের মাধ্যমে সেশন আবার চালু করে সেশন স্টেট সংরক্ষণ করার জন্য Web Receiver SDK, Web Receiver অ্যাপের জন্য ডিফল্ট প্রয়োগ প্রদান করে।

প্রয়োজন হলে, ওয়েব রিসিভারের তৈরি করা লোড অনুরোধ SESSION_STATE মেসেজ ইন্টারসেপ্টরে ওভাররাইড করা যেতে পারে। আপনি লোড করার অনুরোধে কাস্টম ডেটা যোগ করতে চাইলে, আমরা সাজেস্ট করি যে সেগুলি loadRequestData.customData-এ রাখুন।

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.SESSION_STATE,
    function (sessionState) {
        // Override sessionState.loadRequestData if needed.
        const newCredentials = updateCredentials_(sessionState.loadRequestData.credentials);
        sessionState.loadRequestData.credentials = newCredentials;

        // Add custom data if needed.
        sessionState.loadRequestData.customData = {
            'membership': 'PREMIUM'
        };

        return sessionState;
    });

RESUME_SESSION মেসেজ ইন্টারসেপ্টর থেকে loadRequestData.customData কাস্টম ডেটা ফিরিয়ে আনা যেতে পারে।

let cred_ = null;
let membership_ = null;

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.RESUME_SESSION,
    function (resumeSessionRequest) {
        let sessionState = resumeSessionRequest.sessionState;

        // Modify sessionState.loadRequestData if needed.
        cred_ = sessionState.loadRequestData.credentials;

        // Retrieve custom data.
        membership_ = sessionState.loadRequestData.customData.membership;

        return resumeSessionRequest;
    });

কন্টেন্ট প্রিলোড করা

ওয়েব রিসিভার, সারিতে বর্তমান প্লেব্যাক আইটেমের পরে মিডিয়া আইটেম প্রি-লোড করার সুবিধা দেয়।

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

প্রিলোডিং ডিফল্ট হিসেবে HLS, DASH ও Smooth স্ট্রিমিং কন্টেন্টের জন্য কাজ করবে।

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

কাস্টম মেসেজ

ওয়েব রিসিভার অ্যাপ্লিকেশনের জন্য মেসেজ আদান-প্রদান হল মূল ইন্টার‍্যাকশন পদ্ধতি।

প্রেরক যে প্ল্যাটফর্মে (Android, iOS, Web) রান করছে সেটির জন্য প্রেরক API ব্যবহার করে প্রেরক ওয়েব রিসিভারকে মেসেজ ইস্যু করে। ইভেন্ট অবজেক্ট (যা মেসেজের ম্যানিফেস্টেশন) যা ইভেন্ট লিসনারে পাস করা হয়, সেটিতে একটি ডেটা এলিমেন্ট (event.data) থাকে যেখানে ডেটা নির্দিষ্ট ইভেন্টের ধরন সংক্রান্ত প্রপার্টি গ্রহণ করে।

ওয়েব রিসিভার অ্যাপ্লিকেশন নির্দিষ্ট নেমস্পেসে মেসেজ শোনার বিকল্প বেছে নিতে পারে। এর ফলে, Web Receiver অ্যাপ্লিকেশনটি সেই নেমস্পেস প্রোটোকল সাপোর্ট করে বলে ধরে নেওয়া হয়। তারপর, উপযুক্ত প্রোটোকল ব্যবহার করার জন্য সেই নেমস্পেসে যোগাযোগ করতে ইচ্ছুক যেকোনও কানেক্ট করা প্রেরকের উপর নির্ভর করে।

সব নেমস্পেস স্ট্রিং দ্বারা সংজ্ঞায়িত এবং অবশ্যই "urn:x-cast:" দিয়ে শুরু হতে হবে এবং তারপরে যেকোনও স্ট্রিং থাকতে হবে। যেমন, "urn:x-cast:com.example.cast.mynamespace"।

কানেক্ট করা প্রেরকদের থেকে কাস্টম মেসেজ শোনার জন্য Web Receiver-এর কোড স্নিপেট এখানে দেওয়া হল:

const context = cast.framework.CastReceiverContext.getInstance();

const CUSTOM_CHANNEL = 'urn:x-cast:com.example.cast.mynamespace';
context.addCustomMessageListener(CUSTOM_CHANNEL, function(customEvent) {
  // handle customEvent.
});

context.start();

একইভাবে, ওয়েব রিসিভার অ্যাপ্লিকেশন কানেক্ট করা প্রেরকদের মেসেজ পাঠিয়ে ওয়েব রিসিভারের অবস্থা সম্পর্কে প্রেরকদের অবগত রাখতে পারে। একটি ওয়েব রিসিভার অ্যাপ্লিকেশন sendCustomMessage(namespace, senderId, message) ব্যবহার করে CastReceiverContext-এ মেসেজ পাঠাতে পারে। কোনও ওয়েব রিসিভার, কোনও স্বতন্ত্র প্রেরককে মেসেজ পাঠাতে পারে, হয় কোনও প্রাপ্ত মেসেজের উত্তরে অথবা কোনও অ্যাপ্লিকেশন স্টেট পরিবর্তনের কারণে। পয়েন্ট-টু-পয়েন্ট মেসেজিংয়ের (৬৪ কেবি সীমা সহ) বাইরে, একটি ওয়েব রিসিভার সব কানেক্ট করা প্রেরকদের মেসেজ ব্রডকাস্ট করতে পারে।

অডিও ডিভাইসের জন্য কাস্ট করা

শুধুমাত্র অডিও প্লেব্যাকের জন্য সহায়তা পেতে অডিও ডিভাইসের জন্য Google Cast নির্দেশিকা দেখুন।

Android TV

এই বিভাগে আলোচনা করা হয়েছে যে Google Web Receiver কীভাবে আপনার ইনপুটকে প্লেব্যাক হিসেবে ব্যবহার করে, এবং Android TV-র সাথে মানানসই কিনা।

রিমোট কন্ট্রোলের সাথে আপনার অ্যাপ্লিকেশন ইন্টিগ্রেট করা

Android TV ডিভাইসে রান করা Google Web Receiver, ডিভাইসের কন্ট্রোল ইনপুট (যেমন, হ্যান্ড-হেল্ড রিমোট কন্ট্রোল) থেকে পাওয়া ইনপুটকে মিডিয়া প্লেব্যাক মেসেজ হিসেবে ট্রান্সলেট করে। এই মেসেজগুলি urn:x-cast:com.google.cast.media নেমস্পেসের জন্য নির্ধারিত এবং মিডিয়া প্লেব্যাক মেসেজে বর্ণিত। Android TV-র কন্ট্রোল ইনপুট থেকে প্লেব্যাক কন্ট্রোল করার অনুমতি দিতে, আপনার অ্যাপ্লিকেশনকে অবশ্যই এই মেসেজগুলি সমর্থন করতে হবে যাতে অ্যাপ্লিকেশন মিডিয়া প্লেব্যাক কন্ট্রোল করা যায়।

Android TV-এর সাথে কাজ করার উপযুক্ততা সংক্রান্ত নির্দেশিকা

আপনার অ্যাপ্লিকেশন Android TV-এর সাথে মানানসই কিনা তা নিশ্চিত করতে এখানে কিছু সাজেশন এবং সাধারণ সমস্যা এড়ানোর উপায় দেওয়া হল:

  • মনে রাখবেন যে ইউজার-এজেন্ট স্ট্রিংয়ে "Android" ও "CrKey" দুটিই থাকে; কিছু সাইট শুধু মোবাইলের জন্য তৈরি সাইটে রিডাইরেক্ট করতে পারে কারণ তারা "Android" লেবেল শনাক্ত করে। ইউজার-এজেন্ট স্ট্রিংয়ে "Android" লেখা থাকলেই যে সেটি মোবাইল ব্যবহারকারীকে বোঝায়, তা ধরে নেবেন না।
  • ডেটা ফেচ করার জন্য Android-এর মিডিয়া স্ট্যাক ট্রান্সপারেন্ট GZIP ব্যবহার করতে পারে। আপনার মিডিয়া ডেটা Accept-Encoding: gzip-এ রেসপন্ড করতে পারছে কিনা তা নিশ্চিত করুন।
  • Android TV HTML5 মিডিয়া ইভেন্ট Chromecast-এর থেকে আলাদা সময়ে ট্রিগার হতে পারে, এর ফলে Chromecast-এ লুকানো সমস্যাগুলি সামনে আসতে পারে।
  • মিডিয়া আপডেট করার সময়, <audio>/<video> এলিমেন্ট দ্বারা ফায়ার করা মিডিয়া সম্পর্কিত ইভেন্ট ব্যবহার করুন, যেমন timeupdate, pause ও waiting। progress, suspend এবং stalled-এর মতো নেটওয়ার্কিং সম্পর্কিত ইভেন্ট ব্যবহার করা এড়িয়ে চলুন, কারণ এগুলি সাধারণত প্ল্যাটফর্ম নির্ভর হয়। আপনার রিসিভারে মিডিয়া ইভেন্ট ম্যানেজ করা সম্পর্কে আরও তথ্য পেতে, মিডিয়া ইভেন্ট দেখুন।
  • আপনার রিসিভার সাইটের HTTPS সার্টিফিকেট কনফিগার করার সময়, মধ্যবর্তী CA সার্টিফিকেট যোগ করতে ভুলবেন না। যাচাই করতে Qualsys SSL টেস্ট পৃষ্ঠা দেখুন: আপনার সাইটের বিশ্বস্ত সার্টিফিকেশন পাথে যদি "অতিরিক্ত ডাউনলোড" লেবেলযুক্ত CA সার্টিফিকেট থাকে, তাহলে এটি Android-ভিত্তিক প্ল্যাটফর্মে লোড নাও হতে পারে।
  • Chromecast, 720p গ্রাফিক্স প্লেনে রিসিভার পৃষ্ঠা দেখালেও, Android TV সহ অন্যান্য Cast প্ল্যাটফর্ম, পৃষ্ঠাটি 1080p পর্যন্ত দেখাতে পারে। নিশ্চিত করুন আপনার রিসিভার পৃষ্ঠাটি বিভিন্ন রেজোলিউশনে সুন্দরভাবে স্কেল করে।