為網路接收器新增 Ad Breaks API 支援

1. 總覽

Google Cast 標誌

本程式碼實驗室概述如何建構使用 Cast Ad Breaks API 的自訂網頁接收器應用程式。

什麼是 Google Cast?

使用者可以透過 Google Cast,將行動裝置中的內容投放到電視上。使用者就能使用行動裝置當作遙控器,在電視上播放媒體。

您可以使用 Google Cast SDK 擴充應用程式,以便控制電視或音響系統。您可以使用 Cast SDK 根據 Google Cast 設計檢查清單新增必要的 UI 元件。

Google Cast 設計檢查清單可用於標準化 Cast 實作,讓所有支援平台的使用者都能享有直覺的使用體驗。

我們要建構什麼?

完成本程式碼研究室後,您將建構可利用 Break API 的 Cast Receiver。

課程內容

  • 如何在投放內容中加入 VMAP 和 VAST 插播片段
  • 如何略過廣告插播時間點
  • 如何自訂尋找時的預設中斷行為

軟硬體需求

體驗

請先確認您具備以下經驗,再繼續完成本程式碼研究室。

  • 具備一般網頁開發知識。
  • 建構投放網頁接收端應用程式。

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

只閱讀 閱讀並完成練習

您對建構網頁應用程式的體驗滿意嗎?

新手 中級 熟練

2. 取得程式碼範例

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

並解壓縮下載的 ZIP 檔案。

3. 在本機部署接收器

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

如果您沒有可用的伺服器,可以使用 Firebase 代管ngrok

執行伺服器

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

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

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

您必須註冊應用程式,才能在 Chromecast 裝置上執行本程式碼研究室內建的自訂接收器。註冊應用程式後,系統會產生應用程式 ID,您必須設定傳送端應用程式,才能啟動網頁接收端應用程式。

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

按一下「新增應用程式」

「New Receiver Application」畫面的圖片,其中標出「Custom Receiver」選項

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

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

輸入新收件者的詳細資料。請務必使用指向您打算代管 Web Receiver 應用程式的網址。註冊應用程式後,請記下主控台產生的應用程式 ID。稍後會在後續章節中說明如何設定傳送端應用程式,以便使用該 ID。

您也必須註冊 Google Cast 裝置,讓接收器應用程式在發布前存取該裝置。接收器應用程式發布後,所有的 Google Cast 裝置皆可使用該應用程式。為了配合本程式碼研究室的目的,建議您使用未發布的接收器應用程式。

Google Cast SDK 開發人員控制台的圖片,醒目顯示的項目是「新增裝置」按鈕

按一下「新增裝置」

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

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

接收方和裝置需要 5 到 15 分鐘的時間才能完成測試。等待 5 到 15 分鐘後,請重新啟動 Cast 裝置。

5. 準備 Start 專案

開始本程式碼研究室之前,建議您詳閱廣告開發人員指南,概略瞭解廣告插播 API。

您下載的啟動應用程式需新增 Google Cast 支援功能。以下是本程式碼研究室中使用的部分 Google Cast 術語:

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

您現在可以使用慣用的文字編輯器,在這個初始專案上進行建構:

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

請注意,當您在此程式碼研究室中操作時,所選網站代管解決方案應根據變更進行更新。請務必在繼續驗證及測試時,將變更內容推送至代管網站。

應用程式設計

如先前所述,程式碼研究室會使用傳送端應用程式啟動投放工作階段,以及會修改為使用廣告插播 API 的接收端應用程式。

在本程式碼研究室中,Cast 和指令列工具會扮演網路傳送者來啟動接收器應用程式。首先,請在 Chrome 瀏覽器中開啟該工具。輸入 Cast SDK 開發人員工作室提供的 接收端應用程式 ID,然後按一下「Set」,設定測試用的傳送端應用程式。

