選取感興趣的動態廣告解決方案
DAI 廣告連播放送
IMA SDK 可簡化多媒體廣告整合至網站和應用程式的程序。
IMA SDK 可向任何符合 VAST 標準的廣告伺服器要求廣告,並管理應用程式中的廣告播放作業。
透過 IMA DAI SDK,應用程式會針對隨選影片或直播內容,提出廣告和內容影片的串流要求。接著,SDK 會傳回合併的影片串流,因此您不必在應用程式中管理廣告和內容影片之間的切換。
本指南將示範如何使用 CAF 的 IMA DAI SDK 播放 DAI Pod 服務串流。
使用本指南前,請先熟悉 Chromecast 應用程式架構的 Web Receiver 通訊協定。本指南假設您具備 CAF 接收器概念的基本知識,例如訊息攔截器和 mediaInformation 物件,並熟悉如何使用Cast 指揮及控制工具模擬 CAF 傳送器。
如要使用 IMA DAI 廣告連播放送,您必須與廣告連播放送合作夥伴合作,並擁有 Ad Manager 360 Advanced 帳戶。如果您有 Ad Manager 帳戶,請與客戶經理聯絡以瞭解詳情。如要瞭解如何註冊 Ad Manager,請前往 Ad Manager 說明中心。
如要瞭解如何整合其他平台,或使用 IMA 用戶端 SDK,請參閱「互動式媒體廣告 SDK」。
IMA DAI 廣告連播放送功能總覽
使用 IMA CAF DAI SDK 實作 Pod 放送服務涉及兩個主要元件,本指南將說明如下:
StreamRequest
:定義傳送至 Google 廣告伺服器的串流要求的物件。要求會指定網路代碼、自訂資產金鑰和選用的 API 金鑰,以及其他選用參數。StreamManager
:這個物件會處理影片串流與 IMA DAI SDK 之間的通訊,例如觸發追蹤 ping 和將串流事件轉送給發布商。
必要條件
- Cast 開發人員控制台帳戶,且已註冊測試裝置。
- 已在 Cast 開發人員控制台中註冊的代管 網頁接收器應用程式,可修改為代管本指南提供的程式碼。
- 已設定為使用網頁接收器應用程式的傳送應用程式。為了方便說明,本例會使用 投放指令和控制工具做為傳送器。
設定傳送者的 MediaInfo 物件
首先,請設定傳送端應用程式的 MediaInfo
物件,納入下列欄位:
欄位 | 目錄 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
contentId
|
這個媒體項目的專屬 ID。 CONTENT_ID |
||||||||||
contentUrl
|
選用設定。如果動態廣告插播串流無法載入,就會播放備用串流網址。 BACKUP_STREAM_URL |
||||||||||
contentType
|
選用設定。內容備份串流的 Mimetype。只有 DASH 串流才需要這項資訊。 CONTENT_STREAM_MIMETYPE |
||||||||||
streamType
|
用於此值的字串常值或常數會因傳送端平台而異。 | ||||||||||
customData
|
customData 欄位包含額外必填欄位的鍵/值儲存庫。在這個範例中,它包含 DAI 串流參數。在正式版應用程式中,您可以改為傳遞 ID,讓投放接收器應用程式透過伺服器端要求擷取這些參數。
|
以下提供一些程式碼範例,協助您快速上手:
網路
如要在 Cast 網頁傳送端中設定這些值,請先建立含有必要資料的 MediaInfo
物件,然後向網頁接收端提出載入要求。
// Create mediaInfo object
const mediaInfo = new chrome.cast.media.MediaInfo("CONTENT_ID");
mediaInfo.contentUrl = "BACKUP_STREAM_URL";
mediaInfo.contentType = "CONTENT_STREAM_MIMETYPE";
mediaInfo.streamType = chrome.cast.media.StreamType.LIVE;
mediaInfo.customData = {
daiStreamType: "DAI_STREAM_TYPE",
networkCode: "NETWORK-CODE",
customAssetKey: "CUSTOM_ASSET_KEY",
apiKey: "API_KEY"
};
// Make load request to cast web receiver
const castSession = cast.framework.CastContext.getInstance().getCurrentSession();
const request = new chrome.cast.media.LoadRequest(mediaInfo);
castSession.loadMedia(request).then(
() => { console.log('Load succeed'); },
(errorCode) => { console.log('Error code: ' + errorCode); });
Android
如要在 Cast 網頁傳送端中設定這些值,請先建立包含必要資料的 MediaInfo 物件,然後向網頁接收端提出載入要求。
JSONObject customData = new JSONObject()?
.put("daiStreamType", "DAI_STREAM_TYPE")
.put("networkCode", "NETWORK-CODE")
.put("customAssetKey", "CUSTOM_ASSET_KEY")
.put("apiKey", "API_KEY");
MediaInfo mediaInfo = MediaInfo.Builder("CONTENT_ID")
.setContentUrl("BACKUP_STREAM_URL")
.setContentType("CONTENT_STREAM_MIMETYPE")
.setStreamType(MediaInfo.STREAM_TYPE_LIVE)
.setCustomData(customData)
.build();
RemoteMediaClient remoteMediaClient = mCastSession.getRemoteMediaClient();
remoteMediaClient.load(new MediaLoadRequestData.Builder().setMediaInfo(mediaInfo).build());
iOS (Obj-C)
如要在 Cast 網頁傳送端中設定這些值,請先建立含有必要資料的 GCKMediaInformation
物件,然後向網頁接收端提出載入要求。
NSURL url = [NSURL URLWithString:@"BACKUP_STREAM_URL"];
NSDictionary *customData = @{
@"daiStreamType": @"DAI_STREAM_TYPE",
@"networkCode": @"NETWORK-CODE",
@"customAssetKey": @"CUSTOM_ASSET_KEY",
@"apiKey": @"API_KEY"};
mediaInfoBuilder.customData = customData;
GCKMediaInformationBuilder *mediaInfoBuilder =
[[GCKMediaInformationBuilder alloc] initWithContentID: @"CONTENT_ID"];
mediaInfoBuilder.contentURL = url;
mediaInfoBuilder.contentType = @"CONTENT_STREAM_MIMETYPE";
mediaInfoBuilder.streamType = GCKMediaStreamTypeLive;
mediaInfoBuilder.customData = customData;
self.mediaInformation = [mediaInfoBuilder build];
GCKRequest *request = [self.sessionManager.currentSession.remoteMediaClient loadMedia:self.mediaInformation];
if (request != nil) {
request.delegate = self;
}
iOS (Swift)
如要在 Cast 網頁傳送端中設定這些值,請先建立含有必要資料的 GCKMediaInformation
物件,然後向網頁接收端提出載入要求。
let url = URL.init(string: "BACKUP_STREAM_URL")
guard let mediaURL = url else {
print("invalid mediaURL")
return
}
let customData = [
"daiStreamType": "DAI_STREAM_TYPE",
"networkCode": "NETWORK-CODE",
"customAssetKey": "CUSTOM_ASSET_KEY",
"region": "API_KEY"
]
let mediaInfoBuilder = GCKMediaInformationBuilder.init(contentId: "CONTENT_ID")
mediaInfoBuilder.contentURL = mediaUrl
mediaInfoBuilder.contentType = @"CONTENT_STREAM_MIMETYPE"
mediaInfoBuilder.streamType = GCKMediaStreamType.Live
mediaInfoBuilder.customData = customData
mediaInformation = mediaInfoBuilder.build()
guard let mediaInfo = mediaInformation else {
print("invalid mediaInformation")
return
}
if let request = sessionManager.currentSession?.remoteMediaClient?.loadMedia
(mediaInfo) {
request.delegate = self
}
CAC 工具
如要在 Cast Command and Control 工具中設定這些值,請按一下「Load Media」分頁,然後將自訂載入要求類型設為「LOAD」。然後將文字區域中的 JSON 資料替換為以下 JSON:
{
"media": {
"contentId": "CONTENT_ID",
"contentUrl": "BACKUP_STREAM_URL",
"contentType": ""CONTENT_STREAM_MIMETYPE"",
"streamType": "LIVE",
"customData": {
"daiStreamType": "DAI_STREAM_TYPE",
"networkCode": "NETWORK-CODE",
"customAssetKey": "CUSTOM_ASSET_KEY",
"oAuthToken": "API_KEY"
}
}
}
這項自訂載入要求可傳送至接收器,以便測試其餘步驟。
建立基本 CAF 接收器
請參閱 CAF SDK 自訂網頁接收器指南,瞭解如何建立自訂網頁接收器。
接收器的程式碼應如下所示:
<html>
<head>
<script
src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js">
</script>
</head>
<body>
<cast-media-player></cast-media-player>
<script>
// ...
</script>
</body>
</html>
匯入 IMA DAI SDK 並取得 Player Manager
新增指令碼標記,在指令碼載入 CAF 後,將 IMA DAI SDK for CAF 匯入網頁接收器。在指令碼標記中,請在啟動接收器前,將接收器內容和播放器管理員儲存為常數。
<html>
<head>
<script
src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
<script src="//imasdk.googleapis.com/js/sdkloader/cast_dai.js"></script>
</head>
<body>
<cast-media-player></cast-media-player>
<script>
const castContext = cast.framework.CastReceiverContext.getInstance();
const playerManager = castContext.getPlayerManager();
castContext.start();
</script>
</body>
</html>
初始化 IMA 串流管理工具
初始化 IMA 串流管理工具。
<html>
<head>
<script type="text/javascript"
src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
<script src="//imasdk.googleapis.com/js/sdkloader/cast_dai.js"></script>
</head>
<body>
<cast-media-player></cast-media-player>
<script>
const castContext = cast.framework.CastReceiverContext.getInstance();
const playerManager = castContext.getPlayerManager();
const streamManager = new google.ima.cast.dai.api.StreamManager();
castContext.start();
</script>
</body>
</html>
建立 Stream Manager 負載攔截器
在媒體項目傳送至 CAF 之前,請在 LOAD 訊息攔截器中建立串流要求。
const castContext = cast.framework.CastReceiverContext.getInstance();
const playerManager = castContext.getPlayerManager();
const streamManager = new google.ima.cast.dai.api.StreamManager();
/**
* Creates a livestream request object for a Pod Serving stream.
* @param {!LoadRequestData} castRequest The request object from the cast sender
* @return {StreamRequest} an IMA stream request
*/
const createStreamRequest = (castRequest) => { /* ... */};
/**
* Initates a DAI stream request for the final stream manifest.
* @param {!LoadRequestData} castRequest The request object from the cast sender
* @return {Promise<LoadRequestData>} a promise that resolves to an updated castRequest, containing the DAI stream manifest
*/
const createDAICastRequest = (castRequest) => {
return streamManager.requestStream(castRequest, createStreamRequest(castRequest))
.then((castRequestWithPodStreamData) => {
console.log('Successfully made DAI stream request.');
// ...
return castRequestWithPodStreamData;
})
.catch((error) => {
console.log('Failed to make DAI stream request.');
// CAF will automatically fallback to the content URL
// that it can read from the castRequest object.
return castRequest;
});
};
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD, createDAICastRequest);
castContext.start();
建立串流要求
完成 createStreamRequest
函式,根據 CAF 載入要求建立 Pod 服務串流。
/**
* Creates a livestream request object for a Pod Serving stream.
* @param {!LoadRequestData} castRequest The request object from the cast sender
* @return {StreamRequest} an IMA stream request
*/
const createStreamRequest = (castRequest) => {
const customData = castRequest.media.customData;
let streamRequest;
if (customData.daiStreamType == "LIVE") {
streamRequest = new google.ima.cast.dai.api.PodStreamRequest();
streamRequest.customAssetKey = customData.customAssetKey;
streamRequest.networkCode = customData.networkCode;
streamRequest.apiKey = customData.apiKey;
} else if (customData.daiStreamType == "VOD") {
streamRequest = new google.ima.cast.dai.api.PodVodStreamRequest();
streamRequest.networkCode = customData.networkCode;
streamRequest.apiKey = customData.apiKey;
}
return streamRequest;
};
從 VTP 擷取拼接的資訊清單
如果串流要求成功,請使用 streamManager.getStreamId()
擷取串流 ID。您的影片技術合作夥伴 (VTP) 或自訂資訊清單操作工具會提供使用此串流 ID 擷取資訊清單網址的操作說明。
擷取資訊清單網址後,請將現有的 contentUrl
替換為新的 manifestUrl
。
最後,在傳回修改過的串流資訊清單之前,請在 streamManager
上呼叫 loadStreamMetadata
方法,通知 IMA SDK 可以安全地要求串流中繼資料。只有 VOD 串流需要呼叫這個方法。
/**
* Initates a DAI stream request for the final stream manifest.
* @param {!LoadRequestData} castRequest The request object from the cast sender
* @return {Promise<LoadRequestData>} a promise that resolves to an updated castRequest, containing the DAI stream manifest
*/
const createDAICastRequest = (castRequest) => {
return streamManager.requestStream(castRequest, createStreamRequest(castRequest))
.then((castRequestWithPodStreamData) => {
console.log('Successfully made DAI stream request.');
// This is a sample VTP integration. Consult your VTP documentation
// for how to retrieve an ad-stitched stream manifest URL.
const manifestTemplate = "https://.../manifest.m3u8?gam_stream_id=[[STREAMID]]";
const streamId = streamManager.getStreamId();
const manifestUrl = manifestTemplate.replace('[[STREAMID]]', streamId)
// Assign your manifestUrl to the request's content URL.
castRequestWithPodStreamData.media.contentUrl = manifestUrl;
// After generating the manifest URL, VOD streams must notify the
// IMA SDK that it is safe to request ad pod metadata.
// This is only necessary for VOD streams. It is a no-op for
// livestreams, so no conditional is needed.
streamManager.loadStreamMetadata();
return castRequestWithPodStreamData;
})
.catch((error) => {
console.log('Failed to make DAI stream request.');
// CAF will automatically fallback to the content URL
// that it can read from the castRequest object.
return castRequest;
});
};
您現在可以使用 Cast Application Framework 和 IMA DAI SDK for CAF,要求及播放 Pod Serving 串流。