관심 있는 DAI 솔루션을 선택합니다
DAI 광고 모음 게재
IMA SDK를 사용하면 웹사이트와 앱에 멀티미디어 광고를 간편하게 통합할 수 있습니다.
IMA SDK는 모든 VAST 호환 광고 서버에서 광고를 요청하고 앱에서 광고 재생을 관리할 수 있습니다.
IMA DAI SDK를 사용하면 앱이 VOD 또는 라이브 콘텐츠의 광고 및 콘텐츠 동영상에 대한 스트림을 요청합니다. 그러면 SDK가 결합된 동영상 스트림을 반환하므로 앱 내에서 광고와 콘텐츠 동영상 간에 전환을 관리할 필요가 없습니다.
이 가이드에서는 CAF용 IMA DAI SDK를 사용하여 DAI 포드 게재 스트림을 재생하는 방법을 설명합니다.
이 가이드를 사용하기 전에 Chromecast 애플리케이션 프레임워크의 웹 수신기 프로토콜에 익숙해야 합니다. 이 가이드에서는 메시지 인터셉터, mediaInformation 객체와 같은 CAF 수신기 개념에 대한 기본 수준의 지식이 있고 전송 명령어 및 제어 도구를 사용하여 CAF 발신기를 에뮬레이션하는 방법을 알고 있다고 가정합니다.
IMA DAI 광고 모음 게재를 사용하려면 광고 모음 게재 파트너와 협력하고 Ad Manager 360 고급 계정이 있어야 합니다. Ad Manager 계정이 있는 경우 계정 관리자에게 자세한 내용을 문의하세요. Ad Manager 가입에 대한 자세한 내용은 Ad Manager 고객센터를 참고하세요.
다른 플랫폼과 통합하거나 IMA 클라이언트 측 SDK를 사용하는 방법에 대한 자세한 내용은 양방향 미디어 광고 SDK를 참고하세요.
IMA DAI 광고 모음 게재 개요
IMA CAF DAI SDK를 사용하여 광고 모음 게재를 구현하려면 이 가이드에 설명된 두 가지 주요 구성요소가 필요합니다.
StreamRequest
: Google의 광고 서버에 대한 스트림 요청을 정의하는 객체입니다. 요청은 네트워크 코드, 맞춤 애셋 키, 선택적 API 키, 기타 선택적 매개변수를 지정합니다.StreamManager
: 동영상 스트림과 IMA DAI SDK 간의 통신(예: 추적 핑 실행 및 스트림 이벤트를 게시자에게 전달)을 처리하는 객체입니다.
기본 요건
- 등록된 테스트 기기가 있는 전송 개발자 콘솔 계정
- 전송 개발자 콘솔에 등록되었으며 이 가이드에서 제공하는 코드를 호스팅하도록 수정할 수 있는 호스팅된 웹 수신기 앱
- 웹 수신기 앱을 사용하도록 구성된 전송 앱. 이 예시를 위해 전송 명령어 및 제어 도구를 발신기로 사용합니다.
발신자의 MediaInfo 객체 구성
먼저 발신기 앱의 MediaInfo
객체를 구성하여 다음 필드를 포함합니다.
필드 | 목차 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
contentId
|
이 미디어 항목의 고유 식별자입니다.
CONTENT_ID |
||||||||||
contentUrl
|
선택사항입니다. DAI 스트림이 로드할 수 없는 경우 재생할 백업 스트림 URL입니다.
BACKUP_STREAM_URL |
||||||||||
contentType
|
선택사항입니다. 콘텐츠 백업 스트림의 Mimetype입니다. DASH 스트림에만 필요합니다.
CONTENT_STREAM_MIMETYPE |
||||||||||
streamType
|
이 값에 사용되는 문자열 리터럴이나 상수는 발신기 플랫폼에 따라 다릅니다. | ||||||||||
customData
|
customData 필드에는 추가 필수 필드의 키-값 저장소가 포함됩니다. 이 샘플에서는 DAI 스트림 매개변수를 포함합니다. 프로덕션 앱에서는 전송 수신기 앱이 서버 측 요청으로 이러한 매개변수를 검색하는 데 사용할 식별자를 전달할 수 있습니다.
|
다음은 시작하는 데 도움이 되는 몇 가지 코드 샘플입니다.
웹
전송 웹 발신기에서 이러한 값을 구성하려면 먼저 필수 데이터가 있는 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
전송 웹 발신기에서 이러한 값을 구성하려면 먼저 필수 데이터가 있는 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)
전송 웹 발신기에서 이러한 값을 구성하려면 먼저 필수 데이터가 있는 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)
전송 웹 발신기에서 이러한 값을 구성하려면 먼저 필수 데이터가 있는 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 도구
전송 명령어 및 제어 도구에서 이러한 값을 구성하려면 미디어 로드 탭을 클릭하고 커스텀 로드 요청 유형을 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 가져오기 및 플레이어 관리자 가져오기
스크립트에서 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 스트림 관리자 초기화
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
함수를 완료하여 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()
를 사용하여 스트림의 ID를 가져옵니다. 동영상 기술 파트너 (VTP) 또는 맞춤 매니페스트 조작 도구에서 이 스트림 ID를 사용하여 매니페스트 URL을 검색하는 방법을 안내합니다.
매니페스트 URL을 가져온 후 기존 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 애플리케이션 프레임워크와 CAF용 IMA DAI SDK를 사용하여 광고 모음 게재 스트림을 요청하고 재생할 수 있습니다.