注意:如果沒有看到投放圖示,請確認 Web Receiver 和投放裝置已正確註冊至 Cast 開發人員控制台。如果尚未執行,請為所有剛註冊的 Chromecast 裝置重新開機。

接收器應用程式是本程式碼研究室的主要焦點,包含一個 index.html 中定義的主要檢視畫面和一個名為 js/receiver.js 的 JavaScript 檔案。請參閱下文進一步瞭解。

index.html

這個 HTML 檔案包含接收器應用程式的 UI,由 cast-media-player 元素提供。也會載入 CAF SDK 和 Cast 偵錯記錄器程式庫。

receiver.js

這個指令碼會管理接收器應用程式的所有邏輯。目前,它包含基本 CAF 接收器,可初始化投放內容,並在初始化時載入影片資產。我們也新增了部分偵錯記錄器功能,可將記錄回報給 Cast 和指令工具。

6. 將 VMAP 新增至您的內容

Cast Web Receiver SDK 支援透過數位影片多重廣告播放清單 (簡稱 VMAP) 指定的廣告。XML 結構會指定媒體的廣告插播和相關的插播短片中繼資料。為了插入這類廣告,SDK 會在 MediaInformation 物件中提供 vmapAdsRequest 屬性。

js/receiver.js 檔案中建立 VastAdsRequest 物件。找出 LOAD 要求攔截器函式,並將其替換為以下程式碼。這個檔案包含 DoubleClick 的 VMAP 代碼網址範例,並提供隨機的關聯器值,確保針對相同網址的後續要求產生 XML 範本時,會加入尚未觀看的廣告插播。

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

      // Create the VMAP Ads request data and append it to the MediaInformation.
      const vmapUrl =
          'https://pubads.g.doubleclick.net/gampad/ads?sz=640x480&iu=/124319096/external/ad_rule_samples&ciu_szs=300x250&ad_rule=1&impl=s&gdfp_req=1&env=vp&output=vmap&unviewed_position_start=1&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpost&cmsid=496&vid=short_onecue&correlator=' +
          Math.floor(Math.random() * Math.pow(10, 10));
      let vmapRequest = new cast.framework.messages.VastAdsRequest();
      vmapRequest.adTagUrl = vmapUrl;
      loadRequestData.media.vmapAdsRequest = vmapRequest;

      castDebugLogger.warn(
          'MyAPP.LOG', 'Playable URL: ' + loadRequestData.media.contentId);

      return loadRequestData;
    });

將變更儲存至 js/receiver.js,並將檔案上傳到網路伺服器。按一下「投放與指令工具」中的投放圖示,即可在該工具中啟動投放工作階段。系統應先播放 VMAP 廣告,然後播放主要內容。

7. 將 VAST 新增至您的內容

如前所述,Web Receiver SDK 支援多種廣告類型。本節將介紹可用來整合數位影片廣告放送範本 (又稱 VAST) 廣告的 API。如果您已實作上一個部分的 VMAP 程式碼,請將其註解掉。

請在載入要求攔截器之後,將下列內容複製到 js/receiver.js 檔案中。其中包含來自 DoubleClick 的六個 VAST 插播短片和隨機的 correlator 值。這些廣告插播片段已指派給 5 個廣告插播時間點。每個插播廣告的 position 都會設為相對於主要內容的秒數,包括片頭廣告 (position 設為 0) 和片尾廣告 (position 設為 -1)。

