為 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 設計檢查清單,新增必要的使用者介面元件。

我們提供 Google Cast 設計檢查清單,讓所有支援的平台的使用者更容易享有 Cast 使用者體驗。

我們要構建什麼內容?

完成本程式碼研究室後,您會建構 Cast 接收器,運用新的 Break API。

課程內容

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

軟硬體需求

功能

  • 您必須具備網站開發相關知識。
  • 過去曾建構 Cast 發送端和接收端應用程式。

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

僅讀完整內容 閱讀並完成練習

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

新手 中級 有效率

2. 取得範例程式碼

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

解壓縮下載的 ZIP 檔案。

3. 在本機部署接收器

如要將投放接收器與投放裝置搭配使用,你必須將位置放在投放裝置可以存取的位置。假設您已有支援 https 的伺服器,請略過下列操作說明並記下網址,因為在下一節將有用。

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

執行伺服器

您選擇的服務設定完成後,請前往 app-start 並啟動伺服器。

記下代管接收器的網址。您將在下一節使用。

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

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

Google Cast SDK 開發人員控制台的圖片,當中標出「新增應用程式」按鈕

按一下 [新增應用程式]

「新接收端應用程式」畫面的圖片,其中醒目顯示「自訂接收器」選項

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

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

請輸入新接收器的詳細資料,請務必使用結尾的網址

最後一個部分記下指派給新接收器的應用程式 ID

你也可以註冊 Google Cast 裝置,讓裝置存取你的接收器應用程式,再進行發布。發布接收器應用程式後,所有 Google Cast 裝置都能使用該應用程式。在本程式碼研究室中,建議使用未發布的接收器應用程式。

Google Cast SDK 開發人員控制台的圖片,當中標出「新增裝置」按鈕

按一下「新增裝置」

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

輸入 Cast 裝置背面的序號,並為裝置命名。您也可以在存取 Google Cast SDK 開發人員控制台時,透過 Chrome 投放螢幕畫面,藉此查看序號。

收款人和裝置可能需要 5 到 15 分鐘的時間,才能進行測試。您必須在 5 到 15 分鐘後重新啟動投放裝置。

5. 準備「Start Project」

開始使用本程式碼研究室之前,不妨參閱廣告開發人員指南,概略瞭解新版廣告功能。

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

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

您現在可以用自己慣用的文字編輯器,在入門專案上進行建構:

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

請注意,在本程式碼研究室中,http-server 應接收您做的變更。如果沒有顯示,請嘗試終止並重新啟動 http-server

對我們的寄件者而言,我們會使用 CAF 接收器偵錯錯誤來啟動投放工作階段。接收器旨在自動開始播放串流。

應用程式設計

接收器應用程式會初始化投放工作階段,到寄件者傳送 LOAD 要求 (例如播放媒體內容) 之前會保持開啟狀態。

應用程式含有一個主要檢視畫面,分別定義於 index.html 和另一個名為 js/receiver.js 的 JavaScript 檔案,其中包含所有可讓接收器順利運作的邏輯。

index.html

這個 HTML 檔案會包含接收端應用程式的所有使用者介面。目前基本上是空白的。

接收器.js

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

6. 將 VMAP 新增至內容

首先,請在 Chrome 中開啟網路寄件者。輸入您在 Cast SDK 開發人員控制台中提供的接收者應用程式 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,然後在網頁傳送者上按一下滑鼠右鍵,然後選取「投放」。廣告串流應該會立即開始播放。

7. 在內容中加入 VAST

如果您已導入上述 VMAP 程式碼,請將其註解。接下來,我們會逐步說明如何在內容中導入 VAST 廣告。

將下列程式碼複製到 js/receiver.js 檔案中。包含一個來自 DoubleClick 的六個 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,然後在網頁傳送者上按一下滑鼠右鍵,然後選取「投放」。廣告串流應該會立即開始播放。

8. 略過廣告插播時間點

CAF 有一個名為 BreakManager 的新類別,可協助您實作廣告行為的自訂業務規則。假設您想讓客戶在寬限期後略過廣告,

範例中的寄件者沒有媒體控制項。先加入 10 秒的開始偏移,讓串流在片頭廣告播放完畢之後才開始播放,直到第一個片中廣告插播時間點在 15 秒標記前開始。

找出 playerManager.setMessageInterceptor,然後在 return request 前加入以下這行。

request.currentTime = 10;

儲存 receiver.js 檔案並啟動投放工作階段。內容會先載入 10 秒,然後 5 秒鐘後播放廣告。

現在請新增規則,以便在 15 秒時略過片中廣告。

您需要有 BreakManager 執行個體,才能設定中斷載入的攔截器。將下列程式碼複製到 js/receiver.js 檔案中,包含 contextplayerManager 變數的行後方。

const breakManager = playerManager.getBreakManager();

現在,讓我們設定規則攔截規則,忽略所有在 30 秒前發生的廣告插播時間點。這個攔截器的運作方式與 PlayerManager 中的 LOAD 攔截器相同,但載入 BreakClip 時除外。

將下列程式碼複製到 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,然後在網頁傳送者上按一下滑鼠右鍵,然後選取「投放」。

串流已開始,但系統會略過使用者在 15 秒時看到的廣告區塊。

9. 自訂中斷跳轉行為

當使用者向前快轉時,系統會先從 findFrom 和 findTo 開始播放,直到播放 FindTo 位置的內容為止。當使用者倒轉影片時,系統不會播放任何內容。這是預設的中斷行為。

我們會使用 BreakManager 自訂要中斷跳轉的中斷點。我們使用 BreakManager 的 setBreakSeekkceptor 指定所需的自訂行為。每次執行搜尋作業時,都會叫用 setBreakSeekInterceptor。

我們會將回呼函式傳遞至 setBreakSeekInterceptor。系統會傳遞回呼函式,此物件內含的 findFrom 位置和 findTo 位置之間的所有中斷點。

現在,讓我們設定一項規則來攔截尚未在 findFrom 位置和 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;
    }
});

注意:如果未傳回任何值/空值,系統就不會播放任何廣告,如果傳回 trueSeekData,系統就會播放 findFrom to findTo 之間的所有插播點。

將變更儲存至 js/receiver.js,然後在網頁傳送者上按一下滑鼠右鍵,然後選取「投放」。廣告串流應該會立即開始播放。

10. 恭喜

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

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