為 Web Receiver 新增 Ad Breaks API 支援

透過集合功能整理內容 你可以依據偏好儲存及分類內容。

1. 總覽

Google Cast 標誌

本程式碼研究室會說明如何建構使用 Cast Ad Breaks API 的自訂 Web Receiver 應用程式。

什麼是 Google Cast?

Google Cast 可讓使用者將行動裝置的內容投放到電視上。之後,使用者就能利用行動裝置做為電視媒體的遙控器。

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

提供 Google Cast 設計檢查清單,以便在所有支援的平台上提供簡單且可預測的 Cast 使用者體驗。

我們要建構的是什麼?

完成本程式碼研究室後,您將使用全新 Break API 建構 Cast 接收器。

課程內容

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

軟硬體需求

  • 最新的 Google Chrome 瀏覽器。
  • NPM
  • Google Cast 裝置,例如已設定網路連線的 ChromecastAndroid TV
  • 具備 HDMI 輸入端的電視或螢幕,或 Google Home Hub

功能

  • 您必須先具備之前的網站開發知識。
  • 先前建構 Cast 傳送者和接收器應用程式的體驗。

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

唯讀閱讀 閱讀並完成練習

你對建構網頁應用程式體驗的體驗如何?

新手 中級 專業知識

2. 取得程式碼範例

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

將下載的 ZIP 檔案解壓縮。

3. 在本機部署接收器

如要透過投放裝置使用接收器,你必須將 Cast 託管在 Cast 裝置所在的位置。如果您已經有支援 https 的伺服器,只要略過下列操作說明即可,只要記住網址即可。在下一個部分中,您將需要這麼做。

如果您沒有可用的伺服器,請勿煩惱。您可以安裝 node.jshttp-serverngrok 節點模組。

npm install -g http-server
npm install -g ngrok

執行伺服器

如果你使用 http-server,請前往主控台並執行以下操作:

cd app-done
http-server

畫面應如下所示:

Starting up http-server, serving ./
Available on:
  http://127.0.0.1:8080
  http://172.19.17.192:8080
Hit CTRL-C to stop the server

請注意使用的本機通訊埠,然後在新的終端機中執行下列操作,以使用 ngrok 透過 HTTPS 公開本機接收器:

ngrok http 8080

