建立自訂網路接收器

1. 總覽

Google Cast 標誌

本程式碼研究室會說明如何建構自訂網頁接收器應用程式,在支援投放功能的裝置上播放內容。

什麼是 Google Cast?

Google Cast 可讓使用者將行動裝置上的內容投放到電視。這樣一來,使用者就能將行動裝置或電腦的 Chrome 瀏覽器當做遙控器,在電視上播放媒體。

Google Cast SDK 可讓應用程式控制支援 Google Cast 的裝置 (例如電視或音響系統)。Cast SDK 會根據 Google Cast 設計檢查清單提供必要的 UI 元件。

Google Cast 設計檢查清單可讓 Cast 使用者體驗在所有支援平台上都簡單易懂。請按這裡瞭解詳情

我們要建構什麼?

完成本程式碼研究室後,您將取得一個 HTML5 應用程式,做為自己的自訂接收器,以便在支援 Cast 的裝置上顯示影片內容。

課程內容

  • 如何設定接收器開發作業。
  • 支援 Cast 的接收器基本概念 (以 Cast 應用程式架構為依據)。
  • 如何接收投放的影片。
  • 如何整合偵錯記錄器。
  • 如何針對智慧螢幕最佳化接收器。

軟硬體需求

體驗

  • 您必須具有網站開發背景知識。
  • 你也需要具備觀看電視的相關知識 :)

您會如何使用這個教學課程?

只能閱讀 閱讀並完成練習

針對建立網頁應用程式的經驗,您會給予什麼評價?

新手 中級 熟練

請評分你觀看電視的體驗。

新手 中級 熟練

2. 取得程式碼範例

您可以將所有範例程式碼下載到電腦上...

並解壓縮下載的 ZIP 檔案。

3. 在本機部署接收器

如要透過 Cast 裝置使用網路接收器,你必須將網路接收器託管在 Cast 裝置可存取的位置。如果您已擁有支援 HTTPS 的伺服器,請略過下列操作說明,並記下網址,因為您會在下一節中使用到這個網址。

如果你沒有可用伺服器,可改用 Firebase 代管ngrok

執行伺服器

設定所需服務後,請前往 app-start 並啟動伺服器。

請記下代管接收器的網址。您會在下一節中使用這項資訊。

4. 在 Cast 開發人員控制台中註冊應用程式

您必須註冊應用程式,才能在 Chromecast 裝置上執行本程式碼研究室中建構的自訂接收器。註冊應用程式之後,您就會收到應用程式 ID,您的傳送者應用程式必須使用這個 ID 才能執行 API 呼叫,例如啟動接收器應用程式。

圖片:Google Cast SDK 開發人員控制台,其中「Add New Application」按鈕已醒目顯示

按一下「新增應用程式」

「新增接收端應用程式」畫面的圖片,以方框特別標出「自訂接收端」選項

選取「自訂接收器」,這是我們要建構的項目。

「New Custom Receiver」畫面的圖片,顯示使用者在「Receiver Application URL」欄位中輸入的網址

輸入新收件者的詳細資料,請務必使用您最後使用的網址

在上一節中。記下新接收器的應用程式 ID

此外,你必須註冊 Google Cast 裝置,以便在發布前存取接收器應用程式。發布接收器應用程式後,所有 Google Cast 裝置都會提供這項應用程式。為了配合本程式碼研究室的目的,建議您使用未發布的接收器應用程式。

Google Cast SDK 開發人員控制台的圖片,其中醒目顯示「Add New Device」(新增裝置) 按鈕

按一下「新增裝置」

「新增 Cast 接收器裝置」對話方塊的圖片

輸入 Cast 裝置背面所印的序號,並為裝置取個說明性名稱。在 Chrome 中存取 Google Cast SDK 開發人員控制台時,您也可以投放畫面來找出序號

接收器和裝置需要 5 到 15 分鐘才能準備好進行測試。等待 5 到 15 分鐘後,你必須重新啟動投放裝置。

5. 執行範例應用程式

Google Chrome 標誌

在等待新接收器應用程式準備就緒以便進行測試的同時,我們來看看完成的接收器應用程式範例長什麼樣。我們要建立的接收器將可使用自動調整位元率串流播放媒體 (我們將使用透過 HTTP 的動態自動調整串流 (DASH) 編碼的範例內容)。

