Выберите интересующее вас решение 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() , чтобы остановить воспроизведение потока, прекратить отслеживание рекламы и освободить все загруженные ресурсы потока.