یک گیرنده وب سفارشی بسازید

۱. مرور کلی

لوگوی گوگل کست

این آزمایشگاه کد به شما آموزش می‌دهد که چگونه یک برنامه گیرنده وب سفارشی برای پخش محتوا در دستگاه‌های دارای قابلیت Cast بسازید.

گوگل کست چیست؟

گوگل کست به کاربران اجازه می‌دهد محتوا را از دستگاه تلفن همراه به تلویزیون منتقل کنند. سپس کاربران می‌توانند از دستگاه تلفن همراه یا مرورگر کروم دسکتاپ خود به عنوان کنترل از راه دور برای پخش رسانه در تلویزیون استفاده کنند.

کیت توسعه نرم‌افزاری گوگل کست (Google Cast SDK) به برنامه شما اجازه می‌دهد تا دستگاه‌های دارای قابلیت پشتیبانی از گوگل کست (مثلاً تلویزیون یا سیستم صوتی) را کنترل کند. کیت توسعه نرم‌افزاری گوگل کست (Cast SDK) اجزای رابط کاربری لازم را بر اساس چک لیست طراحی گوگل کست (Google Cast Design Checklist) در اختیار شما قرار می‌دهد.

چک لیست طراحی گوگل کست (Google Cast) ارائه شده است تا تجربه کاربری کست (Cast) را در تمام پلتفرم‌های پشتیبانی‌شده ساده و قابل پیش‌بینی کند. برای اطلاعات بیشتر اینجا را ببینید.

قرار است چه چیزی بسازیم؟

وقتی این آزمایشگاه کدنویسی را تکمیل کردید، یک برنامه HTML5 خواهید داشت که به عنوان گیرنده سفارشی شما عمل می‌کند و قادر به نمایش محتوای ویدیویی در دستگاه‌های دارای قابلیت Cast است.

آنچه یاد خواهید گرفت

  • چگونه برای توسعه گیرنده آماده شویم.
  • اصول اولیه یک گیرنده با قابلیت Cast بر اساس چارچوب برنامه Cast.
  • نحوه دریافت ویدیوی کست شده.
  • نحوه ادغام Debug Logger.
  • چگونه گیرنده خود را برای نمایشگرهای هوشمند بهینه کنیم؟

آنچه نیاز دارید

تجربه

  • شما باید دانش قبلی در زمینه توسعه وب داشته باشید.
  • همچنین به دانش قبلی در مورد تماشای تلویزیون نیاز خواهید داشت :)

چگونه از این آموزش استفاده خواهید کرد؟

فقط تا انتها بخوانید آن را بخوانید و تمرین‌ها را انجام دهید

تجربه خود را در ساخت برنامه‌های وب چگونه ارزیابی می‌کنید؟

تازه کار متوسط ماهر

تجربه خود را با تماشای تلویزیون چگونه ارزیابی می‌کنید؟

تازه کار متوسط ماهر

۲. کد نمونه را دریافت کنید

شما می‌توانید تمام کدهای نمونه را روی کامپیوتر خود دانلود کنید...

و فایل زیپ دانلود شده را از حالت فشرده خارج کنید.

۳. نصب گیرنده به صورت محلی

برای اینکه بتوانید از گیرنده وب خود با دستگاه Cast استفاده کنید، باید آن را در جایی میزبانی کنید که دستگاه Cast شما بتواند به آن دسترسی داشته باشد. اگر از قبل سروری دارید که از https پشتیبانی می‌کند، دستورالعمل‌های زیر را رد کنید و URL را یادداشت کنید ، زیرا در بخش بعدی به آن نیاز خواهید داشت.

اگر سروری برای استفاده در دسترس ندارید، می‌توانید از Firebase Hosting یا ngrok استفاده کنید.

سرور را اجرا کنید

پس از تنظیم سرویس مورد نظر خود، به app-start بروید و سرور خود را شروع کنید.

آدرس اینترنتی (URL) گیرنده میزبان خود را یادداشت کنید. در بخش بعدی از آن استفاده خواهید کرد.

۴. یک برنامه را در کنسول توسعه‌دهندگان Cast ثبت کنید

برای اینکه بتوانید یک گیرنده سفارشی، همانطور که در این codelab ساخته شده است، را روی دستگاه‌های Chromecast اجرا کنید، باید برنامه خود را ثبت کنید . پس از ثبت برنامه، یک شناسه برنامه دریافت خواهید کرد که برنامه فرستنده شما باید برای انجام فراخوانی‌های API، مانند راه‌اندازی برنامه گیرنده، از آن استفاده کند.

تصویر کنسول توسعه‌دهندگان SDK گوگل کست با دکمه «افزودن برنامه جدید» هایلایت شده

روی «افزودن برنامه جدید» کلیک کنید

تصویر صفحه «برنامه گیرنده جدید» با گزینه «گیرنده سفارشی» هایلایت شده

«گیرنده سفارشی» را انتخاب کنید، این چیزی است که ما در حال ساخت آن هستیم.

تصویر صفحه «گیرنده سفارشی جدید» که نشانی اینترنتی (URL) را نشان می‌دهد که شخصی در حال تایپ آن در فیلد «نشانی اینترنتی برنامه گیرنده» است

جزئیات گیرنده جدید خود را وارد کنید، حتماً از URL که در نهایت با آن وارد شدید استفاده کنید.

در بخش آخر، شناسه برنامه اختصاص داده شده به گیرنده جدید خود را یادداشت کنید .

همچنین باید دستگاه Google Cast خود را ثبت کنید تا قبل از انتشار، بتواند به برنامه گیرنده شما دسترسی داشته باشد. پس از انتشار برنامه گیرنده، برای همه دستگاه‌های Google Cast در دسترس خواهد بود. برای اهداف این آزمایشگاه کد، توصیه می‌شود با یک برنامه گیرنده منتشر نشده کار کنید.

