Выберите интересующее вас решение DAI.
Подача капсул DAI
IMA SDK упрощают интеграцию мультимедийной рекламы в ваши веб-сайты и приложения.
IMA SDK позволяют запрашивать рекламу у любого рекламного сервера , совместимого с VAST , и управлять воспроизведением рекламы в ваших приложениях.
С помощью SDK IMA DAI приложения отправляют запрос на потоковую передачу рекламного и контентного видео как для видео по запросу, так и для прямых трансляций. Затем SDK возвращает объединенный видеопоток, поэтому вам не нужно управлять переключением между рекламным и контентным видео внутри вашего приложения.
В этом руководстве показано, как воспроизводить поток DAI Pod Serving, используя IMA DAI SDK для CAF.
Перед использованием этого руководства ознакомьтесь с протоколом Web Receiver платформы Chromecast Application Framework . В этом руководстве предполагается базовое понимание концепций приемника CAF, таких как перехватчики сообщений и объекты mediaInformation , а также знакомство с инструментом Cast Command and Control для эмуляции отправителя CAF.
Для использования IMA DAI Pod Serving необходимо сотрудничать с партнером по Pod Serving и иметь учетную запись Ad Manager 360 Advanced . Если у вас уже есть учетная запись Ad Manager, обратитесь к своему менеджеру по работе с клиентами за дополнительной информацией. Информацию о регистрации в Ad Manager можно найти в Справочном центре Ad Manager .
Для получения информации об интеграции с другими платформами или об использовании клиентских SDK IMA см. раздел «SDK для интерактивной рекламы» .
Обзор системы подачи напитков в капсулах IMA DAI
Реализация Pod Serving с использованием IMA CAF DAI SDK включает в себя два основных компонента, которые демонстрируются в этом руководстве:
-
StreamRequest: Объект, определяющий запрос потока данных на рекламные серверы Google. Запросы указывают сетевой код, пользовательский ключ ресурса и необязательный ключ API, а также другие необязательные параметры. -
StreamManager: Объект, который обрабатывает обмен данными между видеопотоком и SDK IMA DAI, например, отправляет запросы на отслеживание и пересылает события потока издателю.
Предварительные требования
- Учетная запись в консоли разработчика Cast с зарегистрированными тестовыми устройствами.
- Приложение веб-приемника , зарегистрированное в консоли разработчика Cast, которое можно модифицировать для размещения кода, предоставленного в этом руководстве.
- Приложение-отправитель, настроенное на использование вашего веб-приложения-приемника. В данном примере в качестве отправителя используйте инструмент Cast Command and Control .
Настройте объекты MediaInfo отправителя.
Сначала настройте объект MediaInfo вашего приложения-отправителя, добавив в него следующие поля:
| Поле | Содержание | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
contentId | Уникальный идентификатор данного медиафайла. CONTENT_ID | ||||||||||
contentUrl | Необязательно. Резервный URL-адрес потока для воспроизведения в случае, если поток DAI не загрузится. BACKUP_STREAM_URL | ||||||||||
contentType | Необязательно. MIME-тип потоков резервного копирования контента. Требуется только для потоков DASH . CONTENT_STREAM_MIMETYPE | ||||||||||
streamType | Строковый литерал или константа, используемая для этого значения, различается в зависимости от платформы отправителя. | ||||||||||
customData | Поле customData содержит хранилище типа «ключ-значение» с дополнительными обязательными полями. В этом примере оно содержит параметры вашего потока DAI. В рабочем приложении вы можете вместо этого передать идентификатор, который ваше приложение-приемник для трансляции будет использовать для получения этих параметров с помощью запроса на стороне сервера.
|
Вот несколько примеров кода, которые помогут вам начать:
Веб
Для настройки этих значений в веб-отправителе 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 , перейдите на вкладку «Загрузка медиафайлов» и установите пользовательский тип запроса на загрузку в значение 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>
Импортируйте SDK IMA DAI и получите менеджер проигрывателя.
Добавьте тег <script> для импорта IMA DAI SDK для CAF в ваш веб-приемник сразу после скрипта загрузки CAF. В теге <script> сохраните контекст приемника и менеджер проигрывателя в качестве констант перед запуском приемника.
<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>
Создайте перехватчик нагрузки менеджера потоков.
Прежде чем ваши медиафайлы будут переданы в 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 , чтобы создать поток Pod Serving на основе запроса загрузки CAF.
/**
* 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() для получения идентификатора потока. Ваш технический партнер по видео (VTP) или пользовательский манипулятор манифеста предоставит инструкции по получению URL-адреса манифеста, используя этот идентификатор потока.
После получения URL-адреса манифеста замените существующий contentUrl новым manifestUrl .
Наконец, перед возвратом измененного манифеста потока вызовите метод loadStreamMetadata вашего streamManager , чтобы сообщить 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;
});
};
Очистка активов IMA DAI
После успешного завершения запроса и показа рекламы в потоке Pod Serving с использованием IMA DAI SDK мы рекомендуем очистить все ресурсы после завершения сессии Pod Serving. Вызовите StreamManager.destroy() , чтобы остановить воспроизведение потока, прекратить отслеживание рекламы и освободить все загруженные ресурсы потока.
Выберите интересующее вас решение DAI.
Подача капсул DAI
IMA SDK упрощают интеграцию мультимедийной рекламы в ваши веб-сайты и приложения.
IMA SDK позволяют запрашивать рекламу у любого рекламного сервера , совместимого с VAST , и управлять воспроизведением рекламы в ваших приложениях.
С помощью SDK IMA DAI приложения отправляют запрос на потоковую передачу рекламного и контентного видео как для видео по запросу, так и для прямых трансляций. Затем SDK возвращает объединенный видеопоток, поэтому вам не нужно управлять переключением между рекламным и контентным видео внутри вашего приложения.
В этом руководстве показано, как воспроизводить поток DAI Pod Serving, используя IMA DAI SDK для CAF.
Перед использованием этого руководства ознакомьтесь с протоколом Web Receiver платформы Chromecast Application Framework . В этом руководстве предполагается базовое понимание концепций приемника CAF, таких как перехватчики сообщений и объекты mediaInformation , а также знакомство с инструментом Cast Command and Control для эмуляции отправителя CAF.
Для использования IMA DAI Pod Serving необходимо сотрудничать с партнером по Pod Serving и иметь учетную запись Ad Manager 360 Advanced . Если у вас уже есть учетная запись Ad Manager, обратитесь к своему менеджеру по работе с клиентами за дополнительной информацией. Информацию о регистрации в Ad Manager можно найти в Справочном центре Ad Manager .
Для получения информации об интеграции с другими платформами или об использовании клиентских SDK IMA см. раздел «SDK для интерактивной рекламы» .
Обзор системы подачи напитков в капсулах IMA DAI
Реализация Pod Serving с использованием IMA CAF DAI SDK включает в себя два основных компонента, которые демонстрируются в этом руководстве:
-
StreamRequest: Объект, определяющий запрос потока данных на рекламные серверы Google. Запросы указывают сетевой код, пользовательский ключ ресурса и необязательный ключ API, а также другие необязательные параметры. -
StreamManager: Объект, который обрабатывает обмен данными между видеопотоком и SDK IMA DAI, например, отправляет запросы на отслеживание и пересылает события потока издателю.
Предварительные требования
- Учетная запись в консоли разработчика Cast с зарегистрированными тестовыми устройствами.
- Приложение веб-приемника , зарегистрированное в консоли разработчика Cast, которое можно модифицировать для размещения кода, предоставленного в этом руководстве.
- Приложение-отправитель, настроенное на использование вашего веб-приложения-приемника. В данном примере в качестве отправителя используйте инструмент Cast Command and Control .
Настройте объекты MediaInfo отправителя.
Сначала настройте объект MediaInfo вашего приложения-отправителя, добавив в него следующие поля:
| Поле | Содержание | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
contentId | Уникальный идентификатор данного медиафайла. CONTENT_ID | ||||||||||
contentUrl | Необязательно. Резервный URL-адрес потока для воспроизведения в случае, если поток DAI не загрузится. BACKUP_STREAM_URL | ||||||||||
contentType | Необязательно. MIME-тип потоков резервного копирования контента. Требуется только для потоков DASH . CONTENT_STREAM_MIMETYPE | ||||||||||
streamType | Строковый литерал или константа, используемая для этого значения, различается в зависимости от платформы отправителя. | ||||||||||
customData | The customData field contains a key-value store of additional required fields. In this sample, it contains your DAI stream parameters. In a production app you might instead pass an identifier that your cast receiver app would use to retrieve these parameters with a server-side request.
|
Here are some code samples to help you get started:
Веб
To configure these values in a Cast web sender, first create a MediaInfo object with the required data, then make a load request to the web receiver.
// 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
To configure these values in a Cast web sender, first create a MediaInfo object with the required data, then make a load request to the web receiver.
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)
To configure these values in a Cast web sender, first create a GCKMediaInformation object with the required data, then make a load request to the web receiver.
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)
To configure these values in a Cast web sender, first create a GCKMediaInformation object with the required data, then make a load request to the web receiver.
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 tool
To configure these values in the Cast Command and Control tool , click the Load Media tab, and set the custom load request type to LOAD. Then replace the JSON data in the text area with this 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"
}
}
}
This custom load request can be sent to the receiver to test the rest of the steps.
Create a basic CAF receiver
Create a custom web receiver, as seen in the CAF SDK Custom Web Receiver Guide .
Your receiver's code should look like this:
<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>
Import the IMA DAI SDK and get the Player Manager
Add a script tag to import the IMA DAI SDK for CAF to your web receiver, just after the script loading CAF. In the script tag, store the receiver context and player manager as constants before starting the receiver.
<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>
Initialize the IMA Stream Manager
Initialize the 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>
Create the Stream Manager Load Interceptor
Before your media items are passed to CAF, create your stream request in a LOAD message interceptor .
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();
Create the stream request
Complete the createStreamRequest function to create a Pod Serving stream based on the CAF load request.
/**
* 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;
};
Retrieve the stitched manifest from your VTP
If your stream request is successful, use streamManager.getStreamId() to retrieve the stream's ID. Your Video Technical Partner (VTP) or custom manifest manipulator will provide instructions to retrieve a manifest URL, using this stream ID.
Once you have retrieved your manifest URL, replace the existing contentUrl with the new manifestUrl .
Lastly, before returning the modified stream manifest, call the loadStreamMetadata method on your streamManager to inform the IMA SDK that it can safely request stream metadata. This call is only necessary for VOD streams.
/**
* 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;
});
};
Clean up IMA DAI assets
When you have successfully finished requesting and displaying ads in a Pod Serving stream with IMA DAI SDK, we suggest you clean up any resources after the Pod Serving session is complete. Call StreamManager.destroy() to stop stream playback, stop all ad tracking, and release all of the loaded stream assets.
Select the DAI solution you're interested in
Pod Serving DAI
IMA SDKs simplify integrating multimedia ads into your websites and apps.
IMA SDKs can request ads from any VAST-compliant ad server and manage ad playback in your apps.
With IMA DAI SDKs, apps make a stream request for ad and content video for either VOD or live content. The SDK then returns a combined video stream, so that you don't have to manage switching between ad and content video within your app.
This guide demonstrates how to play a DAI Pod Serving stream, using the IMA DAI SDK for CAF.
Before using this guide, familiarize yourself with the Chromecast Application Framework's Web Receiver protocol. This guide assumes a basic understanding of CAF receiver concepts, such as message interceptors and mediaInformation objects, and familiarity with using the Cast Command and Control tool , to emulate a CAF sender.
To use IMA DAI Pod Serving, you must be working with a Pod Serving partner and must have an Ad Manager 360 Advanced account. If you have an Ad Manager account, contact your account manager for more details. For information about signing up for Ad Manager, visit the Ad Manager Help Center .
For information on integrating with other platforms, or on using the IMA client-side SDKs, see Interactive Media Ads SDKs .
IMA DAI Pod Serving overview
Implementing Pod Serving using the IMA CAF DAI SDK involves two main components, which are demonstrated in this guide:
-
StreamRequest: An object that defines a stream request to Google's advertising servers. Requests specify a Network Code, Custom Asset Key, and an optional API key, as well as other optional parameters. -
StreamManager: An object that handles communication between the video stream and the IMA DAI SDK, such as firing tracking pings and forwarding stream events to the publisher.
Предварительные требования
- A Cast Developer Console account with registered test devices.
- A hosted web receiver app that is registered with your Cast Developer Console and which can be modified to host the code provided by this guide.
- A sending app that is configured to use your web receiver app. For the purposes of this example, use the Cast Command and Control tool as your sender.
Configure the sender's MediaInfo objects
First, configure your sender app's MediaInfo object to include the following fields:
| Поле | Содержание | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
contentId | A unique identifier for this media item. CONTENT_ID | ||||||||||
contentUrl | Optional. Backup stream URL to play if the DAI stream fails to load. BACKUP_STREAM_URL | ||||||||||
contentType | Optional. Mimetype of the content backup streams. Only needed for DASH streams . CONTENT_STREAM_MIMETYPE | ||||||||||
streamType | The string literal or constant used for this value varies by sender platform. | ||||||||||
customData | The customData field contains a key-value store of additional required fields. In this sample, it contains your DAI stream parameters. In a production app you might instead pass an identifier that your cast receiver app would use to retrieve these parameters with a server-side request.
|
Here are some code samples to help you get started:
Веб
To configure these values in a Cast web sender, first create a MediaInfo object with the required data, then make a load request to the web receiver.
// 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
To configure these values in a Cast web sender, first create a MediaInfo object with the required data, then make a load request to the web receiver.
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)
To configure these values in a Cast web sender, first create a GCKMediaInformation object with the required data, then make a load request to the web receiver.
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)
To configure these values in a Cast web sender, first create a GCKMediaInformation object with the required data, then make a load request to the web receiver.
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 tool
To configure these values in the Cast Command and Control tool , click the Load Media tab, and set the custom load request type to LOAD. Then replace the JSON data in the text area with this 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"
}
}
}
This custom load request can be sent to the receiver to test the rest of the steps.
Create a basic CAF receiver
Create a custom web receiver, as seen in the CAF SDK Custom Web Receiver Guide .
Your receiver's code should look like this:
<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>
Import the IMA DAI SDK and get the Player Manager
Add a script tag to import the IMA DAI SDK for CAF to your web receiver, just after the script loading CAF. In the script tag, store the receiver context and player manager as constants before starting the receiver.
<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>
Initialize the IMA Stream Manager
Initialize the 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>
Create the Stream Manager Load Interceptor
Before your media items are passed to CAF, create your stream request in a LOAD message interceptor .
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();
Create the stream request
Complete the createStreamRequest function to create a Pod Serving stream based on the CAF load request.
/**
* 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;
};
Retrieve the stitched manifest from your VTP
If your stream request is successful, use streamManager.getStreamId() to retrieve the stream's ID. Your Video Technical Partner (VTP) or custom manifest manipulator will provide instructions to retrieve a manifest URL, using this stream ID.
Once you have retrieved your manifest URL, replace the existing contentUrl with the new manifestUrl .
Lastly, before returning the modified stream manifest, call the loadStreamMetadata method on your streamManager to inform the IMA SDK that it can safely request stream metadata. This call is only necessary for VOD streams.
/**
* 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;
});
};
Clean up IMA DAI assets
When you have successfully finished requesting and displaying ads in a Pod Serving stream with IMA DAI SDK, we suggest you clean up any resources after the Pod Serving session is complete. Call StreamManager.destroy() to stop stream playback, stop all ad tracking, and release all of the loaded stream assets.
Select the DAI solution you're interested in
Pod Serving DAI
IMA SDKs simplify integrating multimedia ads into your websites and apps.
IMA SDKs can request ads from any VAST-compliant ad server and manage ad playback in your apps.
With IMA DAI SDKs, apps make a stream request for ad and content video for either VOD or live content. The SDK then returns a combined video stream, so that you don't have to manage switching between ad and content video within your app.
This guide demonstrates how to play a DAI Pod Serving stream, using the IMA DAI SDK for CAF.
Before using this guide, familiarize yourself with the Chromecast Application Framework's Web Receiver protocol. This guide assumes a basic understanding of CAF receiver concepts, such as message interceptors and mediaInformation objects, and familiarity with using the Cast Command and Control tool , to emulate a CAF sender.
To use IMA DAI Pod Serving, you must be working with a Pod Serving partner and must have an Ad Manager 360 Advanced account. If you have an Ad Manager account, contact your account manager for more details. For information about signing up for Ad Manager, visit the Ad Manager Help Center .
For information on integrating with other platforms, or on using the IMA client-side SDKs, see Interactive Media Ads SDKs .
IMA DAI Pod Serving overview
Implementing Pod Serving using the IMA CAF DAI SDK involves two main components, which are demonstrated in this guide:
-
StreamRequest: An object that defines a stream request to Google's advertising servers. Requests specify a Network Code, Custom Asset Key, and an optional API key, as well as other optional parameters. -
StreamManager: An object that handles communication between the video stream and the IMA DAI SDK, such as firing tracking pings and forwarding stream events to the publisher.
Предварительные требования
- A Cast Developer Console account with registered test devices.
- A hosted web receiver app that is registered with your Cast Developer Console and which can be modified to host the code provided by this guide.
- A sending app that is configured to use your web receiver app. For the purposes of this example, use the Cast Command and Control tool as your sender.
Configure the sender's MediaInfo objects
First, configure your sender app's MediaInfo object to include the following fields:
| Поле | Содержание | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
contentId | A unique identifier for this media item. CONTENT_ID | ||||||||||
contentUrl | Optional. Backup stream URL to play if the DAI stream fails to load. BACKUP_STREAM_URL | ||||||||||
contentType | Optional. Mimetype of the content backup streams. Only needed for DASH streams . CONTENT_STREAM_MIMETYPE | ||||||||||
streamType | The string literal or constant used for this value varies by sender platform. | ||||||||||
customData | The customData field contains a key-value store of additional required fields. In this sample, it contains your DAI stream parameters. In a production app you might instead pass an identifier that your cast receiver app would use to retrieve these parameters with a server-side request.
|
Here are some code samples to help you get started:
Веб
To configure these values in a Cast web sender, first create a MediaInfo object with the required data, then make a load request to the web receiver.
// 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
To configure these values in a Cast web sender, first create a MediaInfo object with the required data, then make a load request to the web receiver.
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)
To configure these values in a Cast web sender, first create a GCKMediaInformation object with the required data, then make a load request to the web receiver.
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)
To configure these values in a Cast web sender, first create a GCKMediaInformation object with the required data, then make a load request to the web receiver.
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 tool
To configure these values in the Cast Command and Control tool , click the Load Media tab, and set the custom load request type to LOAD. Then replace the JSON data in the text area with this 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"
}
}
}
This custom load request can be sent to the receiver to test the rest of the steps.
Create a basic CAF receiver
Create a custom web receiver, as seen in the CAF SDK Custom Web Receiver Guide .
Your receiver's code should look like this:
<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>
Import the IMA DAI SDK and get the Player Manager
Add a script tag to import the IMA DAI SDK for CAF to your web receiver, just after the script loading CAF. In the script tag, store the receiver context and player manager as constants before starting the receiver.
<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>
Initialize the IMA Stream Manager
Initialize the 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>
Create the Stream Manager Load Interceptor
Before your media items are passed to CAF, create your stream request in a LOAD message interceptor .
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();
Create the stream request
Complete the createStreamRequest function to create a Pod Serving stream based on the CAF load request.
/**
* 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;
};
Retrieve the stitched manifest from your VTP
If your stream request is successful, use streamManager.getStreamId() to retrieve the stream's ID. Your Video Technical Partner (VTP) or custom manifest manipulator will provide instructions to retrieve a manifest URL, using this stream ID.
Once you have retrieved your manifest URL, replace the existing contentUrl with the new manifestUrl .
Lastly, before returning the modified stream manifest, call the loadStreamMetadata method on your streamManager to inform the IMA SDK that it can safely request stream metadata. This call is only necessary for VOD streams.
/**
* 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;
});
};
Clean up IMA DAI assets
When you have successfully finished requesting and displaying ads in a Pod Serving stream with IMA DAI SDK, we suggest you clean up any resources after the Pod Serving session is complete. Call StreamManager.destroy() to stop stream playback, stop all ad tracking, and release all of the loaded stream assets.