選取感興趣的 DAI 解決方案
廣告連播放送 DAI
IMA SDK 可簡化在您的網站和應用程式中整合多媒體廣告的程序。
IMA SDK 可向任何符合 VAST 規定的廣告伺服器請求廣告,並管理應用程式中的廣告播放作業。
透過 IMA DAI SDK,應用程式會針對 VOD 或直播內容,對廣告和內容影片發出串流請求。接著,SDK 會傳回合併的影片串流,這樣您就不需要費心管理應用程式內廣告和內容影片之間的切換。
本指南說明如何使用 CAF 適用的 IMA DAI SDK 播放即時 DAI 廣告連播放送串流。
使用本指南前,請先熟悉 Chromecast 應用程式架構的網路接收器通訊協定。本指南假設您對 CAF 接收器概念 (例如訊息攔截器和 mediaInformation 物件) 有基本的瞭解,並且瞭解如何使用 Cast 指令與控制工具來模擬 CAF 傳送者。
如要使用 IMA DAI 廣告連播放送功能,您必須與廣告連播放送合作夥伴合作,且必須擁有 Ad Manager 360 進階帳戶。如果你擁有 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 開發人員控制台註冊的代管網路接收器應用程式,可修改此應用程式以代管本指南提供的程式碼。
- 設定為使用網路接收器應用程式的傳送應用程式。如要達到本範例的目的,請使用 Cast 指令與控制工具做為傳送器。
設定傳送者的 MediaInfo 物件
首先,請設定傳送端應用程式的 MediaInfo
物件,納入下列欄位:
廣闊 | 目錄 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
contentId
|
此媒體項目的專屬 ID。
CONTENT_ID |
||||||||||
contentUrl
|
選用設定。如果 DAI 串流載入失敗,要播放的備份串流網址。 BACKUP_STREAM_URL |
||||||||||
contentType
|
選用設定。內容備份串流的 Mime 類型。只有 DASH 串流才需要。 CONTENT_STREAM_MIMETYPE |
||||||||||
streamType
|
這個值使用的字串常值或常數會因傳送者平台而異。 | ||||||||||
customData
|
customData 欄位包含其他必填欄位的鍵/值儲存庫。
|
以下提供的程式碼範例可協助你踏出第一步:
網頁
如要在 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 = {
manifestUrl: "MANIFEST_URL",
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("manifestUrl", "MANIFEST_URL")
.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 = @{
@"manifestUrl": @"MANIFEST_URL",
@"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 = [
"liveConfigID": "MANIFEST_URL",
"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 指令與控制工具中設定這些值,請按一下「Load Media」分頁標籤,並將自訂載入要求類型設為「LOAD」。接著,請將文字區域中的 JSON 資料替換為以下 JSON:
{
"media": {
"contentId": "CONTENT_ID",
"contentUrl": "BACKUP_STREAM_URL",
"contentType": ""CONTENT_STREAM_MIMETYPE"",
"streamType": "LIVE",
"customData": {
"liveConfigID": "MANIFEST_URL",
"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 之後,將 CAF 的 IMA DAI SDK 匯入網路接收器。在指令碼標記中,先將接收器結構定義和玩家管理員儲存為常數,再啟動接收器。
<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 Stream Manager
初始化 IMA Stream Manager。
<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>
建立串流管理員載入攔截器
在您的媒體項目傳遞至 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 streamRequest = new google.ima.cast.dai.api.PodStreamRequest();
const customData = castRequest.media.customData;
streamRequest.customAssetKey = customData.customAssetKey;
streamRequest.networkCode = customData.networkCode;
streamRequest.apiKey = customData.apiKey;
return streamRequest;
};
將內容網址換成資訊清單網址和串流 ID
如果串流要求成功,請使用 streamManager.getStreamId()
擷取串流 ID,並將其插入 manifestUrl 中取代 [[STREAMID]]
。接著將現有的 contentUrl
替換為新的 manifestUrl
,讓 CAF 使用拼接的廣告連播播放直播。
/**
* 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.');
const media = castRequestWithPodStreamData.media;
const manifestUrl = media.customData.manifestUrl || "";
if (manifestUrl) {
console.log('Replacing the contentURL with the manifest URL and stream ID');
const streamId = streamManager.getStreamId();
castRequestWithPodStreamData.media.contentUrl = manifestUrl.replace('[[STREAMID]]', streamId);
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 應用程式架構和 CAF 適用的 IMA DAI SDK,要求並播放後端廣告連播放送串流。