تصویر کنسول توسعه‌دهندگان SDK گوگل کست با دکمه «افزودن دستگاه جدید» هایلایت شده

روی «افزودن دستگاه جدید» کلیک کنید

تصویر پنجره‌ی «افزودن دستگاه گیرنده‌ی پخش»

شماره سریال چاپ شده در پشت دستگاه Cast خود را وارد کنید و یک نام توصیفی به آن بدهید. همچنین می‌توانید با استفاده از Cast کردن صفحه نمایش خود در Chrome هنگام دسترسی به کنسول توسعه‌دهندگان Google Cast SDK، شماره سریال خود را پیدا کنید.

۵ تا ۱۵ دقیقه طول می‌کشد تا گیرنده و دستگاه شما برای آزمایش آماده شوند. پس از ۵ تا ۱۵ دقیقه انتظار، باید دستگاه Cast خود را مجدداً راه‌اندازی کنید.

۵. برنامه نمونه را اجرا کنید

لوگوی گوگل کروم

در حالی که منتظر آماده شدن برنامه گیرنده جدیدمان برای آزمایش هستیم، بیایید ببینیم یک برنامه گیرنده نمونه تکمیل شده چگونه است. گیرنده‌ای که قرار است بسازیم قادر به پخش رسانه با استفاده از پخش تطبیقی ​​بیت خواهد بود (ما از محتوای نمونه کدگذاری شده برای پخش تطبیقی ​​پویا از طریق HTTP (DASH) استفاده خواهیم کرد).

در مرورگر خود، ابزار فرمان و کنترل (CaC) را باز کنید.

تصویر تب «Cast Connect & Logger Controls» از ابزار Command and Control (CaC)

  1. شما باید ابزار CaC ما را ببینید.
  2. از شناسه‌ی پیش‌فرض گیرنده‌ی نمونه «CC1AD845» استفاده کنید و روی دکمه‌ی «تنظیم شناسه‌ی برنامه» کلیک کنید.
  3. روی دکمه‌ی Cast در بالا سمت چپ کلیک کنید و دستگاه Google Cast خود را انتخاب کنید.

تصویر تب «Cast Connect & Logger Controls» از ابزار Command and Control (CaC) که نشان می‌دهد به یک برنامه گیرنده متصل است

  1. به برگه «بارگذاری رسانه» در بالا بروید.

تصویر برگه «بارگذاری رسانه» ابزار فرماندهی و کنترل (CaC)

  1. برای پخش یک ویدیوی نمونه، روی دکمه‌ی «بارگذاری بر اساس محتوا» کلیک کنید.
  2. ویدیو در دستگاه گوگل کست شما شروع به پخش می‌کند تا عملکرد اولیه گیرنده با استفاده از گیرنده پیش‌فرض نشان داده شود.

۶. پروژه اولیه را آماده کنید

ما باید پشتیبانی از گوگل کست را به برنامه‌ی شروع که دانلود کرده‌اید اضافه کنیم. در اینجا برخی از اصطلاحات گوگل کست که در این آزمایشگاه کد استفاده خواهیم کرد، آورده شده است:

  • یک برنامه فرستنده روی دستگاه تلفن همراه یا لپ‌تاپ اجرا می‌شود،
  • یک برنامه گیرنده روی دستگاه Google Cast اجرا می‌شود.

اکنون آماده‌اید تا با استفاده از ویرایشگر متن مورد علاقه‌تان، پروژه‌ی اولیه را توسعه دهید:

  1. انتخاب کنید آیکون پوشه پوشه app-start از کد نمونه‌ای که دانلود کرده‌اید.
  2. js/receiver.js و index.html را باز کنید.

توجه داشته باشید، همانطور که در حال کار با این آزمایشگاه کد هستید، http-server باید تغییراتی را که ایجاد می‌کنید دریافت کند. اگر متوجه شدید که این اتفاق نمی‌افتد، سعی کنید http-server غیرفعال و مجدداً راه‌اندازی کنید.

طراحی اپلیکیشن

برنامه گیرنده، جلسه Cast را راه‌اندازی می‌کند و تا زمانی که درخواست LOAD (به عبارت دیگر، دستور پخش یک قطعه رسانه) از فرستنده برسد، در حالت آماده‌باش قرار می‌گیرد.

این برنامه شامل یک نمای اصلی است که در index.html تعریف شده است و یک فایل جاوا اسکریپت به نام js/receiver.js که شامل تمام منطق لازم برای کار کردن گیرنده ما است.

فهرست.html

این فایل html شامل رابط کاربری برنامه گیرنده ما خواهد بود. فعلاً خالی است و در طول آزمایشگاه کد به آن اضافه خواهیم کرد.

گیرنده.js

این اسکریپت تمام منطق برنامه گیرنده ما را مدیریت خواهد کرد. در حال حاضر این فقط یک فایل خالی است، اما ما قصد داریم آن را با چند خط کد در بخش بعدی به یک گیرنده Cast کاملاً کاربردی تبدیل کنیم.

۷. یک گیرنده‌ی Cast ساده

یک گیرنده Cast ساده، جلسه Cast را در هنگام راه‌اندازی اولیه راه‌اندازی می‌کند. این کار برای اطلاع‌رسانی به همه برنامه‌های فرستنده متصل مبنی بر موفقیت‌آمیز بودن راه‌اندازی گیرنده ضروری است. علاوه بر این، SDK جدید از پیش پیکربندی شده است تا رسانه‌های پخش جریانی با نرخ بیت تطبیقی ​​(با استفاده از DASH، HLS و Smooth Streaming) و فایل‌های MP4 ساده را به صورت پیش‌فرض مدیریت کند. بیایید این را امتحان کنیم.

