Purpose
使用者可以 iframe snippet
,直接無痛使用 SDK
- 可以使用 vast 廣告播放相關的功能
- 可以動態調整部分 video player 參數
Research
HTML iframe
iframe 是 HTML 中的一個元素,通常用來嵌套另一個 HTML 文檔。 如果想要向 iframe 傳遞參數,有以下方法可以實現這個目的:
URL 參數
通過在 iframe 的 src URL 中添加查詢字符串參數,可以將參數傳遞給目標文檔。目標文檔可以使用 JavaScript 來解析這些參數。
1<iframe src="https://example.com/page.html?param1=value1¶m2=value2"></iframe>
在目標文檔中,可以使用 JavaScript 的 URLSearchParams
接口來獲取這些參數:
1let params = new URLSearchParams(window.location.search);2let param1 = params.get('param1');3let param2 = params.get('param2');
窗口消息
使用 window.postMessage
方法在來源和目標窗口之間傳遞消息。這是一種在不同的源之間安全傳遞數據的方法。
1let iframe = document.getElementById('your-iframe-id');2iframe.contentWindow.postMessage('Your message here', 'https://target-origin.com');
在目標窗口中,你可以註冊一個事件來接收消息:
1window.addEventListener('message', function(event) {2 if (event.origin !== 'https://source-origin.com') return;3 console.log(event.data); // Outputs: 'Your message here'4});
我們的目標僅僅是提供使用者簡便的 Snippet Code,最後採用URL 參數
方法。
Result
1<!DOCTYPE html>2<html lang="en">3
4<head>5 <meta charset="UTF-8">6 <meta name="viewport" content="width=device-width, initial-scale=1.0">7 <title>Document</title>8</head>9
10<body>11 <iframe12 src="./target.html?t9=0&poster={POSTER}&autoplay=1&controls=1&preload=1&muted=1&loop=1&t=&src={PATH_TO_M3U8}&vast={PATH_TO_VAST}&clientID={YOUR_CLIENT_ID}"13 width="500" height="300" frameborder="0"></iframe>14</body>15
1 collapsed line
16</html>
1<!doctype html>2<html lang="en">3
4<head>5 <meta charset="UTF-8">6 <meta name="viewport"7 content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">8 <meta http-equiv="X-UA-Compatible" content="ie=edge">9 <link href="https://vjs.fusioncdn.com/7.21.4/video-js.min.css" rel="stylesheet">10 <link href="https://unpkg.com/@videojs/themes@1/dist/fantasy/index.css" rel="stylesheet">11 <script src="https://vjs.fusioncdn.com/7.21.4/video.min.js"></script>12
13 <script src="https://imasdk.googleapis.com/js/sdkloader/ima3.js"></script>14 <script src="https://cdn.jsdelivr.net/npm/videojs-contrib-ads@6.9.0/dist/videojs.ads.min.js"></script>15 <script src="https://cdn.jsdelivr.net/npm/videojs-ima@2.0.0/dist/videojs.ima.min.js"></script>138 collapsed lines
16
17 <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/videojs-contrib-ads@6.9.0/dist/videojs.ads.css" />18 <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/videojs-ima@2.1.0/dist/videojs.ima.css" />19
20 <script src="https://vsp.mlytics.co/{YOUR_TOKEN}.js"></script>21 <script src="https://jsdelivr.fusioncdn.com/npm/@mlytics/p2sp-sdk@latest/bundle/driver.min.js"></script>22 <script23 src="https://jsdelivr.fusioncdn.com/npm/@mlytics/p2sp-sdk@latest/bundle/peripheral/player/videojs-hls.min.js"></script>24</head>25
26<body>27 <video id="video" class="video-js vjs-theme-fantasy" style="width: 100%; height: 100%; background-color: black;" />28
29 <script>30 const loadParameter = () => {31 const params = new URL(window.location).searchParams;32 const fetchParameter = (keyName, type, defaultValue) => {33 let value = params.get(keyName);34 switch (type) {35 case 'number':36 value = Number(value);37 return typeof value === 'number' && !isNaN(value) ? value : defaultValue;38 case 'boolean':39 return [true, 'true', 1, '1'].includes(value) ? true :40 [false, 'false', 0, '0'].includes(value) ? false :41 defaultValue;42 default:43 return value;44 }45 }46
47 window.parameters = {48 clientID: fetchParameter('clientID'),49 src: fetchParameter('src'),50 vast: fetchParameter('vast'),51 t: fetchParameter('t', 'number'),52 poster: fetchParameter('poster'),53 controls: fetchParameter('controls', 'boolean', false),54 autoplay: fetchParameter('autoplay', 'boolean', false),55 loop: fetchParameter('loop', 'boolean', false),56 preload: fetchParameter('preload', 'boolean', false),57 muted: fetchParameter('muted', 'boolean', false)58 }59 // console.log(`parameters: ${JSON.stringify(parameters)}`);60 }61
62 const loadConfig = async () => {63 await new Promise((resolve, reject) => {64 try {65 const element = document.createElement('script');66 element.setAttribute('src', `https://vsp.mlytics.co/${parameters.clientID}-mlysdk.js`);67 element.addEventListener('load', () => {68 resolve();69 });70 element.addEventListener('error', () => {71 reject(new Error('Load mlysdk config failed.'));72 });73 document.getElementsByTagName('head')[0].appendChild(element);74 } catch (error) {75 reject(error);76 }77 });78 }79
80 const loadPlayer = async () => {81 const driver = mlysdk.driver.initialize()82
83 const src = parameters.src;84 const video = document.getElementById('video')85 const adapter = driver.extensions.VideojsHlsPlayerPlugin.create(video, {86 poster: parameters.poster,87 controls: parameters.controls,88 autoplay: parameters.autoplay,89 loop: parameters.loop,90 preload: parameters.preload,91 muted: parameters.muted,92 sources: [{93 src,94 type: 'application/vnd.apple.mpegurl'95 }],96 fluid: true97 })98 const videojsPlayer = adapter.player99
100 videojsPlayer.ima({101 id: 'video',102 debug: false,103 showControlsForAds: true,104 adTagUrl: parameters.vast105 });106 videojsPlayer.ima.initializeAdDisplayContainer();107
108 videojsPlayer.one('adsready', function () {109 const adsManager = this.ima.getAdsManager();110 adsManager.addEventListener(111 google.ima.AdEvent.Type.AD_METADATA,112 onLoadStart);113 adsManager.addEventListener(114 google.ima.AdEvent.Type.STARTED,115 onAdStarted);116 adsManager.addEventListener(117 google.ima.AdEvent.Type.COMPLETE,118 onAdComplete);119 });120
121 function onLoadStart(adEvent) {122 adapter.protocol.media.mux.emit('adrequest', {123 ad_tag_url: parameters.vast,124 });125 }126 function onAdStarted(event) {127 adapter.protocol.media.mux.emit('adbreakstart', {});128 adapter.protocol.media.mux.emit('adplay', {});129 adapter.protocol.media.mux.emit('adplaying', {130 ad_asset_url: event.ad.data.mediaUrl,131 ad_creative_id: event.ad.data.creativeId,132 ad_id: event.ad.data.adId,133 ad_universal_id: event.ad.data.universalAdIdValue134 });135 }136 function onAdComplete(adEvent) {137 adapter.protocol.media.mux.emit('adended', {});138 adapter.protocol.media.mux.emit('adbreakend', {});139 }140 }141
142 (async () => {143 loadParameter();144 await loadConfig();145 loadPlayer();146
147 if (typeof parameters.t === 'number' && parameters.t > 0)148 videojsPlayer.currentTime(parameters.t);149 })();150 </script>151</body>152
153</html>