在瀏覽器中開啟指揮與控制 (CaC) 工具

指揮與控制 (CaC) 工具的「Cast Connect & Logger Controls」分頁圖片

  1. 畫面上應會顯示我們的 CaC 工具。
  2. 使用預設的「CC1AD845」示範接收器 ID,然後按一下「Set App ID」(設定應用程式 ID) 按鈕。
  3. 按一下左上方的「投放」按鈕,然後選取 Google Cast 裝置。

指示已連線至接收器應用程式的「指揮與控制」(CaC) 工具「Cast Connect & Logger Controls」分頁圖片

  1. 前往頂端的「載入媒體」分頁。

命令與控制 (CaC) 工具「Load Media」標籤的圖片

  1. 按一下「Load by Content」按鈕,播放範例影片。
  2. 影片會開始在 Google Cast 裝置上播放,以便您瞭解使用預設接收器的基本接收器功能。

6. 準備 start 專案

我們需要在你下載的啟動應用程式中新增 Google Cast 支援功能。以下是本程式碼研究室中會用到的 Google Cast 術語:

  • 在行動裝置或筆記型電腦上執行傳送端應用程式
  • 在 Google Cast 裝置上執行接收端應用程式。

現在,您可以使用喜愛的文字編輯器,在範例專案上進行建構:

  1. 從下載的範例程式碼中選取 「資料夾」圖示app-start 目錄。
  2. 開啟 js/receiver.jsindex.html

請注意,在您完成本程式碼研究室後,http-server 應會擷取您所做的變更。如果發現並非如此,請嘗試終止並重新啟動 http-server

應用程式設計

接收器應用程式會初始化 Cast 工作階段,並在傳送端傳送 LOAD 要求 (也就是播放媒體內容的指令) 前待命。

應用程式包含一個主要檢視畫面,在 index.html 中定義,以及一個名為 js/receiver.js 的 JavaScript 檔案,其中包含讓接收器運作的所有邏輯。

index.html

這個 HTML 檔案會包含接收器應用程式的 UI。目前檔案為空白,我們會在程式碼研究室中新增內容。

receiver.js

這個指令碼會管理接收器應用程式的所有邏輯。目前它只是一個空白檔案,但我們會在下一節中只用幾行程式碼,將它轉換為功能完整的 Cast 接收器。

7. 基本的 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>

在 <footer> 載入 receiver.js, 前將下列程式碼新增至 index.html <body>,為接收端 SDK 提供用來顯示預設接收器 UI 的空間,其中包含您剛新增的指令碼。

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

接下來,我們需要在 js/receiver.js 中初始化 SDK,其中包含:

  • 取得 CastReceiverContext 的參照,這是整個接收端 SDK 的主要進入點
  • 儲存 PlayerManager 的參照,這個物件會處理播放作業,並提供您所需的所有鉤子,以便插入您自己的自訂邏輯
  • CastReceiverContext 上呼叫 start(),初始化 SDK

js/receiver.js 中新增以下內容。

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

context.start();

8. 投放「基本」影片內容

在本程式碼研究室中,請使用 CaC 工具試用全新的接收器。

將網路瀏覽器指向指揮與控制 (CaC) 工具

指揮與控制 (CaC) 工具的「Cast Connect & Logger Controls」分頁圖片

請務必將您先前在欄位中註冊的應用程式 ID 替換為自己的應用程式 ID,然後按一下「Set App ID」(設定應用程式 ID)。這會指示工具在啟動投放工作階段時使用接收器。

投放媒體

整體來說,如要在投放裝置上播放媒體,必須完成以下操作:

  1. 傳送端會從 Cast SDK 建立 MediaInfo JSON 物件,模擬媒體項目。
  2. 傳送端會連線至投放裝置,啟動接收端應用程式。
  3. 接收器會透過 LOAD 要求載入 MediaInfo 物件,以便播放內容。
  4. 接收端會監控並追蹤媒體狀態。
  5. 傳送端會將播放指令傳送至接收端,根據使用者與傳送端應用程式的互動情形控制播放作業。

在這個首次的基本嘗試中,我們會使用可播放的素材資源網址 (儲存在 MediaInfo.contentUrl 中) 填入 MediaInfo