مقداردهی اولیه

کد زیر را به index.html در قسمت هدر اضافه کنید:

<head>
  ...

  <script src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
</head>

کد زیر را به <body> index.html قبل از بارگذاری فایل footer> فایل receiver.js, اضافه کنید تا SDK گیرنده فضایی برای نمایش رابط کاربری پیش‌فرض گیرنده که با اسکریپتی که اضافه کرده‌اید ارسال می‌شود، داشته باشد.

<cast-media-player></cast-media-player>

حالا باید SDK را در js/receiver.js مقداردهی اولیه کنیم که شامل موارد زیر است:

  • دریافت ارجاع به CastReceiverContext ، نقطه ورود اصلی شما به کل Receiver SDK
  • ذخیره یک ارجاع به PlayerManager ، شیء مدیریت پخش و ارائه تمام قلاب‌های مورد نیاز برای اتصال منطق سفارشی خودتان
  • مقداردهی اولیه SDK با فراخوانی start() در CastReceiverContext

موارد زیر را به js/receiver.js اضافه کنید.

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

context.start();

۸. پخش محتوای ویدیویی «پایه»

برای اهداف این Codelab، از ابزار CaC برای امتحان کردن گیرنده جدید خود استفاده کنید.

مرورگر وب خود را به ابزار فرمان و کنترل (CaC) هدایت کنید.

تصویر تب «Cast Connect & Logger Controls» از ابزار Command and Control (CaC)

حتماً شناسه برنامه خود را که قبلاً در این فیلد ثبت کرده‌اید، جایگزین کنید و روی «تنظیم شناسه برنامه» کلیک کنید. این به ابزار دستور می‌دهد که هنگام شروع جلسه ارسال، از گیرنده شما استفاده کند.

رسانه‌های ریخته‌گری

در سطح بالا، برای پخش رسانه در دستگاه Cast موارد زیر باید اتفاق بیفتد:

  1. فرستنده یک شیء MediaInfo JSON از Cast SDK ایجاد می‌کند که یک آیتم رسانه‌ای را مدل‌سازی می‌کند.
  2. فرستنده برای اجرای برنامه گیرنده به دستگاه Cast متصل می‌شود.
  3. گیرنده، شیء MediaInfo را از طریق یک درخواست LOAD برای پخش محتوا بارگذاری می‌کند.
  4. گیرنده وضعیت رسانه را رصد و پیگیری می‌کند.
  5. فرستنده، دستورات پخش را به گیرنده ارسال می‌کند تا پخش را بر اساس تعاملات کاربر با برنامه فرستنده کنترل کند.

در این اولین تلاش اولیه، قصد داریم MediaInfo با یک URL فایل قابل پخش (که در MediaInfo.contentUrl ذخیره شده است) پر کنیم.

یک فرستنده در دنیای واقعی از یک شناسه رسانه مختص برنامه در MediaInfo.contentId استفاده می‌کند. گیرنده از contentId به عنوان شناسه برای انجام فراخوانی‌های API بک‌اند مناسب جهت حل URL دارایی واقعی و تنظیم آن روی MediaInfo.contentUrl. گیرنده همچنین وظایفی مانند کسب مجوز DRM یا تزریق اطلاعات در مورد وقفه‌های تبلیغاتی را انجام خواهد داد.

ما قصد داریم در بخش بعدی گیرنده شما را برای انجام کاری مشابه گسترش دهیم. فعلاً، روی نماد Cast کلیک کنید و دستگاه خود را برای باز کردن گیرنده خود انتخاب کنید.

تصویر تب «Cast Connect & Logger Controls» از ابزار Command and Control (CaC) که نشان می‌دهد به یک برنامه گیرنده متصل است

به برگه «بارگذاری رسانه» بروید و روی دکمه «بارگذاری بر اساس محتوا» کلیک کنید. گیرنده شما باید شروع به پخش محتوای نمونه کند.

تصویر برگه «بارگذاری رسانه» ابزار فرماندهی و کنترل (CaC)

بنابراین، SDK گیرنده به صورت پیش‌فرض موارد زیر را مدیریت می‌کند:

  • مقداردهی اولیه جلسه Cast
  • درخواست‌های LOAD ورودی از فرستنده‌هایی که حاوی فایل‌های قابل پخش هستند را مدیریت کنید.
  • یک رابط کاربری پخش‌کننده‌ی پایه ارائه دهید که برای نمایش در صفحه نمایش بزرگ آماده باشد.

قبل از رفتن به بخش بعدی، می‌توانید ابزار CaC و کد آن را بررسی کنید، جایی که قرار است گیرنده خود را طوری توسعه دهیم که با یک API نمونه ساده ارتباط برقرار کند تا درخواست‌های LOAD دریافتی از فرستندگان را انجام دهد.

۹. ادغام با یک API خارجی

مطابق با نحوه تعامل اکثر توسعه‌دهندگان با گیرنده‌های Cast خود در برنامه‌های دنیای واقعی، ما قصد داریم گیرنده خود را طوری تغییر دهیم که درخواست‌های LOAD را که به محتوای رسانه مورد نظر ارجاع می‌دهند، به جای ارسال URL یک محتوای قابل پخش، با کلید API آن مدیریت کند.

برنامه‌ها معمولاً این کار را انجام می‌دهند زیرا:

  • ممکن است فرستنده، آدرس اینترنتی محتوا را نداند.
  • برنامه Cast طوری طراحی شده است که احراز هویت، سایر منطق‌های تجاری یا فراخوانی‌های API را مستقیماً روی گیرنده مدیریت کند.