const addVASTBreaksToMedia = (mediaInformation) => {
  mediaInformation.breakClips = [
    {
      id: 'bc1',
      title: 'bc1 (Pre-roll)',
      vastAdsRequest: {
        adTagUrl: generateVastUrl('preroll')
      }
    },
    {
      id: 'bc2',
      title: 'bc2 (Mid-roll)',
      vastAdsRequest: {
        adTagUrl: generateVastUrl('midroll')
      }
    },
    {
      id: 'bc3',
      title: 'bc3 (Mid-roll)',
      vastAdsRequest: {
        adTagUrl: generateVastUrl('midroll')
      }
    },
    {
      id: 'bc4',
      title: 'bc4 (Mid-roll)',
      vastAdsRequest: {
        adTagUrl: generateVastUrl('midroll')
      }
    },
    {
      id: 'bc5',
      title: 'bc5 (Mid-roll)',
      vastAdsRequest: {
        adTagUrl: generateVastUrl('midroll')
      }
    },
    {
      id: 'bc6',
      title: 'bc6 (Post-roll)',
      vastAdsRequest: {
        adTagUrl: generateVastUrl('postroll')
      }
    }
  ];

  mediaInformation.breaks = [
    {id: 'b1', breakClipIds: ['bc1'], position: 0},
    {id: 'b2', breakClipIds: ['bc2'], position: 15},
    {id: 'b3', breakClipIds: ['bc3', 'bc4'], position: 60},
    {id: 'b4', breakClipIds: ['bc5'], position: 100},
    {id: 'b5', breakClipIds: ['bc6'], position: -1}
  ];
};

注意:廣告插播的 breakClipIds 屬性為陣列,表示可為每個廣告插播指派多個廣告插播短片。

在您的 js/receiver.js file 中找出 LOAD 訊息攔截器,並將其替換為以下程式碼。請注意,VMAP 工作已註解為顯示 VAST 類型廣告。

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

      // Create the VMAP Ads request data and append it to the MediaInformation.
      // const vmapUrl =
      //     'https://pubads.g.doubleclick.net/gampad/ads?sz=640x480&iu=/124319096/external/ad_rule_samples&ciu_szs=300x250&ad_rule=1&impl=s&gdfp_req=1&env=vp&output=vmap&unviewed_position_start=1&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpost&cmsid=496&vid=short_onecue&correlator=' +
      //     Math.floor(Math.random() * Math.pow(10, 10));
      // let vmapRequest = new cast.framework.messages.VastAdsRequest();
      // vmapRequest.adTagUrl = vmapUrl;
      // loadRequestData.media.vmapAdsRequest = vmapRequest;

      // Append VAST ad breaks to the MediaInformation.
      addVASTBreaksToMedia(loadRequestData.media);

      castDebugLogger.warn(
          'MyAPP.LOG', 'Playable URL: ' + loadRequestData.media.contentId);

      return loadRequestData;
    });

將變更儲存至 js/receiver.js,並將檔案上傳到網路伺服器。按一下「投放與指令工具」中的投放圖示,即可在該工具中啟動投放工作階段。系統應先播放 VAST 廣告,然後播放主要內容。

8. 廣告插播略過

CAF 有一個名為 BreakManager 的類別,可協助您為廣告行為實作自訂業務規則。其中一個功能可讓應用程式透過程式設計略過廣告插播,並根據某些條件中斷短片。本範例說明如何略過位於內容前 30 秒內的廣告插播,但不包括片尾廣告插播。使用前一個章節中設定的 VAST 廣告時,系統會定義 5 個插播廣告:1 個片頭插播廣告、3 個片中插播廣告 (分別出現在 15、60 和 100 秒),以及 1 個片尾插播廣告。完成這些步驟後,系統只會略過位置在 15 秒的片頭片中廣告。

為此,應用程式應呼叫可透過 BreakManager 取得的 API,設定中斷載入的攔截器。將下列程式碼複製到 js/receiver.js 檔案中,放在包含 contextplayerManager 變數的程式碼行後方,以便取得執行個體的參照。

const breakManager = playerManager.getBreakManager();

應用程式應設定攔截器,並設定規則,以便在 30 秒前發生的任何廣告插播中忽略,同時留意任何片尾插播 (因為其 position 值為 -1)。這個攔截器的運作方式與 PlayerManager 上的 LOAD 攔截器相同,只是這個攔截器專門用於載入插播短片。在 LOAD 要求攔截器後方以及 addVASTBreaksToMedia 函式宣告之前設定此值。