實際傳送者會在 MediaInfo.contentId 中使用應用程式專屬媒體 ID。接收器會使用 contentId 做為 ID,以便發出適當的後端 API 呼叫,解析實際的素材資源網址並將其設為 MediaInfo.contentUrl.。接收器也會處理 DRM 授權取得或插入廣告插播資訊等工作。

我們即將擴充您的接收器,進行下一節的這類工作。請先按一下「投放」圖示,然後選取裝置來開啟接收器。

指示已連線至接收器應用程式的「指揮與控制」(CaC) 工具「Cast Connect & Logger Controls」分頁圖片

前往「Load Media」(載入媒體) 分頁,然後按一下「Load by Content」(按內容載入) 按鈕。接收端應開始播放範例內容。

指揮與控制 (CaC) 工具「Load Media」分頁的圖片

接收端 SDK 可立即處理的內容,如下所示:

  • 初始化投放工作階段
  • 處理來自含有可播放資產的傳送端傳入的 LOAD 要求
  • 提供可在大螢幕上顯示的基本播放器 UI。

歡迎先瀏覽 CaC 工具及其程式碼,再繼續進行下一個部分。接下來我們會擴充接收器,以討論簡單的範例 API 來完成寄件者傳入的 LOAD 要求。

9. 整合外部 API

為了讓開發人員在實際應用程式中與 Cast 接收器互動,我們將修改接收器,以便處理透過 API 金鑰參照所需媒體內容的 LOAD 要求,而非透過可播放資產網址傳送。

應用程式通常會這樣做的原因如下:

  • 寄件者可能不知道內容網址。
  • Cast 應用程式可直接在接收端處理驗證、其他商業邏輯或 API 呼叫。

這項功能主要在 PlayerManager setMessageInterceptor() 方法中實作。這可讓您依類型攔截傳入的訊息,並在訊息傳送至 SDK 的內部訊息處理常式前加以修改。在本節中,我們會處理 LOAD 要求,並會採取以下行動:

  • 讀取傳入的 LOAD 要求及其自訂 contentId
  • 發出 GET 呼叫至我們的 API,根據 contentId 查詢可串流傳輸的資產。
  • 使用串流網址修改 LOAD 要求。
  • 修改 MediaInformation 物件,設定串流類型參數。
  • 請將請求傳送至 SDK 進行播放,如果我們無法查詢要求的媒體,則拒絕指令。

我們提供的範例 API 展示了 SDK 的掛鉤,可用於自訂常見的接收器工作,同時仍可依賴大部分的即用型體驗。

範例 API

請將瀏覽器指向 https://storage.googleapis.com/cpe-sample-media/content.json,查看我們的影片目錄範例。內容包括海報圖片的 PNG 格式網址,以及 DASH 和 HLS 串流。DASH 和 HLS 串流會指向已解多工處理的視訊和音訊來源,這些來源儲存在片段式 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"
  },

  [...]

}

在下一個步驟中,我們會使用 LOAD 要求呼叫接收器,然後將每個項目的鍵 (例如 bbb, fbb_ad) 對應至串流的網址。

攔截 LOAD 要求

在這個步驟中,我們會使用函式建立載入攔截器,該函式會向代管的 JSON 檔案提出 XHR 要求。取得 JSON 檔案後,系統就會剖析內容並設定中繼資料。在以下各節中,我們會自訂 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);
          }
        });
      });
    });

下一節將概略說明如何為 DASH 內容設定載入要求的 media 屬性。

使用 API DASH 範例內容

準備好載入攔截器後,我們會向接收端指定內容類型。這項資訊會向接收端提供主播放清單網址和串流 MIME 類型。將下列程式碼加入 LOAD 攔截器的 Promise() 中的 js/receiver.js 檔案:

...
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 內容的載入方式,請查看下一個步驟。

使用範例 API HLS 內容

範例 API 包含 HLS 內容和 DASH。除了設定 contentType 如同前一個步驟所述,載入要求還需要一些額外的屬性,才能使用範例 API 的 HLS 網址。當接收器設定為播放 HLS 串流時,預設容器類型為傳輸串流 (TS)。因此,如果只修改 contentUrl 屬性,接收端會嘗試開啟 TS 格式的範例 MP4 串流。在載入要求中,MediaInformation 物件應使用其他屬性進行修改,讓接收端知道內容的類型是 MP4,而非 TS。將下列程式碼加入載入攔截器中的 js/receiver.js 檔案,修改 contentUrlcontentType 屬性。此外,請新增 HlsSegmentFormatHlsVideoSegmentFormat 屬性。