این قابلیت عمدتاً در متد setMessageInterceptor() PlayerManager پیاده‌سازی شده است. این متد شما را قادر می‌سازد تا پیام‌های ورودی را بر اساس نوع رهگیری کرده و قبل از رسیدن به کنترل‌کننده پیام داخلی SDK، آنها را تغییر دهید. در این بخش، ما با درخواست‌های LOAD سروکار داریم که در آن موارد زیر را انجام خواهیم داد:

  • درخواست LOAD ورودی و contentId سفارشی آن را بخوانید.
  • برای جستجوی محتوای قابل پخش از طریق contentId یک فراخوانی GET به API ما انجام دهید.
  • درخواست LOAD را با آدرس اینترنتی (URL) مربوط به جریان (stream) تغییر دهید.
  • شیء MediaInformation را برای تنظیم پارامترهای نوع جریان تغییر دهید.
  • درخواست را برای پخش به SDK ارسال کنید، یا اگر قادر به جستجوی رسانه درخواستی نیستیم، دستور را رد کنید.

API نمونه ارائه شده، قلاب‌های SDK را برای سفارشی‌سازی وظایف رایج گیرنده نشان می‌دهد، در حالی که هنوز به یک تجربه عمدتاً آماده متکی است.

نمونه API

مرورگر خود را به آدرس https://storage.googleapis.com/cpe-sample-media/content.json هدایت کنید و نگاهی به کاتالوگ نمونه ویدیوی ما بیندازید. این محتوا شامل URL تصاویر پوستر با فرمت png و همچنین جریان‌های DASH و HLS است. جریان‌های DASH و HLS به منابع ویدیویی و صوتی demux شده که در کانتینرهای mp4 تکه‌تکه ذخیره شده‌اند، اشاره دارند.

{
  "bbb": {
    "author": "The Blender Project",
    "description": "Grumpy Bunny is grumpy",
    "poster": "https://[...]/[...]/BigBuckBunny/images/screenshot1.png",
    "stream": {
      "dash": "https://[...]/[...]/BigBuckBunny/BigBuckBunny_master.mpd",
      "hls": "https://[...]/[...]/BigBuckBunny/BigBuckBunny_master.m3u8",
    "title": "Big Buck Bunny"
  },
  "fbb_ad": {
    "author": "Google Inc.",
    "description": "Introducing Chromecast. The easiest way to enjoy [...]",
    "poster": "https://[...]/[...]/ForBiggerBlazes/images/screenshot8.png",
    "stream": {
      "dash": "https://[...]/[...]/ForBiggerBlazes/ForBiggerBlazes.mpd",
      "hls": "https://[...]/[...]/ForBiggerBlazes/ForBiggerBlazes.m3u8",
    "title": "For Bigger Blazes"
  },

  [...]

}

در مرحله بعدی، کلید هر ورودی (برای مثال، bbb, fbb_ad ) را پس از فراخوانی گیرنده با درخواست LOAD ، به URL جریان نگاشت خواهیم کرد.

درخواست LOAD را رهگیری کنید

در این مرحله، یک رهگیر بارگذاری با تابعی که یک درخواست XHR به فایل JSON میزبانی‌شده ارسال می‌کند، ایجاد خواهیم کرد. پس از دریافت فایل JSON ، محتوا را تجزیه و فراداده (metadata) را تنظیم می‌کنیم. در بخش‌های بعدی، پارامترهای MediaInformation را برای مشخص کردن نوع محتوا سفارشی‌سازی خواهیم کرد.

کد زیر را به فایل js/receiver.js خود، درست قبل از فراخوانی context.start() اضافه کنید.

function makeRequest (method, url) {
  return new Promise(function (resolve, reject) {
    let xhr = new XMLHttpRequest();
    xhr.open(method, url);
    xhr.onload = function () {
      if (this.status >= 200 && this.status < 300) {
        resolve(JSON.parse(xhr.response));
      } else {
        reject({
          status: this.status,
          statusText: xhr.statusText
        });
      }
    };
    xhr.onerror = function () {
      reject({
        status: this.status,
        statusText: xhr.statusText
      });
    };
    xhr.send();
  });
}

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD,
    request => {
      return new Promise((resolve, reject) => {
        // Fetch content repository by requested contentId
        makeRequest('GET', 'https://storage.googleapis.com/cpe-sample-media/content.json').then(function (data) {
          let item = data[request.media.contentId];
          if(!item) {
            // Content could not be found in repository
            reject();
          } else {
            // Add metadata
            let metadata = new
               cast.framework.messages.GenericMediaMetadata();
            metadata.title = item.title;
            metadata.subtitle = item.author;

            request.media.metadata = metadata;

            // Resolve request
            resolve(request);
          }
        });
      });
    });

بخش بعدی نحوه پیکربندی ویژگی media درخواست بارگذاری برای محتوای DASH را شرح می‌دهد.

استفاده از نمونه محتوای API DASH

حالا که رهگیر بارگذاری را آماده کرده‌ایم، نوع محتوا را برای گیرنده مشخص می‌کنیم. این اطلاعات، آدرس لیست پخش اصلی و نوع MIME استریم را در اختیار گیرنده قرار می‌دهد. کد زیر را به فایل js/receiver.js در Promise() رهگیر LOAD اضافه کنید:

...
playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD,
    request => {
      return new Promise((resolve, reject) => {
          ...
          } else {
            // Adjusting request to make requested content playable
            request.media.contentUrl = item.stream.dash;
            request.media.contentType = 'application/dash+xml';
            ...
          }
        });
      });
    });