將下列內容複製到 js/receiver.js 檔案中。

breakManager.setBreakClipLoadInterceptor((breakClip, breakContext) => {
  /**
   * The code will skip playback of break clips if the break position is within
   * the first 30 seconds.
   */
  let breakObj = breakContext.break;
  if (breakObj.position >= 0 && breakObj.position < 30) {
    castDebugLogger.debug(
        'MyAPP.LOG',
        'Break Clip Load Interceptor skipping break with ID: ' + breakObj.id);
    return null;
  } else {
    return breakClip;
  }
});

注意:在此傳回 null 會略過正在處理的 BreakClip。如果 Break 未定義任何插播短片,系統會略過插播本身。

將變更儲存至 js/receiver.js,然後將檔案上傳至網路伺服器。按一下「投放與指令工具」中的投放圖示,即可在該工具中啟動投放工作階段。系統應會處理 VAST 廣告。請注意,系統不會播放片頭和第一個片中 (position 為 15 秒) 廣告。

9. 自訂廣告插播搜尋行為

當尋找過去的片段時,預設實作會取得所有 Break 項目,其位置介於尋找作業的 seekFromseekTo 值之間。從這個插播清單中,SDK 會播放 Break,其 position 最接近 seekTo 值,且 isWatched 屬性設為 false。接著,該廣告插播的 isWatched 屬性會設為 true,播放器就會開始播放廣告插播片段。觀眾看完插播廣告後,系統會從 seekTo 位置繼續播放主要內容。如果沒有這類中斷情形,系統就不會播放中斷,主要內容會在 seekTo 位置繼續播放。

如要自訂跳轉時播放的中斷檔,Cast SDK 在 BreakManager 中提供 setBreakSeekInterceptor API。當應用程式透過該 API 提供自訂邏輯時,SDK 會在執行一或多個中斷點的搜尋作業時呼叫該邏輯。回呼函式會傳遞物件,其中包含 seekFrom 位置和 seekTo 位置之間的所有中斷點。然後,應用程式需要修改並傳回 BreakSeekData

為了說明其用法,以下範例會覆寫預設行為,取得所有已略過的廣告插播,並只播放時間軸上顯示的第一個廣告插播。

將下列內容複製到 js/receiver.js 檔案中,並在定義下方加入 setBreakClipLoadInterceptor

breakManager.setBreakSeekInterceptor((breakSeekData) => {
  /**
   * The code will play an unwatched break between the seekFrom and seekTo
   * position. Note: If the position of a break is less than 30 then it will be
   * skipped due to the setBreakClipLoadInterceptor code.
   */
  castDebugLogger.debug(
      'MyAPP.LOG',
      'Break Seek Interceptor processing break ids ' +
          JSON.stringify(breakSeekData.breaks.map(adBreak => adBreak.id)));

  // Remove all other breaks except for the first one.
  breakSeekData.breaks.splice(1,breakSeekData.breaks.length);
  return breakSeekData;
});

注意:如果函式未傳回值,或傳回 null,則不會播放任何中斷點。

將變更儲存至 js/receiver.js,然後將檔案上傳至網路伺服器。按一下「投放」圖示,在投放與指令列工具上啟動投放工作階段。系統應會處理 VAST 廣告。請注意,系統不會播放片頭和第一個片中 (position 為 15 秒) 廣告。

等到播放時間達到 30 秒,即可略過所有由插斷器略過的插播廣告片段。連上 YouTube 後,前往「媒體控制」分頁分派跳轉指令。在「Seek Into Media」輸入框中填入 300 秒,然後按一下「TO」按鈕。請注意在 Break Seek Interceptor 中顯示的記錄。您現在應覆寫預設行為,以便播放更接近 seekFrom 時間的廣告插播。

10. 恭喜

您現在已瞭解如何使用最新的 Cast Receiver SDK,在接收器應用程式中加入廣告。

詳情請參閱廣告插播開發人員指南。