stormcloud-video-player 0.7.2 → 0.7.4
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 +1026 -1224
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +35 -49
- package/lib/index.d.ts +35 -49
- package/lib/index.js +1024 -1218
- package/lib/index.js.map +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +1000 -1213
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/player/StormcloudVideoPlayer.d.cts +5 -2
- package/lib/players/HlsPlayer.cjs +1000 -1213
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/HlsPlayer.d.cts +1 -1
- package/lib/players/index.cjs +1000 -1213
- package/lib/players/index.cjs.map +1 -1
- package/lib/sdk/adstormPlayer.cjs +1573 -0
- package/lib/sdk/adstormPlayer.cjs.map +1 -0
- package/lib/sdk/adstormPlayer.d.cts +22 -0
- package/lib/{types-BYwfSJb5.d.cts → types-vCa10HuQ.d.cts} +21 -27
- package/lib/ui/StormcloudVideoPlayer.cjs +1022 -1216
- 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
- package/lib/sdk/vastAdLayer.cjs +0 -1620
- package/lib/sdk/vastAdLayer.cjs.map +0 -1
- package/lib/sdk/vastAdLayer.d.cts +0 -42
- package/lib/sdk/vastManager.cjs +0 -627
- package/lib/sdk/vastManager.cjs.map +0 -1
- package/lib/sdk/vastManager.d.cts +0 -8
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/sdk/vastAdLayer.cjs","../../src/sdk/vastAdLayer.ts","../../src/sdk/vastParser.ts"],"names":["__create","Object","create","__defProp","defineProperty","__getOwnPropDesc","getOwnPropertyDescriptor","__getOwnPropNames","getOwnPropertyNames","__getProtoOf","getPrototypeOf","__hasOwnProp","hasOwnProperty","prototype","__export","target","all","name","get","enumerable","__copyProps","from","to","except","desc","key","call","__toESM","mod","isNodeMode","__esModule","value","__toCommonJS","vastAdLayer_exports","createVastAdLayer","module","exports","isHlsType","type","includes","isMp4Type","parseVastXml","xmlString","filter","logPrefix","xmlDoc","parser","DOMParser","parseFromString","parserError","querySelector","console","error","textContent","adElement","warn","adId","getAttribute","title","isNoAdAvailable","toLowerCase","durationText","durationParts","split","duration","parseInt","Math","round","parseFloat","mediaFileElements","querySelectorAll","mediaFiles","log","length","forEach","mf","index","url","trim","width","height","substring","isHls","isMp4","accepted","bitrateAttr","bitrateValue","push","bitrate","sort","a","b","aIsMp4","bIsMp4","trackingUrls","impression","start","firstQuartile","midpoint","thirdQuartile","complete","mute","unmute","pause","resume","fullscreen","exitFullscreen","skip","el","event","eventKey","clickThrough","id","fetchAndParseVastAd","vastTagUrl","response","vastXml","fetch","mode","credentials","headers","Accept","referrerPolicy","ok","Error","statusText","text","createEmptyTrackingState","firePixelWithRetry","retries","delayMs","attempt","method","cache","keepalive","Promise","r","setTimeout","pow","fireTrackingPixels","urls","sessionId","trackingUrl","catch","img","Image","onerror","src","import_hls","require","LOG","resolveBidToVastAd","winner","ad","resolve","vastUrl","contentVideo","options","adPlaying","originalMutedState","originalVolume","max","min","volume","listeners","Map","mainHlsInstance","continueLiveStreamDuringAds","smartTVMode","singleElementMode","forceMP4Ads","destroyed","savedContentVideoStyles","currentLevel","mp4Only","firstFile","debug","adVideoElement","adHls","adContainerEl","currentAd","tornDown","trackingFired","adStallTimerId","currentAdEventHandlers","preloadSlots","emit","payload","set","Array","fn","generateSessionId","Date","now","random","toString","substr","getMainStreamQuality","levels","autoLevel","loadLevel","level","selectBestMediaFile","scoredFiles","candidates","f","isHlsMediaFile","mainQuality","map","file","widthDiff","abs","heightDiff","resolutionDiff","fileBitrate","bitrateDiff","score","video","style","clearAdStallTimer","createAdVideoElement","document","createElement","position","left","top","objectFit","backgroundColor","playsInline","muted","clearTimeout","removeAdEventListeners","removeEventListener","timeupdate","playing","ended","volumechange","play","waiting","setupAdEventListeners","handlers","progress","currentTime","handleAdError","addEventListener","handleAdComplete","e","setAdPlayingFlag","isPlaying","dataset","stormcloudAdPlaying","applyContentVideoAdCoverStyles","restoreContentVideoStyles","display","pointerEvents","teardownCurrentPlayback","destroy","removeAttribute","load","startNativePlayback","mediaFile","startHlsPlayback","Hls","isSupported","enableWorker","lowLatencyMode","loadSource","attachMedia","on","Events","MANIFEST_PARSED","nonFatalNetworkErrors","ERROR","_event","data","fatal","ErrorTypes","NETWORK_ERROR","canPlayType","startPlayback","mp4Fallback","find","playAd","bids","contentVolume","adVolume","container","reject","bidder","cpm","toFixed","currency","detachMedia","visibility","opacity","right","bottom","alignItems","justifyContent","zIndex","parentElement","appendChild"],"mappings":"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","sourcesContent":["\"use strict\";\nvar __create = Object.create;\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __getProtoOf = Object.getPrototypeOf;\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 __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(\n // If the importer is in node compatibility mode or this is not an ESM\n // file that has been converted to a CommonJS file using a Babel-\n // compatible transform (i.e. \"__esModule\" has not been set), then set\n // \"default\" to the CommonJS \"module.exports\" for node compatibility.\n isNodeMode || !mod || !mod.__esModule ? __defProp(target, \"default\", { value: mod, enumerable: true }) : target,\n mod\n));\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n// src/sdk/vastAdLayer.ts\nvar vastAdLayer_exports = {};\n__export(vastAdLayer_exports, {\n createVastAdLayer: () => createVastAdLayer\n});\nmodule.exports = __toCommonJS(vastAdLayer_exports);\n\n// src/sdk/vastParser.ts\nfunction isHlsType(type) {\n return type === \"application/x-mpegURL\" || type.includes(\"m3u8\");\n}\nfunction isMp4Type(type) {\n return type === \"video/mp4\" || type.includes(\"mp4\");\n}\nfunction parseVastXml(xmlString, filter = \"all\", logPrefix = \"[VastParser]\") {\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(\n `${logPrefix} XML parsing error (malformed VAST XML):`,\n parserError.textContent\n );\n return null;\n }\n const adElement = xmlDoc.querySelector(\"Ad\");\n if (!adElement) {\n console.warn(`${logPrefix} No Ad element found in VAST XML`);\n return null;\n }\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n const isNoAdAvailable = adId === \"empty\" || title.toLowerCase().includes(\"no ad available\") || title.toLowerCase() === \"no ad available\";\n const durationText = xmlDoc.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 + Math.round(parseFloat(durationParts[2] || \"0\"));\n const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n const mediaFiles = [];\n console.log(\n `${logPrefix} Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`\n );\n mediaFileElements.forEach((mf, index) => {\n const type = mf.getAttribute(\"type\") || \"\";\n const url = mf.textContent?.trim() || \"\";\n const width = mf.getAttribute(\"width\") || \"\";\n const height = mf.getAttribute(\"height\") || \"\";\n console.log(\n `${logPrefix} MediaFile ${index}: type=\"${type}\", url=\"${url.substring(0, 80)}...\", width=\"${width}\", height=\"${height}\"`\n );\n if (!url) {\n console.warn(`${logPrefix} MediaFile ${index} has empty URL`);\n return;\n }\n const isHls = isHlsType(type);\n const isMp4 = isMp4Type(type);\n let accepted = false;\n if (filter === \"hls-only\") {\n accepted = isHls;\n } else if (filter === \"mp4-first\") {\n accepted = isMp4 || isHls;\n } else {\n accepted = true;\n }\n if (!accepted) {\n console.log(\n `${logPrefix} MediaFile ${index} ignored (type=\"${type}\" not accepted by filter \"${filter}\")`\n );\n return;\n }\n const bitrateAttr = mf.getAttribute(\"bitrate\");\n const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;\n mediaFiles.push({\n url,\n type,\n width: parseInt(width || \"1920\", 10),\n height: parseInt(height || \"1080\", 10),\n bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : void 0\n });\n console.log(`${logPrefix} Added MediaFile: type=\"${type}\" url=\"${url.substring(0, 80)}...\"`);\n });\n if (filter === \"mp4-first\" && mediaFiles.length > 1) {\n mediaFiles.sort((a, b) => {\n const aIsMp4 = isMp4Type(a.type) ? 0 : 1;\n const bIsMp4 = isMp4Type(b.type) ? 0 : 1;\n return aIsMp4 - bIsMp4;\n });\n }\n if (mediaFiles.length === 0) {\n if (isNoAdAvailable) {\n console.warn(\n `${logPrefix} No ads available (VAST response indicates no ads)`\n );\n } else {\n console.warn(`${logPrefix} No compatible media files found in VAST XML`);\n }\n return null;\n }\n const trackingUrls = {\n impression: [],\n start: [],\n firstQuartile: [],\n midpoint: [],\n thirdQuartile: [],\n complete: [],\n mute: [],\n unmute: [],\n pause: [],\n resume: [],\n fullscreen: [],\n exitFullscreen: [],\n skip: [],\n error: []\n };\n xmlDoc.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n xmlDoc.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 = xmlDoc.querySelector(\"ClickThrough\")?.textContent?.trim();\n return {\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough\n };\n } catch (error) {\n console.error(`${logPrefix} Error parsing VAST XML:`, error);\n return null;\n }\n}\nasync function fetchAndParseVastAd(vastTagUrl, filter = \"all\", logPrefix = \"[VastParser]\") {\n const response = await fetch(vastTagUrl, {\n mode: \"cors\",\n credentials: \"include\",\n headers: {\n Accept: \"application/xml, text/xml, */*\"\n },\n referrerPolicy: \"no-referrer-when-downgrade\"\n });\n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.statusText}`);\n }\n const vastXml = await response.text();\n console.log(`${logPrefix} VAST XML received`);\n console.log(\n `${logPrefix} VAST XML content (first 2000 chars):`,\n vastXml.substring(0, 2e3)\n );\n return parseVastXml(vastXml, filter, logPrefix);\n}\nfunction createEmptyTrackingState() {\n return {\n impression: false,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false\n };\n}\nasync function firePixelWithRetry(url, retries = 2, delayMs = 500, logPrefix = \"[VastParser]\") {\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n await fetch(url, {\n method: \"GET\",\n mode: \"no-cors\",\n cache: \"no-cache\",\n keepalive: true\n });\n return;\n } catch {\n if (attempt < retries) {\n await new Promise((r) => setTimeout(r, delayMs * Math.pow(2, attempt)));\n } else {\n console.warn(`${logPrefix} Tracking pixel failed after ${retries + 1} attempts: ${url}`);\n }\n }\n }\n}\nfunction fireTrackingPixels(urls, sessionId, logPrefix = \"[VastParser]\") {\n if (!urls || urls.length === 0) return;\n urls.forEach((url) => {\n try {\n let trackingUrl = url;\n if (sessionId) {\n trackingUrl = `${trackingUrl}${trackingUrl.includes(\"?\") ? \"&\" : \"?\"}session_id=${sessionId}`;\n }\n if (typeof fetch !== \"undefined\") {\n firePixelWithRetry(trackingUrl, 2, 500, logPrefix).catch(() => {\n });\n } else {\n const img = new Image(1, 1);\n img.onerror = () => {\n };\n img.src = trackingUrl;\n }\n console.log(`${logPrefix} Fired tracking pixel: ${trackingUrl}`);\n } catch (error) {\n console.warn(`${logPrefix} Error firing tracking pixel:`, error);\n }\n });\n}\n\n// src/sdk/vastAdLayer.ts\nvar import_hls = __toESM(require(\"hls.js\"), 1);\nvar LOG = \"[VastAdLayer]\";\nfunction resolveBidToVastAd(winner, logPrefix) {\n if (winner.vastXml) {\n const ad = parseVastXml(winner.vastXml, \"mp4-first\", logPrefix);\n return Promise.resolve(ad);\n }\n if (winner.vastUrl) {\n return fetchAndParseVastAd(winner.vastUrl, \"mp4-first\", logPrefix);\n }\n return Promise.resolve(null);\n}\nfunction createVastAdLayer(contentVideo, 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 mainHlsInstance = options?.mainHlsInstance;\n let continueLiveStreamDuringAds = options?.continueLiveStreamDuringAds ?? false;\n const smartTVMode = options?.smartTVMode ?? false;\n const singleElementMode = options?.singleElementMode ?? false;\n const forceMP4Ads = options?.forceMP4Ads ?? (smartTVMode || singleElementMode);\n const debug = options?.debug ?? false;\n let adVideoElement;\n let adHls;\n let adContainerEl;\n let currentAd;\n let sessionId;\n let destroyed = false;\n let tornDown = false;\n let trackingFired = createEmptyTrackingState();\n let adStallTimerId;\n let savedContentVideoStyles;\n let currentAdEventHandlers;\n const preloadSlots = /* @__PURE__ */ new Map();\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(`${LOG} Error in event listener for ${event}:`, error);\n }\n }\n }\n function generateSessionId() {\n return `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n function fireTrackingPixels2(urls) {\n fireTrackingPixels(urls, sessionId, LOG);\n }\n function getMainStreamQuality() {\n if (!mainHlsInstance?.levels) return null;\n const currentLevel = mainHlsInstance.currentLevel;\n if (currentLevel === -1 || !mainHlsInstance.levels[currentLevel]) {\n const autoLevel = mainHlsInstance.loadLevel;\n if (autoLevel !== -1 && mainHlsInstance.levels[autoLevel]) {\n const level2 = mainHlsInstance.levels[autoLevel];\n return {\n width: level2.width || 1920,\n height: level2.height || 1080,\n bitrate: level2.bitrate || 5e6\n };\n }\n return null;\n }\n const level = mainHlsInstance.levels[currentLevel];\n return {\n width: level.width || 1920,\n height: level.height || 1080,\n bitrate: level.bitrate || 5e6\n };\n }\n function selectBestMediaFile(mediaFiles) {\n if (mediaFiles.length === 0) throw new Error(\"No media files available\");\n let candidates = mediaFiles;\n if (forceMP4Ads) {\n const mp4Only = candidates.filter((f) => !isHlsMediaFile(f));\n if (mp4Only.length > 0) {\n candidates = mp4Only;\n if (debug) console.log(`${LOG} forceMP4Ads: filtered to ${mp4Only.length} MP4-only file(s)`);\n } else if (debug) {\n console.warn(`${LOG} forceMP4Ads: no MP4 files available, falling back to all media files`);\n }\n } else {\n const mp4Only = candidates.filter((f) => !isHlsMediaFile(f));\n if (mp4Only.length > 0) {\n candidates = mp4Only;\n if (debug) console.log(`${LOG} Preferring ${mp4Only.length} MP4 file(s) over HLS (mp4-first)`);\n }\n }\n const firstFile = candidates[0];\n if (candidates.length === 1) return firstFile;\n const mainQuality = getMainStreamQuality();\n if (!mainQuality) {\n if (debug) console.log(`${LOG} No main stream quality info, using first media file`);\n return firstFile;\n }\n const scoredFiles = candidates.map((file) => {\n const widthDiff = Math.abs(file.width - mainQuality.width);\n const heightDiff = Math.abs(file.height - mainQuality.height);\n const resolutionDiff = widthDiff + heightDiff;\n const fileBitrate = (file.bitrate || 5e3) * 1e3;\n const bitrateDiff = Math.abs(fileBitrate - mainQuality.bitrate);\n const score = resolutionDiff * 2 + bitrateDiff / 1e3;\n return { file, score };\n });\n scoredFiles.sort((a, b) => a.score - b.score);\n return scoredFiles[0]?.file ?? firstFile;\n }\n function isHlsMediaFile(file) {\n return file.type === \"application/x-mpegURL\" || file.type.includes(\"m3u8\");\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 = \"cover\";\n video.style.backgroundColor = \"#000\";\n video.playsInline = true;\n video.muted = false;\n video.volume = 1;\n return video;\n }\n function clearAdStallTimer() {\n if (adStallTimerId != null) {\n clearTimeout(adStallTimerId);\n adStallTimerId = void 0;\n }\n }\n function removeAdEventListeners() {\n clearAdStallTimer();\n if (!currentAdEventHandlers || !adVideoElement) return;\n const el = adVideoElement;\n el.removeEventListener(\"timeupdate\", currentAdEventHandlers.timeupdate);\n el.removeEventListener(\"playing\", currentAdEventHandlers.playing);\n el.removeEventListener(\"ended\", currentAdEventHandlers.ended);\n el.removeEventListener(\"error\", currentAdEventHandlers.error);\n el.removeEventListener(\"volumechange\", currentAdEventHandlers.volumechange);\n el.removeEventListener(\"pause\", currentAdEventHandlers.pause);\n el.removeEventListener(\"play\", currentAdEventHandlers.play);\n el.removeEventListener(\"waiting\", currentAdEventHandlers.waiting);\n currentAdEventHandlers = void 0;\n }\n function setupAdEventListeners() {\n if (!adVideoElement) return;\n removeAdEventListeners();\n const handlers = {\n timeupdate: () => {\n const ad = currentAd;\n if (!ad || !adVideoElement) return;\n const progress = adVideoElement.currentTime / ad.duration;\n if (progress >= 0.25 && !trackingFired.firstQuartile) {\n trackingFired.firstQuartile = true;\n fireTrackingPixels2(ad.trackingUrls.firstQuartile);\n }\n if (progress >= 0.5 && !trackingFired.midpoint) {\n trackingFired.midpoint = true;\n fireTrackingPixels2(ad.trackingUrls.midpoint);\n }\n if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n trackingFired.thirdQuartile = true;\n fireTrackingPixels2(ad.trackingUrls.thirdQuartile);\n }\n },\n playing: () => {\n clearAdStallTimer();\n const ad = currentAd;\n if (!ad || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels2(ad.trackingUrls.start);\n if (debug) console.log(`${LOG} Ad started playing`);\n },\n ended: () => {\n if (tornDown || !currentAd || trackingFired.complete) return;\n trackingFired.complete = true;\n fireTrackingPixels2(currentAd.trackingUrls.complete);\n if (debug) console.log(`${LOG} Ad completed`);\n handleAdComplete();\n },\n error: (e) => {\n if (tornDown) return;\n console.error(`${LOG} Ad video error:`, e);\n if (currentAd) fireTrackingPixels2(currentAd.trackingUrls.error);\n handleAdError();\n },\n volumechange: () => {\n if (!currentAd || !adVideoElement) return;\n if (adVideoElement.muted) {\n fireTrackingPixels2(currentAd.trackingUrls.mute);\n } else {\n fireTrackingPixels2(currentAd.trackingUrls.unmute);\n }\n },\n pause: () => {\n if (currentAd && adVideoElement && !adVideoElement.ended) {\n fireTrackingPixels2(currentAd.trackingUrls.pause);\n }\n },\n play: () => {\n if (currentAd && adVideoElement && adVideoElement.currentTime > 0) {\n fireTrackingPixels2(currentAd.trackingUrls.resume);\n }\n },\n waiting: () => {\n clearAdStallTimer();\n adStallTimerId = setTimeout(() => {\n adStallTimerId = void 0;\n if (adPlaying) {\n if (debug) console.warn(`${LOG} Ad video stalled for too long, treating as error`);\n handleAdError();\n }\n }, 8e3);\n }\n };\n adVideoElement.addEventListener(\"timeupdate\", handlers.timeupdate);\n adVideoElement.addEventListener(\"playing\", handlers.playing);\n adVideoElement.addEventListener(\"ended\", handlers.ended);\n adVideoElement.addEventListener(\"error\", handlers.error);\n adVideoElement.addEventListener(\"volumechange\", handlers.volumechange);\n adVideoElement.addEventListener(\"pause\", handlers.pause);\n adVideoElement.addEventListener(\"play\", handlers.play);\n adVideoElement.addEventListener(\"waiting\", handlers.waiting);\n currentAdEventHandlers = handlers;\n }\n function setAdPlayingFlag(isPlaying) {\n if (isPlaying) {\n contentVideo.dataset.stormcloudAdPlaying = \"true\";\n } else {\n delete contentVideo.dataset.stormcloudAdPlaying;\n }\n }\n function applyContentVideoAdCoverStyles() {\n if (!singleElementMode) return;\n savedContentVideoStyles = {\n objectFit: contentVideo.style.objectFit,\n width: contentVideo.style.width,\n height: contentVideo.style.height\n };\n contentVideo.style.objectFit = \"cover\";\n contentVideo.style.width = \"100%\";\n contentVideo.style.height = \"100%\";\n }\n function restoreContentVideoStyles() {\n if (!singleElementMode || !savedContentVideoStyles) return;\n contentVideo.style.objectFit = savedContentVideoStyles.objectFit;\n contentVideo.style.width = savedContentVideoStyles.width;\n contentVideo.style.height = savedContentVideoStyles.height;\n savedContentVideoStyles = void 0;\n }\n function handleAdComplete() {\n if (tornDown) return;\n clearAdStallTimer();\n if (debug) console.log(`${LOG} Handling ad completion`);\n adPlaying = false;\n setAdPlayingFlag(false);\n restoreContentVideoStyles();\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n emit(\"ad_impression\");\n emit(\"content_resume\");\n }\n function handleAdError() {\n if (tornDown) return;\n if (!adPlaying) return;\n clearAdStallTimer();\n if (debug) console.log(`${LOG} Handling ad error`);\n adPlaying = false;\n setAdPlayingFlag(false);\n restoreContentVideoStyles();\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n emit(\"ad_error\");\n }\n function teardownCurrentPlayback() {\n removeAdEventListeners();\n if (adHls) {\n adHls.destroy();\n adHls = void 0;\n }\n if (adVideoElement) {\n if (singleElementMode && adVideoElement === contentVideo) {\n contentVideo.pause();\n } else {\n adVideoElement.pause();\n adVideoElement.removeAttribute(\"src\");\n adVideoElement.load();\n }\n }\n }\n function startNativePlayback(mediaFile) {\n if (!adVideoElement) return;\n if (debug) console.log(`${LOG} Starting native MP4 playback: ${mediaFile.url}`);\n adVideoElement.src = mediaFile.url;\n adVideoElement.load();\n adVideoElement.play().catch((error) => {\n console.error(`${LOG} Error starting native ad playback:`, error);\n handleAdError();\n });\n }\n function startHlsPlayback(mediaFile) {\n if (!adVideoElement) return;\n if (debug) console.log(`${LOG} Starting HLS playback: ${mediaFile.url}`);\n if (import_hls.default.isSupported()) {\n if (adHls) {\n adHls.destroy();\n adHls = void 0;\n }\n adHls = new import_hls.default({ enableWorker: true, lowLatencyMode: false });\n adHls.loadSource(mediaFile.url);\n adHls.attachMedia(adVideoElement);\n adHls.on(import_hls.default.Events.MANIFEST_PARSED, () => {\n if (!adPlaying) return;\n adVideoElement.play().catch((error) => {\n console.error(`${LOG} Error starting HLS ad playback:`, error);\n handleAdError();\n });\n });\n let nonFatalNetworkErrors = 0;\n adHls.on(import_hls.default.Events.ERROR, (_event, data) => {\n if (data.fatal) {\n handleAdError();\n } else if (data.type === import_hls.default.ErrorTypes.NETWORK_ERROR) {\n nonFatalNetworkErrors++;\n if (nonFatalNetworkErrors >= 3) {\n if (debug) console.warn(`${LOG} Too many non-fatal HLS network errors (${nonFatalNetworkErrors}), treating as fatal`);\n handleAdError();\n }\n }\n });\n } else if (adVideoElement.canPlayType(\"application/vnd.apple.mpegurl\")) {\n adVideoElement.src = mediaFile.url;\n adVideoElement.play().catch((error) => {\n console.error(`${LOG} Error starting native HLS ad playback:`, error);\n handleAdError();\n });\n } else {\n console.error(`${LOG} HLS not supported on this platform`);\n handleAdError();\n }\n }\n function startPlayback(mediaFile) {\n if (!adVideoElement) return;\n if (singleElementMode && isHlsMediaFile(mediaFile)) {\n const mp4Fallback = currentAd?.mediaFiles.find((f) => !isHlsMediaFile(f));\n if (mp4Fallback) {\n if (debug) console.log(`${LOG} singleElementMode: HLS ad blocked, using MP4 fallback`);\n startNativePlayback(mp4Fallback);\n return;\n }\n }\n if (isHlsMediaFile(mediaFile)) {\n startHlsPlayback(mediaFile);\n } else {\n startNativePlayback(mediaFile);\n }\n }\n async function playAd(bids) {\n if (destroyed) {\n return Promise.reject(new Error(\"Layer has been destroyed\"));\n }\n if (bids.length === 0) {\n return Promise.reject(new Error(\"No bids provided\"));\n }\n const winner = bids[0];\n if (debug) {\n console.log(`${LOG} Winning bid: ${winner.bidder} $${winner.cpm.toFixed(2)} ${winner.currency}`);\n }\n const ad = await resolveBidToVastAd(winner, LOG);\n if (!ad) {\n if (debug) console.warn(`${LOG} Winning bid has no VAST URL or XML`);\n emit(\"ad_error\");\n return Promise.reject(new Error(\"No VAST from bid\"));\n }\n if (debug) {\n console.log(`${LOG} Ad parsed: ${ad.title}, duration: ${ad.duration}s, mediaFiles: ${ad.mediaFiles.length}`);\n }\n sessionId = generateSessionId();\n currentAd = ad;\n trackingFired = { ...createEmptyTrackingState() };\n fireTrackingPixels2(ad.trackingUrls.impression);\n trackingFired.impression = true;\n const contentVolume = contentVideo.volume;\n originalVolume = Math.max(0, Math.min(1, contentVolume || originalVolume));\n if (singleElementMode) {\n mainHlsInstance?.detachMedia();\n teardownCurrentPlayback();\n adVideoElement = contentVideo;\n adHls = void 0;\n adPlaying = true;\n setAdPlayingFlag(true);\n contentVideo.removeAttribute(\"src\");\n contentVideo.load();\n if (!continueLiveStreamDuringAds) {\n contentVideo.pause();\n }\n contentVideo.muted = true;\n contentVideo.volume = 0;\n await new Promise((resolve) => setTimeout(resolve, 200));\n if (destroyed || tornDown) return;\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n applyContentVideoAdCoverStyles();\n emit(\"content_pause\");\n setupAdEventListeners();\n const adVolume2 = originalMutedState ? 1 : originalVolume;\n adVideoElement.volume = Math.max(0, Math.min(1, adVolume2));\n adVideoElement.muted = false;\n const mediaFile2 = selectBestMediaFile(ad.mediaFiles);\n if (debug) console.log(`${LOG} Loading ad from: ${mediaFile2.url}`);\n startPlayback(mediaFile2);\n return;\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 contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl.appendChild(adVideoElement);\n setupAdEventListeners();\n } else {\n teardownCurrentPlayback();\n }\n if (!continueLiveStreamDuringAds) {\n contentVideo.pause();\n }\n contentVideo.muted = true;\n contentVideo.volume = 0;\n adPlaying = true;\n setAdPlayingFlag(true);\n const adVolume = originalMutedState ? 1 : originalVolume;\n adVideoElement.volume = Math.max(0, Math.min(1, adVolume));\n adVideoElement.muted = false;\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n emit(\"content_pause\");\n const mediaFile = selectBestMediaFile(ad.mediaFiles);\n if (debug) console.log(`${LOG} Loading ad from: ${mediaFile.url}`);\n startPlayback(mediaFile);\n }\n function ensureAdContainer() {\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 return adContainerEl;\n }\n async function preloadAd(bids, token) {\n if (destroyed) return;\n const winner = bids[0];\n if (!winner) return;\n if (debug) console.log(`${LOG} [preload] Resolving VAST for token=${token}`);\n const ad = await resolveBidToVastAd(winner, LOG);\n if (!ad || destroyed) return;\n const mediaFile = selectBestMediaFile(ad.mediaFiles);\n if (!mediaFile) return;\n if (smartTVMode || singleElementMode) {\n const slot = { bids, ad, mediaFile, videoEl: null, ready: true };\n preloadSlots.set(token, slot);\n if (debug) console.log(`${LOG} [preload] Metadata-only preload (smartTV/singleElement), token=${token}, url=${mediaFile.url}`);\n return;\n }\n const videoEl = createAdVideoElement();\n videoEl.style.visibility = \"hidden\";\n videoEl.style.pointerEvents = \"none\";\n videoEl.preload = \"auto\";\n const container = ensureAdContainer();\n container.appendChild(videoEl);\n if (isHlsMediaFile(mediaFile) && import_hls.default.isSupported()) {\n const hls = new import_hls.default({ enableWorker: true, lowLatencyMode: false });\n hls.loadSource(mediaFile.url);\n hls.attachMedia(videoEl);\n const slot = { bids, ad, mediaFile, videoEl, hlsInstance: hls, ready: false };\n preloadSlots.set(token, slot);\n hls.on(import_hls.default.Events.MANIFEST_PARSED, () => {\n const s = preloadSlots.get(token);\n if (s) s.ready = true;\n if (debug) console.log(`${LOG} [preload] HLS manifest parsed, token=${token}`);\n });\n hls.on(import_hls.default.Events.ERROR, (_evt, data) => {\n if (!preloadSlots.has(token)) return;\n if (data.fatal) {\n if (debug) console.warn(`${LOG} [preload] HLS error for token=${token}`);\n preloadSlots.delete(token);\n hls.destroy();\n videoEl.remove();\n }\n });\n } else {\n videoEl.src = mediaFile.url;\n videoEl.load();\n const slot = { bids, ad, mediaFile, videoEl, ready: false };\n preloadSlots.set(token, slot);\n videoEl.addEventListener(\"canplay\", () => {\n const s = preloadSlots.get(token);\n if (s) s.ready = true;\n if (debug) console.log(`${LOG} [preload] canplay fired, token=${token}`);\n }, { once: true });\n }\n if (debug) console.log(`${LOG} [preload] Started buffering token=${token}, url=${mediaFile.url}`);\n }\n async function playPreloaded(token) {\n if (destroyed) return Promise.reject(new Error(\"Layer has been destroyed\"));\n const slot = preloadSlots.get(token);\n if (!slot) {\n if (debug) console.warn(`${LOG} [preload] No slot found for token=${token}, nothing to play`);\n return;\n }\n preloadSlots.delete(token);\n if (debug) console.log(`${LOG} [preload] Playing preloaded ad, token=${token}, ready=${slot.ready}`);\n const contentVolume = contentVideo.volume;\n originalVolume = Math.max(0, Math.min(1, contentVolume || originalVolume));\n sessionId = generateSessionId();\n currentAd = slot.ad;\n trackingFired = { ...createEmptyTrackingState() };\n fireTrackingPixels2(slot.ad.trackingUrls.impression);\n trackingFired.impression = true;\n if (singleElementMode) {\n mainHlsInstance?.detachMedia();\n teardownCurrentPlayback();\n adVideoElement = contentVideo;\n adHls = void 0;\n adPlaying = true;\n setAdPlayingFlag(true);\n contentVideo.removeAttribute(\"src\");\n contentVideo.load();\n contentVideo.muted = true;\n contentVideo.volume = 0;\n await new Promise((resolve) => setTimeout(resolve, 200));\n if (destroyed || tornDown) return;\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n applyContentVideoAdCoverStyles();\n emit(\"content_pause\");\n setupAdEventListeners();\n const adVolume2 = originalMutedState ? 1 : originalVolume;\n contentVideo.volume = Math.max(0, Math.min(1, adVolume2));\n contentVideo.muted = false;\n if (debug) console.log(`${LOG} [preload] singleElementMode: attaching ad to contentVideo, url=${slot.mediaFile.url}`);\n startPlayback(slot.mediaFile);\n return;\n }\n if (smartTVMode && !slot.videoEl) {\n teardownCurrentPlayback();\n if (adVideoElement) {\n adVideoElement.remove();\n adVideoElement = void 0;\n }\n const videoEl = createAdVideoElement();\n videoEl.style.visibility = \"visible\";\n videoEl.style.pointerEvents = \"none\";\n const container2 = ensureAdContainer();\n container2.appendChild(videoEl);\n adVideoElement = videoEl;\n setupAdEventListeners();\n if (!continueLiveStreamDuringAds) {\n contentVideo.pause();\n }\n contentVideo.muted = true;\n contentVideo.volume = 0;\n adPlaying = true;\n setAdPlayingFlag(true);\n const adVolume2 = originalMutedState ? 1 : originalVolume;\n adVideoElement.volume = Math.max(0, Math.min(1, adVolume2));\n adVideoElement.muted = false;\n container2.style.display = \"flex\";\n container2.style.pointerEvents = \"auto\";\n emit(\"content_pause\");\n if (debug) console.log(`${LOG} [preload] smartTVMode deferred: creating video element and loading, url=${slot.mediaFile.url}`);\n startPlayback(slot.mediaFile);\n return;\n }\n teardownCurrentPlayback();\n if (adVideoElement && adVideoElement !== slot.videoEl) {\n adVideoElement.remove();\n }\n slot.videoEl.style.visibility = \"visible\";\n slot.videoEl.style.pointerEvents = \"none\";\n adVideoElement = slot.videoEl;\n adHls = slot.hlsInstance;\n if (adHls) {\n let nonFatalNetworkErrors = 0;\n adHls.on(import_hls.default.Events.ERROR, (_event, data) => {\n if (!adPlaying) return;\n if (data.fatal) {\n handleAdError();\n } else if (data.type === import_hls.default.ErrorTypes.NETWORK_ERROR) {\n nonFatalNetworkErrors++;\n if (nonFatalNetworkErrors >= 3) {\n if (debug) console.warn(`${LOG} [preload] Too many non-fatal HLS network errors during playback, treating as fatal`);\n handleAdError();\n }\n }\n });\n }\n setupAdEventListeners();\n if (!continueLiveStreamDuringAds) {\n contentVideo.pause();\n }\n contentVideo.muted = true;\n contentVideo.volume = 0;\n adPlaying = true;\n setAdPlayingFlag(true);\n const adVolume = originalMutedState ? 1 : originalVolume;\n adVideoElement.volume = Math.max(0, Math.min(1, adVolume));\n adVideoElement.muted = false;\n const container = ensureAdContainer();\n container.style.display = \"flex\";\n container.style.pointerEvents = \"auto\";\n emit(\"content_pause\");\n adVideoElement.play().catch((error) => {\n console.error(`${LOG} [preload] Error playing preloaded ad:`, error);\n handleAdError();\n });\n }\n function cancelPreload(token) {\n const slot = preloadSlots.get(token);\n if (!slot) return;\n preloadSlots.delete(token);\n if (slot.hlsInstance) {\n slot.hlsInstance.destroy();\n }\n if (slot.videoEl) {\n slot.videoEl.pause();\n slot.videoEl.removeAttribute(\"src\");\n slot.videoEl.load();\n slot.videoEl.remove();\n }\n if (debug) console.log(`${LOG} [preload] Cancelled and cleaned up token=${token}`);\n }\n return {\n initialize() {\n if (debug) console.log(`${LOG} Initializing`);\n },\n updateOptions(opts) {\n if (opts.continueLiveStreamDuringAds !== void 0) {\n continueLiveStreamDuringAds = opts.continueLiveStreamDuringAds;\n }\n if (opts.mainHlsInstance !== void 0) {\n mainHlsInstance = opts.mainHlsInstance ?? void 0;\n }\n },\n playAd,\n preloadAd,\n playPreloaded,\n hasPreloaded(token) {\n return preloadSlots.has(token);\n },\n cancelPreload,\n pause() {\n if (!adPlaying || !adVideoElement) return;\n try {\n if (!adVideoElement.paused) adVideoElement.pause();\n } catch (error) {\n if (debug) console.warn(`${LOG} Error pausing ad:`, error);\n }\n },\n resume() {\n if (!adPlaying || !adVideoElement) return;\n try {\n if (adVideoElement.paused) adVideoElement.play().catch(() => {\n });\n } catch (error) {\n if (debug) console.warn(`${LOG} Error resuming ad:`, error);\n }\n },\n async stop() {\n tornDown = true;\n if (debug) console.log(`${LOG} Stopping ad`);\n adPlaying = false;\n setAdPlayingFlag(false);\n restoreContentVideoStyles();\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalMutedState ? 0 : originalVolume;\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n if (singleElementMode) {\n teardownCurrentPlayback();\n contentVideo.removeAttribute(\"src\");\n contentVideo.load();\n adVideoElement = void 0;\n } else {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n if (continueLiveStreamDuringAds) {\n contentVideo.play().catch(() => {\n });\n }\n teardownCurrentPlayback();\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.removeAttribute(\"src\");\n adVideoElement.load();\n }\n }\n currentAd = void 0;\n tornDown = false;\n },\n destroy() {\n tornDown = true;\n if (debug) console.log(`${LOG} Destroying`);\n destroyed = true;\n adPlaying = false;\n setAdPlayingFlag(false);\n restoreContentVideoStyles();\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n for (const [token] of Array.from(preloadSlots.entries())) {\n cancelPreload(token);\n }\n teardownCurrentPlayback();\n if (adVideoElement) {\n if (singleElementMode && adVideoElement === contentVideo) {\n contentVideo.removeAttribute(\"src\");\n contentVideo.load();\n } else {\n adVideoElement.pause();\n adVideoElement.removeAttribute(\"src\");\n adVideoElement.remove();\n }\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 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 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 }\n },\n getAdVolume() {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n showPlaceholder() {\n if (singleElementMode) return;\n contentVideo.style.opacity = \"0\";\n contentVideo.style.visibility = \"hidden\";\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.pointerEvents = \"auto\";\n }\n },\n hidePlaceholder() {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n if (!adPlaying) {\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n }\n }\n };\n}\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n createVastAdLayer\n});\n","import type { VastBidResponse } from \"../types\";\nimport type { VastAd, VastMediaFile } from \"./vastParser\";\nimport {\n parseVastXml,\n fetchAndParseVastAd,\n fireTrackingPixels as fireTrackingPixelsShared,\n createEmptyTrackingState,\n} from \"./vastParser\";\nimport Hls from \"hls.js\";\n\nconst LOG = \"[VastAdLayer]\";\n\nexport interface VastAdLayerOptions {\n continueLiveStreamDuringAds?: boolean;\n mainHlsInstance?: Hls;\n smartTVMode?: boolean;\n singleElementMode?: boolean;\n forceMP4Ads?: boolean;\n debug?: boolean;\n}\n\nexport interface VastAdLayerOptionsUpdate {\n continueLiveStreamDuringAds?: boolean;\n mainHlsInstance?: Hls | null;\n}\n\nexport interface VastAdLayer {\n initialize: () => void;\n updateOptions: (opts: VastAdLayerOptionsUpdate) => void;\n playAd: (bids: VastBidResponse[]) => Promise<void>;\n preloadAd: (bids: VastBidResponse[], token: string) => Promise<void>;\n playPreloaded: (token: string) => Promise<void>;\n hasPreloaded: (token: string) => boolean;\n cancelPreload: (token: string) => void;\n pause: () => void;\n resume: () => void;\n stop: () => Promise<void>;\n destroy: () => void;\n isAdPlaying: () => boolean;\n resize: (width: number, height: number) => void;\n on: (event: string, listener: (payload?: any) => void) => void;\n off: (event: string, listener: (payload?: any) => void) => void;\n updateOriginalMutedState: (muted: boolean, volume?: number) => void;\n getOriginalMutedState: () => boolean;\n getOriginalVolume: () => number;\n setAdVolume: (volume: number) => void;\n getAdVolume: () => number;\n showPlaceholder: () => void;\n hidePlaceholder: () => void;\n}\n\nfunction resolveBidToVastAd(winner: VastBidResponse, logPrefix: string): Promise<VastAd | null> {\n if (winner.vastXml) {\n const ad = parseVastXml(winner.vastXml, \"mp4-first\", logPrefix);\n return Promise.resolve(ad);\n }\n if (winner.vastUrl) {\n return fetchAndParseVastAd(winner.vastUrl, \"mp4-first\", logPrefix);\n }\n return Promise.resolve(null);\n}\n\nexport function createVastAdLayer(\n contentVideo: HTMLVideoElement,\n options?: VastAdLayerOptions\n): VastAdLayer {\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 let mainHlsInstance: Hls | undefined = options?.mainHlsInstance;\n let continueLiveStreamDuringAds = options?.continueLiveStreamDuringAds ?? false;\n const smartTVMode = options?.smartTVMode ?? false;\n const singleElementMode = options?.singleElementMode ?? false;\n const forceMP4Ads = options?.forceMP4Ads ?? (smartTVMode || singleElementMode);\n const debug = options?.debug ?? false;\n\n let adVideoElement: HTMLVideoElement | undefined;\n let adHls: Hls | undefined;\n let adContainerEl: HTMLDivElement | undefined;\n let currentAd: VastAd | undefined;\n let sessionId: string | undefined;\n let destroyed = false;\n let tornDown = false;\n let trackingFired = createEmptyTrackingState();\n let adStallTimerId: ReturnType<typeof setTimeout> | undefined;\n let savedContentVideoStyles: { objectFit: string; width: string; height: string } | undefined;\n\n type AdEventHandlers = {\n timeupdate: () => void;\n playing: () => void;\n ended: () => void;\n error: (e: Event) => void;\n volumechange: () => void;\n pause: () => void;\n play: () => void;\n waiting: () => void;\n };\n let currentAdEventHandlers: AdEventHandlers | undefined;\n\n interface PreloadSlot {\n bids: VastBidResponse[];\n ad: VastAd;\n mediaFile: VastMediaFile;\n videoEl: HTMLVideoElement | null;\n hlsInstance?: Hls;\n ready: boolean;\n }\n const preloadSlots = new Map<string, PreloadSlot>();\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(`${LOG} Error in event listener for ${event}:`, error);\n }\n }\n }\n\n function generateSessionId(): string {\n return `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n\n function fireTrackingPixels(urls: string[]): void {\n fireTrackingPixelsShared(urls, sessionId, LOG);\n }\n\n function getMainStreamQuality(): { width: number; height: number; bitrate: number } | null {\n if (!mainHlsInstance?.levels) return null;\n const currentLevel = mainHlsInstance.currentLevel;\n if (currentLevel === -1 || !mainHlsInstance.levels[currentLevel]) {\n const autoLevel = mainHlsInstance.loadLevel;\n if (autoLevel !== -1 && mainHlsInstance.levels[autoLevel]) {\n const level = mainHlsInstance.levels[autoLevel];\n return {\n width: level.width || 1920,\n height: level.height || 1080,\n bitrate: level.bitrate || 5000000,\n };\n }\n return null;\n }\n const level = mainHlsInstance.levels[currentLevel];\n return {\n width: level.width || 1920,\n height: level.height || 1080,\n bitrate: level.bitrate || 5000000,\n };\n }\n\n function selectBestMediaFile(mediaFiles: VastMediaFile[]): VastMediaFile {\n if (mediaFiles.length === 0) throw new Error(\"No media files available\");\n\n let candidates = mediaFiles;\n if (forceMP4Ads) {\n const mp4Only = candidates.filter(f => !isHlsMediaFile(f));\n if (mp4Only.length > 0) {\n candidates = mp4Only;\n if (debug) console.log(`${LOG} forceMP4Ads: filtered to ${mp4Only.length} MP4-only file(s)`);\n } else if (debug) {\n console.warn(`${LOG} forceMP4Ads: no MP4 files available, falling back to all media files`);\n }\n } else {\n const mp4Only = candidates.filter(f => !isHlsMediaFile(f));\n if (mp4Only.length > 0) {\n candidates = mp4Only;\n if (debug) console.log(`${LOG} Preferring ${mp4Only.length} MP4 file(s) over HLS (mp4-first)`);\n }\n }\n\n const firstFile = candidates[0]!;\n if (candidates.length === 1) return firstFile;\n\n const mainQuality = getMainStreamQuality();\n if (!mainQuality) {\n if (debug) console.log(`${LOG} No main stream quality info, using first media file`);\n return firstFile;\n }\n\n const scoredFiles = candidates.map((file) => {\n const widthDiff = Math.abs(file.width - mainQuality.width);\n const heightDiff = Math.abs(file.height - mainQuality.height);\n const resolutionDiff = widthDiff + heightDiff;\n const fileBitrate = (file.bitrate || 5000) * 1000;\n const bitrateDiff = Math.abs(fileBitrate - mainQuality.bitrate);\n const score = resolutionDiff * 2 + bitrateDiff / 1000;\n return { file, score };\n });\n scoredFiles.sort((a, b) => a.score - b.score);\n return scoredFiles[0]?.file ?? firstFile;\n }\n\n function isHlsMediaFile(file: VastMediaFile): boolean {\n return file.type === \"application/x-mpegURL\" || file.type.includes(\"m3u8\");\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 = \"cover\";\n video.style.backgroundColor = \"#000\";\n video.playsInline = true;\n video.muted = false;\n video.volume = 1.0;\n return video;\n }\n\n function clearAdStallTimer(): void {\n if (adStallTimerId != null) {\n clearTimeout(adStallTimerId);\n adStallTimerId = undefined;\n }\n }\n\n function removeAdEventListeners(): void {\n clearAdStallTimer();\n if (!currentAdEventHandlers || !adVideoElement) return;\n const el = adVideoElement;\n el.removeEventListener(\"timeupdate\", currentAdEventHandlers.timeupdate);\n el.removeEventListener(\"playing\", currentAdEventHandlers.playing);\n el.removeEventListener(\"ended\", currentAdEventHandlers.ended);\n el.removeEventListener(\"error\", currentAdEventHandlers.error);\n el.removeEventListener(\"volumechange\", currentAdEventHandlers.volumechange);\n el.removeEventListener(\"pause\", currentAdEventHandlers.pause);\n el.removeEventListener(\"play\", currentAdEventHandlers.play);\n el.removeEventListener(\"waiting\", currentAdEventHandlers.waiting);\n currentAdEventHandlers = undefined;\n }\n\n function setupAdEventListeners(): void {\n if (!adVideoElement) return;\n\n removeAdEventListeners();\n\n const handlers: AdEventHandlers = {\n timeupdate: () => {\n const ad = currentAd;\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 playing: () => {\n clearAdStallTimer();\n const ad = currentAd;\n if (!ad || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels(ad.trackingUrls.start);\n if (debug) console.log(`${LOG} Ad started playing`);\n },\n ended: () => {\n if (tornDown || !currentAd || trackingFired.complete) return;\n trackingFired.complete = true;\n fireTrackingPixels(currentAd.trackingUrls.complete);\n if (debug) console.log(`${LOG} Ad completed`);\n handleAdComplete();\n },\n error: (e: Event) => {\n if (tornDown) return;\n console.error(`${LOG} Ad video error:`, e);\n if (currentAd) fireTrackingPixels(currentAd.trackingUrls.error);\n handleAdError();\n },\n volumechange: () => {\n if (!currentAd || !adVideoElement) return;\n if (adVideoElement.muted) {\n fireTrackingPixels(currentAd.trackingUrls.mute);\n } else {\n fireTrackingPixels(currentAd.trackingUrls.unmute);\n }\n },\n pause: () => {\n if (currentAd && adVideoElement && !adVideoElement.ended) {\n fireTrackingPixels(currentAd.trackingUrls.pause);\n }\n },\n play: () => {\n if (currentAd && adVideoElement && adVideoElement.currentTime > 0) {\n fireTrackingPixels(currentAd.trackingUrls.resume);\n }\n },\n waiting: () => {\n clearAdStallTimer();\n adStallTimerId = setTimeout(() => {\n adStallTimerId = undefined;\n if (adPlaying) {\n if (debug) console.warn(`${LOG} Ad video stalled for too long, treating as error`);\n handleAdError();\n }\n }, 8000);\n },\n };\n\n adVideoElement.addEventListener(\"timeupdate\", handlers.timeupdate);\n adVideoElement.addEventListener(\"playing\", handlers.playing);\n adVideoElement.addEventListener(\"ended\", handlers.ended);\n adVideoElement.addEventListener(\"error\", handlers.error);\n adVideoElement.addEventListener(\"volumechange\", handlers.volumechange);\n adVideoElement.addEventListener(\"pause\", handlers.pause);\n adVideoElement.addEventListener(\"play\", handlers.play);\n adVideoElement.addEventListener(\"waiting\", handlers.waiting);\n\n currentAdEventHandlers = handlers;\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 applyContentVideoAdCoverStyles(): void {\n if (!singleElementMode) return;\n savedContentVideoStyles = {\n objectFit: contentVideo.style.objectFit,\n width: contentVideo.style.width,\n height: contentVideo.style.height,\n };\n contentVideo.style.objectFit = \"cover\";\n contentVideo.style.width = \"100%\";\n contentVideo.style.height = \"100%\";\n }\n\n function restoreContentVideoStyles(): void {\n if (!singleElementMode || !savedContentVideoStyles) return;\n contentVideo.style.objectFit = savedContentVideoStyles.objectFit;\n contentVideo.style.width = savedContentVideoStyles.width;\n contentVideo.style.height = savedContentVideoStyles.height;\n savedContentVideoStyles = undefined;\n }\n\n function handleAdComplete(): void {\n if (tornDown) return;\n clearAdStallTimer();\n if (debug) console.log(`${LOG} Handling ad completion`);\n adPlaying = false;\n setAdPlayingFlag(false);\n\n restoreContentVideoStyles();\n\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n\n emit(\"ad_impression\");\n emit(\"content_resume\");\n }\n\n function handleAdError(): void {\n if (tornDown) return;\n if (!adPlaying) return;\n clearAdStallTimer();\n if (debug) console.log(`${LOG} Handling ad error`);\n adPlaying = false;\n setAdPlayingFlag(false);\n\n restoreContentVideoStyles();\n\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n\n emit(\"ad_error\");\n }\n\n function teardownCurrentPlayback(): void {\n removeAdEventListeners();\n\n if (adHls) {\n adHls.destroy();\n adHls = undefined;\n }\n\n if (adVideoElement) {\n if (singleElementMode && adVideoElement === contentVideo) {\n contentVideo.pause();\n } else {\n adVideoElement.pause();\n adVideoElement.removeAttribute(\"src\");\n adVideoElement.load();\n }\n }\n }\n\n function startNativePlayback(mediaFile: VastMediaFile): void {\n if (!adVideoElement) return;\n if (debug) console.log(`${LOG} Starting native MP4 playback: ${mediaFile.url}`);\n adVideoElement.src = mediaFile.url;\n adVideoElement.load();\n adVideoElement.play().catch((error) => {\n console.error(`${LOG} Error starting native ad playback:`, error);\n handleAdError();\n });\n }\n\n function startHlsPlayback(mediaFile: VastMediaFile): void {\n if (!adVideoElement) return;\n if (debug) console.log(`${LOG} Starting HLS playback: ${mediaFile.url}`);\n\n if (Hls.isSupported()) {\n if (adHls) {\n adHls.destroy();\n adHls = undefined;\n }\n adHls = new Hls({ enableWorker: true, lowLatencyMode: false });\n adHls.loadSource(mediaFile.url);\n adHls.attachMedia(adVideoElement);\n\n adHls.on(Hls.Events.MANIFEST_PARSED, () => {\n if (!adPlaying) return;\n adVideoElement!.play().catch((error) => {\n console.error(`${LOG} Error starting HLS ad playback:`, error);\n handleAdError();\n });\n });\n\n let nonFatalNetworkErrors = 0;\n adHls.on(Hls.Events.ERROR, (_event, data) => {\n if (data.fatal) {\n handleAdError();\n } else if (data.type === Hls.ErrorTypes.NETWORK_ERROR) {\n nonFatalNetworkErrors++;\n if (nonFatalNetworkErrors >= 3) {\n if (debug) console.warn(`${LOG} Too many non-fatal HLS network errors (${nonFatalNetworkErrors}), treating as fatal`);\n handleAdError();\n }\n }\n });\n } else if (adVideoElement.canPlayType(\"application/vnd.apple.mpegurl\")) {\n adVideoElement.src = mediaFile.url;\n adVideoElement.play().catch((error) => {\n console.error(`${LOG} Error starting native HLS ad playback:`, error);\n handleAdError();\n });\n } else {\n console.error(`${LOG} HLS not supported on this platform`);\n handleAdError();\n }\n }\n\n function startPlayback(mediaFile: VastMediaFile): void {\n if (!adVideoElement) return;\n if (singleElementMode && isHlsMediaFile(mediaFile)) {\n const mp4Fallback = currentAd?.mediaFiles.find(f => !isHlsMediaFile(f));\n if (mp4Fallback) {\n if (debug) console.log(`${LOG} singleElementMode: HLS ad blocked, using MP4 fallback`);\n startNativePlayback(mp4Fallback);\n return;\n }\n }\n if (isHlsMediaFile(mediaFile)) {\n startHlsPlayback(mediaFile);\n } else {\n startNativePlayback(mediaFile);\n }\n }\n\n async function playAd(bids: VastBidResponse[]): Promise<void> {\n if (destroyed) {\n return Promise.reject(new Error(\"Layer has been destroyed\"));\n }\n if (bids.length === 0) {\n return Promise.reject(new Error(\"No bids provided\"));\n }\n\n const winner = bids[0]!;\n if (debug) {\n console.log(`${LOG} Winning bid: ${winner.bidder} $${winner.cpm.toFixed(2)} ${winner.currency}`);\n }\n\n const ad = await resolveBidToVastAd(winner, LOG);\n if (!ad) {\n if (debug) console.warn(`${LOG} Winning bid has no VAST URL or XML`);\n emit(\"ad_error\");\n return Promise.reject(new Error(\"No VAST from bid\"));\n }\n\n if (debug) {\n console.log(`${LOG} Ad parsed: ${ad.title}, duration: ${ad.duration}s, mediaFiles: ${ad.mediaFiles.length}`);\n }\n\n sessionId = generateSessionId();\n currentAd = ad;\n trackingFired = { ...createEmptyTrackingState() };\n fireTrackingPixels(ad.trackingUrls.impression);\n trackingFired.impression = true;\n\n const contentVolume = contentVideo.volume;\n originalVolume = Math.max(0, Math.min(1, contentVolume || originalVolume));\n\n if (singleElementMode) {\n mainHlsInstance?.detachMedia();\n teardownCurrentPlayback();\n\n adVideoElement = contentVideo;\n adHls = undefined;\n adPlaying = true;\n setAdPlayingFlag(true);\n\n contentVideo.removeAttribute(\"src\");\n contentVideo.load();\n if (!continueLiveStreamDuringAds) {\n contentVideo.pause();\n }\n contentVideo.muted = true;\n contentVideo.volume = 0;\n\n await new Promise<void>(resolve => setTimeout(resolve, 200));\n if (destroyed || tornDown) return;\n\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n applyContentVideoAdCoverStyles();\n\n emit(\"content_pause\");\n\n setupAdEventListeners();\n\n const adVolume = originalMutedState ? 1 : originalVolume;\n adVideoElement.volume = Math.max(0, Math.min(1, adVolume));\n adVideoElement.muted = false;\n\n const mediaFile = selectBestMediaFile(ad.mediaFiles);\n if (debug) console.log(`${LOG} Loading ad from: ${mediaFile.url}`);\n startPlayback(mediaFile);\n return;\n }\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 contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n\n if (!adVideoElement) {\n adVideoElement = createAdVideoElement();\n adContainerEl.appendChild(adVideoElement);\n setupAdEventListeners();\n } else {\n teardownCurrentPlayback();\n }\n\n if (!continueLiveStreamDuringAds) {\n contentVideo.pause();\n }\n\n contentVideo.muted = true;\n contentVideo.volume = 0;\n adPlaying = true;\n setAdPlayingFlag(true);\n\n const adVolume = originalMutedState ? 1 : originalVolume;\n adVideoElement!.volume = Math.max(0, Math.min(1, adVolume));\n adVideoElement!.muted = false;\n\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n\n emit(\"content_pause\");\n\n const mediaFile = selectBestMediaFile(ad.mediaFiles);\n if (debug) console.log(`${LOG} Loading ad from: ${mediaFile.url}`);\n startPlayback(mediaFile);\n }\n\n function ensureAdContainer(): HTMLDivElement {\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 return adContainerEl;\n }\n\n async function preloadAd(bids: VastBidResponse[], token: string): Promise<void> {\n if (destroyed) return;\n const winner = bids[0];\n if (!winner) return;\n\n if (debug) console.log(`${LOG} [preload] Resolving VAST for token=${token}`);\n const ad = await resolveBidToVastAd(winner, LOG);\n if (!ad || destroyed) return;\n\n const mediaFile = selectBestMediaFile(ad.mediaFiles);\n if (!mediaFile) return;\n\n if (smartTVMode || singleElementMode) {\n const slot: PreloadSlot = { bids, ad, mediaFile, videoEl: null, ready: true };\n preloadSlots.set(token, slot);\n if (debug) console.log(`${LOG} [preload] Metadata-only preload (smartTV/singleElement), token=${token}, url=${mediaFile.url}`);\n return;\n }\n\n const videoEl = createAdVideoElement();\n videoEl.style.visibility = \"hidden\";\n videoEl.style.pointerEvents = \"none\";\n videoEl.preload = \"auto\";\n\n const container = ensureAdContainer();\n container.appendChild(videoEl);\n\n if (isHlsMediaFile(mediaFile) && Hls.isSupported()) {\n const hls = new Hls({ enableWorker: true, lowLatencyMode: false });\n hls.loadSource(mediaFile.url);\n hls.attachMedia(videoEl);\n const slot: PreloadSlot = { bids, ad, mediaFile, videoEl, hlsInstance: hls, ready: false };\n preloadSlots.set(token, slot);\n hls.on(Hls.Events.MANIFEST_PARSED, () => {\n const s = preloadSlots.get(token);\n if (s) s.ready = true;\n if (debug) console.log(`${LOG} [preload] HLS manifest parsed, token=${token}`);\n });\n hls.on(Hls.Events.ERROR, (_evt, data) => {\n if (!preloadSlots.has(token)) return;\n if (data.fatal) {\n if (debug) console.warn(`${LOG} [preload] HLS error for token=${token}`);\n preloadSlots.delete(token);\n hls.destroy();\n videoEl.remove();\n }\n });\n } else {\n videoEl.src = mediaFile.url;\n videoEl.load();\n const slot: PreloadSlot = { bids, ad, mediaFile, videoEl, ready: false };\n preloadSlots.set(token, slot);\n videoEl.addEventListener(\"canplay\", () => {\n const s = preloadSlots.get(token);\n if (s) s.ready = true;\n if (debug) console.log(`${LOG} [preload] canplay fired, token=${token}`);\n }, { once: true });\n }\n\n if (debug) console.log(`${LOG} [preload] Started buffering token=${token}, url=${mediaFile.url}`);\n }\n\n async function playPreloaded(token: string): Promise<void> {\n if (destroyed) return Promise.reject(new Error(\"Layer has been destroyed\"));\n\n const slot = preloadSlots.get(token);\n if (!slot) {\n if (debug) console.warn(`${LOG} [preload] No slot found for token=${token}, nothing to play`);\n return;\n }\n preloadSlots.delete(token);\n\n if (debug) console.log(`${LOG} [preload] Playing preloaded ad, token=${token}, ready=${slot.ready}`);\n\n const contentVolume = contentVideo.volume;\n originalVolume = Math.max(0, Math.min(1, contentVolume || originalVolume));\n\n sessionId = generateSessionId();\n currentAd = slot.ad;\n trackingFired = { ...createEmptyTrackingState() };\n fireTrackingPixels(slot.ad.trackingUrls.impression);\n trackingFired.impression = true;\n\n if (singleElementMode) {\n mainHlsInstance?.detachMedia();\n teardownCurrentPlayback();\n\n adVideoElement = contentVideo;\n adHls = undefined;\n adPlaying = true;\n setAdPlayingFlag(true);\n\n contentVideo.removeAttribute(\"src\");\n contentVideo.load();\n contentVideo.muted = true;\n contentVideo.volume = 0;\n\n await new Promise<void>(resolve => setTimeout(resolve, 200));\n if (destroyed || tornDown) return;\n\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n applyContentVideoAdCoverStyles();\n\n emit(\"content_pause\");\n\n setupAdEventListeners();\n\n const adVolume = originalMutedState ? 1 : originalVolume;\n contentVideo.volume = Math.max(0, Math.min(1, adVolume));\n contentVideo.muted = false;\n\n if (debug) console.log(`${LOG} [preload] singleElementMode: attaching ad to contentVideo, url=${slot.mediaFile.url}`);\n startPlayback(slot.mediaFile);\n return;\n }\n\n if (smartTVMode && !slot.videoEl) {\n teardownCurrentPlayback();\n if (adVideoElement) {\n adVideoElement.remove();\n adVideoElement = undefined;\n }\n\n const videoEl = createAdVideoElement();\n videoEl.style.visibility = \"visible\";\n videoEl.style.pointerEvents = \"none\";\n\n const container = ensureAdContainer();\n container.appendChild(videoEl);\n adVideoElement = videoEl;\n\n setupAdEventListeners();\n\n if (!continueLiveStreamDuringAds) {\n contentVideo.pause();\n }\n contentVideo.muted = true;\n contentVideo.volume = 0;\n adPlaying = true;\n setAdPlayingFlag(true);\n\n const adVolume = originalMutedState ? 1 : originalVolume;\n adVideoElement.volume = Math.max(0, Math.min(1, adVolume));\n adVideoElement.muted = false;\n\n container.style.display = \"flex\";\n container.style.pointerEvents = \"auto\";\n\n emit(\"content_pause\");\n\n if (debug) console.log(`${LOG} [preload] smartTVMode deferred: creating video element and loading, url=${slot.mediaFile.url}`);\n startPlayback(slot.mediaFile);\n return;\n }\n\n teardownCurrentPlayback();\n\n if (adVideoElement && adVideoElement !== slot.videoEl) {\n adVideoElement.remove();\n }\n\n slot.videoEl!.style.visibility = \"visible\";\n slot.videoEl!.style.pointerEvents = \"none\";\n adVideoElement = slot.videoEl!;\n adHls = slot.hlsInstance;\n\n if (adHls) {\n let nonFatalNetworkErrors = 0;\n adHls.on(Hls.Events.ERROR, (_event, data) => {\n if (!adPlaying) return;\n if (data.fatal) {\n handleAdError();\n } else if (data.type === Hls.ErrorTypes.NETWORK_ERROR) {\n nonFatalNetworkErrors++;\n if (nonFatalNetworkErrors >= 3) {\n if (debug) console.warn(`${LOG} [preload] Too many non-fatal HLS network errors during playback, treating as fatal`);\n handleAdError();\n }\n }\n });\n }\n\n setupAdEventListeners();\n\n if (!continueLiveStreamDuringAds) {\n contentVideo.pause();\n }\n\n contentVideo.muted = true;\n contentVideo.volume = 0;\n adPlaying = true;\n setAdPlayingFlag(true);\n\n const adVolume = originalMutedState ? 1 : originalVolume;\n adVideoElement.volume = Math.max(0, Math.min(1, adVolume));\n adVideoElement.muted = false;\n\n const container = ensureAdContainer();\n container.style.display = \"flex\";\n container.style.pointerEvents = \"auto\";\n\n emit(\"content_pause\");\n\n adVideoElement.play().catch((error) => {\n console.error(`${LOG} [preload] Error playing preloaded ad:`, error);\n handleAdError();\n });\n }\n\n function cancelPreload(token: string): void {\n const slot = preloadSlots.get(token);\n if (!slot) return;\n preloadSlots.delete(token);\n if (slot.hlsInstance) {\n slot.hlsInstance.destroy();\n }\n if (slot.videoEl) {\n slot.videoEl.pause();\n slot.videoEl.removeAttribute(\"src\");\n slot.videoEl.load();\n slot.videoEl.remove();\n }\n if (debug) console.log(`${LOG} [preload] Cancelled and cleaned up token=${token}`);\n }\n\n return {\n initialize() {\n if (debug) console.log(`${LOG} Initializing`);\n },\n\n updateOptions(opts: VastAdLayerOptionsUpdate) {\n if (opts.continueLiveStreamDuringAds !== undefined) {\n continueLiveStreamDuringAds = opts.continueLiveStreamDuringAds;\n }\n if (opts.mainHlsInstance !== undefined) {\n mainHlsInstance = opts.mainHlsInstance ?? undefined;\n }\n },\n\n playAd,\n preloadAd,\n playPreloaded,\n hasPreloaded(token: string): boolean {\n return preloadSlots.has(token);\n },\n cancelPreload,\n\n pause() {\n if (!adPlaying || !adVideoElement) return;\n try {\n if (!adVideoElement.paused) adVideoElement.pause();\n } catch (error) {\n if (debug) console.warn(`${LOG} Error pausing ad:`, error);\n }\n },\n\n resume() {\n if (!adPlaying || !adVideoElement) return;\n try {\n if (adVideoElement.paused) adVideoElement.play().catch(() => {});\n } catch (error) {\n if (debug) console.warn(`${LOG} Error resuming ad:`, error);\n }\n },\n\n async stop() {\n tornDown = true;\n if (debug) console.log(`${LOG} Stopping ad`);\n adPlaying = false;\n setAdPlayingFlag(false);\n\n restoreContentVideoStyles();\n\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalMutedState ? 0 : originalVolume;\n\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n\n if (singleElementMode) {\n teardownCurrentPlayback();\n contentVideo.removeAttribute(\"src\");\n contentVideo.load();\n adVideoElement = undefined;\n } else {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n\n if (continueLiveStreamDuringAds) {\n contentVideo.play().catch(() => {});\n }\n\n teardownCurrentPlayback();\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.removeAttribute(\"src\");\n adVideoElement.load();\n }\n }\n\n currentAd = undefined;\n tornDown = false;\n },\n\n destroy() {\n tornDown = true;\n if (debug) console.log(`${LOG} Destroying`);\n destroyed = true;\n adPlaying = false;\n setAdPlayingFlag(false);\n\n restoreContentVideoStyles();\n\n contentVideo.muted = originalMutedState;\n contentVideo.volume = originalVolume;\n\n for (const [token] of Array.from(preloadSlots.entries())) {\n cancelPreload(token);\n }\n\n teardownCurrentPlayback();\n if (adVideoElement) {\n if (singleElementMode && adVideoElement === contentVideo) {\n contentVideo.removeAttribute(\"src\");\n contentVideo.load();\n } else {\n adVideoElement.pause();\n adVideoElement.removeAttribute(\"src\");\n adVideoElement.remove();\n }\n adVideoElement = undefined;\n }\n if (adContainerEl?.parentElement) {\n adContainerEl.parentElement.removeChild(adContainerEl);\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 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\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 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 }\n },\n\n getAdVolume(): number {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n\n showPlaceholder() {\n if (singleElementMode) return;\n contentVideo.style.opacity = \"0\";\n contentVideo.style.visibility = \"hidden\";\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.pointerEvents = \"auto\";\n }\n },\n\n hidePlaceholder() {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n if (!adPlaying) {\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n }\n },\n };\n}\n","export interface VastMediaFile {\n url: string;\n type: string;\n width: number;\n height: number;\n bitrate?: number | undefined;\n}\n\nexport interface VastTrackingUrls {\n impression: string[];\n start: string[];\n firstQuartile: string[];\n midpoint: string[];\n thirdQuartile: string[];\n complete: string[];\n mute: string[];\n unmute: string[];\n pause: string[];\n resume: string[];\n fullscreen: string[];\n exitFullscreen: string[];\n skip: string[];\n error: string[];\n}\n\nexport interface VastAd {\n id: string;\n title: string;\n duration: number;\n mediaFiles: VastMediaFile[];\n trackingUrls: VastTrackingUrls;\n clickThrough?: string | undefined;\n}\n\nexport type MediaFileFilter = \"hls-only\" | \"mp4-first\" | \"all\";\n\nfunction isHlsType(type: string): boolean {\n return type === \"application/x-mpegURL\" || type.includes(\"m3u8\");\n}\n\nfunction isMp4Type(type: string): boolean {\n return type === \"video/mp4\" || type.includes(\"mp4\");\n}\n\nexport function parseVastXml(\n xmlString: string,\n filter: MediaFileFilter = \"all\",\n logPrefix = \"[VastParser]\"\n): VastAd | null {\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(\n `${logPrefix} XML parsing error (malformed VAST XML):`,\n parserError.textContent\n );\n return null;\n }\n\n const adElement = xmlDoc.querySelector(\"Ad\");\n if (!adElement) {\n console.warn(`${logPrefix} No Ad element found in VAST XML`);\n return null;\n }\n\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n\n const isNoAdAvailable =\n adId === \"empty\" ||\n title.toLowerCase().includes(\"no ad available\") ||\n title.toLowerCase() === \"no ad available\";\n\n const durationText =\n xmlDoc.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 Math.round(parseFloat(durationParts[2] || \"0\"));\n\n const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n const mediaFiles: VastMediaFile[] = [];\n\n console.log(\n `${logPrefix} Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`\n );\n\n mediaFileElements.forEach((mf, index) => {\n const type = mf.getAttribute(\"type\") || \"\";\n const url = mf.textContent?.trim() || \"\";\n const width = mf.getAttribute(\"width\") || \"\";\n const height = mf.getAttribute(\"height\") || \"\";\n\n console.log(\n `${logPrefix} MediaFile ${index}: type=\"${type}\", url=\"${url.substring(0, 80)}...\", width=\"${width}\", height=\"${height}\"`\n );\n\n if (!url) {\n console.warn(`${logPrefix} MediaFile ${index} has empty URL`);\n return;\n }\n\n const isHls = isHlsType(type);\n const isMp4 = isMp4Type(type);\n\n let accepted = false;\n if (filter === \"hls-only\") {\n accepted = isHls;\n } else if (filter === \"mp4-first\") {\n accepted = isMp4 || isHls;\n } else {\n accepted = true;\n }\n\n if (!accepted) {\n console.log(\n `${logPrefix} MediaFile ${index} ignored (type=\"${type}\" not accepted by filter \"${filter}\")`\n );\n return;\n }\n\n const bitrateAttr = mf.getAttribute(\"bitrate\");\n const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : undefined;\n\n mediaFiles.push({\n url,\n type,\n width: parseInt(width || \"1920\", 10),\n height: parseInt(height || \"1080\", 10),\n bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : undefined,\n });\n\n console.log(`${logPrefix} Added MediaFile: type=\"${type}\" url=\"${url.substring(0, 80)}...\"`);\n });\n\n if (filter === \"mp4-first\" && mediaFiles.length > 1) {\n mediaFiles.sort((a, b) => {\n const aIsMp4 = isMp4Type(a.type) ? 0 : 1;\n const bIsMp4 = isMp4Type(b.type) ? 0 : 1;\n return aIsMp4 - bIsMp4;\n });\n }\n\n if (mediaFiles.length === 0) {\n if (isNoAdAvailable) {\n console.warn(\n `${logPrefix} No ads available (VAST response indicates no ads)`\n );\n } else {\n console.warn(`${logPrefix} No compatible media files found in VAST XML`);\n }\n return null;\n }\n\n const trackingUrls: VastTrackingUrls = {\n impression: [],\n start: [],\n firstQuartile: [],\n midpoint: [],\n thirdQuartile: [],\n complete: [],\n mute: [],\n unmute: [],\n pause: [],\n resume: [],\n fullscreen: [],\n exitFullscreen: [],\n skip: [],\n error: [],\n };\n\n xmlDoc.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n\n xmlDoc.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 = xmlDoc\n .querySelector(\"ClickThrough\")\n ?.textContent?.trim();\n\n return {\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough,\n };\n } catch (error) {\n console.error(`${logPrefix} Error parsing VAST XML:`, error);\n return null;\n }\n}\n\nexport async function fetchAndParseVastAd(\n vastTagUrl: string,\n filter: MediaFileFilter = \"all\",\n logPrefix = \"[VastParser]\"\n): Promise<VastAd | null> {\n const response = await fetch(vastTagUrl, {\n mode: \"cors\",\n credentials: \"include\",\n headers: {\n Accept: \"application/xml, text/xml, */*\",\n },\n referrerPolicy: \"no-referrer-when-downgrade\",\n });\n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.statusText}`);\n }\n\n const vastXml = await response.text();\n console.log(`${logPrefix} VAST XML received`);\n console.log(\n `${logPrefix} VAST XML content (first 2000 chars):`,\n vastXml.substring(0, 2000)\n );\n\n return parseVastXml(vastXml, filter, logPrefix);\n}\n\nexport function createEmptyTrackingState() {\n return {\n impression: false,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false,\n };\n}\n\nasync function firePixelWithRetry(\n url: string,\n retries = 2,\n delayMs = 500,\n logPrefix = \"[VastParser]\"\n): Promise<void> {\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n await fetch(url, {\n method: \"GET\",\n mode: \"no-cors\",\n cache: \"no-cache\",\n keepalive: true,\n });\n return;\n } catch {\n if (attempt < retries) {\n await new Promise((r) => setTimeout(r, delayMs * Math.pow(2, attempt)));\n } else {\n console.warn(`${logPrefix} Tracking pixel failed after ${retries + 1} attempts: ${url}`);\n }\n }\n }\n}\n\nexport function fireTrackingPixels(\n urls: string[],\n sessionId?: string,\n logPrefix = \"[VastParser]\"\n): void {\n if (!urls || urls.length === 0) return;\n\n urls.forEach((url) => {\n try {\n let trackingUrl = url;\n\n if (sessionId) {\n trackingUrl = `${trackingUrl}${\n trackingUrl.includes(\"?\") ? \"&\" : \"?\"\n }session_id=${sessionId}`;\n }\n\n if (typeof fetch !== \"undefined\") {\n firePixelWithRetry(trackingUrl, 2, 500, logPrefix).catch(() => {});\n } else {\n const img = new Image(1, 1);\n img.onerror = () => {};\n img.src = trackingUrl;\n }\n\n console.log(`${logPrefix} Fired tracking pixel: ${trackingUrl}`);\n } catch (error) {\n console.warn(`${logPrefix} Error firing tracking pixel:`, error);\n }\n });\n}\n"]}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { V as VastBidResponse } from '../types-BYwfSJb5.cjs';
|
|
2
|
-
import Hls from 'hls.js';
|
|
3
|
-
|
|
4
|
-
interface VastAdLayerOptions {
|
|
5
|
-
continueLiveStreamDuringAds?: boolean;
|
|
6
|
-
mainHlsInstance?: Hls;
|
|
7
|
-
smartTVMode?: boolean;
|
|
8
|
-
singleElementMode?: boolean;
|
|
9
|
-
forceMP4Ads?: boolean;
|
|
10
|
-
debug?: boolean;
|
|
11
|
-
}
|
|
12
|
-
interface VastAdLayerOptionsUpdate {
|
|
13
|
-
continueLiveStreamDuringAds?: boolean;
|
|
14
|
-
mainHlsInstance?: Hls | null;
|
|
15
|
-
}
|
|
16
|
-
interface VastAdLayer {
|
|
17
|
-
initialize: () => void;
|
|
18
|
-
updateOptions: (opts: VastAdLayerOptionsUpdate) => void;
|
|
19
|
-
playAd: (bids: VastBidResponse[]) => Promise<void>;
|
|
20
|
-
preloadAd: (bids: VastBidResponse[], token: string) => Promise<void>;
|
|
21
|
-
playPreloaded: (token: string) => Promise<void>;
|
|
22
|
-
hasPreloaded: (token: string) => boolean;
|
|
23
|
-
cancelPreload: (token: string) => void;
|
|
24
|
-
pause: () => void;
|
|
25
|
-
resume: () => void;
|
|
26
|
-
stop: () => Promise<void>;
|
|
27
|
-
destroy: () => void;
|
|
28
|
-
isAdPlaying: () => boolean;
|
|
29
|
-
resize: (width: number, height: number) => void;
|
|
30
|
-
on: (event: string, listener: (payload?: any) => void) => void;
|
|
31
|
-
off: (event: string, listener: (payload?: any) => void) => void;
|
|
32
|
-
updateOriginalMutedState: (muted: boolean, volume?: number) => void;
|
|
33
|
-
getOriginalMutedState: () => boolean;
|
|
34
|
-
getOriginalVolume: () => number;
|
|
35
|
-
setAdVolume: (volume: number) => void;
|
|
36
|
-
getAdVolume: () => number;
|
|
37
|
-
showPlaceholder: () => void;
|
|
38
|
-
hidePlaceholder: () => void;
|
|
39
|
-
}
|
|
40
|
-
declare function createVastAdLayer(contentVideo: HTMLVideoElement, options?: VastAdLayerOptions): VastAdLayer;
|
|
41
|
-
|
|
42
|
-
export { type VastAdLayer, type VastAdLayerOptions, type VastAdLayerOptionsUpdate, createVastAdLayer };
|