這項操作會將 ngrok 通道設為本機 HTTP 伺服器,以指派給全球的 HTTPS 安全端點,供您在下一個步驟中使用 (https://116ec943.eu.ngrok.io):

ngrok by @inconshreveable                                                                                                                                                                                                                                     (Ctrl+C to quit)

Session Status         online
Version                2.2.4
Web Interface          http://127.0.0.1:8080
Forwarding             http://116ec943.eu.ngrok.io -> localhost:8080
Forwarding             https://116ec943.eu.ngrok.io -> localhost:8080

在程式碼研究室期間,您應讓 ngrokhttp-server 保持執行。您所做的本機變更會立即生效。

4. 在 Cast Developer Console 中註冊應用程式

您必須註冊應用程式,才能在 Chromecast 裝置上執行本程式碼研究室內建的自訂接收器。註冊應用程式後,您會收到應用程式 ID 傳送的應用程式 ID,以便啟動 API 呼叫 (例如啟動接收器應用程式)。

Google Cast SDK Developer Console 的圖片,以方框特別標出「##9; New New Application'」按鈕

按一下「新增應用程式」

'新增接收端應用程式'畫面,以 '自訂接收器'選項醒目顯示

選取「自訂接收器」,也就是我們正在建構的內容。

'新增自訂接收器'畫面:使用者輸入「#39;Receiver 應用程式網址'」欄位的網址

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

一節。記下指派給新接收者的申請 ID

你必須先註冊 Google Cast 裝置,才能讓裝置存取接收器應用程式。發布應用程式後,該應用程式將適用於所有 Google Cast 裝置。在這個程式碼研究室中,建議您與未發布的接收端應用程式搭配使用。

Google Cast SDK Developer Console 的圖片,以方框特別標出「' Add Device」' 按鈕

按一下「新增裝置」。

「新增投放接收裝置」'「對話方塊」圖片

輸入顯示在投放裝置背面的序號,並輸入描述性名稱。在存取 Google Cast SDK Developer Console 時,您也可以在 Chrome 中投放螢幕,藉此找出序號

接收器和裝置需要 5 到 15 分鐘才能完成測試。等候 5 至 15 分鐘後,你必須重新啟動投放裝置。

5. 準備起始專案

在開始本程式碼研究室之前,建議您詳閱 Google Ads 開發人員指南,概略瞭解新的廣告功能。

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

  • 寄件者應用程式位於行動裝置或筆記型電腦上執行
  • 接收端應用程式會在 Google Cast 裝置上執行。

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

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

請注意,當您逐步完成本程式碼研究室時,http-server 應挑選您進行的變更。如果發現不符合狀況,請嘗試終止並重新啟動 http-server

針對我們的傳送者,我們會使用 CAF 接收器偵錯偵錯 來啟動投放工作階段。接收端旨在自動開始直播。

應用程式設計

接收端應用程式會初始化 Cast 工作階段,並待命中,直到收到傳送者的 LOAD 要求 (例如播放媒體的指令) 為止。

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

index.html

這個 HTML 檔案將包含接收器應用程式的所有 UI。目前,它基本上是空的。

接收器.js

這個指令碼會管理接收器應用程式的所有邏輯。目前它含有基本的 CAF 接收器。

6. 將 VMAP 新增至內容

首先,請在 Chrome 中開啟網路寄件者。輸入您在 Cast SDK Developer Console 上提供的接收端應用程式 ID,然後按一下 [設定'']。

在接收端中,我們必須新增一些邏輯才能在內容中加入廣告。

將下列程式碼複製到 js/receiver.js 檔案中。其中包含 DoubleClick 的 VMAP 廣告代碼連結範例及隨機。

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

js/receiver.js file 中,找出 playerManager.setMessageInterceptor 函式,並在函式的最後 return request; 行中加入以下內容。

request.media.vmapAdsRequest = {
    adTagUrl: vmapUrl,
};

注意:指派給上述 vmapAdsRequest 的物件是 VastAdsRequest 物件的簡短版本。

儲存您對「js/receiver.js」所做的變更,然後在網路傳送者上按一下滑鼠右鍵,然後選取「投放&#39」即可啟動投放工作階段。廣告串流會立即開始播放。

7. 在您的內容中新增 VAST

如果您已實作上述的 VMAP 程式碼,請將其加上註解。以下將說明如何在內容中導入 VAST 廣告。

將下列程式碼複製到 js/receiver.js 檔案中。其中包含六個 VAST 廣告插播片段,以及部分隨機處理。這些插播片段會指派給 5 個廣告插播。也指定了每個廣告插播時間點。

const addVASTBreaksToMedia = (mediaInformation) => {
    mediaInformation.breakClips = [
        {
            id: "bc1",
            title: "bc1 (Pre-roll)",
            vastAdsRequest: {
                adTagUrl: 'https://pubads.g.doubleclick.net/gampad/ads?slotname=/124319096/external/ad_rule_samples&sz=640x480&ciu_szs=300x250&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpost&url=&unviewed_position_start=1&output=xml_vast3&impl=s&env=vp&gdfp_req=1&ad_rule=0&vad_type=linear&vpos=preroll&pod=1&ppos=1&lip=true&min_ad_duration=0&max_ad_duration=30000&vrid=6256&correlator=' + Math.floor(Math.random() * Math.pow(10, 10)) + '&video_doc_id=short_onecue&cmsid=496&kfa=0&tfcd=0'
            }
        },
        {
            id: "bc2",
            title: "bc2 (Mid-roll)",
            vastAdsRequest: {
                adTagUrl: 'https://pubads.g.doubleclick.net/gampad/ads?slotname=/124319096/external/ad_rule_samples&sz=640x480&ciu_szs=300x250&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpost&url=&unviewed_position_start=1&output=xml_vast3&impl=s&env=vp&gdfp_req=1&ad_rule=0&cue=15000&vad_type=linear&vpos=midroll&pod=2&mridx=1&rmridx=1&ppos=1&lip=true&min_ad_duration=0&max_ad_duration=30000&vrid=6256&correlator=' + Math.floor(Math.random() * Math.pow(10, 10)) + '&video_doc_id=short_onecue&cmsid=496&kfa=0&tfcd=0'
            }
        },
        {
            id: "bc3",
            title: "bc3 (Mid-roll)",
            vastAdsRequest: {
                adTagUrl: 'https://pubads.g.doubleclick.net/gampad/ads?slotname=/124319096/external/ad_rule_samples&sz=640x480&ciu_szs=300x250&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpost&url=&unviewed_position_start=1&output=xml_vast3&impl=s&env=vp&gdfp_req=1&ad_rule=0&cue=15000&vad_type=linear&vpos=midroll&pod=2&mridx=1&rmridx=1&ppos=1&lip=true&min_ad_duration=0&max_ad_duration=30000&vrid=6256&correlator=' + Math.floor(Math.random() * Math.pow(10, 10)) + '&video_doc_id=short_onecue&cmsid=496&kfa=0&tfcd=0'
            }
        },
        {
            id: "bc4",
            title: "bc4 (Mid-roll)",
            vastAdsRequest: {
                adTagUrl: 'https://pubads.g.doubleclick.net/gampad/ads?slotname=/124319096/external/ad_rule_samples&sz=640x480&ciu_szs=300x250&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpost&url=&unviewed_position_start=1&output=xml_vast3&impl=s&env=vp&gdfp_req=1&ad_rule=0&cue=15000&vad_type=linear&vpos=midroll&pod=2&mridx=1&rmridx=1&ppos=1&lip=true&min_ad_duration=0&max_ad_duration=30000&vrid=6256&correlator=' + Math.floor(Math.random() * Math.pow(10, 10)) + '&video_doc_id=short_onecue&cmsid=496&kfa=0&tfcd=0'
            }
        },
        {
            id: "bc5",
            title: "bc5 (Mid-roll)",
            vastAdsRequest: {
                adTagUrl: 'https://pubads.g.doubleclick.net/gampad/ads?slotname=/124319096/external/ad_rule_samples&sz=640x480&ciu_szs=300x250&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpost&url=&unviewed_position_start=1&output=xml_vast3&impl=s&env=vp&gdfp_req=1&ad_rule=0&cue=15000&vad_type=linear&vpos=midroll&pod=2&mridx=1&rmridx=1&ppos=1&lip=true&min_ad_duration=0&max_ad_duration=30000&vrid=6256&correlator=' + Math.floor(Math.random() * Math.pow(10, 10)) + '&video_doc_id=short_onecue&cmsid=496&kfa=0&tfcd=0'
            }
        },
        {
            id: "bc6",
            title: "bc6 (Post-roll)",
            vastAdsRequest: {
                adTagUrl: 'https://pubads.g.doubleclick.net/gampad/ads?slotname=/124319096/external/ad_rule_samples&sz=640x480&ciu_szs=300x250&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpost&url=&unviewed_position_start=1&output=xml_vast3&impl=s&env=vp&gdfp_req=1&ad_rule=0&vad_type=linear&vpos=postroll&pod=3&ppos=1&lip=true&min_ad_duration=0&max_ad_duration=30000&vrid=6256&correlator=' + Math.floor(Math.random() * Math.pow(10, 10)) + '&video_doc_id=short_onecue&cmsid=496&kfa=0&tfcd=0'
            }
        }
    ];
    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 訊息攔截器 (亦即開頭為 playerManager.setMessageInterceptor 的行),然後在函式的最後 return request; 行前加入以下內容。

addVASTBreaksToMedia(request.media);

儲存您對「js/receiver.js」所做的變更,然後在網路傳送者上按一下滑鼠右鍵,然後選取「投放&#39」即可啟動投放工作階段。廣告串流會立即開始播放。

8. 略過廣告插播

CAF 有一個名為 BreakManager 的新類別,可協助您針對廣告行為導入自訂業務規則。假設您想讓客戶在一段指定時間內略過寬限期,以便略過廣告。

我們範例中的寄件者沒有媒體控制項。加入 10 秒的起始偏移,讓串流在片頭廣告結束後開始播放,但在第 15 秒標記的第一個片中廣告插播之前。

找出 playerManager.setMessageInterceptor,並在 return request 前面新增以下這行程式碼。

request.currentTime = 10;

儲存 receiver.js 檔案並啟動 Cast 工作階段。您應該會在內容載入 10 秒後載入內容,然後在 5 秒後播放廣告。

現在,我們新增一項規則,在第 15 秒時略過片中廣告。

您需要有 BreakManager 的執行個體,以設定中斷載入的攔截器。在含有 contextplayerManager 變數的行後面,將以下這行複製到 js/receiver.js 檔案中。

const breakManager = playerManager.getBreakManager();

現在,讓我們設定規則,以忽略在 30 秒前發生的所有廣告插播。這個攔截器的運作方式與 PlayerManager 上的 LOAD 攔截器類似,但這個攔截器專門用於載入 BreakClips。

將下列程式碼複製到 js/receiver.js 檔案中。

breakManager.setBreakClipLoadInterceptor((breakClip, breakCtx) => {
  /** Below code will skip playback of break clips if the break position is less than 30 **/
  let breakObj = breakCtx.break;
  if(breakObj.position < 30)
    return null;
  else
    return breakClip;
});

注意:這裡會列出應略過的 BreakClips 空值。

儲存您對「js/receiver.js」所做的變更,然後在網路傳送者上按一下滑鼠右鍵,然後選取「投放&#39」即可啟動投放工作階段。

串流應開始播放,但系統會略過先前在 15 秒觀看的廣告區塊。

9. 自訂休息搜尋行為

當使用者向前跳動時,在 FindFrom 位置開始播放之前,searchFrom 和 findTo 之間最後一播放的未播放廣告就會播放。當使用者倒轉時,不會播放任何休息時間。這是預設的破壞行為。

我們會利用 BreakManager 自訂要在跳轉結束後播放的插播內容,我們使用 BreakManager 的 setBreakSeekInterceptor 來指定所需的自訂行為。每次執行跳轉作業時,系統都會叫用 setBreakSeekInterceptor。

我們會將回呼函式傳送至 setBreakSeekInterceptor。回呼函式會傳遞物件,其中包含「FromFrom」位置和「FindTo」位置之間的所有中斷點。

現在,讓我們以一種規則設定攔截器,然後在觀景點位置和 FindTo 位置之間從未觀看的中斷點規則進行播放。

將下列程式碼複製到 js/receiver.js 檔案中。

breakManager.setBreakSeekInterceptor(function(breakSeekData) {
     /**
     *
     * Below code will play an unwatched break between 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
     */

    let breakToPlay;
    for (let i = 0; i < breakSeekData.breaks.length; i++) {
        if (!breakSeekData.breaks[i].isWatched) {
            breakToPlay = breakSeekData.breaks[i];
        }
    }
    if (breakToPlay){
        breakSeekData.breaks = [breakToPlay];
        return breakSeekData;
    }
});

注意:如果傳回空白/空值,則不會播放任何中斷效果。我們如果依照原先的類型傳回 returnSeekData,就會播放到 SeeFrom 和 findTo 之間的所有中斷點。

儲存您對「js/receiver.js」所做的變更,然後在網路傳送者上按一下滑鼠右鍵,然後選取「投放&#39」即可啟動投放工作階段。廣告串流會立即開始播放。

10. 恭喜

現在您已瞭解如何使用最新的 Cast Receiver SDK 將廣告新增至接收端應用程式。

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