stormcloud-video-player 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/stormcloud-vp.min.js +1 -1
- package/lib/index.cjs +14 -1
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +14 -1
- package/lib/index.js.map +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +10 -1
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/player/StormcloudVideoPlayer.d.cts +1 -1
- package/lib/players/HlsPlayer.cjs +10 -1
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/HlsPlayer.d.cts +1 -1
- package/lib/players/index.cjs +10 -1
- package/lib/players/index.cjs.map +1 -1
- package/lib/sdk/adstormPlayer.cjs +8 -1
- package/lib/sdk/adstormPlayer.cjs.map +1 -1
- package/lib/sdk/adstormPlayer.d.cts +1 -1
- package/lib/sdk/hlsAdPlayer.cjs +4 -0
- package/lib/sdk/hlsAdPlayer.cjs.map +1 -1
- package/lib/sdk/hlsAdPlayer.d.cts +1 -1
- package/lib/{types-Ca4ZDaWw.d.cts → types-2vzNGNdf.d.cts} +1 -0
- package/lib/ui/StormcloudVideoPlayer.cjs +10 -1
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/ui/StormcloudVideoPlayer.d.cts +1 -1
- package/lib/utils/tracking.d.cts +1 -1
- package/package.json +1 -1
|
@@ -265,6 +265,7 @@ function createAdStormPlayer(contentVideo, options) {
|
|
|
265
265
|
var adContainerEl;
|
|
266
266
|
var currentAd;
|
|
267
267
|
var destroyed = false;
|
|
268
|
+
var allowNativeHls = false;
|
|
268
269
|
var trackingFired = {
|
|
269
270
|
impression: false,
|
|
270
271
|
start: false,
|
|
@@ -722,7 +723,9 @@ function createAdStormPlayer(contentVideo, options) {
|
|
|
722
723
|
}, 300);
|
|
723
724
|
contentVideo.muted = true;
|
|
724
725
|
contentVideo.volume = 0;
|
|
725
|
-
|
|
726
|
+
if (allowNativeHls) {
|
|
727
|
+
contentVideo.pause();
|
|
728
|
+
}
|
|
726
729
|
adPlaying = true;
|
|
727
730
|
setAdPlayingFlag(true);
|
|
728
731
|
if (adVideoElement) {
|
|
@@ -898,6 +901,10 @@ function createAdStormPlayer(contentVideo, options) {
|
|
|
898
901
|
}
|
|
899
902
|
}, 300);
|
|
900
903
|
}
|
|
904
|
+
},
|
|
905
|
+
setAllowNativeHls: function setAllowNativeHls(value) {
|
|
906
|
+
allowNativeHls = value;
|
|
907
|
+
log("allowNativeHls set to: ".concat(value));
|
|
901
908
|
}
|
|
902
909
|
};
|
|
903
910
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/ubuntu24/Dev/stormcloud-vp/lib/sdk/adstormPlayer.cjs","../../src/sdk/adstormPlayer.ts"],"names":["__defProp","Object","defineProperty","__getOwnPropDesc","getOwnPropertyDescriptor","__getOwnPropNames","getOwnPropertyNames","__hasOwnProp","prototype","hasOwnProperty","__export","target","all","name","get","enumerable","__copyProps","to","from","except","desc","key","call","__toCommonJS","mod","value","adstormPlayer_exports","createAdStormPlayer","exports","SUPPORTED_VIDEO_EXTENSIONS","UNSUPPORTED_VIDEO_EXTENSIONS","getFileExtension","url","pathname","URL","lastDot","lastIndexOf","slice","toLowerCase","ext","split","isUnsupportedFormat","indexOf","replaceFlvExtension","replace","isSupportedFormat","mimeType","includes","contentVideo","options","licenseKey","debug","adPlaying","originalMutedState","originalVolume","Math","max","min","volume","listeners","Map","adVideoElement","adContainerEl","currentAd","destroyed","trackingFired","impression","start","firstQuartile","midpoint","thirdQuartile","complete","log","args","console","emit","event","payload","set","Array","fn","error","warn","fireTrackingPixels","urls","length","forEach","img","Image","src","buildVastUrl","durationSeconds","metadata","baseUrl","defaultMetadata","video","codec","width","videoWidth","height","videoHeight","fps","bitrate","profile","pix_fmt","has_b_frames","audio","sample_rate","finalMetadata","metadataStr","encodeURIComponent","JSON","stringify","ceil","parseVastXml","xmlString","ads","parser","DOMParser","xmlDoc","parseFromString","parserError","querySelector","textContent","adElements","querySelectorAll","adElement","adId","getAttribute","title","durationText","durationParts","duration","parseInt","parseFloat","mediaFileElements","mediaFiles","mf","push","type","trim","originalUrl","trackingUrls","el","eventKey","clickThrough","id","selectBestMediaFile","mp4Files","filter","candidates","targetWidth","targetHeight","sort","a","b","diffA","abs","diffB","createAdVideoElement","document","createElement","style","position","left","top","objectFit","backgroundColor","zIndex","playsInline","muted","setAdPlayingFlag","isPlaying","dataset","stormcloudAdPlaying","setupAdEventListeners","ad","addEventListener","progress","currentTime","handleAdComplete","e","handleAdError","opacity","setTimeout","display","pointerEvents","visibility","fetchVast","vastUrl","response","xmlText","fetch","headers","ok"],"mappings":"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","sourcesContent":["\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n// src/sdk/adstormPlayer.ts\nvar adstormPlayer_exports = {};\n__export(adstormPlayer_exports, {\n createAdStormPlayer: () => createAdStormPlayer\n});\nmodule.exports = __toCommonJS(adstormPlayer_exports);\nvar SUPPORTED_VIDEO_EXTENSIONS = [\".mp4\", \".webm\", \".ogg\", \".m3u8\", \".ts\"];\nvar UNSUPPORTED_VIDEO_EXTENSIONS = [\".flv\", \".f4v\", \".swf\", \".wmv\", \".avi\", \".mov\", \".mkv\"];\nfunction getFileExtension(url) {\n try {\n const pathname = new URL(url, \"http://dummy\").pathname;\n const lastDot = pathname.lastIndexOf(\".\");\n if (lastDot === -1) return \"\";\n return pathname.slice(lastDot).toLowerCase();\n } catch {\n const lastDot = url.lastIndexOf(\".\");\n if (lastDot === -1) return \"\";\n const ext = url.slice(lastDot).split(/[?#]/)[0];\n return (ext || \"\").toLowerCase();\n }\n}\nfunction isUnsupportedFormat(url) {\n const ext = getFileExtension(url);\n return UNSUPPORTED_VIDEO_EXTENSIONS.indexOf(ext) !== -1;\n}\nfunction replaceFlvExtension(url) {\n const ext = getFileExtension(url);\n if (ext === \".flv\") {\n return url.replace(/\\.flv(\\?|$)/i, \".mp4$1\");\n }\n return url;\n}\nfunction isSupportedFormat(url, mimeType) {\n if (isUnsupportedFormat(url)) {\n return false;\n }\n const ext = getFileExtension(url);\n if (SUPPORTED_VIDEO_EXTENSIONS.indexOf(ext) !== -1) {\n return true;\n }\n if (ext === \"\" || ext === \".\") {\n return mimeType.includes(\"video/mp4\") || mimeType.includes(\"video/webm\") || mimeType.includes(\"m3u8\") || mimeType.includes(\"application/x-mpegurl\");\n }\n return false;\n}\nfunction createAdStormPlayer(contentVideo, options) {\n const { licenseKey, debug = false } = options;\n let adPlaying = false;\n let originalMutedState = false;\n let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));\n const listeners = /* @__PURE__ */ new Map();\n let adVideoElement;\n let adContainerEl;\n let currentAd;\n let destroyed = false;\n let trackingFired = {\n impression: false,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false\n };\n function log(...args) {\n if (debug) {\n console.log(\"[AdStormPlayer]\", ...args);\n }\n }\n function emit(event, payload) {\n const set = listeners.get(event);\n if (!set) return;\n for (const fn of Array.from(set)) {\n try {\n fn(payload);\n } catch (error) {\n console.warn(`[AdStormPlayer] Error in event listener for ${event}:`, error);\n }\n }\n }\n function fireTrackingPixels(urls) {\n if (!urls || urls.length === 0) return;\n urls.forEach((url) => {\n try {\n const img = new Image(1, 1);\n img.src = url;\n log(\"Fired tracking pixel:\", url);\n } catch (error) {\n console.warn(\"[AdStormPlayer] Error firing tracking pixel:\", error);\n }\n });\n }\n function buildVastUrl(durationSeconds, metadata) {\n const baseUrl = `https://adstorm.co/api-adstorm-dev/adstorm/vast/${licenseKey}/pod`;\n const defaultMetadata = {\n video: {\n codec: \"h264\",\n width: contentVideo.videoWidth || 1280,\n height: contentVideo.videoHeight || 720,\n fps: 29.97,\n bitrate: 5e3,\n profile: \"high\",\n pix_fmt: \"yuv420p\",\n has_b_frames: 0\n },\n audio: {\n codec: \"aac\",\n sample_rate: 48e3,\n bitrate: 128\n }\n };\n const finalMetadata = metadata || defaultMetadata;\n const metadataStr = encodeURIComponent(JSON.stringify(finalMetadata));\n return `${baseUrl}?duration=${Math.ceil(durationSeconds)}&metadata=${metadataStr}`;\n }\n function parseVastXml(xmlString) {\n const ads = [];\n try {\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n const parserError = xmlDoc.querySelector(\"parsererror\");\n if (parserError) {\n console.error(\"[AdStormPlayer] XML parsing error:\", parserError.textContent);\n return [];\n }\n const adElements = xmlDoc.querySelectorAll(\"Ad\");\n adElements.forEach((adElement) => {\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = adElement.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n const durationText = adElement.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n const durationParts = durationText.split(\":\");\n const duration = parseInt(durationParts[0] || \"0\", 10) * 3600 + parseInt(durationParts[1] || \"0\", 10) * 60 + parseFloat(durationParts[2] || \"0\");\n const mediaFileElements = adElement.querySelectorAll(\"MediaFile\");\n const mediaFiles = [];\n mediaFileElements.forEach((mf) => {\n const type = mf.getAttribute(\"type\") || \"\";\n let url = mf.textContent?.trim() || \"\";\n const width = parseInt(mf.getAttribute(\"width\") || \"1920\", 10);\n const height = parseInt(mf.getAttribute(\"height\") || \"1080\", 10);\n const bitrate = mf.getAttribute(\"bitrate\") ? parseInt(mf.getAttribute(\"bitrate\"), 10) : void 0;\n if (!url) {\n log(`Skipping empty MediaFile URL`);\n return;\n }\n const originalUrl = url;\n url = replaceFlvExtension(url);\n if (url !== originalUrl) {\n log(`Converted FLV to MP4: ${originalUrl} -> ${url}`);\n }\n if (isUnsupportedFormat(url)) {\n const ext = getFileExtension(url);\n log(`Skipping unsupported format: ${url} (extension: ${ext}, declared type: ${type})`);\n return;\n }\n if (isSupportedFormat(url, type)) {\n mediaFiles.push({ url, type, width, height, bitrate });\n log(`Found media file: ${url} (${type}, ${width}x${height})`);\n } else {\n log(`Skipping incompatible media file: ${url} (type: ${type})`);\n }\n });\n if (mediaFiles.length === 0) {\n log(\"No valid media files found in ad:\", adId);\n return;\n }\n const trackingUrls = {\n impression: [],\n start: [],\n firstQuartile: [],\n midpoint: [],\n thirdQuartile: [],\n complete: [],\n error: []\n };\n adElement.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n adElement.querySelectorAll(\"Tracking\").forEach((el) => {\n const event = el.getAttribute(\"event\");\n const url = el.textContent?.trim();\n if (event && url) {\n const eventKey = event;\n if (trackingUrls[eventKey]) {\n trackingUrls[eventKey].push(url);\n }\n }\n });\n const clickThrough = adElement.querySelector(\"ClickThrough\")?.textContent?.trim();\n ads.push({\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough\n });\n log(`Parsed ad: ${title}, duration: ${duration}s, media files: ${mediaFiles.length}`);\n });\n } catch (error) {\n console.error(\"[AdStormPlayer] Error parsing VAST XML:\", error);\n }\n return ads;\n }\n function selectBestMediaFile(mediaFiles) {\n if (mediaFiles.length === 0) return null;\n if (mediaFiles.length === 1) return mediaFiles[0];\n const mp4Files = mediaFiles.filter((mf) => mf.type.includes(\"video/mp4\"));\n const candidates = mp4Files.length > 0 ? mp4Files : mediaFiles;\n const targetWidth = contentVideo.videoWidth || 1280;\n const targetHeight = contentVideo.videoHeight || 720;\n candidates.sort((a, b) => {\n const diffA = Math.abs(a.width - targetWidth) + Math.abs(a.height - targetHeight);\n const diffB = Math.abs(b.width - targetWidth) + Math.abs(b.height - targetHeight);\n return diffA - diffB;\n });\n return candidates[0] || null;\n }\n function createAdVideoElement() {\n const video = document.createElement(\"video\");\n video.style.position = \"absolute\";\n video.style.left = \"0\";\n video.style.top = \"0\";\n video.style.width = \"100%\";\n video.style.height = \"100%\";\n video.style.objectFit = \"contain\";\n video.style.backgroundColor = \"#000\";\n video.style.zIndex = \"15\";\n video.playsInline = true;\n video.muted = false;\n video.volume = originalMutedState ? 0 : originalVolume;\n return video;\n }\n function setAdPlayingFlag(isPlaying) {\n if (isPlaying) {\n contentVideo.dataset.stormcloudAdPlaying = \"true\";\n } else {\n delete contentVideo.dataset.stormcloudAdPlaying;\n }\n }\n function setupAdEventListeners() {\n if (!adVideoElement || !currentAd) return;\n const ad = currentAd;\n adVideoElement.addEventListener(\"timeupdate\", () => {\n if (!ad || !adVideoElement) return;\n const progress = adVideoElement.currentTime / ad.duration;\n if (progress >= 0.25 && !trackingFired.firstQuartile) {\n trackingFired.firstQuartile = true;\n fireTrackingPixels(ad.trackingUrls.firstQuartile);\n }\n if (progress >= 0.5 && !trackingFired.midpoint) {\n trackingFired.midpoint = true;\n fireTrackingPixels(ad.trackingUrls.midpoint);\n }\n if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n trackingFired.thirdQuartile = true;\n fireTrackingPixels(ad.trackingUrls.thirdQuartile);\n }\n });\n adVideoElement.addEventListener(\"playing\", () => {\n if (!ad || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels(ad.trackingUrls.start);\n log(\"Ad started playing\");\n });\n adVideoElement.addEventListener(\"ended\", () => {\n if (!ad || trackingFired.complete) return;\n trackingFired.complete = true;\n fireTrackingPixels(ad.trackingUrls.complete);\n log(\"Ad completed\");\n handleAdComplete();\n });\n adVideoElement.addEventListener(\"error\", (e) => {\n console.error(\"[AdStormPlayer] Ad video error:\", e);\n if (ad) {\n fireTrackingPixels(ad.trackingUrls.error);\n }\n handleAdError();\n });\n }\n function handleAdComplete() {\n log(\"Handling ad completion\");\n adPlaying = false;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n emit(\"content_resume\");\n emit(\"all_ads_completed\");\n }\n function handleAdError() {\n log(\"Handling ad error\");\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n emit(\"ad_error\");\n }\n async function fetchVast(durationSeconds) {\n const vastUrl = buildVastUrl(durationSeconds);\n log(\"Fetching VAST from:\", vastUrl);\n const response = await fetch(vastUrl, {\n headers: {\n \"Accept\": \"application/xml\"\n }\n });\n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.status} ${response.statusText}`);\n }\n const xmlText = await response.text();\n log(\"VAST response received, length:\", xmlText.length);\n return parseVastXml(xmlText);\n }\n return {\n initialize() {\n log(\"Initializing\");\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n container.style.transition = \"opacity 0.3s ease-in-out\";\n container.style.opacity = \"0\";\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n },\n async requestAds(duration) {\n log(\"Requesting ads for duration:\", duration);\n if (adPlaying) {\n return Promise.reject(new Error(\"Ad already playing\"));\n }\n try {\n let durationSeconds = 30;\n const parsed = parseInt(duration, 10);\n if (!isNaN(parsed) && parsed > 0) {\n durationSeconds = parsed;\n }\n const ads = await fetchVast(durationSeconds);\n if (ads.length === 0) {\n log(\"No ads available from VAST response\");\n emit(\"ad_error\");\n return Promise.resolve();\n }\n currentAd = ads[0];\n log(`Ad loaded: ${currentAd.title}, duration: ${currentAd.duration}s`);\n fireTrackingPixels(currentAd.trackingUrls.impression);\n trackingFired.impression = true;\n return Promise.resolve();\n } catch (error) {\n console.error(\"[AdStormPlayer] Error requesting ads:\", error);\n emit(\"ad_error\");\n return Promise.reject(error);\n }\n },\n async play() {\n if (!currentAd) {\n return Promise.reject(new Error(\"No ad loaded\"));\n }\n log(\"Starting ad playback\");\n try {\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl?.appendChild(adVideoElement);\n setupAdEventListeners();\n }\n trackingFired = {\n impression: trackingFired.impression,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false\n };\n contentVideo.style.transition = \"opacity 0.3s ease-in-out\";\n contentVideo.style.opacity = \"0\";\n setTimeout(() => {\n contentVideo.style.visibility = \"hidden\";\n }, 300);\n contentVideo.muted = true;\n contentVideo.volume = 0;\n contentVideo.pause();\n adPlaying = true;\n setAdPlayingFlag(true);\n if (adVideoElement) {\n adVideoElement.volume = originalMutedState ? 0 : originalVolume;\n adVideoElement.muted = originalMutedState;\n }\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n adContainerEl.offsetHeight;\n adContainerEl.style.opacity = \"1\";\n }\n emit(\"content_pause\");\n const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n if (!mediaFile) {\n throw new Error(\"No media file available\");\n }\n log(\"Playing media file:\", mediaFile.url);\n adVideoElement.src = mediaFile.url;\n await adVideoElement.play();\n return Promise.resolve();\n } catch (error) {\n console.error(\"[AdStormPlayer] Error playing ad:\", error);\n handleAdError();\n return Promise.reject(error);\n }\n },\n async stop() {\n log(\"Stopping ad\");\n adPlaying = false;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n }\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n currentAd = void 0;\n },\n destroy() {\n log(\"Destroying\");\n destroyed = true;\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n adVideoElement.remove();\n adVideoElement = void 0;\n }\n if (adContainerEl?.parentElement) {\n adContainerEl.parentElement.removeChild(adContainerEl);\n }\n adContainerEl = void 0;\n currentAd = void 0;\n listeners.clear();\n },\n isAdPlaying() {\n return adPlaying;\n },\n resize(width, height) {\n log(`Resizing to ${width}x${height}`);\n if (adContainerEl) {\n adContainerEl.style.width = `${width}px`;\n adContainerEl.style.height = `${height}px`;\n }\n if (adVideoElement) {\n adVideoElement.style.width = `${width}px`;\n adVideoElement.style.height = `${height}px`;\n }\n },\n on(event, listener) {\n if (!listeners.has(event)) listeners.set(event, /* @__PURE__ */ new Set());\n listeners.get(event).add(listener);\n },\n off(event, listener) {\n listeners.get(event)?.delete(listener);\n },\n updateOriginalMutedState(muted, volume) {\n const nextVolume = typeof volume === \"number\" && !Number.isNaN(volume) ? Math.max(0, Math.min(1, volume)) : originalVolume;\n log(`updateOriginalMutedState: muted=${muted}, volume=${nextVolume}`);\n originalMutedState = muted;\n originalVolume = nextVolume;\n },\n getOriginalMutedState() {\n return originalMutedState;\n },\n getOriginalVolume() {\n return originalVolume;\n },\n setAdVolume(volume) {\n if (adVideoElement && adPlaying) {\n adVideoElement.volume = Math.max(0, Math.min(1, volume));\n adVideoElement.muted = volume === 0;\n }\n },\n getAdVolume() {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n showPlaceholder() {\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.opacity = \"1\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n },\n hidePlaceholder() {\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n }\n };\n}\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n createAdStormPlayer\n});\n","import type { AdController } from \"../types\";\n\ninterface VastMediaFile {\n url: string;\n type: string;\n width: number;\n height: number;\n bitrate?: number | undefined;\n}\n\nconst SUPPORTED_VIDEO_EXTENSIONS = ['.mp4', '.webm', '.ogg', '.m3u8', '.ts'];\nconst UNSUPPORTED_VIDEO_EXTENSIONS = ['.flv', '.f4v', '.swf', '.wmv', '.avi', '.mov', '.mkv'];\n\nfunction getFileExtension(url: string): string {\n try {\n const pathname = new URL(url, 'http://dummy').pathname;\n const lastDot = pathname.lastIndexOf('.');\n if (lastDot === -1) return '';\n return pathname.slice(lastDot).toLowerCase();\n } catch {\n const lastDot = url.lastIndexOf('.');\n if (lastDot === -1) return '';\n const ext = url.slice(lastDot).split(/[?#]/)[0];\n return (ext || '').toLowerCase();\n }\n}\n\nfunction isUnsupportedFormat(url: string): boolean {\n const ext = getFileExtension(url);\n return UNSUPPORTED_VIDEO_EXTENSIONS.indexOf(ext) !== -1;\n}\n\nfunction replaceFlvExtension(url: string): string {\n const ext = getFileExtension(url);\n if (ext === '.flv') {\n return url.replace(/\\.flv(\\?|$)/i, '.mp4$1');\n }\n return url;\n}\n\nfunction isSupportedFormat(url: string, mimeType: string): boolean {\n if (isUnsupportedFormat(url)) {\n return false;\n }\n \n const ext = getFileExtension(url);\n \n if (SUPPORTED_VIDEO_EXTENSIONS.indexOf(ext) !== -1) {\n return true;\n }\n \n if (ext === '' || ext === '.') {\n return mimeType.includes('video/mp4') || \n mimeType.includes('video/webm') || \n mimeType.includes('m3u8') ||\n mimeType.includes('application/x-mpegurl');\n }\n \n return false;\n}\n\ninterface VastTrackingUrls {\n impression: string[];\n start: string[];\n firstQuartile: string[];\n midpoint: string[];\n thirdQuartile: string[];\n complete: string[];\n error: string[];\n}\n\ninterface VastAd {\n id: string;\n title: string;\n duration: number;\n mediaFiles: VastMediaFile[];\n trackingUrls: VastTrackingUrls;\n clickThrough?: string | undefined;\n}\n\ninterface AdStormMetadata {\n video?: {\n codec?: string;\n width?: number;\n height?: number;\n fps?: number;\n bitrate?: number;\n profile?: string;\n pix_fmt?: string;\n has_b_frames?: number;\n };\n audio?: {\n codec?: string;\n sample_rate?: number;\n bitrate?: number;\n };\n}\n\nexport interface AdStormPlayerOptions {\n licenseKey: string;\n debug?: boolean;\n}\n\nexport function createAdStormPlayer(\n contentVideo: HTMLVideoElement,\n options: AdStormPlayerOptions\n): AdController {\n const { licenseKey, debug = false } = options;\n \n let adPlaying = false;\n let originalMutedState = false;\n let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));\n const listeners = new Map<string, Set<(payload?: any) => void>>();\n \n let adVideoElement: HTMLVideoElement | undefined;\n let adContainerEl: HTMLDivElement | undefined;\n let currentAd: VastAd | undefined;\n let destroyed = false;\n \n let trackingFired = {\n impression: false,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false,\n };\n\n function log(...args: any[]): void {\n if (debug) {\n console.log(\"[AdStormPlayer]\", ...args);\n }\n }\n\n function emit(event: string, payload?: any): void {\n const set = listeners.get(event);\n if (!set) return;\n for (const fn of Array.from(set)) {\n try {\n fn(payload);\n } catch (error) {\n console.warn(`[AdStormPlayer] Error in event listener for ${event}:`, error);\n }\n }\n }\n\n function fireTrackingPixels(urls: string[]): void {\n if (!urls || urls.length === 0) return;\n \n urls.forEach((url) => {\n try {\n const img = new Image(1, 1);\n img.src = url;\n log(\"Fired tracking pixel:\", url);\n } catch (error) {\n console.warn(\"[AdStormPlayer] Error firing tracking pixel:\", error);\n }\n });\n }\n\n function buildVastUrl(durationSeconds: number, metadata?: AdStormMetadata): string {\n const baseUrl = `https://adstorm.co/api-adstorm-dev/adstorm/vast/${licenseKey}/pod`;\n \n const defaultMetadata: AdStormMetadata = {\n video: {\n codec: \"h264\",\n width: contentVideo.videoWidth || 1280,\n height: contentVideo.videoHeight || 720,\n fps: 29.97,\n bitrate: 5000,\n profile: \"high\",\n pix_fmt: \"yuv420p\",\n has_b_frames: 0,\n },\n audio: {\n codec: \"aac\",\n sample_rate: 48000,\n bitrate: 128,\n },\n };\n \n const finalMetadata = metadata || defaultMetadata;\n const metadataStr = encodeURIComponent(JSON.stringify(finalMetadata));\n \n return `${baseUrl}?duration=${Math.ceil(durationSeconds)}&metadata=${metadataStr}`;\n }\n\n function parseVastXml(xmlString: string): VastAd[] {\n const ads: VastAd[] = [];\n \n try {\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n \n const parserError = xmlDoc.querySelector(\"parsererror\");\n if (parserError) {\n console.error(\"[AdStormPlayer] XML parsing error:\", parserError.textContent);\n return [];\n }\n \n const adElements = xmlDoc.querySelectorAll(\"Ad\");\n \n adElements.forEach((adElement) => {\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = adElement.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n \n const durationText = adElement.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n const durationParts = durationText.split(\":\");\n const duration =\n parseInt(durationParts[0] || \"0\", 10) * 3600 +\n parseInt(durationParts[1] || \"0\", 10) * 60 +\n parseFloat(durationParts[2] || \"0\");\n \n const mediaFileElements = adElement.querySelectorAll(\"MediaFile\");\n const mediaFiles: VastMediaFile[] = [];\n \n mediaFileElements.forEach((mf) => {\n const type = mf.getAttribute(\"type\") || \"\";\n let url = mf.textContent?.trim() || \"\";\n const width = parseInt(mf.getAttribute(\"width\") || \"1920\", 10);\n const height = parseInt(mf.getAttribute(\"height\") || \"1080\", 10);\n const bitrate = mf.getAttribute(\"bitrate\") \n ? parseInt(mf.getAttribute(\"bitrate\")!, 10) \n : undefined;\n \n if (!url) {\n log(`Skipping empty MediaFile URL`);\n return;\n }\n \n const originalUrl = url;\n url = replaceFlvExtension(url);\n if (url !== originalUrl) {\n log(`Converted FLV to MP4: ${originalUrl} -> ${url}`);\n }\n \n if (isUnsupportedFormat(url)) {\n const ext = getFileExtension(url);\n log(`Skipping unsupported format: ${url} (extension: ${ext}, declared type: ${type})`);\n return;\n }\n \n if (isSupportedFormat(url, type)) {\n mediaFiles.push({ url, type, width, height, bitrate });\n log(`Found media file: ${url} (${type}, ${width}x${height})`);\n } else {\n log(`Skipping incompatible media file: ${url} (type: ${type})`);\n }\n });\n \n if (mediaFiles.length === 0) {\n log(\"No valid media files found in ad:\", adId);\n return;\n }\n \n const trackingUrls: VastTrackingUrls = {\n impression: [],\n start: [],\n firstQuartile: [],\n midpoint: [],\n thirdQuartile: [],\n complete: [],\n error: [],\n };\n \n adElement.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n \n adElement.querySelectorAll(\"Tracking\").forEach((el) => {\n const event = el.getAttribute(\"event\");\n const url = el.textContent?.trim();\n if (event && url) {\n const eventKey = event as keyof VastTrackingUrls;\n if (trackingUrls[eventKey]) {\n trackingUrls[eventKey].push(url);\n }\n }\n });\n \n const clickThrough = adElement.querySelector(\"ClickThrough\")?.textContent?.trim();\n \n ads.push({\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough,\n });\n \n log(`Parsed ad: ${title}, duration: ${duration}s, media files: ${mediaFiles.length}`);\n });\n \n } catch (error) {\n console.error(\"[AdStormPlayer] Error parsing VAST XML:\", error);\n }\n \n return ads;\n }\n\n function selectBestMediaFile(mediaFiles: VastMediaFile[]): VastMediaFile | null {\n if (mediaFiles.length === 0) return null;\n if (mediaFiles.length === 1) return mediaFiles[0]!;\n \n const mp4Files = mediaFiles.filter(mf => mf.type.includes(\"video/mp4\"));\n const candidates = mp4Files.length > 0 ? mp4Files : mediaFiles;\n \n const targetWidth = contentVideo.videoWidth || 1280;\n const targetHeight = contentVideo.videoHeight || 720;\n \n candidates.sort((a, b) => {\n const diffA = Math.abs(a.width - targetWidth) + Math.abs(a.height - targetHeight);\n const diffB = Math.abs(b.width - targetWidth) + Math.abs(b.height - targetHeight);\n return diffA - diffB;\n });\n \n return candidates[0] || null;\n }\n\n function createAdVideoElement(): HTMLVideoElement {\n const video = document.createElement(\"video\");\n video.style.position = \"absolute\";\n video.style.left = \"0\";\n video.style.top = \"0\";\n video.style.width = \"100%\";\n video.style.height = \"100%\";\n video.style.objectFit = \"contain\";\n video.style.backgroundColor = \"#000\";\n video.style.zIndex = \"15\";\n video.playsInline = true;\n video.muted = false;\n video.volume = originalMutedState ? 0 : originalVolume;\n \n return video;\n }\n\n function setAdPlayingFlag(isPlaying: boolean): void {\n if (isPlaying) {\n contentVideo.dataset.stormcloudAdPlaying = \"true\";\n } else {\n delete contentVideo.dataset.stormcloudAdPlaying;\n }\n }\n\n function setupAdEventListeners(): void {\n if (!adVideoElement || !currentAd) return;\n \n const ad = currentAd;\n \n adVideoElement.addEventListener(\"timeupdate\", () => {\n if (!ad || !adVideoElement) return;\n \n const progress = adVideoElement.currentTime / ad.duration;\n \n if (progress >= 0.25 && !trackingFired.firstQuartile) {\n trackingFired.firstQuartile = true;\n fireTrackingPixels(ad.trackingUrls.firstQuartile);\n }\n \n if (progress >= 0.5 && !trackingFired.midpoint) {\n trackingFired.midpoint = true;\n fireTrackingPixels(ad.trackingUrls.midpoint);\n }\n \n if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n trackingFired.thirdQuartile = true;\n fireTrackingPixels(ad.trackingUrls.thirdQuartile);\n }\n });\n \n adVideoElement.addEventListener(\"playing\", () => {\n if (!ad || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels(ad.trackingUrls.start);\n log(\"Ad started playing\");\n });\n \n adVideoElement.addEventListener(\"ended\", () => {\n if (!ad || trackingFired.complete) return;\n trackingFired.complete = true;\n fireTrackingPixels(ad.trackingUrls.complete);\n log(\"Ad completed\");\n handleAdComplete();\n });\n \n adVideoElement.addEventListener(\"error\", (e) => {\n console.error(\"[AdStormPlayer] Ad video error:\", e);\n if (ad) {\n fireTrackingPixels(ad.trackingUrls.error);\n }\n handleAdError();\n });\n }\n\n function handleAdComplete(): void {\n log(\"Handling ad completion\");\n adPlaying = false;\n setAdPlayingFlag(false);\n \n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n \n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n \n emit(\"content_resume\");\n emit(\"all_ads_completed\");\n }\n\n function handleAdError(): void {\n log(\"Handling ad error\");\n adPlaying = false;\n setAdPlayingFlag(false);\n \n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n \n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n \n emit(\"ad_error\");\n }\n\n async function fetchVast(durationSeconds: number): Promise<VastAd[]> {\n const vastUrl = buildVastUrl(durationSeconds);\n log(\"Fetching VAST from:\", vastUrl);\n \n const response = await fetch(vastUrl, {\n headers: {\n \"Accept\": \"application/xml\",\n },\n });\n \n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.status} ${response.statusText}`);\n }\n \n const xmlText = await response.text();\n log(\"VAST response received, length:\", xmlText.length);\n \n return parseVastXml(xmlText);\n }\n\n return {\n initialize() {\n log(\"Initializing\");\n \n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n container.style.transition = \"opacity 0.3s ease-in-out\";\n container.style.opacity = \"0\";\n \n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n },\n\n async requestAds(duration: string) {\n log(\"Requesting ads for duration:\", duration);\n \n if (adPlaying) {\n return Promise.reject(new Error(\"Ad already playing\"));\n }\n \n try {\n let durationSeconds = 30;\n const parsed = parseInt(duration, 10);\n if (!isNaN(parsed) && parsed > 0) {\n durationSeconds = parsed;\n }\n \n const ads = await fetchVast(durationSeconds);\n \n if (ads.length === 0) {\n log(\"No ads available from VAST response\");\n emit(\"ad_error\");\n return Promise.resolve();\n }\n \n currentAd = ads[0];\n log(`Ad loaded: ${currentAd!.title}, duration: ${currentAd!.duration}s`);\n \n fireTrackingPixels(currentAd!.trackingUrls.impression);\n trackingFired.impression = true;\n \n return Promise.resolve();\n } catch (error) {\n console.error(\"[AdStormPlayer] Error requesting ads:\", error);\n emit(\"ad_error\");\n return Promise.reject(error);\n }\n },\n\n async play() {\n if (!currentAd) {\n return Promise.reject(new Error(\"No ad loaded\"));\n }\n \n log(\"Starting ad playback\");\n \n try {\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl?.appendChild(adVideoElement);\n setupAdEventListeners();\n }\n \n trackingFired = {\n impression: trackingFired.impression,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false,\n };\n \n contentVideo.style.transition = \"opacity 0.3s ease-in-out\";\n contentVideo.style.opacity = \"0\";\n setTimeout(() => {\n contentVideo.style.visibility = \"hidden\";\n }, 300);\n contentVideo.muted = true;\n contentVideo.volume = 0;\n contentVideo.pause();\n \n adPlaying = true;\n setAdPlayingFlag(true);\n \n if (adVideoElement) {\n adVideoElement.volume = originalMutedState ? 0 : originalVolume;\n adVideoElement.muted = originalMutedState;\n }\n \n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n adContainerEl.offsetHeight;\n adContainerEl.style.opacity = \"1\";\n }\n \n emit(\"content_pause\");\n \n const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n if (!mediaFile) {\n throw new Error(\"No media file available\");\n }\n \n log(\"Playing media file:\", mediaFile.url);\n adVideoElement!.src = mediaFile.url;\n \n await adVideoElement!.play();\n \n return Promise.resolve();\n } catch (error) {\n console.error(\"[AdStormPlayer] Error playing ad:\", error);\n handleAdError();\n return Promise.reject(error);\n }\n },\n\n async stop() {\n log(\"Stopping ad\");\n adPlaying = false;\n setAdPlayingFlag(false);\n \n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n \n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n }\n \n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n \n currentAd = undefined;\n },\n\n destroy() {\n log(\"Destroying\");\n destroyed = true;\n adPlaying = false;\n setAdPlayingFlag(false);\n \n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n \n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n adVideoElement.remove();\n adVideoElement = undefined;\n }\n \n if (adContainerEl?.parentElement) {\n adContainerEl.parentElement.removeChild(adContainerEl);\n }\n \n adContainerEl = undefined;\n currentAd = undefined;\n listeners.clear();\n },\n\n isAdPlaying() {\n return adPlaying;\n },\n\n resize(width: number, height: number) {\n log(`Resizing to ${width}x${height}`);\n \n if (adContainerEl) {\n adContainerEl.style.width = `${width}px`;\n adContainerEl.style.height = `${height}px`;\n }\n \n if (adVideoElement) {\n adVideoElement.style.width = `${width}px`;\n adVideoElement.style.height = `${height}px`;\n }\n },\n\n on(event: string, listener: (payload?: any) => void) {\n if (!listeners.has(event)) listeners.set(event, new Set());\n listeners.get(event)!.add(listener);\n },\n\n off(event: string, listener: (payload?: any) => void) {\n listeners.get(event)?.delete(listener);\n },\n\n updateOriginalMutedState(muted: boolean, volume?: number) {\n const nextVolume =\n typeof volume === \"number\" && !Number.isNaN(volume)\n ? Math.max(0, Math.min(1, volume))\n : originalVolume;\n log(`updateOriginalMutedState: muted=${muted}, volume=${nextVolume}`);\n originalMutedState = muted;\n originalVolume = nextVolume;\n },\n\n getOriginalMutedState() {\n return originalMutedState;\n },\n\n getOriginalVolume() {\n return originalVolume;\n },\n\n setAdVolume(volume: number) {\n if (adVideoElement && adPlaying) {\n adVideoElement.volume = Math.max(0, Math.min(1, volume));\n adVideoElement.muted = volume === 0;\n }\n },\n\n getAdVolume(): number {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n\n showPlaceholder() {\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n \n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n \n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.opacity = \"1\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n },\n\n hidePlaceholder() {\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n },\n };\n}\n\n"]}
|
|
1
|
+
{"version":3,"sources":["/home/ubuntu24/Dev/stormcloud-vp/lib/sdk/adstormPlayer.cjs","../../src/sdk/adstormPlayer.ts"],"names":["__defProp","Object","defineProperty","__getOwnPropDesc","getOwnPropertyDescriptor","__getOwnPropNames","getOwnPropertyNames","__hasOwnProp","prototype","hasOwnProperty","all","__export","target","name","get","enumerable","__copyProps","to","from","except","desc","key","call","__toCommonJS","mod","value","adstormPlayer_exports","createAdStormPlayer","SUPPORTED_VIDEO_EXTENSIONS","UNSUPPORTED_VIDEO_EXTENSIONS","getFileExtension","url","pathname","URL","lastDot","lastIndexOf","slice","toLowerCase","ext","split","isUnsupportedFormat","indexOf","replaceFlvExtension","replace","isSupportedFormat","mimeType","includes","contentVideo","options","licenseKey","debug","adPlaying","originalMutedState","originalVolume","Math","max","min","volume","listeners","Map","adVideoElement","adContainerEl","currentAd","destroyed","allowNativeHls","trackingFired","impression","start","firstQuartile","midpoint","thirdQuartile","complete","log","args","console","emit","event","payload","set","Array","fn","error","warn","fireTrackingPixels","urls","length","forEach","img","Image","src","buildVastUrl","durationSeconds","metadata","baseUrl","defaultMetadata","video","codec","width","videoWidth","height","videoHeight","fps","bitrate","profile","pix_fmt","has_b_frames","audio","sample_rate","finalMetadata","metadataStr","encodeURIComponent","JSON","stringify","ceil","parseVastXml","xmlString","ads","durationParts","parser","DOMParser","xmlDoc","parseFromString","parserError","querySelector","textContent","adElements","querySelectorAll","adElement","adId","getAttribute","title","durationText","duration","parseInt","parseFloat","mediaFileElements","mediaFiles","mf","push","type","trim","originalUrl","clickThrough","trackingUrls","el","eventKey","id","selectBestMediaFile","candidates","mp4Files","targetWidth","targetHeight","sort","a","b","diffA","abs","diffB","createAdVideoElement","document","createElement","style","position","left","top","objectFit","backgroundColor","zIndex","playsInline","muted","setAdPlayingFlag","isPlaying","dataset","stormcloudAdPlaying","setupAdEventListeners","ad","addEventListener","progress","currentTime","handleAdComplete","e","handleAdError","opacity","setTimeout","display","pointerEvents","visibility","fetchVast","vastUrl","response","xmlText","fetch","headers","ok","Error","status","statusText","text"],"mappings":"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","sourcesContent":["\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n// src/sdk/adstormPlayer.ts\nvar adstormPlayer_exports = {};\n__export(adstormPlayer_exports, {\n createAdStormPlayer: () => createAdStormPlayer\n});\nmodule.exports = __toCommonJS(adstormPlayer_exports);\nvar SUPPORTED_VIDEO_EXTENSIONS = [\".mp4\", \".webm\", \".ogg\", \".m3u8\", \".ts\"];\nvar UNSUPPORTED_VIDEO_EXTENSIONS = [\".flv\", \".f4v\", \".swf\", \".wmv\", \".avi\", \".mov\", \".mkv\"];\nfunction getFileExtension(url) {\n try {\n const pathname = new URL(url, \"http://dummy\").pathname;\n const lastDot = pathname.lastIndexOf(\".\");\n if (lastDot === -1) return \"\";\n return pathname.slice(lastDot).toLowerCase();\n } catch {\n const lastDot = url.lastIndexOf(\".\");\n if (lastDot === -1) return \"\";\n const ext = url.slice(lastDot).split(/[?#]/)[0];\n return (ext || \"\").toLowerCase();\n }\n}\nfunction isUnsupportedFormat(url) {\n const ext = getFileExtension(url);\n return UNSUPPORTED_VIDEO_EXTENSIONS.indexOf(ext) !== -1;\n}\nfunction replaceFlvExtension(url) {\n const ext = getFileExtension(url);\n if (ext === \".flv\") {\n return url.replace(/\\.flv(\\?|$)/i, \".mp4$1\");\n }\n return url;\n}\nfunction isSupportedFormat(url, mimeType) {\n if (isUnsupportedFormat(url)) {\n return false;\n }\n const ext = getFileExtension(url);\n if (SUPPORTED_VIDEO_EXTENSIONS.indexOf(ext) !== -1) {\n return true;\n }\n if (ext === \"\" || ext === \".\") {\n return mimeType.includes(\"video/mp4\") || mimeType.includes(\"video/webm\") || mimeType.includes(\"m3u8\") || mimeType.includes(\"application/x-mpegurl\");\n }\n return false;\n}\nfunction createAdStormPlayer(contentVideo, options) {\n const { licenseKey, debug = false } = options;\n let adPlaying = false;\n let originalMutedState = false;\n let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));\n const listeners = /* @__PURE__ */ new Map();\n let adVideoElement;\n let adContainerEl;\n let currentAd;\n let destroyed = false;\n let allowNativeHls = false;\n let trackingFired = {\n impression: false,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false\n };\n function log(...args) {\n if (debug) {\n console.log(\"[AdStormPlayer]\", ...args);\n }\n }\n function emit(event, payload) {\n const set = listeners.get(event);\n if (!set) return;\n for (const fn of Array.from(set)) {\n try {\n fn(payload);\n } catch (error) {\n console.warn(`[AdStormPlayer] Error in event listener for ${event}:`, error);\n }\n }\n }\n function fireTrackingPixels(urls) {\n if (!urls || urls.length === 0) return;\n urls.forEach((url) => {\n try {\n const img = new Image(1, 1);\n img.src = url;\n log(\"Fired tracking pixel:\", url);\n } catch (error) {\n console.warn(\"[AdStormPlayer] Error firing tracking pixel:\", error);\n }\n });\n }\n function buildVastUrl(durationSeconds, metadata) {\n const baseUrl = `https://adstorm.co/api-adstorm-dev/adstorm/vast/${licenseKey}/pod`;\n const defaultMetadata = {\n video: {\n codec: \"h264\",\n width: contentVideo.videoWidth || 1280,\n height: contentVideo.videoHeight || 720,\n fps: 29.97,\n bitrate: 5e3,\n profile: \"high\",\n pix_fmt: \"yuv420p\",\n has_b_frames: 0\n },\n audio: {\n codec: \"aac\",\n sample_rate: 48e3,\n bitrate: 128\n }\n };\n const finalMetadata = metadata || defaultMetadata;\n const metadataStr = encodeURIComponent(JSON.stringify(finalMetadata));\n return `${baseUrl}?duration=${Math.ceil(durationSeconds)}&metadata=${metadataStr}`;\n }\n function parseVastXml(xmlString) {\n const ads = [];\n try {\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n const parserError = xmlDoc.querySelector(\"parsererror\");\n if (parserError) {\n console.error(\"[AdStormPlayer] XML parsing error:\", parserError.textContent);\n return [];\n }\n const adElements = xmlDoc.querySelectorAll(\"Ad\");\n adElements.forEach((adElement) => {\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = adElement.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n const durationText = adElement.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n const durationParts = durationText.split(\":\");\n const duration = parseInt(durationParts[0] || \"0\", 10) * 3600 + parseInt(durationParts[1] || \"0\", 10) * 60 + parseFloat(durationParts[2] || \"0\");\n const mediaFileElements = adElement.querySelectorAll(\"MediaFile\");\n const mediaFiles = [];\n mediaFileElements.forEach((mf) => {\n const type = mf.getAttribute(\"type\") || \"\";\n let url = mf.textContent?.trim() || \"\";\n const width = parseInt(mf.getAttribute(\"width\") || \"1920\", 10);\n const height = parseInt(mf.getAttribute(\"height\") || \"1080\", 10);\n const bitrate = mf.getAttribute(\"bitrate\") ? parseInt(mf.getAttribute(\"bitrate\"), 10) : void 0;\n if (!url) {\n log(`Skipping empty MediaFile URL`);\n return;\n }\n const originalUrl = url;\n url = replaceFlvExtension(url);\n if (url !== originalUrl) {\n log(`Converted FLV to MP4: ${originalUrl} -> ${url}`);\n }\n if (isUnsupportedFormat(url)) {\n const ext = getFileExtension(url);\n log(`Skipping unsupported format: ${url} (extension: ${ext}, declared type: ${type})`);\n return;\n }\n if (isSupportedFormat(url, type)) {\n mediaFiles.push({ url, type, width, height, bitrate });\n log(`Found media file: ${url} (${type}, ${width}x${height})`);\n } else {\n log(`Skipping incompatible media file: ${url} (type: ${type})`);\n }\n });\n if (mediaFiles.length === 0) {\n log(\"No valid media files found in ad:\", adId);\n return;\n }\n const trackingUrls = {\n impression: [],\n start: [],\n firstQuartile: [],\n midpoint: [],\n thirdQuartile: [],\n complete: [],\n error: []\n };\n adElement.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n adElement.querySelectorAll(\"Tracking\").forEach((el) => {\n const event = el.getAttribute(\"event\");\n const url = el.textContent?.trim();\n if (event && url) {\n const eventKey = event;\n if (trackingUrls[eventKey]) {\n trackingUrls[eventKey].push(url);\n }\n }\n });\n const clickThrough = adElement.querySelector(\"ClickThrough\")?.textContent?.trim();\n ads.push({\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough\n });\n log(`Parsed ad: ${title}, duration: ${duration}s, media files: ${mediaFiles.length}`);\n });\n } catch (error) {\n console.error(\"[AdStormPlayer] Error parsing VAST XML:\", error);\n }\n return ads;\n }\n function selectBestMediaFile(mediaFiles) {\n if (mediaFiles.length === 0) return null;\n if (mediaFiles.length === 1) return mediaFiles[0];\n const mp4Files = mediaFiles.filter((mf) => mf.type.includes(\"video/mp4\"));\n const candidates = mp4Files.length > 0 ? mp4Files : mediaFiles;\n const targetWidth = contentVideo.videoWidth || 1280;\n const targetHeight = contentVideo.videoHeight || 720;\n candidates.sort((a, b) => {\n const diffA = Math.abs(a.width - targetWidth) + Math.abs(a.height - targetHeight);\n const diffB = Math.abs(b.width - targetWidth) + Math.abs(b.height - targetHeight);\n return diffA - diffB;\n });\n return candidates[0] || null;\n }\n function createAdVideoElement() {\n const video = document.createElement(\"video\");\n video.style.position = \"absolute\";\n video.style.left = \"0\";\n video.style.top = \"0\";\n video.style.width = \"100%\";\n video.style.height = \"100%\";\n video.style.objectFit = \"contain\";\n video.style.backgroundColor = \"#000\";\n video.style.zIndex = \"15\";\n video.playsInline = true;\n video.muted = false;\n video.volume = originalMutedState ? 0 : originalVolume;\n return video;\n }\n function setAdPlayingFlag(isPlaying) {\n if (isPlaying) {\n contentVideo.dataset.stormcloudAdPlaying = \"true\";\n } else {\n delete contentVideo.dataset.stormcloudAdPlaying;\n }\n }\n function setupAdEventListeners() {\n if (!adVideoElement || !currentAd) return;\n const ad = currentAd;\n adVideoElement.addEventListener(\"timeupdate\", () => {\n if (!ad || !adVideoElement) return;\n const progress = adVideoElement.currentTime / ad.duration;\n if (progress >= 0.25 && !trackingFired.firstQuartile) {\n trackingFired.firstQuartile = true;\n fireTrackingPixels(ad.trackingUrls.firstQuartile);\n }\n if (progress >= 0.5 && !trackingFired.midpoint) {\n trackingFired.midpoint = true;\n fireTrackingPixels(ad.trackingUrls.midpoint);\n }\n if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n trackingFired.thirdQuartile = true;\n fireTrackingPixels(ad.trackingUrls.thirdQuartile);\n }\n });\n adVideoElement.addEventListener(\"playing\", () => {\n if (!ad || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels(ad.trackingUrls.start);\n log(\"Ad started playing\");\n });\n adVideoElement.addEventListener(\"ended\", () => {\n if (!ad || trackingFired.complete) return;\n trackingFired.complete = true;\n fireTrackingPixels(ad.trackingUrls.complete);\n log(\"Ad completed\");\n handleAdComplete();\n });\n adVideoElement.addEventListener(\"error\", (e) => {\n console.error(\"[AdStormPlayer] Ad video error:\", e);\n if (ad) {\n fireTrackingPixels(ad.trackingUrls.error);\n }\n handleAdError();\n });\n }\n function handleAdComplete() {\n log(\"Handling ad completion\");\n adPlaying = false;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n emit(\"content_resume\");\n emit(\"all_ads_completed\");\n }\n function handleAdError() {\n log(\"Handling ad error\");\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n emit(\"ad_error\");\n }\n async function fetchVast(durationSeconds) {\n const vastUrl = buildVastUrl(durationSeconds);\n log(\"Fetching VAST from:\", vastUrl);\n const response = await fetch(vastUrl, {\n headers: {\n \"Accept\": \"application/xml\"\n }\n });\n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.status} ${response.statusText}`);\n }\n const xmlText = await response.text();\n log(\"VAST response received, length:\", xmlText.length);\n return parseVastXml(xmlText);\n }\n return {\n initialize() {\n log(\"Initializing\");\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n container.style.transition = \"opacity 0.3s ease-in-out\";\n container.style.opacity = \"0\";\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n },\n async requestAds(duration) {\n log(\"Requesting ads for duration:\", duration);\n if (adPlaying) {\n return Promise.reject(new Error(\"Ad already playing\"));\n }\n try {\n let durationSeconds = 30;\n const parsed = parseInt(duration, 10);\n if (!isNaN(parsed) && parsed > 0) {\n durationSeconds = parsed;\n }\n const ads = await fetchVast(durationSeconds);\n if (ads.length === 0) {\n log(\"No ads available from VAST response\");\n emit(\"ad_error\");\n return Promise.resolve();\n }\n currentAd = ads[0];\n log(`Ad loaded: ${currentAd.title}, duration: ${currentAd.duration}s`);\n fireTrackingPixels(currentAd.trackingUrls.impression);\n trackingFired.impression = true;\n return Promise.resolve();\n } catch (error) {\n console.error(\"[AdStormPlayer] Error requesting ads:\", error);\n emit(\"ad_error\");\n return Promise.reject(error);\n }\n },\n async play() {\n if (!currentAd) {\n return Promise.reject(new Error(\"No ad loaded\"));\n }\n log(\"Starting ad playback\");\n try {\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl?.appendChild(adVideoElement);\n setupAdEventListeners();\n }\n trackingFired = {\n impression: trackingFired.impression,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false\n };\n contentVideo.style.transition = \"opacity 0.3s ease-in-out\";\n contentVideo.style.opacity = \"0\";\n setTimeout(() => {\n contentVideo.style.visibility = \"hidden\";\n }, 300);\n contentVideo.muted = true;\n contentVideo.volume = 0;\n if (allowNativeHls) {\n contentVideo.pause();\n }\n adPlaying = true;\n setAdPlayingFlag(true);\n if (adVideoElement) {\n adVideoElement.volume = originalMutedState ? 0 : originalVolume;\n adVideoElement.muted = originalMutedState;\n }\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n adContainerEl.offsetHeight;\n adContainerEl.style.opacity = \"1\";\n }\n emit(\"content_pause\");\n const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n if (!mediaFile) {\n throw new Error(\"No media file available\");\n }\n log(\"Playing media file:\", mediaFile.url);\n adVideoElement.src = mediaFile.url;\n await adVideoElement.play();\n return Promise.resolve();\n } catch (error) {\n console.error(\"[AdStormPlayer] Error playing ad:\", error);\n handleAdError();\n return Promise.reject(error);\n }\n },\n async stop() {\n log(\"Stopping ad\");\n adPlaying = false;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n }\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n currentAd = void 0;\n },\n destroy() {\n log(\"Destroying\");\n destroyed = true;\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n adVideoElement.remove();\n adVideoElement = void 0;\n }\n if (adContainerEl?.parentElement) {\n adContainerEl.parentElement.removeChild(adContainerEl);\n }\n adContainerEl = void 0;\n currentAd = void 0;\n listeners.clear();\n },\n isAdPlaying() {\n return adPlaying;\n },\n resize(width, height) {\n log(`Resizing to ${width}x${height}`);\n if (adContainerEl) {\n adContainerEl.style.width = `${width}px`;\n adContainerEl.style.height = `${height}px`;\n }\n if (adVideoElement) {\n adVideoElement.style.width = `${width}px`;\n adVideoElement.style.height = `${height}px`;\n }\n },\n on(event, listener) {\n if (!listeners.has(event)) listeners.set(event, /* @__PURE__ */ new Set());\n listeners.get(event).add(listener);\n },\n off(event, listener) {\n listeners.get(event)?.delete(listener);\n },\n updateOriginalMutedState(muted, volume) {\n const nextVolume = typeof volume === \"number\" && !Number.isNaN(volume) ? Math.max(0, Math.min(1, volume)) : originalVolume;\n log(`updateOriginalMutedState: muted=${muted}, volume=${nextVolume}`);\n originalMutedState = muted;\n originalVolume = nextVolume;\n },\n getOriginalMutedState() {\n return originalMutedState;\n },\n getOriginalVolume() {\n return originalVolume;\n },\n setAdVolume(volume) {\n if (adVideoElement && adPlaying) {\n adVideoElement.volume = Math.max(0, Math.min(1, volume));\n adVideoElement.muted = volume === 0;\n }\n },\n getAdVolume() {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n showPlaceholder() {\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.opacity = \"1\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n },\n hidePlaceholder() {\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n },\n setAllowNativeHls(value) {\n allowNativeHls = value;\n log(`allowNativeHls set to: ${value}`);\n }\n };\n}\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n createAdStormPlayer\n});\n","import type { AdController } from \"../types\";\n\ninterface VastMediaFile {\n url: string;\n type: string;\n width: number;\n height: number;\n bitrate?: number | undefined;\n}\n\nconst SUPPORTED_VIDEO_EXTENSIONS = ['.mp4', '.webm', '.ogg', '.m3u8', '.ts'];\nconst UNSUPPORTED_VIDEO_EXTENSIONS = ['.flv', '.f4v', '.swf', '.wmv', '.avi', '.mov', '.mkv'];\n\nfunction getFileExtension(url: string): string {\n try {\n const pathname = new URL(url, 'http://dummy').pathname;\n const lastDot = pathname.lastIndexOf('.');\n if (lastDot === -1) return '';\n return pathname.slice(lastDot).toLowerCase();\n } catch {\n const lastDot = url.lastIndexOf('.');\n if (lastDot === -1) return '';\n const ext = url.slice(lastDot).split(/[?#]/)[0];\n return (ext || '').toLowerCase();\n }\n}\n\nfunction isUnsupportedFormat(url: string): boolean {\n const ext = getFileExtension(url);\n return UNSUPPORTED_VIDEO_EXTENSIONS.indexOf(ext) !== -1;\n}\n\nfunction replaceFlvExtension(url: string): string {\n const ext = getFileExtension(url);\n if (ext === '.flv') {\n return url.replace(/\\.flv(\\?|$)/i, '.mp4$1');\n }\n return url;\n}\n\nfunction isSupportedFormat(url: string, mimeType: string): boolean {\n if (isUnsupportedFormat(url)) {\n return false;\n }\n \n const ext = getFileExtension(url);\n \n if (SUPPORTED_VIDEO_EXTENSIONS.indexOf(ext) !== -1) {\n return true;\n }\n \n if (ext === '' || ext === '.') {\n return mimeType.includes('video/mp4') || \n mimeType.includes('video/webm') || \n mimeType.includes('m3u8') ||\n mimeType.includes('application/x-mpegurl');\n }\n \n return false;\n}\n\ninterface VastTrackingUrls {\n impression: string[];\n start: string[];\n firstQuartile: string[];\n midpoint: string[];\n thirdQuartile: string[];\n complete: string[];\n error: string[];\n}\n\ninterface VastAd {\n id: string;\n title: string;\n duration: number;\n mediaFiles: VastMediaFile[];\n trackingUrls: VastTrackingUrls;\n clickThrough?: string | undefined;\n}\n\ninterface AdStormMetadata {\n video?: {\n codec?: string;\n width?: number;\n height?: number;\n fps?: number;\n bitrate?: number;\n profile?: string;\n pix_fmt?: string;\n has_b_frames?: number;\n };\n audio?: {\n codec?: string;\n sample_rate?: number;\n bitrate?: number;\n };\n}\n\nexport interface AdStormPlayerOptions {\n licenseKey: string;\n debug?: boolean;\n}\n\nexport function createAdStormPlayer(\n contentVideo: HTMLVideoElement,\n options: AdStormPlayerOptions\n): AdController {\n const { licenseKey, debug = false } = options;\n \n let adPlaying = false;\n let originalMutedState = false;\n let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));\n const listeners = new Map<string, Set<(payload?: any) => void>>();\n \n let adVideoElement: HTMLVideoElement | undefined;\n let adContainerEl: HTMLDivElement | undefined;\n let currentAd: VastAd | undefined;\n let destroyed = false;\n let allowNativeHls = false;\n \n let trackingFired = {\n impression: false,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false,\n };\n\n function log(...args: any[]): void {\n if (debug) {\n console.log(\"[AdStormPlayer]\", ...args);\n }\n }\n\n function emit(event: string, payload?: any): void {\n const set = listeners.get(event);\n if (!set) return;\n for (const fn of Array.from(set)) {\n try {\n fn(payload);\n } catch (error) {\n console.warn(`[AdStormPlayer] Error in event listener for ${event}:`, error);\n }\n }\n }\n\n function fireTrackingPixels(urls: string[]): void {\n if (!urls || urls.length === 0) return;\n \n urls.forEach((url) => {\n try {\n const img = new Image(1, 1);\n img.src = url;\n log(\"Fired tracking pixel:\", url);\n } catch (error) {\n console.warn(\"[AdStormPlayer] Error firing tracking pixel:\", error);\n }\n });\n }\n\n function buildVastUrl(durationSeconds: number, metadata?: AdStormMetadata): string {\n const baseUrl = `https://adstorm.co/api-adstorm-dev/adstorm/vast/${licenseKey}/pod`;\n \n const defaultMetadata: AdStormMetadata = {\n video: {\n codec: \"h264\",\n width: contentVideo.videoWidth || 1280,\n height: contentVideo.videoHeight || 720,\n fps: 29.97,\n bitrate: 5000,\n profile: \"high\",\n pix_fmt: \"yuv420p\",\n has_b_frames: 0,\n },\n audio: {\n codec: \"aac\",\n sample_rate: 48000,\n bitrate: 128,\n },\n };\n \n const finalMetadata = metadata || defaultMetadata;\n const metadataStr = encodeURIComponent(JSON.stringify(finalMetadata));\n \n return `${baseUrl}?duration=${Math.ceil(durationSeconds)}&metadata=${metadataStr}`;\n }\n\n function parseVastXml(xmlString: string): VastAd[] {\n const ads: VastAd[] = [];\n \n try {\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n \n const parserError = xmlDoc.querySelector(\"parsererror\");\n if (parserError) {\n console.error(\"[AdStormPlayer] XML parsing error:\", parserError.textContent);\n return [];\n }\n \n const adElements = xmlDoc.querySelectorAll(\"Ad\");\n \n adElements.forEach((adElement) => {\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = adElement.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n \n const durationText = adElement.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n const durationParts = durationText.split(\":\");\n const duration =\n parseInt(durationParts[0] || \"0\", 10) * 3600 +\n parseInt(durationParts[1] || \"0\", 10) * 60 +\n parseFloat(durationParts[2] || \"0\");\n \n const mediaFileElements = adElement.querySelectorAll(\"MediaFile\");\n const mediaFiles: VastMediaFile[] = [];\n \n mediaFileElements.forEach((mf) => {\n const type = mf.getAttribute(\"type\") || \"\";\n let url = mf.textContent?.trim() || \"\";\n const width = parseInt(mf.getAttribute(\"width\") || \"1920\", 10);\n const height = parseInt(mf.getAttribute(\"height\") || \"1080\", 10);\n const bitrate = mf.getAttribute(\"bitrate\") \n ? parseInt(mf.getAttribute(\"bitrate\")!, 10) \n : undefined;\n \n if (!url) {\n log(`Skipping empty MediaFile URL`);\n return;\n }\n \n const originalUrl = url;\n url = replaceFlvExtension(url);\n if (url !== originalUrl) {\n log(`Converted FLV to MP4: ${originalUrl} -> ${url}`);\n }\n \n if (isUnsupportedFormat(url)) {\n const ext = getFileExtension(url);\n log(`Skipping unsupported format: ${url} (extension: ${ext}, declared type: ${type})`);\n return;\n }\n \n if (isSupportedFormat(url, type)) {\n mediaFiles.push({ url, type, width, height, bitrate });\n log(`Found media file: ${url} (${type}, ${width}x${height})`);\n } else {\n log(`Skipping incompatible media file: ${url} (type: ${type})`);\n }\n });\n \n if (mediaFiles.length === 0) {\n log(\"No valid media files found in ad:\", adId);\n return;\n }\n \n const trackingUrls: VastTrackingUrls = {\n impression: [],\n start: [],\n firstQuartile: [],\n midpoint: [],\n thirdQuartile: [],\n complete: [],\n error: [],\n };\n \n adElement.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n \n adElement.querySelectorAll(\"Tracking\").forEach((el) => {\n const event = el.getAttribute(\"event\");\n const url = el.textContent?.trim();\n if (event && url) {\n const eventKey = event as keyof VastTrackingUrls;\n if (trackingUrls[eventKey]) {\n trackingUrls[eventKey].push(url);\n }\n }\n });\n \n const clickThrough = adElement.querySelector(\"ClickThrough\")?.textContent?.trim();\n \n ads.push({\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough,\n });\n \n log(`Parsed ad: ${title}, duration: ${duration}s, media files: ${mediaFiles.length}`);\n });\n \n } catch (error) {\n console.error(\"[AdStormPlayer] Error parsing VAST XML:\", error);\n }\n \n return ads;\n }\n\n function selectBestMediaFile(mediaFiles: VastMediaFile[]): VastMediaFile | null {\n if (mediaFiles.length === 0) return null;\n if (mediaFiles.length === 1) return mediaFiles[0]!;\n \n const mp4Files = mediaFiles.filter(mf => mf.type.includes(\"video/mp4\"));\n const candidates = mp4Files.length > 0 ? mp4Files : mediaFiles;\n \n const targetWidth = contentVideo.videoWidth || 1280;\n const targetHeight = contentVideo.videoHeight || 720;\n \n candidates.sort((a, b) => {\n const diffA = Math.abs(a.width - targetWidth) + Math.abs(a.height - targetHeight);\n const diffB = Math.abs(b.width - targetWidth) + Math.abs(b.height - targetHeight);\n return diffA - diffB;\n });\n \n return candidates[0] || null;\n }\n\n function createAdVideoElement(): HTMLVideoElement {\n const video = document.createElement(\"video\");\n video.style.position = \"absolute\";\n video.style.left = \"0\";\n video.style.top = \"0\";\n video.style.width = \"100%\";\n video.style.height = \"100%\";\n video.style.objectFit = \"contain\";\n video.style.backgroundColor = \"#000\";\n video.style.zIndex = \"15\";\n video.playsInline = true;\n video.muted = false;\n video.volume = originalMutedState ? 0 : originalVolume;\n \n return video;\n }\n\n function setAdPlayingFlag(isPlaying: boolean): void {\n if (isPlaying) {\n contentVideo.dataset.stormcloudAdPlaying = \"true\";\n } else {\n delete contentVideo.dataset.stormcloudAdPlaying;\n }\n }\n\n function setupAdEventListeners(): void {\n if (!adVideoElement || !currentAd) return;\n \n const ad = currentAd;\n \n adVideoElement.addEventListener(\"timeupdate\", () => {\n if (!ad || !adVideoElement) return;\n \n const progress = adVideoElement.currentTime / ad.duration;\n \n if (progress >= 0.25 && !trackingFired.firstQuartile) {\n trackingFired.firstQuartile = true;\n fireTrackingPixels(ad.trackingUrls.firstQuartile);\n }\n \n if (progress >= 0.5 && !trackingFired.midpoint) {\n trackingFired.midpoint = true;\n fireTrackingPixels(ad.trackingUrls.midpoint);\n }\n \n if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n trackingFired.thirdQuartile = true;\n fireTrackingPixels(ad.trackingUrls.thirdQuartile);\n }\n });\n \n adVideoElement.addEventListener(\"playing\", () => {\n if (!ad || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels(ad.trackingUrls.start);\n log(\"Ad started playing\");\n });\n \n adVideoElement.addEventListener(\"ended\", () => {\n if (!ad || trackingFired.complete) return;\n trackingFired.complete = true;\n fireTrackingPixels(ad.trackingUrls.complete);\n log(\"Ad completed\");\n handleAdComplete();\n });\n \n adVideoElement.addEventListener(\"error\", (e) => {\n console.error(\"[AdStormPlayer] Ad video error:\", e);\n if (ad) {\n fireTrackingPixels(ad.trackingUrls.error);\n }\n handleAdError();\n });\n }\n\n function handleAdComplete(): void {\n log(\"Handling ad completion\");\n adPlaying = false;\n setAdPlayingFlag(false);\n \n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n \n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n \n emit(\"content_resume\");\n emit(\"all_ads_completed\");\n }\n\n function handleAdError(): void {\n log(\"Handling ad error\");\n adPlaying = false;\n setAdPlayingFlag(false);\n \n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n \n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n \n emit(\"ad_error\");\n }\n\n async function fetchVast(durationSeconds: number): Promise<VastAd[]> {\n const vastUrl = buildVastUrl(durationSeconds);\n log(\"Fetching VAST from:\", vastUrl);\n \n const response = await fetch(vastUrl, {\n headers: {\n \"Accept\": \"application/xml\",\n },\n });\n \n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.status} ${response.statusText}`);\n }\n \n const xmlText = await response.text();\n log(\"VAST response received, length:\", xmlText.length);\n \n return parseVastXml(xmlText);\n }\n\n return {\n initialize() {\n log(\"Initializing\");\n \n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n container.style.transition = \"opacity 0.3s ease-in-out\";\n container.style.opacity = \"0\";\n \n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n },\n\n async requestAds(duration: string) {\n log(\"Requesting ads for duration:\", duration);\n \n if (adPlaying) {\n return Promise.reject(new Error(\"Ad already playing\"));\n }\n \n try {\n let durationSeconds = 30;\n const parsed = parseInt(duration, 10);\n if (!isNaN(parsed) && parsed > 0) {\n durationSeconds = parsed;\n }\n \n const ads = await fetchVast(durationSeconds);\n \n if (ads.length === 0) {\n log(\"No ads available from VAST response\");\n emit(\"ad_error\");\n return Promise.resolve();\n }\n \n currentAd = ads[0];\n log(`Ad loaded: ${currentAd!.title}, duration: ${currentAd!.duration}s`);\n \n fireTrackingPixels(currentAd!.trackingUrls.impression);\n trackingFired.impression = true;\n \n return Promise.resolve();\n } catch (error) {\n console.error(\"[AdStormPlayer] Error requesting ads:\", error);\n emit(\"ad_error\");\n return Promise.reject(error);\n }\n },\n\n async play() {\n if (!currentAd) {\n return Promise.reject(new Error(\"No ad loaded\"));\n }\n \n log(\"Starting ad playback\");\n \n try {\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl?.appendChild(adVideoElement);\n setupAdEventListeners();\n }\n \n trackingFired = {\n impression: trackingFired.impression,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false,\n };\n \n contentVideo.style.transition = \"opacity 0.3s ease-in-out\";\n contentVideo.style.opacity = \"0\";\n setTimeout(() => {\n contentVideo.style.visibility = \"hidden\";\n }, 300);\n contentVideo.muted = true;\n contentVideo.volume = 0;\n \n if (allowNativeHls) {\n contentVideo.pause();\n }\n \n adPlaying = true;\n setAdPlayingFlag(true);\n \n if (adVideoElement) {\n adVideoElement.volume = originalMutedState ? 0 : originalVolume;\n adVideoElement.muted = originalMutedState;\n }\n \n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n adContainerEl.offsetHeight;\n adContainerEl.style.opacity = \"1\";\n }\n \n emit(\"content_pause\");\n \n const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n if (!mediaFile) {\n throw new Error(\"No media file available\");\n }\n \n log(\"Playing media file:\", mediaFile.url);\n adVideoElement!.src = mediaFile.url;\n \n await adVideoElement!.play();\n \n return Promise.resolve();\n } catch (error) {\n console.error(\"[AdStormPlayer] Error playing ad:\", error);\n handleAdError();\n return Promise.reject(error);\n }\n },\n\n async stop() {\n log(\"Stopping ad\");\n adPlaying = false;\n setAdPlayingFlag(false);\n \n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n \n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n }\n \n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n \n currentAd = undefined;\n },\n\n destroy() {\n log(\"Destroying\");\n destroyed = true;\n adPlaying = false;\n setAdPlayingFlag(false);\n \n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n \n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n adVideoElement.remove();\n adVideoElement = undefined;\n }\n \n if (adContainerEl?.parentElement) {\n adContainerEl.parentElement.removeChild(adContainerEl);\n }\n \n adContainerEl = undefined;\n currentAd = undefined;\n listeners.clear();\n },\n\n isAdPlaying() {\n return adPlaying;\n },\n\n resize(width: number, height: number) {\n log(`Resizing to ${width}x${height}`);\n \n if (adContainerEl) {\n adContainerEl.style.width = `${width}px`;\n adContainerEl.style.height = `${height}px`;\n }\n \n if (adVideoElement) {\n adVideoElement.style.width = `${width}px`;\n adVideoElement.style.height = `${height}px`;\n }\n },\n\n on(event: string, listener: (payload?: any) => void) {\n if (!listeners.has(event)) listeners.set(event, new Set());\n listeners.get(event)!.add(listener);\n },\n\n off(event: string, listener: (payload?: any) => void) {\n listeners.get(event)?.delete(listener);\n },\n\n updateOriginalMutedState(muted: boolean, volume?: number) {\n const nextVolume =\n typeof volume === \"number\" && !Number.isNaN(volume)\n ? Math.max(0, Math.min(1, volume))\n : originalVolume;\n log(`updateOriginalMutedState: muted=${muted}, volume=${nextVolume}`);\n originalMutedState = muted;\n originalVolume = nextVolume;\n },\n\n getOriginalMutedState() {\n return originalMutedState;\n },\n\n getOriginalVolume() {\n return originalVolume;\n },\n\n setAdVolume(volume: number) {\n if (adVideoElement && adPlaying) {\n adVideoElement.volume = Math.max(0, Math.min(1, volume));\n adVideoElement.muted = volume === 0;\n }\n },\n\n getAdVolume(): number {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n\n showPlaceholder() {\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n \n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n \n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.opacity = \"1\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n },\n\n hidePlaceholder() {\n if (adContainerEl) {\n adContainerEl.style.opacity = \"0\";\n setTimeout(() => {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n }, 300);\n }\n },\n\n setAllowNativeHls(value: boolean) {\n allowNativeHls = value;\n log(`allowNativeHls set to: ${value}`);\n },\n };\n}\n\n"]}
|
package/lib/sdk/hlsAdPlayer.cjs
CHANGED
|
@@ -229,6 +229,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
229
229
|
var adPlaying = false;
|
|
230
230
|
var originalMutedState = false;
|
|
231
231
|
var originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));
|
|
232
|
+
var allowNativeHls = false;
|
|
232
233
|
var listeners = /* @__PURE__ */ new Map();
|
|
233
234
|
var licenseKey = options === null || options === void 0 ? void 0 : options.licenseKey;
|
|
234
235
|
var mainHlsInstance = options === null || options === void 0 ? void 0 : options.mainHlsInstance;
|
|
@@ -996,6 +997,9 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
996
997
|
adContainerEl.style.display = "none";
|
|
997
998
|
adContainerEl.style.pointerEvents = "none";
|
|
998
999
|
}
|
|
1000
|
+
},
|
|
1001
|
+
setAllowNativeHls: function setAllowNativeHls(value) {
|
|
1002
|
+
allowNativeHls = value;
|
|
999
1003
|
}
|
|
1000
1004
|
};
|
|
1001
1005
|
}
|