1. 總覽

本程式碼研究室將說明如何建構使用 Cast Ad Breaks API 的自訂網頁接收器應用程式。
什麼是 Google Cast?
使用者可以透過 Google Cast,將行動裝置中的內容投放到電視上。使用者就能將行動裝置當成遙控器,控制電視上的媒體播放。
透過 Google Cast SDK,您可以擴充應用程式,控制電視或音響系統。Cast SDK 可讓您根據 Google Cast 設計檢查清單新增必要的使用者介面元件。
Google Cast 設計檢查清單可協助您標準化 Cast 實作項目,確保使用者在所有支援的平台上都能獲得直覺體驗。
我們要建構什麼內容?
完成本程式碼研究室後,您將建構出可運用 Break API 的 Cast 接收器。
課程內容
- 如何在 Cast 內容中加入 VMAP 和 VAST 插斷
- 如何略過休息片段
- 如何自訂搜尋時的預設中斷行為
軟硬體需求
- 最新版 Google Chrome 瀏覽器。
- HTTPS 代管服務,例如 Firebase 代管或 ngrok。
- 已設定網路連線的 Google Cast 裝置,例如 Chromecast 或 Android TV。
- 具備 HDMI 輸入端的電視或螢幕,或是 Google Home Hub
體驗
請務必先具備下列經驗,再繼續完成本程式碼研究室。
- 具備一般網頁開發知識。
- 建構 Cast 網頁接收器應用程式。
您會如何使用本教學課程?
您對建構網頁應用程式的體驗滿意嗎?
2. 取得程式碼範例
將所有範例程式碼下載至電腦...
並解壓縮下載的 ZIP 檔案。
3. 在本機部署接收器
如要透過 Cast 裝置使用網頁接收器,必須將接收器代管在 Cast 裝置可存取的位置。如果您已有支援 HTTPS 的伺服器,請略過下列操作說明,並記下網址,因為您會在下一節用到。
如果沒有可用的伺服器,可以使用 Firebase Hosting 或 ngrok。
執行伺服器
設定好所選服務後,請前往 app-start 並啟動伺服器。
請記下代管接收器的網址。您會在下一節中使用這項資訊。
4. 在 Cast 開發人員控制台中註冊應用程式
您必須註冊應用程式,才能在 Chromecast 裝置上執行自訂接收器 (如本程式碼研究室所建構)。註冊應用程式後,系統會產生應用程式 ID,傳送端應用程式必須設定這個 ID,才能啟動網頁接收器應用程式。

按一下「新增應用程式」

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

輸入新收款人的詳細資料。請務必使用指向您打算託管 Web Receiver 應用程式的網址。註冊應用程式後,請記下控制台產生的應用程式 ID。稍後會設定傳送端應用程式,以使用該 ID。
您也必須註冊 Google Cast 裝置,才能在發布接收器應用程式前存取該應用程式。發布接收器應用程式後,所有 Google Cast 裝置都能使用。為方便進行本程式碼研究室,建議使用未發布的接收器應用程式。

按一下「新增裝置」

輸入 Cast 裝置背面印製的序號,並為裝置取個清楚易懂的名稱。你也可以在存取 Google Cast SDK 開發人員控制台時,透過 Chrome 投放螢幕畫面來查看序號
接收器和裝置需要 5 到 15 分鐘才能準備好進行測試。等待 5 到 15 分鐘後,請重新啟動 Cast 裝置。
5. 準備啟動專案
開始進行本程式碼研究室之前,建議先參閱廣告開發人員指南,瞭解廣告插播 API 的總覽。
請在下載的起始應用程式中新增 Google Cast 支援功能。以下是本程式碼研究室使用的部分 Google Cast 術語:
- 傳送者應用程式在行動裝置或筆電上執行,
- Google Cast 裝置上執行接收端應用程式。
現在,您可以使用慣用的文字編輯器,在入門專案的基礎上進行建構:
- 從下載的程式碼範例中選取

