1. 總覽
本程式碼研究室會指導您如何建構使用 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 廣告插播
- 如何略過廣告插播片段
- 如何自訂跳轉時的預設行為
軟硬體需求
- 最新版的 Google Chrome 瀏覽器。
- HTTPS 代管服務,例如 Firebase 託管或 ngrok。
- 支援網際網路連線的 Google Cast 裝置,例如 Chromecast 或 Android TV。
- 具備 HDMI 輸入端的電視或螢幕或 Google Home Hub
功能
- 您必須具備網站開發相關知識。
- 過去曾建構 Cast 發送端和接收端應用程式。
您要如何使用這個教學課程?
針對網頁應用程式的建構體驗,您會給予什麼評價?
2. 取得範例程式碼
您可以將所有程式碼範例下載到電腦上...
解壓縮下載的 ZIP 檔案。
3. 在本機部署接收器
如要將投放接收器與投放裝置搭配使用,你必須將位置放在投放裝置可以存取的位置。假設您已有支援 https 的伺服器,請略過下列操作說明並記下網址,因為在下一節將有用。
如果您沒有可用伺服器,可以使用 Firebase 託管或 ngrok。
執行伺服器
您選擇的服務設定完成後,請前往 app-start
並啟動伺服器。
記下代管接收器的網址。您將在下一節使用。
4. 在 Cast 開發人員控制台中註冊應用程式
您必須註冊應用程式,才能在 Chromecast 裝置上執行本程式碼研究室內建的自訂接收器。註冊應用程式後,您會收到應用程式 ID 用來執行 API 呼叫的應用程式 ID,例如啟動接收器應用程式。
按一下 [新增應用程式]
選取「自訂接收器」,這就是我們建構的內容。
請輸入新接收器的詳細資料,請務必使用結尾的網址
最後一個部分記下指派給新接收器的應用程式 ID。
你也可以註冊 Google Cast 裝置,讓裝置存取你的接收器應用程式,再進行發布。發布接收器應用程式後,所有 Google Cast 裝置都能使用該應用程式。在本程式碼研究室中,建議使用未發布的接收器應用程式。
按一下「新增裝置」
輸入 Cast 裝置背面的序號,並為裝置命名。您也可以在存取 Google Cast SDK 開發人員控制台時,透過 Chrome 投放螢幕畫面,藉此查看序號。
收款人和裝置可能需要 5 到 15 分鐘的時間,才能進行測試。您必須在 5 到 15 分鐘後重新啟動投放裝置。
5. 準備「Start Project」
開始使用本程式碼研究室之前,不妨參閱廣告開發人員指南,概略瞭解新版廣告功能。
我們需要為你下載的啟動應用程式新增 Google Cast 支援。以下是本程式碼研究室會使用的一些 Google Cast 術語:
- 傳送者應用程式是在行動裝置或筆記型電腦上執行,
- 「接收器」應用程式會在 Google Cast 裝置上執行。
您現在可以用自己慣用的文字編輯器,在入門專案上進行建構:
- 從程式碼範例下載中選取
app-start
目錄。 - 開啟
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
檔案中,包含 context
和 playerManager
變數的行後方。
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 在接收端應用程式中加入廣告。
詳情請參閱廣告插播開發人員指南。