...
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;
            ...
          }
        });
      });
    });

測試

再次開啟指令與控制 (CaC) 工具,並將應用程式 ID 設為接收端的應用程式 ID。使用「投放」按鈕選取你的裝置。

前往「Load Media」(載入媒體) 分頁。這次請刪除「Load by Content」按鈕旁邊「Content URL」欄位中的文字,這麼做會強制應用程式傳送 LOAD 要求,其中只包含媒體的 contentId 參照。

指揮與控制 (CaC) 工具「Load Media」分頁的圖片

假設所有修改作業都能與接收器修改作業順利搭配運作,攔截器應將 MediaInfo 物件調整成 SDK 可以在螢幕上播放的內容。

按一下「Load by Content」按鈕,確認媒體是否正常播放。您可以隨意在 content.json 檔案中將內容 ID 變更為其他 ID。

10. 為智慧螢幕進行最佳化調整

智慧螢幕是具備觸控功能的裝置,可讓接收端應用程式支援觸控控制項。

本節說明如何在智慧型螢幕上啟動接收器應用程式時進行最佳化,以及如何自訂播放器控制項。

存取 UI 控制項

您可以使用 cast.framework.ui.Controls.GetInstance() 存取智慧螢幕的 UI 控制項物件。請在 context.start() 上方 js/receiver.js 檔案中加入下列程式碼:

...

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

context.start();

如果您未使用 <cast-media-player> 元素,就必須在 CastReceiverOptions 中設定 touchScreenOptimizedApp。在本程式碼研究室中,我們使用的是 <cast-media-player> 元素。

context.start({ touchScreenOptimizedApp: true });

系統會根據 MetadataTypeMediaStatus.supportedMediaCommands 為每個版位指派預設控制按鈕。

影片控制選項

針對 MetadataType.MOVIEMetadataType.TV_SHOWMetadataType.GENERIC,智慧螢幕的 UI 控制項物件會如以下範例所示顯示。

播放影片的圖片,上方有 UI 控制項

  1. --playback-logo-image
  2. MediaMetadata.subtitle
  3. MediaMetadata.title
  4. MediaStatus.currentTime
  5. MediaInformation.duration
  6. ControlsSlot.SLOT_SECONDARY_1ControlsButton.QUEUE_PREV
  7. ControlsSlot.SLOT_PRIMARY_1ControlsButton.SEEK_BACKWARD_30
  8. PLAY/PAUSE
  9. ControlsSlot.SLOT_PRIMARY_2ControlsButton.SEEK_FORWARD_30
  10. ControlsSlot.SLOT_SECONDARY_2ControlsButton.QUEUE_NEXT

音訊控制

針對 MetadataType.MUSIC_TRACK,智慧螢幕的 UI 控制項物件會顯示如下:

圖片顯示正在播放音樂,並在頂端疊加 UI 控制項

  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_1ControlsButton.NO_BUTTON
  9. ControlsSlot.SLOT_PRIMARY_1ControlsButton.QUEUE_PREV
  10. PLAY/PAUSE
  11. ControlsSlot.SLOT_PRIMARY_2ControlsButton.QUEUE_NEXT
  12. ControlsSlot.SLOT_SECONDARY_2ControlsButton.NO_BUTTON

更新支援的媒體指令

UI Controls 物件也會決定 ControlsButton 是否根據 MediaStatus.supportedMediaCommands 顯示。

supportedMediaCommands 的值等於 ALL_BASIC_MEDIA 時,預設控制項版面配置會顯示如下:

媒體播放器控制項圖片:進度列、已啟用的「播放」按鈕、「快轉」和「倒轉」按鈕

supportedMediaCommands 的值等於 ALL_BASIC_MEDIA | QUEUE_PREV | QUEUE_NEXT 時,預設控制項版面配置會顯示如下:

媒體播放器控制項的圖片:進度列、「播放」按鈕、「快轉」和「倒轉」按鈕,以及啟用的「排隊上一個」和「排隊下一個」按鈕

