為網路接收器新增 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」按鈕已醒目顯示

按一下「新增應用程式」

「新接收端應用程式」的圖片顯示「Custom Receiver」已醒目顯示選項

選取 [自訂接收器],也就是我們要建構的接收器。

「新增自訂接收端」的圖片畫面顯示使用者正在輸入「接收端應用程式網址」的網址欄位

輸入新收件者的詳細資料。請務必使用指向您打算代管 Web Receiver 應用程式的網址。請記下註冊應用程式後,控制台產生的應用程式 ID。傳送方應用程式會在後續部分中設定使用該 ID。

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

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

按一下「新增裝置」

「Add Cast Receiver Device」對話方塊的圖片

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

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

5. 準備 Start 專案

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

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

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

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

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

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

應用程式設計

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

在這個程式碼研究室中,投放和指令工具會充當網路傳送端,啟動接收端應用程式。首先,請在 Chrome 瀏覽器中開啟這項工具。輸入 Cast SDK 開發人員工作室提供的 接收端應用程式 ID,然後按一下「Set」,設定要測試的傳送端應用程式。

注意:如果發現投放圖示未顯示,請確認 Web Receiver 和投放裝置已正確註冊至 Cast 開發人員控制台。如果尚未註冊任何已註冊的投放裝置,請先恢復原廠設定。

接收器應用程式是本程式碼研究室的主要重點,包含在 index.html 中定義的主要檢視畫面,以及名為 js/receiver.js 的 JavaScript 檔案。詳細說明如下。

index.html

此 HTML 檔案包含 cast-media-player 元素提供的接收器應用程式的 UI。也會載入 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 秒,即可略過所有由插播短片載入攔截器略過的插播廣告。到達後,請前往「Media Control」分頁,傳送跳轉指令。將「Seek Into Media」輸入欄位填入 300 秒,然後按一下「TO」按鈕。請注意在 Break Seek Interceptor 中顯示的記錄。您現在應覆寫預設行為,以便播放更接近 seekFrom 時間的廣告插播。

10. 恭喜

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

詳情請參閱《廣告插播時間點》開發人員指南。