app-start目錄。 - 開啟
js/receiver.js和 index.html
請注意,在完成本程式碼研究室的練習時,您選擇的網路主機代管解決方案應會更新所做的變更。繼續驗證及測試變更時,請務必將變更推送至主機網站。
應用程式設計
如前所述,本程式碼研究室會使用傳送端應用程式啟動 Cast 工作階段,並修改接收端應用程式以使用廣告插播 API。
在本程式碼研究室中,Cast 和指令工具會做為 Web 傳送器,啟動接收器應用程式。首先,請在 Chrome 瀏覽器中開啟這項工具。輸入 Cast SDK 開發人員控制台提供的「接收器應用程式 ID」,然後按一下「設定」,設定用於測試的傳送器應用程式。
注意:如果找不到 Cast 圖示,請確認 Web Receiver 和 Cast 裝置已在 Cast 開發人員控制台中正確註冊。如果尚未執行這項操作,請重新啟動剛註冊的任何投放裝置。
本程式碼研究室主要著重於接收器應用程式,該應用程式包含 index.html 中定義的一個主要檢視區塊,以及名為 js/receiver.js 的 JavaScript 檔案。詳情請見下文。
index.html
這個 HTML 檔案包含 cast-media-player 元素提供的接收器應用程式 UI。同時也會載入 CAF SDK 和 Cast Debug Logger 程式庫。
receiver.js
這個指令碼會管理接收器應用程式的所有邏輯。目前指令碼包含基本的 CAF 接收器,可初始化 Cast 內容並在初始化時載入影片資產。此外,我們也新增了部分偵錯記錄器功能,可將記錄回傳給 Cast 和 Command 工具。
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 所做的變更,然後將檔案上傳至網路伺服器。在「投放和指令工具」上按一下「投放」圖示,發起 Cast 工作階段。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 所做的變更,然後將檔案上傳至網路伺服器。在「投放和指令工具」上按一下「投放」圖示,發起 Cast 工作階段。系統應先播放 VAST 廣告,再播放主要內容。
8. 略過廣告插播
CAF 有一個名為 BreakManager 的類別,可協助您實作廣告行為的自訂業務規則。其中一項功能可讓應用程式根據特定條件,以程式輔助方式略過中斷和中斷片段。這個範例說明如何略過廣告插播,但廣告插播的位置必須在內容的前 30 秒內,且不能是片尾廣告。使用上一節設定的 VAST 廣告時,系統會定義 5 個中斷點:1 個片頭中斷點、3 個片中中斷點 (分別在 15 秒、60 秒和 100 秒),以及 1 個片尾中斷點。完成上述步驟後,系統只會略過位置在 15 秒的片頭和片中廣告。
如要這麼做,應用程式應呼叫 BreakManager 提供的 API,為中斷載入設定攔截器。將下列程式碼行複製到 js/receiver.js 檔案中,放在包含 context 和 playerManager 變數的程式碼行之後,即可取得執行個體的參照。
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 所做的變更,然後將檔案上傳至網路伺服器。在「投放和指令工具」上按一下「投放」圖示,發起 Cast 工作階段。系統應會處理 VAST 廣告。請注意,系統不會播放片頭和第一個片中 (position 為 15 秒) 廣告。
9. 自訂中斷搜尋行為
搜尋過去的插斷時,預設實作會取得位置介於搜尋作業 seekFrom 和 seekTo 值之間的所有 Break 項目。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 所做的變更,然後將檔案上傳至網路伺服器。在「投放和指令工具」上按一下「投放」圖示,發起 Cast 工作階段。系統應會處理 VAST 廣告。請注意,系統不會播放片頭和第一個片中 (position 為 15 秒) 廣告。
等待播放時間達到 30 秒,略過中斷片段載入攔截器略過的所有中斷。到達所需時間後,請前往「Media Control」(媒體控制) 分頁,然後傳送搜尋指令。在「Seek Into Media」輸入欄位中填入 300 秒,然後按一下「TO」按鈕。請注意 Break Seek Interceptor 中列印的記錄。現在應該會覆寫預設行為,在 seekFrom 時間附近播放中斷。
10. 恭喜
您現在已瞭解如何使用最新版 Cast 接收器 SDK,在接收器應用程式中加入廣告。
詳情請參閱中插廣告開發人員指南。