當 supportedMediaCommands 的值等於 PAUSE | QUEUE_PREV | QUEUE_NEXT 時,預設控制項版面配置會顯示如下:

媒體播放器控制項的圖片:進度列、「播放」按鈕,以及已啟用的「排隊上一個」和「排隊下一個」按鈕

當系統提供文字音軌時,隱藏式輔助字幕按鈕一律會顯示在 SLOT_1 上。

媒體播放器控制項的圖片:進度列、&#39;Play&#39; 按鈕、&#39;Skip forward&#39; 和 &#39;Skip backward&#39; 按鈕、&#39;Queue previous&#39; 和 &#39;Queue next&#39; 按鈕,以及啟用的 &#39;Closed Caption&#39; 按鈕

如要在啟動接收器結構定義後動態變更 supportedMediaCommands 的值,可以呼叫 PlayerManager.setSupportedMediaCommands 來覆寫值。此外,您可以使用 addSupportedMediaCommands 新增指令,或使用 removeSupportedMediaCommands 移除現有指令。

自訂控制按鈕

您可以使用 PlayerDataBinder 自訂控制項。將下列程式碼新增至 touchControls 下方的 js/receiver.js 檔案,設定控制項的第一個空格:

...

// 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();

11. 在智慧螢幕上實作媒體瀏覽功能

媒體瀏覽是一項 CAF 接收器功能,可讓使用者在觸控裝置上探索其他內容。為實作此功能,您將使用 PlayerDataBinder 設定 BrowseContent UI。接著,您可以根據要顯示的內容,使用 BrowseItems 填入資料。

BrowseContent

以下是 BrowseContent UI 及其屬性的範例:

顯示兩個影片縮圖和第三個影片縮圖的 BrowseContent UI 圖片

  1. BrowseContent.title
  2. BrowseContent.items

顯示比例

請使用 targetAspectRatio property 選取最適合圖片素材資源的顯示比例。CAF Receiver SDK 支援三種顯示比例:SQUARE_1_TO_1PORTRAIT_2_TO_3LANDSCAPE_16_TO_9

BrowseItem

使用 BrowseItem 顯示每個項目的標題、副標題、時間長度和圖片:

顯示兩個影片縮圖和第三個影片縮圖的 BrowseContent UI 圖片

  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,藉此移除媒體瀏覽 UI。

12. 偵錯接收器應用程式

Cast Receiver SDK 提供另一種方法,可讓開發人員使用 CastDebugLogger API 和搭配的 指令與控制 (CaC) 工具擷取記錄,輕鬆對接收器應用程式進行偵錯。

初始化

如要整合 API,請在 index.html 檔案中新增 CastDebugLogger 來源指令碼。來源應在 Cast Receiver SDK 宣告後的 <head> 標記中宣告。

<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 例項並啟用記錄器:

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 的重疊圖層。

圖片:播放影片時,畫面左上角的紅色背景上顯示「DEBUG MODE」訊息

記錄播放器事件

使用 CastDebugLogger,您可以輕鬆記錄由 CAF Receiver SDK 觸發的播放器事件,並使用不同的記錄器等級記錄事件資料。loggerLevelByEvents 設定檔會使用 cast.framework.events.EventTypecast.framework.events.category 指定要記錄哪些事件。

請在 castDebugLogger 宣告下方加入下列程式碼,以便在系統觸發玩家 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
}

記錄訊息和自訂標記

CastDebugLogger API 可讓您建立記錄訊息,並以不同顏色顯示在接收器偵錯疊加上。您可以使用下列記錄方法,按優先順序由高到低依序列出:

  • 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 設定為選用項目。如果未為其記錄器層級設定自訂標記,所有記錄訊息都會顯示在偵錯疊加畫面上。

請在 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 會在接收端上提供偵錯疊加畫面,在投放裝置上顯示自訂記錄訊息。使用 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();
  }
});

圖片顯示偵錯重疊,在影片畫面頂端的半透明背景上顯示偵錯記錄訊息清單

13. 恭喜

您現在已瞭解如何使用 Cast Web Receiver SDK 建立自訂網頁接收器應用程式。

詳情請參閱網路接收端開發人員指南。