پس از تکمیل این مرحله، می‌توانید برای بارگیری با محتوای DASH به بخش «آزمایش» بروید. اگر می‌خواهید بارگیری با محتوای HLS را آزمایش کنید، مرحله بعدی را بررسی کنید.

استفاده از نمونه محتوای HLS API

API نمونه شامل محتوای HLS و همچنین DASH است. علاوه بر تنظیم contentType مانند کاری که در مرحله قبل انجام دادیم، درخواست بارگذاری به برخی ویژگی‌های اضافی نیاز دارد تا بتواند از آدرس‌های اینترنتی HLS API نمونه استفاده کند. هنگامی که گیرنده برای پخش جریان‌های HLS پیکربندی شده است، نوع کانتینر پیش‌فرض مورد انتظار، جریان انتقال (TS) است. در نتیجه، گیرنده سعی می‌کند جریان‌های MP4 نمونه را با فرمت TS باز کند، اگر فقط ویژگی contentUrl تغییر داده شده باشد. در درخواست بارگذاری، شیء MediaInformation باید با ویژگی‌های اضافی اصلاح شود تا گیرنده بداند که محتوا از نوع MP4 است و نه TS. کد زیر را به فایل js/receiver.js خود در load interceptor اضافه کنید تا ویژگی‌های contentUrl و contentType تغییر دهید. علاوه بر این، ویژگی‌های HlsSegmentFormat و HlsVideoSegmentFormat را نیز اضافه کنید.

...
playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD,
    request => {
      return new Promise((resolve, reject) => {
          ...
          } else {
            // Adjusting request to make requested content playable
            request.media.contentUrl = item.stream.hls;
            request.media.contentType = 'application/x-mpegurl';
            request.media.hlsSegmentFormat = cast.framework.messages.HlsSegmentFormat.FMP4;
            request.media.hlsVideoSegmentFormat = cast.framework.messages.HlsVideoSegmentFormat.FMP4;
            ...
          }
        });
      });
    });

آزمایش کردن آن

دوباره، ابزار Command and Control (CaC) را باز کنید و App ID خود را روی App ID گیرنده خود تنظیم کنید. دستگاه خود را با استفاده از دکمه Cast انتخاب کنید.

به برگه «بارگذاری رسانه» بروید. این بار متن موجود در فیلد «URL محتوا» کنار دکمه «بارگذاری بر اساس محتوا» را حذف کنید ، که باعث می‌شود برنامه ما مجبور شود یک درخواست LOAD حاوی تنها مرجع contentId به رسانه ما ارسال کند.

تصویر برگه «بارگذاری رسانه» ابزار فرماندهی و کنترل (CaC)

با فرض اینکه همه چیز با تغییرات شما در گیرنده خوب پیش رفته باشد، رهگیر باید مراقب شکل‌دهی شیء MediaInfo به چیزی باشد که SDK بتواند روی صفحه نمایش پخش کند.

برای بررسی پخش صحیح فایل‌های رسانه‌ای، روی دکمه‌ی «بارگذاری بر اساس محتوا» کلیک کنید. می‌توانید شناسه‌ی محتوا (Content ID) را در فایل content.json به شناسه‌ی دیگری تغییر دهید.

۱۰. بهینه‌سازی برای نمایشگرهای هوشمند

نمایشگرهای هوشمند دستگاه‌هایی با قابلیت لمسی هستند که به برنامه‌های گیرنده اجازه می‌دهند از کنترل‌های لمسی پشتیبانی کنند.

این بخش نحوه بهینه‌سازی برنامه گیرنده شما هنگام اجرا روی نمایشگرهای هوشمند و نحوه سفارشی‌سازی کنترل‌های پخش‌کننده را توضیح می‌دهد.

دسترسی به کنترل‌های رابط کاربری

شیء کنترل‌های رابط کاربری برای نمایشگرهای هوشمند با استفاده از cast.framework.ui.Controls.GetInstance() قابل دسترسی است. کد زیر را به فایل js/receiver.js خود در بالای context.start() اضافه کنید:

...

// Optimizing for smart displays
const touchControls = cast.framework.ui.Controls.getInstance();

context.start();

اگر از عنصر <cast-media-player> استفاده نمی‌کنید، باید touchScreenOptimizedApp در CastReceiverOptions تنظیم کنید. در این آزمایشگاه کد، ما از عنصر <cast-media-player> استفاده می‌کنیم.

context.start({ touchScreenOptimizedApp: true });

دکمه‌های کنترل پیش‌فرض بر اساس MetadataType و MediaStatus.supportedMediaCommands به هر اسلات اختصاص داده می‌شوند.

کنترل‌های ویدیویی

برای MetadataType.MOVIE ، MetadataType.TV_SHOW و MetadataType.GENERIC ، شیء UI Controls برای Smart Displays مانند مثال زیر نمایش داده خواهد شد.

تصویر پخش ویدیو با کنترل‌های رابط کاربری که در بالا قرار گرفته‌اند

  1. --playback-logo-image
  2. MediaMetadata.subtitle
  3. MediaMetadata.title
  4. MediaStatus.currentTime
  5. MediaInformation.duration
  6. ControlsSlot.SLOT_SECONDARY_1 : ControlsButton.QUEUE_PREV
  7. ControlsSlot.SLOT_PRIMARY_1 : ControlsButton.SEEK_BACKWARD_30
  8. PLAY/PAUSE
  9. ControlsSlot.SLOT_PRIMARY_2 : ControlsButton.SEEK_FORWARD_30
  10. ControlsSlot.SLOT_SECONDARY_2 : ControlsButton.QUEUE_NEXT

کنترل‌های صوتی

برای MetadataType.MUSIC_TRACK ، شیء UI Controls برای Smart Displays به صورت زیر نمایش داده خواهد شد:

