IMA SDK를 사용하면 멀티미디어 광고를 웹사이트와 앱에 쉽게 통합할 수 있습니다. IMA SDK는 모든 VAST 호환 광고 서버에서 광고를 요청하고 앱에서 광고 재생을 관리할 수 있습니다. IMA DAI SDK를 사용하면 앱에서 광고 및 콘텐츠 동영상(VOD 또는 라이브 콘텐츠)의 스트림을 요청합니다. 그러면 SDK가 결합된 동영상 스트림을 반환하므로 앱 내에서 광고와 콘텐츠 동영상 간의 전환을 관리할 필요가 없습니다.
관심 있는 DAI 솔루션 선택
DAI를 게재하는 광고 모음
이 가이드에서는 hls.js를 사용하여 재생하는 동영상 플레이어와 함께 HTML5용 IMA DAI SDK를 사용하여 실시간 또는 VOD 콘텐츠의 DAI 광고 모음 게재 스트림을 재생하는 방법을 설명합니다. HLS.js 및 Safari 재생을 모두 지원하고 완료된 샘플 통합을 보거나 확인하려면 HLS 포드 게재 예를 참고하세요. DASH.js 지원은 DASH 포드 제공 예시를 참조하세요. 이러한 샘플 앱은 HTML5 DAI GitHub 출시 페이지에서 다운로드할 수 있습니다.
DAI 광고 모음 게재 개요
IMA DAI SDK를 사용하여 광고 모음 게재를 구현하려면 이 가이드에 설명된 두 가지 주요 구성요소가 필요합니다.
PodStreamRequest
/PodVodStreamRequest
: Google의 광고 서버에 대한 스트림 요청을 정의하는 객체입니다. 요청은 네트워크 코드를 지정하며,PodStreamRequest
에는 맞춤 애셋 키와 선택적 API 키도 필요합니다. 둘 다 다른 선택적 매개변수를 포함합니다.StreamManager
: 추적 핑을 실행하고 스트림 이벤트를 게시자에게 전달하는 등 동영상 스트림과 IMA DAI SDK 간의 통신을 처리하는 객체입니다.
기본 요건
시작하기 전에 다음이 필요합니다.
빈 파일 3개:
- dai.html
- dai.css
- dai.js
컴퓨터에 설치된 Python, 테스트에 사용할 웹 서버 또는 기타 호스팅된 개발 환경
개발 환경 구성
SDK는 로드되는 페이지와 동일한 프로토콜을 사용하여 종속 항목을 로드하므로 웹 서버를 사용하여 앱을 테스트해야 합니다. 로컬 개발 서버를 빠르게 시작하는 방법은 Python의 기본 제공 서버를 사용하는 것입니다.
명령줄을 사용하여
index.html
파일이 포함된 디렉터리에서 다음을 실행합니다.python -m http.server 8000
웹브라우저에서
http://localhost:8000/
으로 이동합니다.Apache HTTP 서버와 같은 다른 호스팅된 개발 환경 또는 웹 서버도 사용할 수 있습니다.
간단한 동영상 플레이어 만들기
먼저 dai.html을 수정하여 간단한 HTML5 동영상 요소와 광고 UI 요소에
사용할 div를 만듭니다. 또한 dai.css 및 dai.js 파일을 로드하고 hls.js
동영상 플레이어를 가져오는 데 필요한 태그를 추가합니다.
그런 다음 dai.css를 수정하여 페이지 요소의 크기와 위치를 지정합니다.
마지막으로 dai.js에서 스트림 요청 정보를 저장할 변수와 페이지가 로드될 때 실행할 initPlayer()
함수를 정의합니다.
스트림 요청 상수는 다음과 같습니다.
BACKUP_STREAM
: 광고 프로세스에 치명적인 오류가 발생하는 경우 재생할 백업 스트림의 URL입니다.STREAM_URL
: 라이브 스트림에만 사용됩니다. 매니페스트 조작기 또는 서드 파티 파트너가 광고 모음 게재를 사용하여 제공하는 동영상 스트림 URL입니다. 요청하기 전에 IMA DAI SDK에서 제공한 스트림 ID를 삽입해야 합니다. 이 경우 스트림 URL에는 자리표시자[[STREAMID]]
가 포함되며 이는 요청하기 전에 스트림 ID로 대체됩니다.NETWORK_CODE
: Ad Manager 360 계정의 네트워크 코드입니다.CUSTOM_ASSET_KEY
: 라이브 스트림에만 사용됩니다. Ad Manager 360에서 광고 모음 게재 이벤트를 식별하는 맞춤 애셋 키입니다. 이는 매니페스트 조작자 또는 서드 파티 포드 게재 파트너가 만들 수 있습니다.API_KEY
: 라이브 스트림에만 사용됩니다. IMA DAI SDK에서 스트림 ID를 검색하는 데 필요할 수 있는 API 키입니다(선택사항).
dai.html
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<script src="dai.js"></script>
<link rel="stylesheet" href="dai.css" type="text/css">
</head>
<body onLoad="initPlayer()">
<h2>IMA DAI SDK Demo (HLS.JS)</h2>
<video id="video"></video>
<div id="ad-ui"></div>
</body>
</html>
dai.css
#video,
#ad-ui {
width: 640px;
height: 360px;
position: absolute;
top: 35px;
left: 0;
}
#ad-ui {
cursor: pointer;
}
dai.js
var BACKUP_STREAM =
'https://storage.googleapis.com/interactive-media-ads/media/bbb.m3u8'
// Stream Config.
const STREAM_URL = "https://encodersim.sandbox.google.com/masterPlaylist/...&stream_id=[[STREAMID]]";
const NETWORK_CODE = "51636543";
const CUSTOM_ASSET_KEY = "google-sample";
const API_KEY = "";
var hls = new Hls(); // hls.js video player
var videoElement;
var adUiElement;
function initPlayer() {
videoElement = document.getElementById('video');
adUiElement = document.getElementById('adUi');
}
IMA DAI SDK 로드
다음으로 dai.html의 dai.js 태그 앞에 있는 스크립트 태그를 사용하여 DAI 프레임워크를 추가합니다.
dai.html
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<script type="text/javascript" src="//imasdk.googleapis.com/js/sdkloader/ima3_dai.js"></script>
<script src="dai.js"></script>
<link rel="stylesheet" href="dai.css" type="text/css">
</head>
...
StreamManager 초기화 및 라이브 또는 VOD 스트림 요청
라이브 스트림 광고 모음 게재
광고 집합을 요청하려면 DAI 스트림 요청 및 관리를 담당하는 ima.dai.api.StreamManager
를 만듭니다. 생성자는 동영상 요소를 가져오고 결과 인스턴스는 광고 UI 요소를 사용하여 광고 상호작용을 처리합니다.
그런 다음, 라이브 스트림을 게재하는 포드를 요청하는 함수를 정의합니다. 이 함수는 먼저 PodStreamRequest
를 만들고 2단계에서 제공된 StreamRequest 매개변수로 구성한 후 이 요청 객체를 사용하여 streamManager.requestStream()
를 호출합니다.
dai.js
function initPlayer() {
videoElement = document.getElementById('video');
adUiElement = document.getElementById('adUi');
streamManager = new google.ima.dai.api.StreamManager(videoElement, adUiElement)
requestLivePodStream(NETWORK_CODE, CUSTOM_ASSET_KEY, API_KEY);
}
function requestLivePodStream(networkCode, customAssetKey, apiKey) {
// clear HLS.js instance, if in use
if (hls) {
hls.destroy();
}
// Generate a Pod Serving live Stream Request
const streamRequest = new google.ima.dai.api.PodStreamRequest();
streamRequest.networkCode = networkCode;
streamRequest.customAssetKey = customAssetKey;
streamRequest.apiKey = apiKey;
streamRequest.format = 'hls';
streamManager.requestStream(streamRequest);
}
VOD 광고 모음 게재
광고 집합을 요청하려면 DAI 스트림 요청 및 관리를 담당하는 ima.dai.api.StreamManager
를 만듭니다. 생성자는 동영상 요소를 가져오고 결과 인스턴스는 광고 UI 요소를 사용하여 광고 상호작용을 처리합니다.
그런 다음 광고 모음 게재 VOD 스트림을 요청하는 함수를 정의합니다. 이 함수는 먼저 PodVodStreamRequest
를 만들고 2단계에서 제공된 StreamRequest 매개변수로 구성한 후 이 요청 객체를 사용하여 streamManager.requestStream()
를 호출합니다.
dai.js
function initPlayer() {
videoElement = document.getElementById('video');
adUiElement = document.getElementById('adUi');
streamManager = new google.ima.dai.api.StreamManager(videoElement, adUiElement)
requestVodPodStream(NETWORK_CODE);
}
function requestVodPodStream(networkCode) {
// clear HLS.js instance, if in use
if (hls) {
hls.destroy();
}
// Generate a Pod Serving VOD Stream Request
const streamRequest = new google.ima.dai.api.PodVodStreamRequest();
streamRequest.networkCode = networkCode;
streamRequest.format = 'hls';
streamManager.requestStream(streamRequest);
}
스트림 이벤트 처리
라이브 스트림 광고 모음 게재
다음으로, 주요 동영상 이벤트에 대한 이벤트 리스너를 구현합니다. 이 예에서는 onStreamEvent()
함수를 호출하여 STREAM_INITIALIZED
, ERROR
, AD_BREAK_STARTED
, AD_BREAK_ENDED
이벤트를 처리합니다. 이 함수는 스트림 로드 및 오류를 처리하고, SDK에 필요한 광고가 재생되는 동안 플레이어 컨트롤을 사용 중지합니다. 스트림이 로드되면 동영상 플레이어는 loadStream()
함수를 사용하여 제공된 URL을 로드하고 재생합니다.
dai.js
var isAdBreak;
function initPlayer() {
videoElement = document.getElementById('video');
adUiElement = document.getElementById('adUi');
streamManager = new google.ima.dai.api.StreamManager(videoElement, adUiElement);
streamManager.addEventListener(
[google.ima.dai.api.StreamEvent.Type.STREAM_INITIALIZED,
google.ima.dai.api.StreamEvent.Type.ERROR,
google.ima.dai.api.StreamEvent.Type.AD_BREAK_STARTED,
google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED],
onStreamEvent,
false);
...
function onStreamEvent(e) {
switch (e.type) {
case google.ima.dai.api.StreamEvent.Type.STREAM_INITIALIZED:
console.log('Stream initialized');
loadStream(e.getStreamData().streamId);
break;
case google.ima.dai.api.StreamEvent.Type.ERROR:
console.log('Error loading stream, playing backup stream.' + e);
loadStream('');
break;
case google.ima.dai.api.StreamEvent.Type.AD_BREAK_STARTED:
console.log('Ad Break Started');
isAdBreak = true;
videoElement.controls = false;
adUiElement.style.display = 'block';
break;
case google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED:
console.log('Ad Break Ended');
isAdBreak = false;
videoElement.controls = true;
adUiElement.style.display = 'none';
break;
default:
break;
}
}
function loadStream(streamID) {
var url;
if(streamID) {
url = STREAM_URL.replace('[[STREAMID]]', streamID);
} else {
console.log('Stream Initialization Failed');
url = BACKUP_STREAM;
}
console.log('Loading:' + url);
hls.loadSource(url);
hls.attachMedia(videoElement);
}
VOD 광고 모음 게재
다음으로, 주요 동영상 이벤트에 대한 이벤트 리스너를 구현합니다. 이 예에서는 onStreamEvent()
함수를 호출하여 STREAM_INITIALIZED
, LOADED
, ERROR
, AD_BREAK_STARTED
, AD_BREAK_ENDED
이벤트를 처리합니다. 이 함수는 스트림 로드 및 오류를 처리하며 광고가 재생되는 동안 SDK에 필요한 플레이어 컨트롤을 사용 중지합니다.
또한 VOD 포드 게재 스트림을 사용하려면 STREAM_INITIALIZED
이벤트에 대한 응답으로 StreamManager.loadStreamMetadata()
를 호출해야 합니다. 동영상 기술 파트너 (VTP)에게도 스트림 URL을 요청해야 합니다. loadStreamMetadata()
호출이 성공하면 LOADED
이벤트가 트리거됩니다. 여기서 스트림 URL로 loadStream()
함수를 호출하여 스트림을 로드하고 재생해야 합니다.
var isAdBreak;
function initPlayer() {
videoElement = document.getElementById('video');
adUiElement = document.getElementById('adUi');
streamManager = new google.ima.dai.api.StreamManager(videoElement, adUiElement);
streamManager.addEventListener(
[google.ima.dai.api.StreamEvent.Type.STREAM_INITIALIZED,
google.ima.dai.api.StreamEvent.Type.ERROR,
google.ima.dai.api.StreamEvent.Type.AD_BREAK_STARTED,
google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED],
onStreamEvent,
false);
...
function onStreamEvent(e) {
switch (e.type) {
case google.ima.dai.api.StreamEvent.Type.STREAM_INITIALIZED:
const streamId = e.getStreamData().streamId;
// 'vtpInterface' is a place holder for your own video technology
// partner (VTP) API calls.
vtpInterface.requestStreamURL({
'streamId': streamId,
})
.then( (vtpStreamUrl) => {
streamUrl = vtpStreamUrl;
streamManager.loadStreamMetadata();
}, (error) => {
// Handle the error.
});
break;
case google.ima.dai.api.StreamEvent.Type.LOADED:
loadStream(streamUrl);
break;
case google.ima.dai.api.StreamEvent.Type.ERROR:
console.log('Error loading stream, playing backup stream.' + e);
loadStream();
break;
case google.ima.dai.api.StreamEvent.Type.AD_BREAK_STARTED:
console.log('Ad Break Started');
isAdBreak = true;
videoElement.controls = false;
adUiElement.style.display = 'block';
break;
case google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED:
console.log('Ad Break Ended');
isAdBreak = false;
videoElement.controls = true;
adUiElement.style.display = 'none';
break;
default:
break;
}
}
function loadStream(url) {
if(url) {
console.log('Loading:' + url);
hls.loadSource(url);
} else {
console.log('Stream Initialization Failed');
hls.loadSource(BACKUP_STREAM);
}
hls.attachMedia(videoElement);
}
스트림 메타데이터 처리
이 단계에서는 광고 이벤트가 발생할 때 SDK에 알리는 메타데이터의 이벤트 리스너를 구현합니다. 인스트림 메타데이터 이벤트 리슨은 스트림 형식 (HLS 또는 DASH), 스트림 유형 (라이브 또는 VOD 스트림), 플레이어 유형 및 사용 중인 DAI 백엔드 유형에 따라 다를 수 있습니다. 자세한 내용은 예약된 메타데이터 가이드를 참고하세요.
HLS 스트림 형식 (라이브 및 VOD 스트림, HLS.js 플레이어)
HLS.js 플레이어를 사용하는 경우 HLS.js FRAG_PARSING_METADATA
이벤트를 수신 대기하여 ID3 메타데이터를 가져오고 이를 StreamManager.processMetadata()
를 사용하여 SDK에 전달합니다.
모든 것이 로드되고 준비된 후 동영상을 자동으로 재생하려면 HLS.js MANIFEST_PARSED
이벤트를 수신 대기하여 재생을 트리거합니다.
function loadStream(streamID) {
hls.loadSource(url);
hls.attachMedia(videoElement);
// Timed metadata is passed HLS stream events to the streamManager.
hls.on(Hls.Events.FRAG_PARSING_METADATA, parseID3Events);
hls.on(Hls.Events.MANIFEST_PARSED, startPlayback);
}
function parseID3Events(event, data) {
if (streamManager && data) {
// For each ID3 tag in the metadata, pass in the type - ID3, the
// tag data (a byte array), and the presentation timestamp (PTS).
data.samples.forEach((sample) => {
streamManager.processMetadata('ID3', sample.data, sample.pts);
});
}
}
function startPlayback() {
console.log('Video Play');
videoElement.play();
}
DASH.js (DASH 스트림 형식, 라이브 및 VOD 스트림 유형)
DASH.js 플레이어를 사용하는 경우 라이브 또는 VOD 스트림의 ID3 메타데이터를 수신 대기하려면 다른 문자열을 사용해야 합니다.
- 라이브 스트림:
'https://developer.apple.com/streaming/emsg-id3'
- VOD 스트림:
'urn:google:dai:2018'
StreamManager.processMetadata()
를 사용하여 ID3 메타데이터를 SDK에 전달합니다.
모든 것이 로드되고 준비된 후 동영상 컨트롤을 자동으로 표시하려면 DASH.js MANIFEST_LOADED
이벤트를 수신합니다.
const googleLiveSchema = 'https://developer.apple.com/streaming/emsg-id3';
const googleVodSchema = 'urn:google:dai:2018';
dashPlayer.on(googleLiveSchema, processMetadata);
dashPlayer.on(googleVodSchema, processMetadata);
dashPlayer.on(dashjs.MediaPlayer.events.MANIFEST_LOADED, loadlistener);
function processMetadata(metadataEvent) {
const messageData = metadataEvent.event.messageData;
const timestamp = metadataEvent.event.calculatedPresentationTime;
// Use StreamManager.processMetadata() if your video player provides raw
// ID3 tags, as with dash.js.
streamManager.processMetadata('ID3', messageData, timestamp);
}
function loadlistener() {
showControls();
// This listener must be removed, otherwise it triggers as addional
// manifests are loaded. The manifest is loaded once for the content,
// but additional manifests are loaded for upcoming ad breaks.
dashPlayer.off(dashjs.MediaPlayer.events.MANIFEST_LOADED, loadlistener);
}
라이브 스트림이 포함된 Shaka Player (DASH 스트림 형식)
라이브 스트림 재생에 Shaka 플레이어를 사용하는 경우 문자열 'emsg'
을 사용하여 메타데이터 이벤트를 수신 대기합니다.
그런 다음 StreamManager.onTimedMetadata()
호출에 이벤트 메시지 데이터를 사용합니다.
shakaPlayer.addEventListener('emsg', (event) => onEmsgEvent(event));
function onEmsgEvent(metadataEvent) {
// Use StreamManager.onTimedMetadata() if your video player provides
// processed metadata, as with Shaka player livestreams.
streamManager.onTimedMetadata({'TXXX': metadataEvent.detail.messageData});
}
VOD 스트림이 있는 Shaka Player (DASH 스트림 형식)
VOD 스트림 재생에 Shaka 플레이어를 사용하는 경우 문자열 'timelineregionenter'
을 사용하여 메타데이터 이벤트를 수신 대기합니다. 그런 다음 StreamManager.processMetadata()
호출에 이벤트 메시지 데이터를 'urn:google:dai:2018'
문자열과 함께 사용합니다.
shakaPlayer.addEventListener('timelineregionenter', (event) => onTimelineEvent(event));
function onTimelineEvent(metadataEvent) {
const detail = metadataEvent.detail;
if ( detail.eventElement.attributes &&
detail.eventElement.attributes['messageData'] &&
detail.eventElement.attributes['messageData'].value ) {
const mediaId = detail.eventElement.attributes['messageData'].value;
const pts = detail.startTime;
// Use StreamManager.processMetadata() if your video player provides raw
// ID3 tags, as with Shaka player VOD streams.
streamManager.processMetadata('urn:google:dai:2018', mediaId, pts);
}
}
플레이어 이벤트 처리
광고 시점에 SDK가 일시중지되면 사용자가 재생을 다시 시작할 수 있도록 이벤트 리스너를 동영상 요소의 pause
및 start
이벤트에 추가합니다.
function loadStream(streamUrl) {
...
videoElement.addEventListener('pause', onStreamPause);
videoElement.addEventListener('play', onStreamPlay);
}
function onStreamPause() {
console.log('paused');
if (isAdBreak) {
videoElement.controls = true;
adUiElement.style.display = 'none';
}
}
function onStreamPlay() {
console.log('played');
if (isAdBreak) {
videoElement.controls = false;
adUiElement.style.display = 'block';
}
}
작업이 끝났습니다. 이제 HTML5용 IMA DAI SDK를 사용하여 광고 모음 게재 스트림에서 광고를 요청하고 표시합니다. 고급 SDK 기능에 관한 자세한 내용은 다른 가이드 또는 GitHub 샘플을 참고하세요.