IMA SDK ช่วยให้ผสานรวมโฆษณามัลติมีเดียลงในเว็บไซต์และแอปได้อย่างง่ายดาย IMA SDK สามารถส่งคําขอโฆษณาจากเซิร์ฟเวอร์โฆษณา ที่เป็นไปตามข้อกําหนดของ VAST ใดก็ได้ และจัดการการเล่นโฆษณาในแอป เมื่อใช้ IMA DAI SDK แอปจะส่งคําขอสตรีมสําหรับโฆษณาและวิดีโอเนื้อหา ไม่ว่าจะเป็น VOD หรือเนื้อหาสด จากนั้น SDK จะแสดงผลสตรีมวิดีโอแบบรวม คุณจึงไม่ต้องจัดการการสลับระหว่างวิดีโอโฆษณากับวิดีโอเนื้อหาภายในแอป
เลือกโซลูชัน DAI ที่คุณสนใจ
DAI ของ Pod Serving
คู่มือนี้แสดงวิธีเล่นสตรีม DAI Pod Serving สำหรับเนื้อหาแบบสดหรือ VOD โดยใช้ IMA DAI SDK สำหรับ HTML5 กับโปรแกรมเล่นวิดีโอที่อาศัย hls.js ในการเล่น หากต้องการดูหรือทําตามการผสานรวมตัวอย่างที่เสร็จสมบูรณ์ซึ่งรองรับทั้ง HLS.js และการเล่นใน Safari โปรดดูตัวอย่างการแสดงพ็อด HLS ดูการรองรับ DASH.js ได้ที่ตัวอย่างการแสดงพ็อด DASH คุณสามารถดาวน์โหลดตัวอย่างแอปเหล่านี้ได้จากหน้ารุ่น GitHub ของ HTML5 DAI
ภาพรวมของ DAI Pod Serving
การใช้ Pod Serving โดยใช้ IMA DAI SDK ประกอบด้วยองค์ประกอบหลัก 2 อย่างดังที่แสดงในคู่มือนี้
PodStreamRequest
/PodVodStreamRequest
: ออบเจ็กต์ที่กําหนดคําขอสตรีมไปยังเซิร์ฟเวอร์โฆษณาของ Google คำขอจะระบุรหัสเครือข่าย และPodStreamRequest
จะต้องมีคีย์ชิ้นงานที่กำหนดเองและคีย์ API (ไม่บังคับ) ด้วย ทั้ง 2 รายการมีพารามิเตอร์อื่นๆ ที่ไม่บังคับStreamManager
: ออบเจ็กต์ที่จัดการการสื่อสารระหว่างสตรีมวิดีโอกับ IMA DAI SDK เช่น การเรียกใช้การติดตาม Ping และการส่งต่อเหตุการณ์สตรีมไปยังผู้เผยแพร่โฆษณา
ข้อกำหนดเบื้องต้น
ก่อนเริ่มต้น คุณต้องมีสิ่งต่อไปนี้
ไฟล์ว่าง 3 ไฟล์ ได้แก่
- dai.html
- dai.css
- dai.js
Python ที่ติดตั้งในคอมพิวเตอร์ หรือเว็บเซิร์ฟเวอร์ หรือสภาพแวดล้อมการพัฒนาที่โฮสต์อื่นๆ เพื่อใช้ทดสอบ
กำหนดค่าสภาพแวดล้อมการพัฒนา
เนื่องจาก SDK จะโหลดไลบรารีที่ใช้ร่วมกันโดยใช้โปรโตคอลเดียวกับหน้าที่โหลด คุณจึงต้องใช้เว็บเซิร์ฟเวอร์เพื่อทดสอบแอป วิธีเริ่มต้นเซิร์ฟเวอร์สำหรับนักพัฒนาซอฟต์แวร์ในเครื่องอย่างรวดเร็วคือการใช้เซิร์ฟเวอร์ในตัวของ Python
ใช้บรรทัดคำสั่งจากไดเรกทอรีที่มีไฟล์
index.html
ให้เรียกใช้คำสั่งต่อไปนี้python -m http.server 8000
ในเว็บเบราว์เซอร์ ให้ไปที่
http://localhost:8000/
คุณยังใช้สภาพแวดล้อมการพัฒนาหรือเว็บเซิร์ฟเวอร์ที่โฮสต์อื่นๆ ก็ได้ เช่น Apache HTTP Server
สร้างวิดีโอเพลเยอร์
ก่อนอื่น ให้แก้ไข dai.html เพื่อสร้างองค์ประกอบวิดีโอ HTML5 และ div เพื่อใช้กับองค์ประกอบ UI ของโฆษณา นอกจากนี้ ให้เพิ่มแท็กที่จําเป็นเพื่อโหลดไฟล์ dai.css และ dai.js รวมถึงนําเข้าโปรแกรมเล่นวิดีโอ hls.js
จากนั้นแก้ไข dai.css เพื่อระบุขนาดและตำแหน่งขององค์ประกอบหน้าเว็บ
สุดท้าย ใน dai.js ให้กําหนดตัวแปรเพื่อเก็บข้อมูลคําขอสตรีม และฟังก์ชัน initPlayer()
เพื่อเรียกใช้เมื่อโหลดหน้าเว็บ
ค่าคงที่ของคำขอสตรีมมีดังนี้
BACKUP_STREAM
: URL สตรีมสำรองที่จะเล่นในกรณีที่กระบวนการแสดงโฆษณาพบข้อผิดพลาดร้ายแรงSTREAM_URL
: ใช้สำหรับสตรีมแบบสดเท่านั้น URL สตรีมวิดีโอที่ได้จากเครื่องมือจัดการไฟล์ Manifest หรือพาร์ทเนอร์บุคคลที่สามที่ใช้การแสดงโฆษณาในพ็อด คุณควรต้องแทรกรหัสสตรีมที่ IMA DAI SDK ระบุไว้ก่อนส่งคำขอ ในกรณีนี้ URL ของสตรีมจะมีตัวยึดตําแหน่ง[[STREAMID]]
ซึ่งระบบจะแทนที่ด้วยรหัสสตรีมก่อนที่จะส่งคําขอNETWORK_CODE
: รหัสเครือข่ายสําหรับบัญชี Ad Manager 360CUSTOM_ASSET_KEY
: ใช้สำหรับสตรีมแบบสดเท่านั้น คีย์ของชิ้นงานที่กําหนดเองซึ่งระบุเหตุการณ์การแสดงพ็อดใน Ad Manager 360 ซึ่งสร้างโดยเครื่องมือจัดการไฟล์ Manifest หรือพาร์ทเนอร์การแสดงโฆษณาพ็อดบุคคลที่สามAPI_KEY
: ใช้สำหรับสตรีมแบบสดเท่านั้น คีย์ API ที่ไม่บังคับซึ่งอาจต้องใช้ในการดึงข้อมูลรหัสสตรีมจาก IMA DAI SDK
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 โดยใช้แท็กสคริปต์ใน dai.html ก่อนแท็กสำหรับ dai.js
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
การแสดงพ็อดสตรีมแบบสด
หากต้องการขอชุดโฆษณา ให้สร้าง ima.dai.api.StreamManager
ซึ่งมีหน้าที่รับผิดชอบในการขอและจัดการสตรีม DAI ตัวสร้างคอนสตรัคเตอร์ใช้องค์ประกอบวิดีโอ และอินสแตนซ์ที่ได้จะใช้องค์ประกอบ UI ของโฆษณาเพื่อจัดการการโต้ตอบกับโฆษณา
จากนั้นให้กําหนดฟังก์ชันเพื่อขอสตรีมแบบสดของ Pod Serving ฟังก์ชันนี้จะสร้าง PodStreamRequest
ก่อน จากนั้นกําหนดค่าด้วยพารามิเตอร์ streamRequest ที่ระบุไว้ในขั้นตอนที่ 2 แล้วจึงเรียกใช้ 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 Pod Serving
หากต้องการขอชุดโฆษณา ให้สร้าง ima.dai.api.StreamManager
ซึ่งมีหน้าที่รับผิดชอบในการขอและจัดการสตรีม DAI ตัวสร้างคอนสตรัคเตอร์ใช้องค์ประกอบวิดีโอ และอินสแตนซ์ที่ได้จะใช้องค์ประกอบ UI ของโฆษณาเพื่อจัดการการโต้ตอบกับโฆษณา
จากนั้นให้กําหนดฟังก์ชันเพื่อขอสตรีม VOD ที่ให้บริการพอด ฟังก์ชันนี้จะสร้าง PodVodStreamRequest
ก่อน จากนั้นกําหนดค่าด้วยพารามิเตอร์ streamRequest ที่ระบุไว้ในขั้นตอนที่ 2 แล้วจึงเรียกใช้ 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);
}
จัดการเหตุการณ์สตรีม
การแสดงพ็อดสตรีมแบบสด
ถัดไป ให้ใช้ Listener เหตุการณ์สําหรับเหตุการณ์วิดีโอที่สําคัญ ตัวอย่างนี้จัดการเหตุการณ์ STREAM_INITIALIZED
, ERROR
, AD_BREAK_STARTED
และ AD_BREAK_ENDED
โดยเรียกใช้ฟังก์ชัน onStreamEvent()
ฟังก์ชันนี้จะจัดการกับการโหลดสตรีมและข้อผิดพลาด รวมถึงปิดใช้การควบคุมโปรแกรมเล่นขณะที่โฆษณาเล่นอยู่ ซึ่ง SDK กำหนด เมื่อโหลดสตรีมแล้ว วิดีโอเพลเยอร์จะโหลดและเล่น URL ที่ระบุโดยใช้ฟังก์ชัน loadStream()
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 Pod Serving
ถัดไป ให้ใช้ Listener เหตุการณ์สําหรับเหตุการณ์วิดีโอที่สําคัญ ตัวอย่างนี้จัดการเหตุการณ์ STREAM_INITIALIZED
, LOADED
, ERROR
, AD_BREAK_STARTED
และ AD_BREAK_ENDED
โดยการเรียกใช้ฟังก์ชัน onStreamEvent()
ฟังก์ชันนี้จะจัดการกับการโหลดสตรีมและข้อผิดพลาด รวมถึงปิดใช้การควบคุมโปรแกรมเล่นขณะที่โฆษณาเล่นอยู่ ซึ่ง SDK กำหนดให้ต้องดำเนินการ
นอกจากนี้ สตรีมการส่งพ็อด VOD ยังต้องมีการเรียกใช้ StreamManager.loadStreamMetadata()
เพื่อตอบสนองต่อเหตุการณ์ STREAM_INITIALIZED
นอกจากนี้ คุณยังต้องขอ URL สตรีมจากพาร์ทเนอร์เทคโนโลยีวิดีโอ (VTP) ด้วย เมื่อการเรียก loadStreamMetadata()
สําเร็จแล้ว ระบบจะทริกเกอร์เหตุการณ์ LOADED
ซึ่งคุณควรเรียกใช้ฟังก์ชัน loadStream()
ด้วย URL สตรีมเพื่อโหลดและเล่นสตรีม
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);
}
จัดการข้อมูลเมตาของสตรีม
ในขั้นตอนนี้ คุณจะใช้ Listener เหตุการณ์สําหรับข้อมูลเมตาเพื่อแจ้ง SDK เมื่อเกิดเหตุการณ์โฆษณา การฟังเหตุการณ์ข้อมูลเมตาในสตรีมอาจแตกต่างกันไป โดยขึ้นอยู่กับรูปแบบสตรีม (HLS หรือ DASH), ประเภทสตรีม (สตรีมแบบสดหรือ VOD), ประเภทโปรแกรมเล่น และประเภทแบ็กเอนด์ DAI ที่ใช้ ดูข้อมูลเพิ่มเติมได้ที่คู่มือข้อมูลเมตาแบบกำหนดเวลา
รูปแบบสตรีม HLS (สตรีมแบบสดและ VOD, โปรแกรมเล่น HLS.js)
หากคุณใช้โปรแกรมเล่น HLS.js ให้ฟังเหตุการณ์ FRAG_PARSING_METADATA
ของ HLS.js เพื่อรับข้อมูลเมตา ID3 และส่งไปยัง SDK ด้วย StreamManager.processMetadata()
หากต้องการเล่นวิดีโอโดยอัตโนมัติหลังจากที่โหลดทุกอย่างและพร้อมใช้งานแล้ว ให้ฟังเหตุการณ์ 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 คุณต้องใช้สตริงอื่นเพื่อฟังข้อมูลเมตา ID3 สำหรับสตรีมแบบสดหรือ VOD ดังนี้
- สตรีมแบบสด:
'https://developer.apple.com/streaming/emsg-id3'
- สตรีม VOD:
'urn:google:dai:2018'
ส่งข้อมูลเมตา ID3 ไปยัง SDK ด้วย StreamManager.processMetadata()
หากต้องการแสดงตัวควบคุมวิดีโอโดยอัตโนมัติหลังจากที่โหลดทุกอย่างและพร้อมใช้งานแล้ว ให้ฟังเหตุการณ์ 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 Player เพื่อเล่นสตรีมแบบสด ให้ใช้สตริง '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});
}
Shaka Player ที่มีสตรีม VOD (รูปแบบสตรีม DASH)
หากคุณใช้ Shaka Player เพื่อเล่นสตรีม VOD ให้ใช้สตริง '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);
}
}
จัดการเหตุการณ์ของผู้เล่น
เพิ่ม Listener เหตุการณ์ลงในเหตุการณ์ pause
และ start
ขององค์ประกอบวิดีโอเพื่อให้ผู้ใช้เล่นต่อได้เมื่อ SDK หยุดชั่วคราวในช่วงพักโฆษณา
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';
}
}
เท่านี้ก็เรียบร้อย ตอนนี้คุณกำลังขอและแสดงโฆษณาในสตรีมการแสดงโฆษณาแบบพ็อดด้วย IMA DAI SDK สําหรับ HTML5 ดูข้อมูลเกี่ยวกับฟีเจอร์ SDK ขั้นสูงเพิ่มเติมได้ในคู่มืออื่นๆ หรือตัวอย่างใน GitHub