تصویر پخش موسیقی با کنترل‌های رابط کاربری که در بالا قرار گرفته‌اند

  1. --playback-logo-image
  2. MusicTrackMediaMetadata.albumName
  3. MusicTrackMediaMetadata.title
  4. MusicTrackMediaMetadata.albumArtist
  5. MusicTrackMediaMetadata.images[0]
  6. MediaStatus.currentTime
  7. MediaInformation.duration
  8. ControlsSlot.SLOT_SECONDARY_1 : ControlsButton.NO_BUTTON
  9. ControlsSlot.SLOT_PRIMARY_1 : ControlsButton.QUEUE_PREV
  10. PLAY/PAUSE
  11. ControlsSlot.SLOT_PRIMARY_2 : ControlsButton.QUEUE_NEXT
  12. ControlsSlot.SLOT_SECONDARY_2 : ControlsButton.NO_BUTTON

به‌روزرسانی دستورات رسانه‌ای پشتیبانی‌شده

شیء UI Controls همچنین بر اساس MediaStatus.supportedMediaCommands تعیین می‌کند که آیا یک ControlsButton نمایش داده شود یا خیر.

وقتی مقدار supportedMediaCommands برابر با ALL_BASIC_MEDIA باشد، طرح کنترل پیش‌فرض به صورت زیر نمایش داده می‌شود:

تصویر کنترل‌های پخش‌کننده رسانه: نوار پیشرفت، دکمه «پخش»، دکمه‌های «پرش به جلو» و «پرش به عقب» فعال هستند

وقتی مقدار supportedMediaCommands برابر با ALL_BASIC_MEDIA | QUEUE_PREV | QUEUE_NEXT باشد، طرح کنترل پیش‌فرض به صورت زیر نمایش داده می‌شود:

تصویر کنترل‌های پخش‌کننده رسانه: نوار پیشرفت، دکمه «پخش»، دکمه‌های «پرش به جلو» و «پرش به عقب» و دکمه‌های «در صف قرار دادن قبلی» و «در صف قرار دادن بعدی» فعال هستند

وقتی مقدار supportedMediaCommands برابر با PAUSE | QUEUE_PREV | QUEUE_NEXT باشد، طرح کنترل پیش‌فرض به صورت زیر نمایش داده می‌شود:

تصویر کنترل‌های پخش‌کننده رسانه: نوار پیشرفت، دکمه «پخش» و دکمه‌های «در صف قرار دادن قبلی» و «در صف قرار دادن بعدی» فعال هستند

وقتی آهنگ‌های متنی موجود باشند، دکمه‌ی زیرنویس همیشه در SLOT_1 نمایش داده می‌شود.

تصویر کنترل‌های پخش‌کننده رسانه: نوار پیشرفت، دکمه «پخش»، دکمه‌های «پرش به جلو» و «پرش به عقب»، دکمه‌های «در صف قرار دادن قبلی» و «در صف قرار دادن بعدی» و دکمه‌های «زیرنویس بسته» فعال هستند

برای تغییر پویای مقدار supportedMediaCommands پس از شروع یک زمینه گیرنده، می‌توانید PlayerManager.setSupportedMediaCommands را برای لغو مقدار فراخوانی کنید. همچنین، می‌توانید با استفاده از addSupportedMediaCommands یک دستور جدید اضافه کنید یا با استفاده از removeSupportedMediaCommands یک دستور موجود را حذف کنید.

سفارشی‌سازی دکمه‌های کنترل

شما می‌توانید کنترل‌ها را با استفاده از PlayerDataBinder سفارشی کنید. کد زیر را به فایل js/receiver.js خود، زیر touchControls، اضافه کنید تا اولین جایگاه کنترل‌هایتان را تنظیم کنید:

...

// Optimizing for smart displays
const touchControls = cast.framework.ui.Controls.getInstance();
const playerData = new cast.framework.ui.PlayerData();
const playerDataBinder = new cast.framework.ui.PlayerDataBinder(playerData);

playerDataBinder.addEventListener(
  cast.framework.ui.PlayerDataEventType.MEDIA_CHANGED,
  (e) => {
    if (!e.value) return;

    // Clear default buttons and re-assign
    touchControls.clearDefaultSlotAssignments();
    touchControls.assignButton(
      cast.framework.ui.ControlsSlot.SLOT_PRIMARY_1,
      cast.framework.ui.ControlsButton.SEEK_BACKWARD_30
    );
  });

context.start();

۱۱. پیاده‌سازی مرور رسانه در نمایشگرهای هوشمند

مرور رسانه یک ویژگی گیرنده CAF است که به کاربران امکان می‌دهد محتوای اضافی را در دستگاه‌های لمسی کاوش کنند. برای پیاده‌سازی این امر، PlayerDataBinder برای تنظیم رابط کاربری BrowseContent استفاده خواهید کرد. سپس می‌توانید آن را با BrowseItems بر اساس محتوایی که می‌خواهید نمایش دهید، پر کنید.

مرور محتوا

در زیر مثالی از رابط کاربری BrowseContent و ویژگی‌های آن آمده است:

تصویر رابط کاربری BrowseContent که دو تصویر کوچک ویدیو و بخشی از ویدیوی سوم را نشان می‌دهد

  1. BrowseContent.title
  2. BrowseContent.items

نسبت ابعاد

از targetAspectRatio property برای انتخاب بهترین نسبت ابعاد برای تصاویر خود استفاده کنید. سه نسبت ابعاد توسط CAF Receiver SDK پشتیبانی می‌شوند: SQUARE_1_TO_1 ، PORTRAIT_2_TO_3 ، LANDSCAPE_16_TO_9 .

مرور آیتم

BrowseItem برای نمایش عنوان، زیرنویس، مدت زمان و تصویر برای هر آیتم استفاده کنید:

تصویر رابط کاربری BrowseContent که دو تصویر کوچک ویدیو و بخشی از ویدیوی سوم را نشان می‌دهد

  1. BrowseItem.image
  2. BrowseItem.duration
  3. BrowseItem.title
  4. BrowseItem.subtitle

تنظیم داده‌های مرور رسانه

شما می‌توانید با فراخوانی setBrowseContent فهرستی از محتوای رسانه‌ای را برای مرور ارائه دهید. کد زیر را به فایل js/receiver.js خود در زیر playerDataBinder و در شنونده رویداد MEDIA_CHANGED اضافه کنید تا موارد مرور را با عنوان "Up Next" تنظیم کنید.

// Optimizing for smart displays
const touchControls = cast.framework.ui.Controls.getInstance();
const playerData = new cast.framework.ui.PlayerData();
const playerDataBinder = new cast.framework.ui.PlayerDataBinder(playerData);

...

let browseItems = getBrowseItems();

function getBrowseItems() {
  let browseItems = [];
  makeRequest('GET', 'https://storage.googleapis.com/cpe-sample-media/content.json')
  .then(function (data) {
    for (let key in data) {
      let item = new cast.framework.ui.BrowseItem();
      item.entity = key;
      item.title = data[key].title;
      item.subtitle = data[key].description;
      item.image = new cast.framework.messages.Image(data[key].poster);
      item.imageType = cast.framework.ui.BrowseImageType.MOVIE;
      browseItems.push(item);
    }
  });
  return browseItems;
}

let browseContent = new cast.framework.ui.BrowseContent();
browseContent.title = 'Up Next';
browseContent.items = browseItems;
browseContent.targetAspectRatio = cast.framework.ui.BrowseImageAspectRatio.LANDSCAPE_16_TO_9;

playerDataBinder.addEventListener(
  cast.framework.ui.PlayerDataEventType.MEDIA_CHANGED,
  (e) => {
    if (!e.value) return;

    ....

    // Media browse
    touchControls.setBrowseContent(browseContent);
  });

کلیک روی یک آیتم مرور رسانه، رهگیر LOAD را فعال می‌کند. کد زیر را به رهگیر LOAD خود اضافه کنید تا request.media.contentId را به request.media.entity از آیتم مرور رسانه نگاشت کند:

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

      // Map contentId to entity
      if (request.media && request.media.entity) {
        request.media.contentId = request.media.entity;
      }

      return new Promise((resolve, reject) => {
            ...
        });
    });

همچنین می‌توانید شیء BrowseContent را روی null تنظیم کنید تا رابط کاربری Media Browse حذف شود.

۱۲. اشکال‌زدایی برنامه‌های گیرنده

کیت توسعه نرم‌افزاری Cast Receiver گزینه دیگری را برای توسعه‌دهندگان فراهم می‌کند تا با استفاده از API CastDebugLogger و یک ابزار همراه Command and Control (CaC) برای ثبت گزارش‌ها، به راحتی برنامه‌های گیرنده را اشکال‌زدایی کنند.

مقداردهی اولیه

برای گنجاندن API، اسکریپت منبع CastDebugLogger را در فایل index.html خود اضافه کنید. منبع باید در تگ <head> پس از اعلان SDK مربوط به Cast Receiver تعریف شود.

<head>
  ...
  <script src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
  <!-- Cast Debug Logger -->
  <script src="//www.gstatic.com/cast/sdk/libs/devtools/debug_layer/caf_receiver_logger.js"></script>
</head>

در js/receiver.js در بالای فایل و زیر playerManager ، کد زیر را برای بازیابی نمونه CastDebugLogger و فعال کردن logger اضافه کنید:

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

// Debug Logger
const castDebugLogger = cast.debug.CastDebugLogger.getInstance();
const LOG_TAG = 'MyAPP.LOG';

// Enable debug logger and show a 'DEBUG MODE' overlay at top left corner.
context.addEventListener(cast.framework.system.EventType.READY, () => {
  if (!castDebugLogger.debugOverlayElement_) {
      castDebugLogger.setEnabled(true);
  }
});

وقتی ثبت‌کننده‌ی اشکال‌زدایی فعال باشد، یک پوشش روی گیرنده نمایش داده می‌شود که DEBUG MODE را نشان می‌دهد.

تصویری از یک ویدیو که در حال پخش است و پیام «حالت اشکال‌زدایی» در گوشه سمت چپ بالای قاب با پس‌زمینه قرمز ظاهر می‌شود

رویدادهای بازیکن را ثبت کنید

با استفاده از CastDebugLogger می‌توانید به راحتی رویدادهای بازیکن را که توسط CAF Receiver SDK ایجاد می‌شوند، ثبت کنید و از سطوح مختلف ثبت‌کننده برای ثبت داده‌های رویداد استفاده کنید. پیکربندی loggerLevelByEvents از cast.framework.events.EventType و cast.framework.events.category برای مشخص کردن اینکه کدام رویدادها ثبت خواهند شد، استفاده می‌کند.

کد زیر را زیر تعریف castDebugLogger اضافه کنید تا هنگام فعال شدن رویداد player CORE یا پخش تغییر mediaStatus گزارش ثبت شود:

// Debug Logger
const castDebugLogger = cast.debug.CastDebugLogger.getInstance();

// Enable debug logger and show a 'DEBUG MODE' overlay at top left corner.
context.addEventListener(cast.framework.system.EventType.READY, () => {
  if (!castDebugLogger.debugOverlayElement_) {
      castDebugLogger.setEnabled(true);
  }
});

// Set verbosity level for Core events.
castDebugLogger.loggerLevelByEvents = {
  'cast.framework.events.category.CORE': cast.framework.LoggerLevel.INFO,
  'cast.framework.events.EventType.MEDIA_STATUS': cast.framework.LoggerLevel.DEBUG
}

پیام‌های لاگ و تگ‌های سفارشی

API مربوط به CastDebugLogger به شما امکان می‌دهد پیام‌های لاگی ایجاد کنید که با رنگ‌های مختلف روی پوشش اشکال‌زدایی گیرنده ظاهر می‌شوند. روش‌های لاگ زیر به ترتیب از بالاترین به پایین‌ترین اولویت در دسترس هستند:

  • castDebugLogger.error(custom_tag, message);
  • castDebugLogger.warn(custom_tag, message);
  • castDebugLogger.info(custom_tag, message);
  • castDebugLogger.debug(custom_tag, message);

برای هر متد لاگ، پارامتر اول یک تگ سفارشی است. این می‌تواند هر رشته‌ی شناسایی باشد که به نظرتان معنادار باشد. CastDebugLogger از تگ‌ها برای فیلتر کردن لاگ‌ها استفاده می‌کند. نحوه‌ی استفاده از تگ‌ها در ادامه به تفصیل توضیح داده شده است. پارامتر دوم پیام لاگ است.

برای نمایش لاگ‌ها در عمل، لاگ‌ها را به رهگیر LOAD خود اضافه کنید.

playerManager.setMessageInterceptor(
  cast.framework.messages.MessageType.LOAD,
  request => {
    castDebugLogger.info(LOG_TAG, 'Intercepting LOAD request');

    // Map contentId to entity
    if (request.media && request.media.entity) {
      request.media.contentId = request.media.entity;
    }

    return new Promise((resolve, reject) => {
      // Fetch content repository by requested contentId
      makeRequest('GET', 'https://storage.googleapis.com/cpe-sample-media/content.json')
        .then(function (data) {
          let item = data[request.media.contentId];
          if(!item) {
            // Content could not be found in repository
            castDebugLogger.error(LOG_TAG, 'Content not found');
            reject();
          } else {
            // Adjusting request to make requested content playable
            request.media.contentUrl = item.stream.dash;
            request.media.contentType = 'application/dash+xml';
            castDebugLogger.warn(LOG_TAG, 'Playable URL:', request.media.contentUrl);

            // Add metadata
            let metadata = new cast.framework.messages.MovieMediaMetadata();
            metadata.metadataType = cast.framework.messages.MetadataType.MOVIE;
            metadata.title = item.title;
            metadata.subtitle = item.author;

            request.media.metadata = metadata;

            // Resolve request
            resolve(request);
          }
      });
    });
  });

شما می‌توانید با تنظیم سطح گزارش در loggerLevelByTags برای هر برچسب سفارشی، کنترل کنید که کدام پیام‌ها در پوشش اشکال‌زدایی نمایش داده شوند. برای مثال، فعال کردن یک برچسب سفارشی با سطح گزارش cast.framework.LoggerLevel.DEBUG تمام پیام‌های اضافه شده با پیام‌های گزارش خطا، هشدار، اطلاعات و اشکال‌زدایی را نمایش می‌دهد. فعال کردن یک برچسب سفارشی با سطح WARNING فقط پیام‌های گزارش خطا و هشدار را نمایش می‌دهد.

پیکربندی loggerLevelByTags اختیاری است. اگر یک تگ سفارشی برای سطح logger خود پیکربندی نشده باشد، تمام پیام‌های گزارش در پوشش اشکال‌زدایی نمایش داده می‌شوند.

کد زیر را زیر ثبت‌کننده رویداد CORE اضافه کنید:

// Set verbosity level for Core events.
castDebugLogger.loggerLevelByEvents = {
  'cast.framework.events.category.CORE': cast.framework.LoggerLevel.INFO,
  'cast.framework.events.EventType.MEDIA_STATUS': cast.framework.LoggerLevel.DEBUG
}

// Set verbosity level for custom tags.
castDebugLogger.loggerLevelByTags = {
    [LOG_TAG]: cast.framework.LoggerLevel.DEBUG,
};

اشکال‌زدایی روی هم افتادگی

ابزار Cast Debug Logger یک پوشش اشکال‌زدایی روی گیرنده فراهم می‌کند تا پیام‌های لاگ سفارشی شما را روی دستگاه Cast نمایش دهد. showDebugLogs برای تغییر وضعیت پوشش اشکال‌زدایی و clearDebugLogs برای پاک کردن پیام‌های لاگ روی پوشش استفاده کنید.

برای پیش‌نمایش پوشش اشکال‌زدایی روی گیرنده خود، کد زیر را اضافه کنید.

context.addEventListener(cast.framework.system.EventType.READY, () => {
  if (!castDebugLogger.debugOverlayElement_) {
      // Enable debug logger and show a 'DEBUG MODE' overlay at top left corner.
      castDebugLogger.setEnabled(true);

      // Show debug overlay
      castDebugLogger.showDebugLogs(true);

      // Clear log messages on debug overlay
      castDebugLogger.clearDebugLogs();
  }
});

تصویری که لایه اشکال‌زدایی را نشان می‌دهد، فهرستی از پیام‌های گزارش اشکال‌زدایی در یک پس‌زمینه شفاف در بالای یک قاب ویدیویی

۱۳. تبریک

اکنون می‌دانید که چگونه با استفاده از SDK گیرنده وب Cast Web، یک برنامه گیرنده وب سفارشی ایجاد کنید.

برای جزئیات بیشتر، به راهنمای توسعه‌دهنده‌ی گیرنده‌ی وب مراجعه کنید.