stormcloud-video-player 0.8.19 → 0.8.21
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 +54 -12
- package/lib/index.cjs.map +1 -1
- package/lib/index.js +54 -12
- package/lib/index.js.map +1 -1
- package/lib/player/AdConfigManager.cjs +61 -8
- package/lib/player/AdConfigManager.cjs.map +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +54 -12
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/players/HlsPlayer.cjs +54 -12
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/index.cjs +54 -12
- package/lib/players/index.cjs.map +1 -1
- package/lib/sdk/hlsAdPlayer.cjs +5 -4
- package/lib/sdk/hlsAdPlayer.cjs.map +1 -1
- package/lib/ui/StormcloudVideoPlayer.cjs +54 -12
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/utils/ctvVastSignals.cjs +12 -1
- package/lib/utils/ctvVastSignals.cjs.map +1 -1
- package/lib/utils/vastEnvironmentSignals.cjs +12 -1
- package/lib/utils/vastEnvironmentSignals.cjs.map +1 -1
- package/lib/utils/vastMacros.cjs +49 -3
- package/lib/utils/vastMacros.cjs.map +1 -1
- package/package.json +1 -1
package/lib/sdk/hlsAdPlayer.cjs
CHANGED
|
@@ -625,6 +625,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
625
625
|
handleAdComplete();
|
|
626
626
|
});
|
|
627
627
|
adVideoElement.addEventListener("error", function(e) {
|
|
628
|
+
if (!adPlaying) return;
|
|
628
629
|
console.error("[HlsAdPlayer] Ad video error:", e);
|
|
629
630
|
if (currentAd) {
|
|
630
631
|
fireTrackingPixels(currentAd.trackingUrls.error);
|
|
@@ -826,15 +827,15 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
826
827
|
adVideoElement.muted = originalMutedState;
|
|
827
828
|
console.log("[HlsAdPlayer] Set ad video volume to ".concat(adVideoElement.volume, ", muted: ").concat(adVideoElement.muted, ", originalMutedState: ").concat(originalMutedState, ", contentVolume: ").concat(contentVolume));
|
|
828
829
|
}
|
|
830
|
+
mediaFile = selectBestMediaFile(currentAd.mediaFiles);
|
|
831
|
+
if (!mediaFile) {
|
|
832
|
+
throw new Error("No media file available for ad");
|
|
833
|
+
}
|
|
829
834
|
if (adContainerEl) {
|
|
830
835
|
adContainerEl.style.display = "flex";
|
|
831
836
|
adContainerEl.style.pointerEvents = "auto";
|
|
832
837
|
}
|
|
833
838
|
emit("content_pause");
|
|
834
|
-
mediaFile = selectBestMediaFile(currentAd.mediaFiles);
|
|
835
|
-
if (!mediaFile) {
|
|
836
|
-
throw new Error("No media file available for ad");
|
|
837
|
-
}
|
|
838
839
|
isHlsAd = isHlsMediaFile(mediaFile);
|
|
839
840
|
console.log("[HlsAdPlayer] Loading ".concat(isHlsAd ? "HLS" : "progressive", " ad from: ").concat(mediaFile.url));
|
|
840
841
|
if (isHlsAd && import_hls.default.isSupported()) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/sdk/hlsAdPlayer.cjs","../../src/sdk/hlsAdPlayer.ts"],"names":["__create","Object","create","__defProp","__getOwnPropDesc","defineProperty","getOwnPropertyDescriptor","__getProtoOf","getPrototypeOf","__hasOwnProp","prototype","hasOwnProperty","__export","target","all","name","get","enumerable","__copyProps","to","from","except","desc","key","call","__getOwnPropNames","__toESM","mod","isNodeMode","__esModule","value","__toCommonJS","hlsAdPlayer_exports","createHlsAdPlayer","module","exports","import_hls","require","MAX_VAST_WRAPPER_DEPTH","contentVideo","options","adPlaying","originalMutedState","originalVolume","Math","max","min","volume","listeners","Map","licenseKey","mainHlsInstance","adVideoElement","adHls","adContainerEl","currentAd","sessionId","preloadedAds","preloadingAds","destroyed","pendingTimeouts","trackingFired","impression","start","firstQuartile","midpoint","thirdQuartile","complete","fireTrackingPixels","urls","emit","event","payload","set","Array","fn","error","console","warn","generateSessionId","Date","now","random","toString","substr","length","forEach","url","trackingUrl","includes","img","Image","src","log","getMainStreamQuality","levels","currentLevel","autoLevel","loadLevel","level","width","height","bitrate","selectBestMediaFile","mediaFiles","firstFile","Error","mainQuality","scoredFiles","map","file","widthDiff","abs","heightDiff","resolutionDiff","fileBitrate","bitrateDiff","score","sort","a","b","bestMatch","resolution","isHlsMediaFile","mediaFile","type","toLowerCase","isProgressiveMediaFile","startsWith","endsWith","createEmptyTrackingUrls","mute","unmute","pause","resume","fullscreen","exitFullscreen","skip","extractTrackingUrls","xmlDoc","trackingUrls","querySelectorAll","el","textContent","trim","push","getAttribute","eventKey","mergeTrackingUrls","source","keys","concat","parseVastXml","xmlString","parser","DOMParser","parseFromString","parserError","querySelector","adElement","adId","title","clickThrough","wrapperUri","vastAdTagUri","isNoAdAvailable","durationText","durationParts","split","duration","parseInt","mediaFileElements","mf","index","bitrateAttr","bitrateValue","ad","id","fetchVastXml","vastTagUrl","response","fetch","mode","referrerPolicy","ok","statusText","text","depth","accumulatedTracking","vastXml","parsed","style","playsInline","substring","fetchAndParseVastAd","createAdVideoElement","video","document","createElement","position","left","top","objectFit","backgroundColor","muted","setupAdEventListeners","addEventListener","progress","currentTime","handleAdComplete","e","handleAdError","ended","setAdPlayingFlag","isPlaying","dataset","stormcloudAdPlaying","display","pointerEvents","continueLiveStreamDuringAds","paused","play","catch","initialize","container","right","bottom","alignItems","justifyContent","zIndex","parentElement","appendChild","requestAds","Promise","reject","has","delete","resolve","contentVolume","isHlsAd"],"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/hlsAdPlayer.ts\nvar hlsAdPlayer_exports = {};\n__export(hlsAdPlayer_exports, {\n createHlsAdPlayer: () => createHlsAdPlayer\n});\nmodule.exports = __toCommonJS(hlsAdPlayer_exports);\nvar import_hls = __toESM(require(\"hls.js\"), 1);\nvar MAX_VAST_WRAPPER_DEPTH = 5;\nfunction createHlsAdPlayer(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 const licenseKey = options?.licenseKey;\n const mainHlsInstance = options?.mainHlsInstance;\n let adVideoElement;\n let adHls;\n let adContainerEl;\n let currentAd;\n let sessionId;\n const preloadedAds = /* @__PURE__ */ new Map();\n const preloadingAds = /* @__PURE__ */ new Map();\n let destroyed = false;\n let pendingTimeouts = [];\n let trackingFired = {\n impression: false,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false\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(\n `[HlsAdPlayer] Error in event listener for ${event}:`,\n error\n );\n }\n }\n }\n function generateSessionId() {\n return `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n function fireTrackingPixels(urls) {\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 (licenseKey) {\n trackingUrl = `${trackingUrl}${trackingUrl.includes(\"?\") ? \"&\" : \"?\"}license_key=${licenseKey}`;\n }\n const img = new Image(1, 1);\n img.src = trackingUrl;\n console.log(`[HlsAdPlayer] Fired tracking pixel: ${trackingUrl}`);\n } catch (error) {\n console.warn(`[HlsAdPlayer] Error firing tracking pixel:`, error);\n }\n });\n }\n function getMainStreamQuality() {\n if (!mainHlsInstance || !mainHlsInstance.levels) {\n return null;\n }\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) {\n throw new Error(\"No media files available\");\n }\n const firstFile = mediaFiles[0];\n if (!firstFile) {\n throw new Error(\"No media files available\");\n }\n if (mediaFiles.length === 1) {\n return firstFile;\n }\n const mainQuality = getMainStreamQuality();\n if (!mainQuality) {\n console.log(\n \"[HlsAdPlayer] No main stream quality info, using first media file\"\n );\n return firstFile;\n }\n console.log(\"[HlsAdPlayer] Main stream quality:\", mainQuality);\n const scoredFiles = mediaFiles.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, resolutionDiff, bitrateDiff };\n });\n scoredFiles.sort((a, b) => a.score - b.score);\n const bestMatch = scoredFiles[0];\n if (!bestMatch) {\n console.log(\"[HlsAdPlayer] No best match found, using first media file\");\n return firstFile;\n }\n console.log(\"[HlsAdPlayer] Selected media file:\", {\n url: bestMatch.file.url,\n resolution: `${bestMatch.file.width}x${bestMatch.file.height}`,\n bitrate: bestMatch.file.bitrate,\n score: bestMatch.score,\n resolutionDiff: bestMatch.resolutionDiff,\n bitrateDiff: bestMatch.bitrateDiff\n });\n return bestMatch.file;\n }\n function isHlsMediaFile(mediaFile) {\n const type = mediaFile.type.toLowerCase();\n const url = mediaFile.url.toLowerCase();\n return type === \"application/x-mpegurl\" || type === \"application/vnd.apple.mpegurl\" || type.includes(\"mpegurl\") || url.includes(\".m3u8\");\n }\n function isProgressiveMediaFile(mediaFile) {\n const type = mediaFile.type.toLowerCase();\n const url = mediaFile.url.toLowerCase();\n return type.startsWith(\"video/\") || url.endsWith(\".mp4\") || url.includes(\".mp4?\");\n }\n function createEmptyTrackingUrls() {\n return {\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 function extractTrackingUrls(xmlDoc) {\n const trackingUrls = createEmptyTrackingUrls();\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 xmlDoc.querySelectorAll(\"Error\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.error.push(url);\n });\n return trackingUrls;\n }\n function mergeTrackingUrls(target, source) {\n Object.keys(target).forEach((key) => {\n if (source[key] && source[key].length > 0) {\n target[key] = target[key].concat(source[key]);\n }\n });\n return target;\n }\n function parseVastXml(xmlString) {\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 \"[HlsAdPlayer] XML parsing error (malformed VAST XML):\",\n parserError.textContent\n );\n return { type: \"empty\" };\n }\n const adElement = xmlDoc.querySelector(\"Ad\");\n if (!adElement) {\n console.warn(\"[HlsAdPlayer] No Ad element found in VAST XML\");\n return { type: \"empty\" };\n }\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n const clickThrough = xmlDoc.querySelector(\"ClickThrough\")?.textContent?.trim();\n const wrapperUri = xmlDoc.querySelector(\"VASTAdTagURI\")?.textContent?.trim();\n if (wrapperUri) {\n console.log(\n `[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ${wrapperUri}`\n );\n return {\n type: \"wrapper\",\n vastAdTagUri: wrapperUri,\n trackingUrls: extractTrackingUrls(xmlDoc),\n clickThrough\n };\n }\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 + parseInt(durationParts[2] || \"0\", 10);\n const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n const mediaFiles = [];\n console.log(\n `[HlsAdPlayer] 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 `[HlsAdPlayer] MediaFile ${index}: type=\"${type}\", url=\"${url}\", width=\"${width}\", height=\"${height}\"`\n );\n const mediaFile = {\n url,\n type,\n width: parseInt(width || \"1920\", 10),\n height: parseInt(height || \"1080\", 10),\n bitrate: void 0\n };\n if (!url) {\n console.warn(`[HlsAdPlayer] MediaFile ${index} has empty URL`);\n return;\n }\n const bitrateAttr = mf.getAttribute(\"bitrate\");\n const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;\n mediaFile.bitrate = bitrateValue && bitrateValue > 0 ? bitrateValue : void 0;\n if (isHlsMediaFile(mediaFile) || isProgressiveMediaFile(mediaFile)) {\n mediaFiles.push(mediaFile);\n console.log(\n `[HlsAdPlayer] Added ${isHlsMediaFile(mediaFile) ? \"HLS\" : \"progressive\"} MediaFile: ${url}`\n );\n } else {\n console.log(\n `[HlsAdPlayer] MediaFile ${index} ignored (type=\"${type}\" is not supported)`\n );\n }\n });\n if (mediaFiles.length === 0) {\n if (isNoAdAvailable) {\n console.warn(\n \"[HlsAdPlayer] No ads available (VAST response indicates no ads)\"\n );\n } else {\n console.warn(\"[HlsAdPlayer] No supported media files found in VAST XML\");\n }\n return { type: \"empty\" };\n }\n return {\n type: \"inline\",\n ad: {\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls: extractTrackingUrls(xmlDoc),\n clickThrough\n }\n };\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error parsing VAST XML:\", error);\n return { type: \"empty\" };\n }\n }\n async function fetchVastXml(vastTagUrl) {\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 return response.text();\n }\n async function fetchAndParseVastAd(vastTagUrl, depth = 0, accumulatedTracking = createEmptyTrackingUrls()) {\n const vastXml = await fetchVastXml(vastTagUrl);\n console.log(\"[HlsAdPlayer] VAST XML received\");\n console.log(\n \"[HlsAdPlayer] VAST XML content (first 2000 chars):\",\n vastXml.substring(0, 2e3)\n );\n const parsed = parseVastXml(vastXml);\n if (parsed.type === \"empty\") {\n return null;\n }\n if (parsed.type === \"wrapper\") {\n if (depth >= MAX_VAST_WRAPPER_DEPTH) {\n console.warn(\n `[HlsAdPlayer] VAST wrapper depth limit (${MAX_VAST_WRAPPER_DEPTH}) reached, aborting redirect chain`\n );\n return null;\n }\n mergeTrackingUrls(accumulatedTracking, parsed.trackingUrls);\n return fetchAndParseVastAd(\n parsed.vastAdTagUri,\n depth + 1,\n accumulatedTracking\n );\n }\n mergeTrackingUrls(parsed.ad.trackingUrls, accumulatedTracking);\n return parsed.ad;\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.playsInline = true;\n video.muted = false;\n video.volume = 1;\n console.log(\n `[HlsAdPlayer] Created ad video element with volume ${video.volume}`\n );\n return video;\n }\n function setupAdEventListeners() {\n if (!adVideoElement || !currentAd) return;\n adVideoElement.addEventListener(\"timeupdate\", () => {\n if (!currentAd || !adVideoElement) return;\n const progress = adVideoElement.currentTime / currentAd.duration;\n if (progress >= 0.25 && !trackingFired.firstQuartile) {\n trackingFired.firstQuartile = true;\n fireTrackingPixels(currentAd.trackingUrls.firstQuartile);\n }\n if (progress >= 0.5 && !trackingFired.midpoint) {\n trackingFired.midpoint = true;\n fireTrackingPixels(currentAd.trackingUrls.midpoint);\n }\n if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n trackingFired.thirdQuartile = true;\n fireTrackingPixels(currentAd.trackingUrls.thirdQuartile);\n }\n });\n adVideoElement.addEventListener(\"playing\", () => {\n if (!currentAd || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels(currentAd.trackingUrls.start);\n console.log(\"[HlsAdPlayer] Ad started playing\");\n });\n adVideoElement.addEventListener(\"ended\", () => {\n if (!currentAd || trackingFired.complete) return;\n trackingFired.complete = true;\n fireTrackingPixels(currentAd.trackingUrls.complete);\n console.log(\"[HlsAdPlayer] Ad completed\");\n handleAdComplete();\n });\n adVideoElement.addEventListener(\"error\", (e) => {\n console.error(\"[HlsAdPlayer] Ad video error:\", e);\n if (currentAd) {\n fireTrackingPixels(currentAd.trackingUrls.error);\n }\n handleAdError();\n });\n adVideoElement.addEventListener(\"volumechange\", () => {\n if (!currentAd) return;\n if (adVideoElement.muted) {\n fireTrackingPixels(currentAd.trackingUrls.mute);\n } else {\n fireTrackingPixels(currentAd.trackingUrls.unmute);\n }\n });\n adVideoElement.addEventListener(\"pause\", () => {\n if (currentAd && !adVideoElement.ended) {\n fireTrackingPixels(currentAd.trackingUrls.pause);\n }\n });\n adVideoElement.addEventListener(\"play\", () => {\n if (currentAd && adVideoElement.currentTime > 0) {\n fireTrackingPixels(currentAd.trackingUrls.resume);\n }\n });\n }\n function setAdPlayingFlag(isPlaying) {\n if (isPlaying) {\n contentVideo.dataset.stormcloudAdPlaying = \"true\";\n } else {\n delete contentVideo.dataset.stormcloudAdPlaying;\n }\n }\n function handleAdComplete() {\n console.log(\"[HlsAdPlayer] Handling ad completion\");\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = true;\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n if (options?.continueLiveStreamDuringAds) {\n if (contentVideo.paused) {\n console.log(\"[HlsAdPlayer] Content video paused in live mode, resuming playback\");\n contentVideo.play().catch(() => {\n });\n } else {\n console.log(\"[HlsAdPlayer] Content video already playing in live mode\");\n }\n }\n emit(\"content_resume\");\n }\n function handleAdError() {\n console.log(\"[HlsAdPlayer] Handling ad error\");\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = true;\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n emit(\"ad_error\");\n }\n return {\n initialize() {\n console.log(\"[HlsAdPlayer] 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 = \"30\";\n container.style.backgroundColor = \"#000\";\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n },\n async requestAds(vastTagUrl) {\n console.log(\"[HlsAdPlayer] Requesting ads:\", vastTagUrl);\n if (adPlaying) {\n console.warn(\n \"[HlsAdPlayer] Cannot request new ads while an ad is playing\"\n );\n return Promise.reject(new Error(\"Ad already playing\"));\n }\n try {\n sessionId = generateSessionId();\n let ad;\n if (preloadedAds.has(vastTagUrl)) {\n ad = preloadedAds.get(vastTagUrl);\n preloadedAds.delete(vastTagUrl);\n console.log(\n \"[HlsAdPlayer] Using preloaded VAST response:\",\n vastTagUrl\n );\n } else {\n ad = await fetchAndParseVastAd(vastTagUrl);\n }\n if (!ad) {\n console.warn(\"[HlsAdPlayer] No ads available from VAST response\");\n emit(\"ad_error\");\n return Promise.reject(new Error(\"No ads available from VAST response\"));\n }\n currentAd = ad;\n console.log(\n `[HlsAdPlayer] Ad parsed: ${ad.title}, duration: ${ad.duration}s`\n );\n fireTrackingPixels(ad.trackingUrls.impression);\n trackingFired.impression = true;\n return Promise.resolve();\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error requesting ads:\", error);\n emit(\"ad_error\");\n return Promise.reject(error);\n }\n },\n async play() {\n if (!currentAd) {\n console.warn(\n \"[HlsAdPlayer] Cannot play: No ad loaded (no ads available)\"\n );\n return Promise.reject(new Error(\"No ad loaded\"));\n }\n console.log(\"[HlsAdPlayer] 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 const contentVolume = contentVideo.volume;\n originalVolume = Math.max(\n 0,\n Math.min(1, contentVolume || originalVolume)\n );\n if (!options?.continueLiveStreamDuringAds) {\n contentVideo.pause();\n console.log(\"[HlsAdPlayer] Content paused (VOD mode)\");\n } else {\n console.log(\"[HlsAdPlayer] Content continues (Live mode)\");\n }\n console.log(\"[HlsAdPlayer] FORCE MUTING main video\");\n contentVideo.muted = true;\n adPlaying = true;\n setAdPlayingFlag(true);\n if (adVideoElement) {\n adVideoElement.volume = Math.max(0, Math.min(1, originalVolume));\n adVideoElement.muted = originalMutedState;\n console.log(\n `[HlsAdPlayer] Set ad video volume to ${adVideoElement.volume}, muted: ${adVideoElement.muted}, originalMutedState: ${originalMutedState}, contentVolume: ${contentVolume}`\n );\n }\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n emit(\"content_pause\");\n const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n if (!mediaFile) {\n throw new Error(\"No media file available for ad\");\n }\n const isHlsAd = isHlsMediaFile(mediaFile);\n console.log(\n `[HlsAdPlayer] Loading ${isHlsAd ? \"HLS\" : \"progressive\"} ad from: ${mediaFile.url}`\n );\n if (isHlsAd && import_hls.default.isSupported()) {\n if (adHls) {\n adHls.destroy();\n }\n adHls = new import_hls.default({\n enableWorker: true,\n lowLatencyMode: false\n });\n adHls.loadSource(mediaFile.url);\n adHls.attachMedia(adVideoElement);\n adHls.on(import_hls.default.Events.MANIFEST_PARSED, () => {\n console.log(\"[HlsAdPlayer] HLS manifest parsed, starting playback\");\n adVideoElement.play().catch((error) => {\n console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n handleAdError();\n });\n });\n adHls.on(import_hls.default.Events.ERROR, (event, data) => {\n console.error(\"[HlsAdPlayer] HLS error:\", data);\n if (data.fatal) {\n handleAdError();\n }\n });\n } else if (isHlsAd && adVideoElement.canPlayType(\"application/vnd.apple.mpegurl\")) {\n adVideoElement.src = mediaFile.url;\n adVideoElement.play().catch((error) => {\n console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n handleAdError();\n });\n } else if (!isHlsAd && isProgressiveMediaFile(mediaFile)) {\n if (adHls) {\n adHls.destroy();\n adHls = void 0;\n }\n adVideoElement.src = mediaFile.url;\n adVideoElement.load();\n adVideoElement.play().catch((error) => {\n console.error(\"[HlsAdPlayer] Error starting progressive ad playback:\", error);\n handleAdError();\n });\n } else {\n throw new Error(`Unsupported ad media file type: ${mediaFile.type}`);\n }\n return Promise.resolve();\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error playing ad:\", error);\n handleAdError();\n return Promise.reject(error);\n }\n },\n pause() {\n if (!adPlaying || !adVideoElement) {\n return;\n }\n try {\n if (adVideoElement && !adVideoElement.paused) {\n adVideoElement.pause();\n }\n } catch (error) {\n console.warn(\"[HlsAdPlayer] Error pausing ad:\", error);\n }\n },\n resume() {\n if (!adPlaying || !adVideoElement) {\n return;\n }\n try {\n if (adVideoElement && adVideoElement.paused) {\n adVideoElement.play().catch(() => {\n });\n }\n } catch (error) {\n console.warn(\"[HlsAdPlayer] Error resuming ad:\", error);\n }\n },\n async stop() {\n console.log(\"[HlsAdPlayer] Stopping ad\");\n adPlaying = false;\n setAdPlayingFlag(false);\n const previousMutedState = contentVideo.muted;\n contentVideo.muted = originalMutedState;\n contentVideo.volume = Math.max(0, Math.min(1, originalVolume));\n console.log(\n `[HlsAdPlayer] Restored mute state on stop: ${previousMutedState} -> ${originalMutedState}, volume: ${contentVideo.volume}`\n );\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n if (options?.continueLiveStreamDuringAds) {\n if (contentVideo.paused) {\n console.log(\"[HlsAdPlayer] Content video paused in live mode, resuming playback on stop\");\n contentVideo.play().catch(() => {\n });\n }\n }\n if (adHls) {\n adHls.destroy();\n adHls = void 0;\n }\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n }\n currentAd = void 0;\n },\n destroy() {\n console.log(\"[HlsAdPlayer] Destroying\");\n destroyed = true;\n for (const timeoutId of pendingTimeouts) {\n clearTimeout(timeoutId);\n }\n pendingTimeouts = [];\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = Math.max(0, Math.min(1, originalVolume));\n if (adHls) {\n adHls.destroy();\n adHls = void 0;\n }\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 preloadedAds.clear();\n preloadingAds.clear();\n },\n isAdPlaying() {\n return adPlaying;\n },\n resize(width, height) {\n console.log(`[HlsAdPlayer] 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 console.log(\n `[HlsAdPlayer] updateOriginalMutedState called: { muted: ${originalMutedState} -> ${muted}, volume: ${originalVolume} -> ${nextVolume} }`\n );\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 const clamped = Math.max(0, Math.min(1, volume));\n adVideoElement.volume = clamped;\n adVideoElement.muted = clamped === 0;\n }\n },\n getAdVolume() {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n showPlaceholder() {\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 getLoadedAdDuration() {\n return currentAd?.duration;\n },\n getLoadedAdId() {\n return currentAd?.id;\n }\n };\n}\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n createHlsAdPlayer\n});\n","import type { AdController } from \"../types\";\nimport Hls from \"hls.js\";\n\ninterface VastMediaFile {\n url: string;\n type: string;\n width: number;\n height: number;\n bitrate?: number | undefined;\n}\n\ninterface 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\ninterface VastAd {\n id: string;\n title: string;\n duration: number;\n mediaFiles: VastMediaFile[];\n trackingUrls: VastTrackingUrls;\n clickThrough?: string | undefined;\n}\n\ntype VastParseResult =\n | { type: \"inline\"; ad: VastAd }\n | {\n type: \"wrapper\";\n vastAdTagUri: string;\n trackingUrls: VastTrackingUrls;\n clickThrough?: string | undefined;\n }\n | { type: \"empty\" };\n\nconst MAX_VAST_WRAPPER_DEPTH = 5;\n\nexport function createHlsAdPlayer(\n contentVideo: HTMLVideoElement,\n options?: {\n continueLiveStreamDuringAds?: boolean;\n licenseKey?: string;\n mainHlsInstance?: Hls;\n }\n): AdController {\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 const licenseKey = options?.licenseKey;\n const mainHlsInstance = options?.mainHlsInstance;\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 const preloadedAds = new Map<string, VastAd>();\n const preloadingAds = new Map<string, Promise<void>>();\n let destroyed = false;\n let pendingTimeouts: number[] = [];\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 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(\n `[HlsAdPlayer] Error in event listener for ${event}:`,\n error\n );\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 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 (licenseKey) {\n trackingUrl = `${trackingUrl}${\n trackingUrl.includes(\"?\") ? \"&\" : \"?\"\n }license_key=${licenseKey}`;\n }\n\n const img = new Image(1, 1);\n img.src = trackingUrl;\n console.log(`[HlsAdPlayer] Fired tracking pixel: ${trackingUrl}`);\n } catch (error) {\n console.warn(`[HlsAdPlayer] Error firing tracking pixel:`, error);\n }\n });\n }\n\n function getMainStreamQuality(): {\n width: number;\n height: number;\n bitrate: number;\n } | null {\n if (!mainHlsInstance || !mainHlsInstance.levels) {\n return null;\n }\n\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\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) {\n throw new Error(\"No media files available\");\n }\n\n const firstFile = mediaFiles[0];\n if (!firstFile) {\n throw new Error(\"No media files available\");\n }\n\n if (mediaFiles.length === 1) {\n return firstFile;\n }\n\n const mainQuality = getMainStreamQuality();\n if (!mainQuality) {\n console.log(\n \"[HlsAdPlayer] No main stream quality info, using first media file\"\n );\n return firstFile;\n }\n\n console.log(\"[HlsAdPlayer] Main stream quality:\", mainQuality);\n\n const scoredFiles = mediaFiles.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\n const fileBitrate = (file.bitrate || 5000) * 1000;\n const bitrateDiff = Math.abs(fileBitrate - mainQuality.bitrate);\n\n const score = resolutionDiff * 2 + bitrateDiff / 1000;\n\n return { file, score, resolutionDiff, bitrateDiff };\n });\n\n scoredFiles.sort((a, b) => a.score - b.score);\n\n const bestMatch = scoredFiles[0];\n if (!bestMatch) {\n console.log(\"[HlsAdPlayer] No best match found, using first media file\");\n return firstFile;\n }\n\n console.log(\"[HlsAdPlayer] Selected media file:\", {\n url: bestMatch.file.url,\n resolution: `${bestMatch.file.width}x${bestMatch.file.height}`,\n bitrate: bestMatch.file.bitrate,\n score: bestMatch.score,\n resolutionDiff: bestMatch.resolutionDiff,\n bitrateDiff: bestMatch.bitrateDiff,\n });\n\n return bestMatch.file;\n }\n\n function isHlsMediaFile(mediaFile: VastMediaFile): boolean {\n const type = mediaFile.type.toLowerCase();\n const url = mediaFile.url.toLowerCase();\n return (\n type === \"application/x-mpegurl\" ||\n type === \"application/vnd.apple.mpegurl\" ||\n type.includes(\"mpegurl\") ||\n url.includes(\".m3u8\")\n );\n }\n\n function isProgressiveMediaFile(mediaFile: VastMediaFile): boolean {\n const type = mediaFile.type.toLowerCase();\n const url = mediaFile.url.toLowerCase();\n return (\n type.startsWith(\"video/\") ||\n url.endsWith(\".mp4\") ||\n url.includes(\".mp4?\")\n );\n }\n\n function createEmptyTrackingUrls(): VastTrackingUrls {\n return {\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\n function extractTrackingUrls(xmlDoc: Document): VastTrackingUrls {\n const trackingUrls = createEmptyTrackingUrls();\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 xmlDoc.querySelectorAll(\"Error\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.error.push(url);\n });\n\n return trackingUrls;\n }\n\n function mergeTrackingUrls(\n target: VastTrackingUrls,\n source: VastTrackingUrls\n ): VastTrackingUrls {\n (Object.keys(target) as Array<keyof VastTrackingUrls>).forEach((key) => {\n if (source[key] && source[key].length > 0) {\n target[key] = target[key].concat(source[key]);\n }\n });\n return target;\n }\n\n function parseVastXml(xmlString: string): VastParseResult {\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 \"[HlsAdPlayer] XML parsing error (malformed VAST XML):\",\n parserError.textContent\n );\n return { type: \"empty\" };\n }\n\n const adElement = xmlDoc.querySelector(\"Ad\");\n if (!adElement) {\n console.warn(\"[HlsAdPlayer] No Ad element found in VAST XML\");\n return { type: \"empty\" };\n }\n\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n\n const clickThrough = xmlDoc\n .querySelector(\"ClickThrough\")\n ?.textContent?.trim();\n\n const wrapperUri = xmlDoc\n .querySelector(\"VASTAdTagURI\")\n ?.textContent?.trim();\n if (wrapperUri) {\n console.log(\n `[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ${wrapperUri}`\n );\n return {\n type: \"wrapper\",\n vastAdTagUri: wrapperUri,\n trackingUrls: extractTrackingUrls(xmlDoc),\n clickThrough,\n };\n }\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 parseInt(durationParts[2] || \"0\", 10);\n\n const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n const mediaFiles: VastMediaFile[] = [];\n\n console.log(\n `[HlsAdPlayer] 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 `[HlsAdPlayer] MediaFile ${index}: type=\"${type}\", url=\"${url}\", width=\"${width}\", height=\"${height}\"`\n );\n\n const mediaFile: VastMediaFile = {\n url,\n type,\n width: parseInt(width || \"1920\", 10),\n height: parseInt(height || \"1080\", 10),\n bitrate: undefined,\n };\n\n if (!url) {\n console.warn(`[HlsAdPlayer] MediaFile ${index} has empty URL`);\n return;\n }\n\n const bitrateAttr = mf.getAttribute(\"bitrate\");\n const bitrateValue = bitrateAttr\n ? parseInt(bitrateAttr, 10)\n : undefined;\n mediaFile.bitrate =\n bitrateValue && bitrateValue > 0 ? bitrateValue : undefined;\n\n if (isHlsMediaFile(mediaFile) || isProgressiveMediaFile(mediaFile)) {\n mediaFiles.push(mediaFile);\n console.log(\n `[HlsAdPlayer] Added ${isHlsMediaFile(mediaFile) ? \"HLS\" : \"progressive\"} MediaFile: ${url}`\n );\n } else {\n console.log(\n `[HlsAdPlayer] MediaFile ${index} ignored (type=\"${type}\" is not supported)`\n );\n }\n });\n\n if (mediaFiles.length === 0) {\n if (isNoAdAvailable) {\n console.warn(\n \"[HlsAdPlayer] No ads available (VAST response indicates no ads)\"\n );\n } else {\n console.warn(\"[HlsAdPlayer] No supported media files found in VAST XML\");\n }\n return { type: \"empty\" };\n }\n\n return {\n type: \"inline\",\n ad: {\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls: extractTrackingUrls(xmlDoc),\n clickThrough,\n },\n };\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error parsing VAST XML:\", error);\n return { type: \"empty\" };\n }\n }\n\n async function fetchVastXml(vastTagUrl: string): Promise<string> {\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 return response.text();\n }\n\n async function fetchAndParseVastAd(\n vastTagUrl: string,\n depth = 0,\n accumulatedTracking: VastTrackingUrls = createEmptyTrackingUrls()\n ): Promise<VastAd | null> {\n const vastXml = await fetchVastXml(vastTagUrl);\n console.log(\"[HlsAdPlayer] VAST XML received\");\n console.log(\n \"[HlsAdPlayer] VAST XML content (first 2000 chars):\",\n vastXml.substring(0, 2000)\n );\n\n const parsed = parseVastXml(vastXml);\n\n if (parsed.type === \"empty\") {\n return null;\n }\n\n if (parsed.type === \"wrapper\") {\n if (depth >= MAX_VAST_WRAPPER_DEPTH) {\n console.warn(\n `[HlsAdPlayer] VAST wrapper depth limit (${MAX_VAST_WRAPPER_DEPTH}) reached, aborting redirect chain`\n );\n return null;\n }\n\n mergeTrackingUrls(accumulatedTracking, parsed.trackingUrls);\n return fetchAndParseVastAd(\n parsed.vastAdTagUri,\n depth + 1,\n accumulatedTracking\n );\n }\n\n mergeTrackingUrls(parsed.ad.trackingUrls, accumulatedTracking);\n return parsed.ad;\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.playsInline = true;\n video.muted = false;\n\n video.volume = 1.0;\n console.log(\n `[HlsAdPlayer] Created ad video element with volume ${video.volume}`\n );\n\n return video;\n }\n\n function setupAdEventListeners(): void {\n if (!adVideoElement || !currentAd) return;\n\n adVideoElement.addEventListener(\"timeupdate\", () => {\n if (!currentAd || !adVideoElement) return;\n\n const progress = adVideoElement.currentTime / currentAd.duration;\n\n if (progress >= 0.25 && !trackingFired.firstQuartile) {\n trackingFired.firstQuartile = true;\n fireTrackingPixels(currentAd.trackingUrls.firstQuartile);\n }\n\n if (progress >= 0.5 && !trackingFired.midpoint) {\n trackingFired.midpoint = true;\n fireTrackingPixels(currentAd.trackingUrls.midpoint);\n }\n\n if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n trackingFired.thirdQuartile = true;\n fireTrackingPixels(currentAd.trackingUrls.thirdQuartile);\n }\n });\n\n adVideoElement.addEventListener(\"playing\", () => {\n if (!currentAd || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels(currentAd.trackingUrls.start);\n console.log(\"[HlsAdPlayer] Ad started playing\");\n });\n\n adVideoElement.addEventListener(\"ended\", () => {\n if (!currentAd || trackingFired.complete) return;\n trackingFired.complete = true;\n fireTrackingPixels(currentAd.trackingUrls.complete);\n console.log(\"[HlsAdPlayer] Ad completed\");\n\n handleAdComplete();\n });\n\n adVideoElement.addEventListener(\"error\", (e) => {\n console.error(\"[HlsAdPlayer] Ad video error:\", e);\n if (currentAd) {\n fireTrackingPixels(currentAd.trackingUrls.error);\n }\n handleAdError();\n });\n\n adVideoElement.addEventListener(\"volumechange\", () => {\n if (!currentAd) return;\n if (adVideoElement!.muted) {\n fireTrackingPixels(currentAd.trackingUrls.mute);\n } else {\n fireTrackingPixels(currentAd.trackingUrls.unmute);\n }\n });\n\n adVideoElement.addEventListener(\"pause\", () => {\n if (currentAd && !adVideoElement!.ended) {\n fireTrackingPixels(currentAd.trackingUrls.pause);\n }\n });\n\n adVideoElement.addEventListener(\"play\", () => {\n if (currentAd && adVideoElement!.currentTime > 0) {\n fireTrackingPixels(currentAd.trackingUrls.resume);\n }\n });\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 handleAdComplete(): void {\n console.log(\"[HlsAdPlayer] Handling ad completion\");\n adPlaying = false;\n setAdPlayingFlag(false);\n\n contentVideo.muted = true;\n\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n \n if (options?.continueLiveStreamDuringAds) {\n if (contentVideo.paused) {\n console.log(\"[HlsAdPlayer] Content video paused in live mode, resuming playback\");\n contentVideo.play().catch(() => {});\n } else {\n console.log(\"[HlsAdPlayer] Content video already playing in live mode\");\n }\n }\n\n emit(\"content_resume\");\n }\n\n function handleAdError(): void {\n console.log(\"[HlsAdPlayer] Handling ad error\");\n adPlaying = false;\n setAdPlayingFlag(false);\n\n contentVideo.muted = true;\n\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n\n emit(\"ad_error\");\n }\n\n return {\n initialize() {\n console.log(\"[HlsAdPlayer] 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 = \"30\";\n container.style.backgroundColor = \"#000\";\n\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n },\n\n async requestAds(vastTagUrl: string) {\n console.log(\"[HlsAdPlayer] Requesting ads:\", vastTagUrl);\n\n if (adPlaying) {\n console.warn(\n \"[HlsAdPlayer] Cannot request new ads while an ad is playing\"\n );\n return Promise.reject(new Error(\"Ad already playing\"));\n }\n\n try {\n sessionId = generateSessionId();\n let ad: VastAd | null | undefined;\n\n if (preloadedAds.has(vastTagUrl)) {\n ad = preloadedAds.get(vastTagUrl);\n preloadedAds.delete(vastTagUrl);\n console.log(\n \"[HlsAdPlayer] Using preloaded VAST response:\",\n vastTagUrl\n );\n } else {\n ad = await fetchAndParseVastAd(vastTagUrl);\n }\n\n if (!ad) {\n console.warn(\"[HlsAdPlayer] No ads available from VAST response\");\n emit(\"ad_error\");\n return Promise.reject(new Error(\"No ads available from VAST response\"));\n }\n\n currentAd = ad;\n console.log(\n `[HlsAdPlayer] Ad parsed: ${ad.title}, duration: ${ad.duration}s`\n );\n\n fireTrackingPixels(ad.trackingUrls.impression);\n trackingFired.impression = true;\n\n return Promise.resolve();\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error requesting ads:\", error);\n emit(\"ad_error\");\n return Promise.reject(error);\n }\n },\n async play() {\n if (!currentAd) {\n console.warn(\n \"[HlsAdPlayer] Cannot play: No ad loaded (no ads available)\"\n );\n return Promise.reject(new Error(\"No ad loaded\"));\n }\n\n console.log(\"[HlsAdPlayer] 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 const contentVolume = contentVideo.volume;\n originalVolume = Math.max(\n 0,\n Math.min(1, contentVolume || originalVolume)\n );\n\n if (!options?.continueLiveStreamDuringAds) {\n contentVideo.pause();\n console.log(\"[HlsAdPlayer] Content paused (VOD mode)\");\n } else {\n console.log(\"[HlsAdPlayer] Content continues (Live mode)\");\n }\n\n console.log(\"[HlsAdPlayer] FORCE MUTING main video\");\n contentVideo.muted = true;\n adPlaying = true;\n setAdPlayingFlag(true);\n\n if (adVideoElement) {\n adVideoElement.volume = Math.max(0, Math.min(1, originalVolume));\n adVideoElement.muted = originalMutedState;\n console.log(\n `[HlsAdPlayer] Set ad video volume to ${adVideoElement.volume}, muted: ${adVideoElement.muted}, originalMutedState: ${originalMutedState}, contentVolume: ${contentVolume}`\n );\n }\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(currentAd.mediaFiles);\n if (!mediaFile) {\n throw new Error(\"No media file available for ad\");\n }\n\n const isHlsAd = isHlsMediaFile(mediaFile);\n console.log(\n `[HlsAdPlayer] Loading ${isHlsAd ? \"HLS\" : \"progressive\"} ad from: ${mediaFile.url}`\n );\n\n if (isHlsAd && Hls.isSupported()) {\n if (adHls) {\n adHls.destroy();\n }\n\n adHls = new Hls({\n enableWorker: true,\n lowLatencyMode: false,\n });\n\n adHls.loadSource(mediaFile.url);\n adHls.attachMedia(adVideoElement);\n\n adHls.on(Hls.Events.MANIFEST_PARSED, () => {\n console.log(\"[HlsAdPlayer] HLS manifest parsed, starting playback\");\n adVideoElement!.play().catch((error) => {\n console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n handleAdError();\n });\n });\n\n adHls.on(Hls.Events.ERROR, (event, data) => {\n console.error(\"[HlsAdPlayer] HLS error:\", data);\n if (data.fatal) {\n handleAdError();\n }\n });\n } else if (isHlsAd && (\n adVideoElement.canPlayType(\"application/vnd.apple.mpegurl\")\n )) {\n adVideoElement.src = mediaFile.url;\n adVideoElement.play().catch((error) => {\n console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n handleAdError();\n });\n } else if (!isHlsAd && isProgressiveMediaFile(mediaFile)) {\n if (adHls) {\n adHls.destroy();\n adHls = undefined;\n }\n\n adVideoElement.src = mediaFile.url;\n adVideoElement.load();\n adVideoElement.play().catch((error) => {\n console.error(\"[HlsAdPlayer] Error starting progressive ad playback:\", error);\n handleAdError();\n });\n } else {\n throw new Error(`Unsupported ad media file type: ${mediaFile.type}`);\n }\n\n return Promise.resolve();\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error playing ad:\", error);\n handleAdError();\n return Promise.reject(error);\n }\n },\n pause() {\n if (!adPlaying || !adVideoElement) {\n return;\n }\n\n try {\n if (adVideoElement && !adVideoElement.paused) {\n adVideoElement.pause();\n }\n } catch (error) {\n console.warn(\"[HlsAdPlayer] Error pausing ad:\", error);\n }\n },\n resume() {\n if (!adPlaying || !adVideoElement) {\n return;\n }\n\n try {\n if (adVideoElement && adVideoElement.paused) {\n adVideoElement.play().catch(() => {});\n }\n } catch (error) {\n console.warn(\"[HlsAdPlayer] Error resuming ad:\", error);\n }\n },\n async stop() {\n console.log(\"[HlsAdPlayer] Stopping ad\");\n adPlaying = false;\n setAdPlayingFlag(false);\n\n const previousMutedState = contentVideo.muted;\n contentVideo.muted = originalMutedState;\n contentVideo.volume = Math.max(0, Math.min(1, originalVolume));\n console.log(\n `[HlsAdPlayer] Restored mute state on stop: ${previousMutedState} -> ${originalMutedState}, volume: ${contentVideo.volume}`\n );\n\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n\n if (options?.continueLiveStreamDuringAds) {\n if (contentVideo.paused) {\n console.log(\"[HlsAdPlayer] Content video paused in live mode, resuming playback on stop\");\n contentVideo.play().catch(() => {});\n }\n }\n\n if (adHls) {\n adHls.destroy();\n adHls = undefined;\n }\n\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n }\n\n currentAd = undefined;\n },\n\n destroy() {\n console.log(\"[HlsAdPlayer] Destroying\");\n destroyed = true;\n \n for (const timeoutId of pendingTimeouts) {\n clearTimeout(timeoutId);\n }\n pendingTimeouts = [];\n \n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = Math.max(0, Math.min(1, originalVolume));\n\n if (adHls) {\n adHls.destroy();\n adHls = undefined;\n }\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 preloadedAds.clear();\n preloadingAds.clear();\n },\n\n isAdPlaying() {\n return adPlaying;\n },\n\n resize(width: number, height: number) {\n console.log(`[HlsAdPlayer] 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 console.log(\n `[HlsAdPlayer] updateOriginalMutedState called: { muted: ${originalMutedState} -> ${muted}, volume: ${originalVolume} -> ${nextVolume} }`\n );\n originalMutedState = muted;\n originalVolume = nextVolume;\n },\n\n getOriginalMutedState() {\n return originalMutedState;\n },\n getOriginalVolume() {\n return originalVolume;\n },\n\n setAdVolume(volume: number) {\n if (adVideoElement && adPlaying) {\n const clamped = Math.max(0, Math.min(1, volume));\n adVideoElement.volume = clamped;\n adVideoElement.muted = clamped === 0;\n }\n },\n\n getAdVolume(): number {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n showPlaceholder() {\n contentVideo.style.opacity = \"0\";\n contentVideo.style.visibility = \"hidden\";\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\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\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 \n if (!adPlaying) {\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n }\n },\n getLoadedAdDuration() {\n return currentAd?.duration;\n },\n getLoadedAdId() {\n return currentAd?.id;\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/sdk/hlsAdPlayer.cjs","../../src/sdk/hlsAdPlayer.ts"],"names":["__create","Object","create","__defProp","__getOwnPropDesc","defineProperty","getOwnPropertyDescriptor","__getProtoOf","getPrototypeOf","__hasOwnProp","prototype","hasOwnProperty","__export","target","all","name","get","enumerable","__copyProps","to","from","except","desc","key","call","__getOwnPropNames","__toESM","mod","isNodeMode","__esModule","value","__toCommonJS","hlsAdPlayer_exports","createHlsAdPlayer","module","exports","import_hls","require","MAX_VAST_WRAPPER_DEPTH","contentVideo","options","adPlaying","originalMutedState","originalVolume","Math","max","min","volume","listeners","Map","licenseKey","mainHlsInstance","adVideoElement","adHls","adContainerEl","currentAd","sessionId","preloadedAds","preloadingAds","destroyed","pendingTimeouts","trackingFired","impression","start","firstQuartile","midpoint","thirdQuartile","complete","fireTrackingPixels","urls","emit","event","payload","set","Array","fn","error","console","warn","generateSessionId","Date","now","random","toString","substr","length","forEach","url","trackingUrl","includes","img","Image","src","log","getMainStreamQuality","levels","currentLevel","autoLevel","loadLevel","level","width","height","bitrate","selectBestMediaFile","mediaFiles","firstFile","Error","mainQuality","scoredFiles","map","file","widthDiff","abs","heightDiff","resolutionDiff","fileBitrate","bitrateDiff","score","sort","a","b","bestMatch","resolution","isHlsMediaFile","mediaFile","type","toLowerCase","isProgressiveMediaFile","startsWith","endsWith","createEmptyTrackingUrls","mute","unmute","pause","resume","fullscreen","exitFullscreen","skip","extractTrackingUrls","xmlDoc","trackingUrls","querySelectorAll","el","textContent","trim","push","getAttribute","eventKey","mergeTrackingUrls","source","keys","concat","parseVastXml","xmlString","parser","DOMParser","parseFromString","parserError","querySelector","adElement","adId","title","clickThrough","wrapperUri","vastAdTagUri","isNoAdAvailable","durationText","durationParts","split","duration","parseInt","mediaFileElements","mf","index","bitrateAttr","bitrateValue","ad","id","fetchVastXml","vastTagUrl","fetch","mode","credentials","response","ok","statusText","text","fetchAndParseVastAd","depth","accumulatedTracking","vastXml","parsed","video","document","muted","substring","createAdVideoElement","createElement","style","position","left","top","objectFit","backgroundColor","playsInline","setupAdEventListeners","addEventListener","progress","currentTime","handleAdComplete","e","handleAdError","ended","setAdPlayingFlag","isPlaying","dataset","stormcloudAdPlaying","display","pointerEvents","continueLiveStreamDuringAds","paused","play","catch","initialize","container","right","bottom","alignItems","justifyContent","zIndex","parentElement","appendChild","requestAds","Promise","reject","has","delete","resolve","contentVolume","isHlsAd"],"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/hlsAdPlayer.ts\nvar hlsAdPlayer_exports = {};\n__export(hlsAdPlayer_exports, {\n createHlsAdPlayer: () => createHlsAdPlayer\n});\nmodule.exports = __toCommonJS(hlsAdPlayer_exports);\nvar import_hls = __toESM(require(\"hls.js\"), 1);\nvar MAX_VAST_WRAPPER_DEPTH = 5;\nfunction createHlsAdPlayer(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 const licenseKey = options?.licenseKey;\n const mainHlsInstance = options?.mainHlsInstance;\n let adVideoElement;\n let adHls;\n let adContainerEl;\n let currentAd;\n let sessionId;\n const preloadedAds = /* @__PURE__ */ new Map();\n const preloadingAds = /* @__PURE__ */ new Map();\n let destroyed = false;\n let pendingTimeouts = [];\n let trackingFired = {\n impression: false,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false\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(\n `[HlsAdPlayer] Error in event listener for ${event}:`,\n error\n );\n }\n }\n }\n function generateSessionId() {\n return `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n function fireTrackingPixels(urls) {\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 (licenseKey) {\n trackingUrl = `${trackingUrl}${trackingUrl.includes(\"?\") ? \"&\" : \"?\"}license_key=${licenseKey}`;\n }\n const img = new Image(1, 1);\n img.src = trackingUrl;\n console.log(`[HlsAdPlayer] Fired tracking pixel: ${trackingUrl}`);\n } catch (error) {\n console.warn(`[HlsAdPlayer] Error firing tracking pixel:`, error);\n }\n });\n }\n function getMainStreamQuality() {\n if (!mainHlsInstance || !mainHlsInstance.levels) {\n return null;\n }\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) {\n throw new Error(\"No media files available\");\n }\n const firstFile = mediaFiles[0];\n if (!firstFile) {\n throw new Error(\"No media files available\");\n }\n if (mediaFiles.length === 1) {\n return firstFile;\n }\n const mainQuality = getMainStreamQuality();\n if (!mainQuality) {\n console.log(\n \"[HlsAdPlayer] No main stream quality info, using first media file\"\n );\n return firstFile;\n }\n console.log(\"[HlsAdPlayer] Main stream quality:\", mainQuality);\n const scoredFiles = mediaFiles.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, resolutionDiff, bitrateDiff };\n });\n scoredFiles.sort((a, b) => a.score - b.score);\n const bestMatch = scoredFiles[0];\n if (!bestMatch) {\n console.log(\"[HlsAdPlayer] No best match found, using first media file\");\n return firstFile;\n }\n console.log(\"[HlsAdPlayer] Selected media file:\", {\n url: bestMatch.file.url,\n resolution: `${bestMatch.file.width}x${bestMatch.file.height}`,\n bitrate: bestMatch.file.bitrate,\n score: bestMatch.score,\n resolutionDiff: bestMatch.resolutionDiff,\n bitrateDiff: bestMatch.bitrateDiff\n });\n return bestMatch.file;\n }\n function isHlsMediaFile(mediaFile) {\n const type = mediaFile.type.toLowerCase();\n const url = mediaFile.url.toLowerCase();\n return type === \"application/x-mpegurl\" || type === \"application/vnd.apple.mpegurl\" || type.includes(\"mpegurl\") || url.includes(\".m3u8\");\n }\n function isProgressiveMediaFile(mediaFile) {\n const type = mediaFile.type.toLowerCase();\n const url = mediaFile.url.toLowerCase();\n return type.startsWith(\"video/\") || url.endsWith(\".mp4\") || url.includes(\".mp4?\");\n }\n function createEmptyTrackingUrls() {\n return {\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 function extractTrackingUrls(xmlDoc) {\n const trackingUrls = createEmptyTrackingUrls();\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 xmlDoc.querySelectorAll(\"Error\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.error.push(url);\n });\n return trackingUrls;\n }\n function mergeTrackingUrls(target, source) {\n Object.keys(target).forEach((key) => {\n if (source[key] && source[key].length > 0) {\n target[key] = target[key].concat(source[key]);\n }\n });\n return target;\n }\n function parseVastXml(xmlString) {\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 \"[HlsAdPlayer] XML parsing error (malformed VAST XML):\",\n parserError.textContent\n );\n return { type: \"empty\" };\n }\n const adElement = xmlDoc.querySelector(\"Ad\");\n if (!adElement) {\n console.warn(\"[HlsAdPlayer] No Ad element found in VAST XML\");\n return { type: \"empty\" };\n }\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n const clickThrough = xmlDoc.querySelector(\"ClickThrough\")?.textContent?.trim();\n const wrapperUri = xmlDoc.querySelector(\"VASTAdTagURI\")?.textContent?.trim();\n if (wrapperUri) {\n console.log(\n `[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ${wrapperUri}`\n );\n return {\n type: \"wrapper\",\n vastAdTagUri: wrapperUri,\n trackingUrls: extractTrackingUrls(xmlDoc),\n clickThrough\n };\n }\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 + parseInt(durationParts[2] || \"0\", 10);\n const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n const mediaFiles = [];\n console.log(\n `[HlsAdPlayer] 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 `[HlsAdPlayer] MediaFile ${index}: type=\"${type}\", url=\"${url}\", width=\"${width}\", height=\"${height}\"`\n );\n const mediaFile = {\n url,\n type,\n width: parseInt(width || \"1920\", 10),\n height: parseInt(height || \"1080\", 10),\n bitrate: void 0\n };\n if (!url) {\n console.warn(`[HlsAdPlayer] MediaFile ${index} has empty URL`);\n return;\n }\n const bitrateAttr = mf.getAttribute(\"bitrate\");\n const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;\n mediaFile.bitrate = bitrateValue && bitrateValue > 0 ? bitrateValue : void 0;\n if (isHlsMediaFile(mediaFile) || isProgressiveMediaFile(mediaFile)) {\n mediaFiles.push(mediaFile);\n console.log(\n `[HlsAdPlayer] Added ${isHlsMediaFile(mediaFile) ? \"HLS\" : \"progressive\"} MediaFile: ${url}`\n );\n } else {\n console.log(\n `[HlsAdPlayer] MediaFile ${index} ignored (type=\"${type}\" is not supported)`\n );\n }\n });\n if (mediaFiles.length === 0) {\n if (isNoAdAvailable) {\n console.warn(\n \"[HlsAdPlayer] No ads available (VAST response indicates no ads)\"\n );\n } else {\n console.warn(\"[HlsAdPlayer] No supported media files found in VAST XML\");\n }\n return { type: \"empty\" };\n }\n return {\n type: \"inline\",\n ad: {\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls: extractTrackingUrls(xmlDoc),\n clickThrough\n }\n };\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error parsing VAST XML:\", error);\n return { type: \"empty\" };\n }\n }\n async function fetchVastXml(vastTagUrl) {\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 return response.text();\n }\n async function fetchAndParseVastAd(vastTagUrl, depth = 0, accumulatedTracking = createEmptyTrackingUrls()) {\n const vastXml = await fetchVastXml(vastTagUrl);\n console.log(\"[HlsAdPlayer] VAST XML received\");\n console.log(\n \"[HlsAdPlayer] VAST XML content (first 2000 chars):\",\n vastXml.substring(0, 2e3)\n );\n const parsed = parseVastXml(vastXml);\n if (parsed.type === \"empty\") {\n return null;\n }\n if (parsed.type === \"wrapper\") {\n if (depth >= MAX_VAST_WRAPPER_DEPTH) {\n console.warn(\n `[HlsAdPlayer] VAST wrapper depth limit (${MAX_VAST_WRAPPER_DEPTH}) reached, aborting redirect chain`\n );\n return null;\n }\n mergeTrackingUrls(accumulatedTracking, parsed.trackingUrls);\n return fetchAndParseVastAd(\n parsed.vastAdTagUri,\n depth + 1,\n accumulatedTracking\n );\n }\n mergeTrackingUrls(parsed.ad.trackingUrls, accumulatedTracking);\n return parsed.ad;\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.playsInline = true;\n video.muted = false;\n video.volume = 1;\n console.log(\n `[HlsAdPlayer] Created ad video element with volume ${video.volume}`\n );\n return video;\n }\n function setupAdEventListeners() {\n if (!adVideoElement || !currentAd) return;\n adVideoElement.addEventListener(\"timeupdate\", () => {\n if (!currentAd || !adVideoElement) return;\n const progress = adVideoElement.currentTime / currentAd.duration;\n if (progress >= 0.25 && !trackingFired.firstQuartile) {\n trackingFired.firstQuartile = true;\n fireTrackingPixels(currentAd.trackingUrls.firstQuartile);\n }\n if (progress >= 0.5 && !trackingFired.midpoint) {\n trackingFired.midpoint = true;\n fireTrackingPixels(currentAd.trackingUrls.midpoint);\n }\n if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n trackingFired.thirdQuartile = true;\n fireTrackingPixels(currentAd.trackingUrls.thirdQuartile);\n }\n });\n adVideoElement.addEventListener(\"playing\", () => {\n if (!currentAd || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels(currentAd.trackingUrls.start);\n console.log(\"[HlsAdPlayer] Ad started playing\");\n });\n adVideoElement.addEventListener(\"ended\", () => {\n if (!currentAd || trackingFired.complete) return;\n trackingFired.complete = true;\n fireTrackingPixels(currentAd.trackingUrls.complete);\n console.log(\"[HlsAdPlayer] Ad completed\");\n handleAdComplete();\n });\n adVideoElement.addEventListener(\"error\", (e) => {\n if (!adPlaying) return;\n console.error(\"[HlsAdPlayer] Ad video error:\", e);\n if (currentAd) {\n fireTrackingPixels(currentAd.trackingUrls.error);\n }\n handleAdError();\n });\n adVideoElement.addEventListener(\"volumechange\", () => {\n if (!currentAd) return;\n if (adVideoElement.muted) {\n fireTrackingPixels(currentAd.trackingUrls.mute);\n } else {\n fireTrackingPixels(currentAd.trackingUrls.unmute);\n }\n });\n adVideoElement.addEventListener(\"pause\", () => {\n if (currentAd && !adVideoElement.ended) {\n fireTrackingPixels(currentAd.trackingUrls.pause);\n }\n });\n adVideoElement.addEventListener(\"play\", () => {\n if (currentAd && adVideoElement.currentTime > 0) {\n fireTrackingPixels(currentAd.trackingUrls.resume);\n }\n });\n }\n function setAdPlayingFlag(isPlaying) {\n if (isPlaying) {\n contentVideo.dataset.stormcloudAdPlaying = \"true\";\n } else {\n delete contentVideo.dataset.stormcloudAdPlaying;\n }\n }\n function handleAdComplete() {\n console.log(\"[HlsAdPlayer] Handling ad completion\");\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = true;\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n if (options?.continueLiveStreamDuringAds) {\n if (contentVideo.paused) {\n console.log(\"[HlsAdPlayer] Content video paused in live mode, resuming playback\");\n contentVideo.play().catch(() => {\n });\n } else {\n console.log(\"[HlsAdPlayer] Content video already playing in live mode\");\n }\n }\n emit(\"content_resume\");\n }\n function handleAdError() {\n console.log(\"[HlsAdPlayer] Handling ad error\");\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = true;\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n emit(\"ad_error\");\n }\n return {\n initialize() {\n console.log(\"[HlsAdPlayer] 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 = \"30\";\n container.style.backgroundColor = \"#000\";\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n },\n async requestAds(vastTagUrl) {\n console.log(\"[HlsAdPlayer] Requesting ads:\", vastTagUrl);\n if (adPlaying) {\n console.warn(\n \"[HlsAdPlayer] Cannot request new ads while an ad is playing\"\n );\n return Promise.reject(new Error(\"Ad already playing\"));\n }\n try {\n sessionId = generateSessionId();\n let ad;\n if (preloadedAds.has(vastTagUrl)) {\n ad = preloadedAds.get(vastTagUrl);\n preloadedAds.delete(vastTagUrl);\n console.log(\n \"[HlsAdPlayer] Using preloaded VAST response:\",\n vastTagUrl\n );\n } else {\n ad = await fetchAndParseVastAd(vastTagUrl);\n }\n if (!ad) {\n console.warn(\"[HlsAdPlayer] No ads available from VAST response\");\n emit(\"ad_error\");\n return Promise.reject(new Error(\"No ads available from VAST response\"));\n }\n currentAd = ad;\n console.log(\n `[HlsAdPlayer] Ad parsed: ${ad.title}, duration: ${ad.duration}s`\n );\n fireTrackingPixels(ad.trackingUrls.impression);\n trackingFired.impression = true;\n return Promise.resolve();\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error requesting ads:\", error);\n emit(\"ad_error\");\n return Promise.reject(error);\n }\n },\n async play() {\n if (!currentAd) {\n console.warn(\n \"[HlsAdPlayer] Cannot play: No ad loaded (no ads available)\"\n );\n return Promise.reject(new Error(\"No ad loaded\"));\n }\n console.log(\"[HlsAdPlayer] 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 const contentVolume = contentVideo.volume;\n originalVolume = Math.max(\n 0,\n Math.min(1, contentVolume || originalVolume)\n );\n if (!options?.continueLiveStreamDuringAds) {\n contentVideo.pause();\n console.log(\"[HlsAdPlayer] Content paused (VOD mode)\");\n } else {\n console.log(\"[HlsAdPlayer] Content continues (Live mode)\");\n }\n console.log(\"[HlsAdPlayer] FORCE MUTING main video\");\n contentVideo.muted = true;\n adPlaying = true;\n setAdPlayingFlag(true);\n if (adVideoElement) {\n adVideoElement.volume = Math.max(0, Math.min(1, originalVolume));\n adVideoElement.muted = originalMutedState;\n console.log(\n `[HlsAdPlayer] Set ad video volume to ${adVideoElement.volume}, muted: ${adVideoElement.muted}, originalMutedState: ${originalMutedState}, contentVolume: ${contentVolume}`\n );\n }\n const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n if (!mediaFile) {\n throw new Error(\"No media file available for ad\");\n }\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n emit(\"content_pause\");\n const isHlsAd = isHlsMediaFile(mediaFile);\n console.log(\n `[HlsAdPlayer] Loading ${isHlsAd ? \"HLS\" : \"progressive\"} ad from: ${mediaFile.url}`\n );\n if (isHlsAd && import_hls.default.isSupported()) {\n if (adHls) {\n adHls.destroy();\n }\n adHls = new import_hls.default({\n enableWorker: true,\n lowLatencyMode: false\n });\n adHls.loadSource(mediaFile.url);\n adHls.attachMedia(adVideoElement);\n adHls.on(import_hls.default.Events.MANIFEST_PARSED, () => {\n console.log(\"[HlsAdPlayer] HLS manifest parsed, starting playback\");\n adVideoElement.play().catch((error) => {\n console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n handleAdError();\n });\n });\n adHls.on(import_hls.default.Events.ERROR, (event, data) => {\n console.error(\"[HlsAdPlayer] HLS error:\", data);\n if (data.fatal) {\n handleAdError();\n }\n });\n } else if (isHlsAd && adVideoElement.canPlayType(\"application/vnd.apple.mpegurl\")) {\n adVideoElement.src = mediaFile.url;\n adVideoElement.play().catch((error) => {\n console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n handleAdError();\n });\n } else if (!isHlsAd && isProgressiveMediaFile(mediaFile)) {\n if (adHls) {\n adHls.destroy();\n adHls = void 0;\n }\n adVideoElement.src = mediaFile.url;\n adVideoElement.load();\n adVideoElement.play().catch((error) => {\n console.error(\"[HlsAdPlayer] Error starting progressive ad playback:\", error);\n handleAdError();\n });\n } else {\n throw new Error(`Unsupported ad media file type: ${mediaFile.type}`);\n }\n return Promise.resolve();\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error playing ad:\", error);\n handleAdError();\n return Promise.reject(error);\n }\n },\n pause() {\n if (!adPlaying || !adVideoElement) {\n return;\n }\n try {\n if (adVideoElement && !adVideoElement.paused) {\n adVideoElement.pause();\n }\n } catch (error) {\n console.warn(\"[HlsAdPlayer] Error pausing ad:\", error);\n }\n },\n resume() {\n if (!adPlaying || !adVideoElement) {\n return;\n }\n try {\n if (adVideoElement && adVideoElement.paused) {\n adVideoElement.play().catch(() => {\n });\n }\n } catch (error) {\n console.warn(\"[HlsAdPlayer] Error resuming ad:\", error);\n }\n },\n async stop() {\n console.log(\"[HlsAdPlayer] Stopping ad\");\n adPlaying = false;\n setAdPlayingFlag(false);\n const previousMutedState = contentVideo.muted;\n contentVideo.muted = originalMutedState;\n contentVideo.volume = Math.max(0, Math.min(1, originalVolume));\n console.log(\n `[HlsAdPlayer] Restored mute state on stop: ${previousMutedState} -> ${originalMutedState}, volume: ${contentVideo.volume}`\n );\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n if (options?.continueLiveStreamDuringAds) {\n if (contentVideo.paused) {\n console.log(\"[HlsAdPlayer] Content video paused in live mode, resuming playback on stop\");\n contentVideo.play().catch(() => {\n });\n }\n }\n if (adHls) {\n adHls.destroy();\n adHls = void 0;\n }\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n }\n currentAd = void 0;\n },\n destroy() {\n console.log(\"[HlsAdPlayer] Destroying\");\n destroyed = true;\n for (const timeoutId of pendingTimeouts) {\n clearTimeout(timeoutId);\n }\n pendingTimeouts = [];\n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = Math.max(0, Math.min(1, originalVolume));\n if (adHls) {\n adHls.destroy();\n adHls = void 0;\n }\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 preloadedAds.clear();\n preloadingAds.clear();\n },\n isAdPlaying() {\n return adPlaying;\n },\n resize(width, height) {\n console.log(`[HlsAdPlayer] 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 console.log(\n `[HlsAdPlayer] updateOriginalMutedState called: { muted: ${originalMutedState} -> ${muted}, volume: ${originalVolume} -> ${nextVolume} }`\n );\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 const clamped = Math.max(0, Math.min(1, volume));\n adVideoElement.volume = clamped;\n adVideoElement.muted = clamped === 0;\n }\n },\n getAdVolume() {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n showPlaceholder() {\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 getLoadedAdDuration() {\n return currentAd?.duration;\n },\n getLoadedAdId() {\n return currentAd?.id;\n }\n };\n}\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n createHlsAdPlayer\n});\n","import type { AdController } from \"../types\";\nimport Hls from \"hls.js\";\n\ninterface VastMediaFile {\n url: string;\n type: string;\n width: number;\n height: number;\n bitrate?: number | undefined;\n}\n\ninterface 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\ninterface VastAd {\n id: string;\n title: string;\n duration: number;\n mediaFiles: VastMediaFile[];\n trackingUrls: VastTrackingUrls;\n clickThrough?: string | undefined;\n}\n\ntype VastParseResult =\n | { type: \"inline\"; ad: VastAd }\n | {\n type: \"wrapper\";\n vastAdTagUri: string;\n trackingUrls: VastTrackingUrls;\n clickThrough?: string | undefined;\n }\n | { type: \"empty\" };\n\nconst MAX_VAST_WRAPPER_DEPTH = 5;\n\nexport function createHlsAdPlayer(\n contentVideo: HTMLVideoElement,\n options?: {\n continueLiveStreamDuringAds?: boolean;\n licenseKey?: string;\n mainHlsInstance?: Hls;\n }\n): AdController {\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 const licenseKey = options?.licenseKey;\n const mainHlsInstance = options?.mainHlsInstance;\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 const preloadedAds = new Map<string, VastAd>();\n const preloadingAds = new Map<string, Promise<void>>();\n let destroyed = false;\n let pendingTimeouts: number[] = [];\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 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(\n `[HlsAdPlayer] Error in event listener for ${event}:`,\n error\n );\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 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 (licenseKey) {\n trackingUrl = `${trackingUrl}${\n trackingUrl.includes(\"?\") ? \"&\" : \"?\"\n }license_key=${licenseKey}`;\n }\n\n const img = new Image(1, 1);\n img.src = trackingUrl;\n console.log(`[HlsAdPlayer] Fired tracking pixel: ${trackingUrl}`);\n } catch (error) {\n console.warn(`[HlsAdPlayer] Error firing tracking pixel:`, error);\n }\n });\n }\n\n function getMainStreamQuality(): {\n width: number;\n height: number;\n bitrate: number;\n } | null {\n if (!mainHlsInstance || !mainHlsInstance.levels) {\n return null;\n }\n\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\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) {\n throw new Error(\"No media files available\");\n }\n\n const firstFile = mediaFiles[0];\n if (!firstFile) {\n throw new Error(\"No media files available\");\n }\n\n if (mediaFiles.length === 1) {\n return firstFile;\n }\n\n const mainQuality = getMainStreamQuality();\n if (!mainQuality) {\n console.log(\n \"[HlsAdPlayer] No main stream quality info, using first media file\"\n );\n return firstFile;\n }\n\n console.log(\"[HlsAdPlayer] Main stream quality:\", mainQuality);\n\n const scoredFiles = mediaFiles.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\n const fileBitrate = (file.bitrate || 5000) * 1000;\n const bitrateDiff = Math.abs(fileBitrate - mainQuality.bitrate);\n\n const score = resolutionDiff * 2 + bitrateDiff / 1000;\n\n return { file, score, resolutionDiff, bitrateDiff };\n });\n\n scoredFiles.sort((a, b) => a.score - b.score);\n\n const bestMatch = scoredFiles[0];\n if (!bestMatch) {\n console.log(\"[HlsAdPlayer] No best match found, using first media file\");\n return firstFile;\n }\n\n console.log(\"[HlsAdPlayer] Selected media file:\", {\n url: bestMatch.file.url,\n resolution: `${bestMatch.file.width}x${bestMatch.file.height}`,\n bitrate: bestMatch.file.bitrate,\n score: bestMatch.score,\n resolutionDiff: bestMatch.resolutionDiff,\n bitrateDiff: bestMatch.bitrateDiff,\n });\n\n return bestMatch.file;\n }\n\n function isHlsMediaFile(mediaFile: VastMediaFile): boolean {\n const type = mediaFile.type.toLowerCase();\n const url = mediaFile.url.toLowerCase();\n return (\n type === \"application/x-mpegurl\" ||\n type === \"application/vnd.apple.mpegurl\" ||\n type.includes(\"mpegurl\") ||\n url.includes(\".m3u8\")\n );\n }\n\n function isProgressiveMediaFile(mediaFile: VastMediaFile): boolean {\n const type = mediaFile.type.toLowerCase();\n const url = mediaFile.url.toLowerCase();\n return (\n type.startsWith(\"video/\") ||\n url.endsWith(\".mp4\") ||\n url.includes(\".mp4?\")\n );\n }\n\n function createEmptyTrackingUrls(): VastTrackingUrls {\n return {\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\n function extractTrackingUrls(xmlDoc: Document): VastTrackingUrls {\n const trackingUrls = createEmptyTrackingUrls();\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 xmlDoc.querySelectorAll(\"Error\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.error.push(url);\n });\n\n return trackingUrls;\n }\n\n function mergeTrackingUrls(\n target: VastTrackingUrls,\n source: VastTrackingUrls\n ): VastTrackingUrls {\n (Object.keys(target) as Array<keyof VastTrackingUrls>).forEach((key) => {\n if (source[key] && source[key].length > 0) {\n target[key] = target[key].concat(source[key]);\n }\n });\n return target;\n }\n\n function parseVastXml(xmlString: string): VastParseResult {\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 \"[HlsAdPlayer] XML parsing error (malformed VAST XML):\",\n parserError.textContent\n );\n return { type: \"empty\" };\n }\n\n const adElement = xmlDoc.querySelector(\"Ad\");\n if (!adElement) {\n console.warn(\"[HlsAdPlayer] No Ad element found in VAST XML\");\n return { type: \"empty\" };\n }\n\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n\n const clickThrough = xmlDoc\n .querySelector(\"ClickThrough\")\n ?.textContent?.trim();\n\n const wrapperUri = xmlDoc\n .querySelector(\"VASTAdTagURI\")\n ?.textContent?.trim();\n if (wrapperUri) {\n console.log(\n `[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ${wrapperUri}`\n );\n return {\n type: \"wrapper\",\n vastAdTagUri: wrapperUri,\n trackingUrls: extractTrackingUrls(xmlDoc),\n clickThrough,\n };\n }\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 parseInt(durationParts[2] || \"0\", 10);\n\n const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n const mediaFiles: VastMediaFile[] = [];\n\n console.log(\n `[HlsAdPlayer] 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 `[HlsAdPlayer] MediaFile ${index}: type=\"${type}\", url=\"${url}\", width=\"${width}\", height=\"${height}\"`\n );\n\n const mediaFile: VastMediaFile = {\n url,\n type,\n width: parseInt(width || \"1920\", 10),\n height: parseInt(height || \"1080\", 10),\n bitrate: undefined,\n };\n\n if (!url) {\n console.warn(`[HlsAdPlayer] MediaFile ${index} has empty URL`);\n return;\n }\n\n const bitrateAttr = mf.getAttribute(\"bitrate\");\n const bitrateValue = bitrateAttr\n ? parseInt(bitrateAttr, 10)\n : undefined;\n mediaFile.bitrate =\n bitrateValue && bitrateValue > 0 ? bitrateValue : undefined;\n\n if (isHlsMediaFile(mediaFile) || isProgressiveMediaFile(mediaFile)) {\n mediaFiles.push(mediaFile);\n console.log(\n `[HlsAdPlayer] Added ${isHlsMediaFile(mediaFile) ? \"HLS\" : \"progressive\"} MediaFile: ${url}`\n );\n } else {\n console.log(\n `[HlsAdPlayer] MediaFile ${index} ignored (type=\"${type}\" is not supported)`\n );\n }\n });\n\n if (mediaFiles.length === 0) {\n if (isNoAdAvailable) {\n console.warn(\n \"[HlsAdPlayer] No ads available (VAST response indicates no ads)\"\n );\n } else {\n console.warn(\"[HlsAdPlayer] No supported media files found in VAST XML\");\n }\n return { type: \"empty\" };\n }\n\n return {\n type: \"inline\",\n ad: {\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls: extractTrackingUrls(xmlDoc),\n clickThrough,\n },\n };\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error parsing VAST XML:\", error);\n return { type: \"empty\" };\n }\n }\n\n async function fetchVastXml(vastTagUrl: string): Promise<string> {\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 return response.text();\n }\n\n async function fetchAndParseVastAd(\n vastTagUrl: string,\n depth = 0,\n accumulatedTracking: VastTrackingUrls = createEmptyTrackingUrls()\n ): Promise<VastAd | null> {\n const vastXml = await fetchVastXml(vastTagUrl);\n console.log(\"[HlsAdPlayer] VAST XML received\");\n console.log(\n \"[HlsAdPlayer] VAST XML content (first 2000 chars):\",\n vastXml.substring(0, 2000)\n );\n\n const parsed = parseVastXml(vastXml);\n\n if (parsed.type === \"empty\") {\n return null;\n }\n\n if (parsed.type === \"wrapper\") {\n if (depth >= MAX_VAST_WRAPPER_DEPTH) {\n console.warn(\n `[HlsAdPlayer] VAST wrapper depth limit (${MAX_VAST_WRAPPER_DEPTH}) reached, aborting redirect chain`\n );\n return null;\n }\n\n mergeTrackingUrls(accumulatedTracking, parsed.trackingUrls);\n return fetchAndParseVastAd(\n parsed.vastAdTagUri,\n depth + 1,\n accumulatedTracking\n );\n }\n\n mergeTrackingUrls(parsed.ad.trackingUrls, accumulatedTracking);\n return parsed.ad;\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.playsInline = true;\n video.muted = false;\n\n video.volume = 1.0;\n console.log(\n `[HlsAdPlayer] Created ad video element with volume ${video.volume}`\n );\n\n return video;\n }\n\n function setupAdEventListeners(): void {\n if (!adVideoElement || !currentAd) return;\n\n adVideoElement.addEventListener(\"timeupdate\", () => {\n if (!currentAd || !adVideoElement) return;\n\n const progress = adVideoElement.currentTime / currentAd.duration;\n\n if (progress >= 0.25 && !trackingFired.firstQuartile) {\n trackingFired.firstQuartile = true;\n fireTrackingPixels(currentAd.trackingUrls.firstQuartile);\n }\n\n if (progress >= 0.5 && !trackingFired.midpoint) {\n trackingFired.midpoint = true;\n fireTrackingPixels(currentAd.trackingUrls.midpoint);\n }\n\n if (progress >= 0.75 && !trackingFired.thirdQuartile) {\n trackingFired.thirdQuartile = true;\n fireTrackingPixels(currentAd.trackingUrls.thirdQuartile);\n }\n });\n\n adVideoElement.addEventListener(\"playing\", () => {\n if (!currentAd || trackingFired.start) return;\n trackingFired.start = true;\n fireTrackingPixels(currentAd.trackingUrls.start);\n console.log(\"[HlsAdPlayer] Ad started playing\");\n });\n\n adVideoElement.addEventListener(\"ended\", () => {\n if (!currentAd || trackingFired.complete) return;\n trackingFired.complete = true;\n fireTrackingPixels(currentAd.trackingUrls.complete);\n console.log(\"[HlsAdPlayer] Ad completed\");\n\n handleAdComplete();\n });\n\n adVideoElement.addEventListener(\"error\", (e) => {\n if (!adPlaying) return;\n console.error(\"[HlsAdPlayer] Ad video error:\", e);\n if (currentAd) {\n fireTrackingPixels(currentAd.trackingUrls.error);\n }\n handleAdError();\n });\n\n adVideoElement.addEventListener(\"volumechange\", () => {\n if (!currentAd) return;\n if (adVideoElement!.muted) {\n fireTrackingPixels(currentAd.trackingUrls.mute);\n } else {\n fireTrackingPixels(currentAd.trackingUrls.unmute);\n }\n });\n\n adVideoElement.addEventListener(\"pause\", () => {\n if (currentAd && !adVideoElement!.ended) {\n fireTrackingPixels(currentAd.trackingUrls.pause);\n }\n });\n\n adVideoElement.addEventListener(\"play\", () => {\n if (currentAd && adVideoElement!.currentTime > 0) {\n fireTrackingPixels(currentAd.trackingUrls.resume);\n }\n });\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 handleAdComplete(): void {\n console.log(\"[HlsAdPlayer] Handling ad completion\");\n adPlaying = false;\n setAdPlayingFlag(false);\n\n contentVideo.muted = true;\n\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n \n if (options?.continueLiveStreamDuringAds) {\n if (contentVideo.paused) {\n console.log(\"[HlsAdPlayer] Content video paused in live mode, resuming playback\");\n contentVideo.play().catch(() => {});\n } else {\n console.log(\"[HlsAdPlayer] Content video already playing in live mode\");\n }\n }\n\n emit(\"content_resume\");\n }\n\n function handleAdError(): void {\n console.log(\"[HlsAdPlayer] Handling ad error\");\n adPlaying = false;\n setAdPlayingFlag(false);\n\n contentVideo.muted = true;\n\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n\n emit(\"ad_error\");\n }\n\n return {\n initialize() {\n console.log(\"[HlsAdPlayer] 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 = \"30\";\n container.style.backgroundColor = \"#000\";\n\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n },\n\n async requestAds(vastTagUrl: string) {\n console.log(\"[HlsAdPlayer] Requesting ads:\", vastTagUrl);\n\n if (adPlaying) {\n console.warn(\n \"[HlsAdPlayer] Cannot request new ads while an ad is playing\"\n );\n return Promise.reject(new Error(\"Ad already playing\"));\n }\n\n try {\n sessionId = generateSessionId();\n let ad: VastAd | null | undefined;\n\n if (preloadedAds.has(vastTagUrl)) {\n ad = preloadedAds.get(vastTagUrl);\n preloadedAds.delete(vastTagUrl);\n console.log(\n \"[HlsAdPlayer] Using preloaded VAST response:\",\n vastTagUrl\n );\n } else {\n ad = await fetchAndParseVastAd(vastTagUrl);\n }\n\n if (!ad) {\n console.warn(\"[HlsAdPlayer] No ads available from VAST response\");\n emit(\"ad_error\");\n return Promise.reject(new Error(\"No ads available from VAST response\"));\n }\n\n currentAd = ad;\n console.log(\n `[HlsAdPlayer] Ad parsed: ${ad.title}, duration: ${ad.duration}s`\n );\n\n fireTrackingPixels(ad.trackingUrls.impression);\n trackingFired.impression = true;\n\n return Promise.resolve();\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error requesting ads:\", error);\n emit(\"ad_error\");\n return Promise.reject(error);\n }\n },\n async play() {\n if (!currentAd) {\n console.warn(\n \"[HlsAdPlayer] Cannot play: No ad loaded (no ads available)\"\n );\n return Promise.reject(new Error(\"No ad loaded\"));\n }\n\n console.log(\"[HlsAdPlayer] 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 const contentVolume = contentVideo.volume;\n originalVolume = Math.max(\n 0,\n Math.min(1, contentVolume || originalVolume)\n );\n\n if (!options?.continueLiveStreamDuringAds) {\n contentVideo.pause();\n console.log(\"[HlsAdPlayer] Content paused (VOD mode)\");\n } else {\n console.log(\"[HlsAdPlayer] Content continues (Live mode)\");\n }\n\n console.log(\"[HlsAdPlayer] FORCE MUTING main video\");\n contentVideo.muted = true;\n adPlaying = true;\n setAdPlayingFlag(true);\n\n if (adVideoElement) {\n adVideoElement.volume = Math.max(0, Math.min(1, originalVolume));\n adVideoElement.muted = originalMutedState;\n console.log(\n `[HlsAdPlayer] Set ad video volume to ${adVideoElement.volume}, muted: ${adVideoElement.muted}, originalMutedState: ${originalMutedState}, contentVolume: ${contentVolume}`\n );\n }\n\n const mediaFile = selectBestMediaFile(currentAd.mediaFiles);\n if (!mediaFile) {\n throw new Error(\"No media file available for ad\");\n }\n\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n\n emit(\"content_pause\");\n\n const isHlsAd = isHlsMediaFile(mediaFile);\n console.log(\n `[HlsAdPlayer] Loading ${isHlsAd ? \"HLS\" : \"progressive\"} ad from: ${mediaFile.url}`\n );\n\n if (isHlsAd && Hls.isSupported()) {\n if (adHls) {\n adHls.destroy();\n }\n\n adHls = new Hls({\n enableWorker: true,\n lowLatencyMode: false,\n });\n\n adHls.loadSource(mediaFile.url);\n adHls.attachMedia(adVideoElement);\n\n adHls.on(Hls.Events.MANIFEST_PARSED, () => {\n console.log(\"[HlsAdPlayer] HLS manifest parsed, starting playback\");\n adVideoElement!.play().catch((error) => {\n console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n handleAdError();\n });\n });\n\n adHls.on(Hls.Events.ERROR, (event, data) => {\n console.error(\"[HlsAdPlayer] HLS error:\", data);\n if (data.fatal) {\n handleAdError();\n }\n });\n } else if (isHlsAd && (\n adVideoElement.canPlayType(\"application/vnd.apple.mpegurl\")\n )) {\n adVideoElement.src = mediaFile.url;\n adVideoElement.play().catch((error) => {\n console.error(\"[HlsAdPlayer] Error starting ad playback:\", error);\n handleAdError();\n });\n } else if (!isHlsAd && isProgressiveMediaFile(mediaFile)) {\n if (adHls) {\n adHls.destroy();\n adHls = undefined;\n }\n\n adVideoElement.src = mediaFile.url;\n adVideoElement.load();\n adVideoElement.play().catch((error) => {\n console.error(\"[HlsAdPlayer] Error starting progressive ad playback:\", error);\n handleAdError();\n });\n } else {\n throw new Error(`Unsupported ad media file type: ${mediaFile.type}`);\n }\n\n return Promise.resolve();\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error playing ad:\", error);\n handleAdError();\n return Promise.reject(error);\n }\n },\n pause() {\n if (!adPlaying || !adVideoElement) {\n return;\n }\n\n try {\n if (adVideoElement && !adVideoElement.paused) {\n adVideoElement.pause();\n }\n } catch (error) {\n console.warn(\"[HlsAdPlayer] Error pausing ad:\", error);\n }\n },\n resume() {\n if (!adPlaying || !adVideoElement) {\n return;\n }\n\n try {\n if (adVideoElement && adVideoElement.paused) {\n adVideoElement.play().catch(() => {});\n }\n } catch (error) {\n console.warn(\"[HlsAdPlayer] Error resuming ad:\", error);\n }\n },\n async stop() {\n console.log(\"[HlsAdPlayer] Stopping ad\");\n adPlaying = false;\n setAdPlayingFlag(false);\n\n const previousMutedState = contentVideo.muted;\n contentVideo.muted = originalMutedState;\n contentVideo.volume = Math.max(0, Math.min(1, originalVolume));\n console.log(\n `[HlsAdPlayer] Restored mute state on stop: ${previousMutedState} -> ${originalMutedState}, volume: ${contentVideo.volume}`\n );\n\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n\n if (options?.continueLiveStreamDuringAds) {\n if (contentVideo.paused) {\n console.log(\"[HlsAdPlayer] Content video paused in live mode, resuming playback on stop\");\n contentVideo.play().catch(() => {});\n }\n }\n\n if (adHls) {\n adHls.destroy();\n adHls = undefined;\n }\n\n if (adVideoElement) {\n adVideoElement.pause();\n adVideoElement.src = \"\";\n }\n\n currentAd = undefined;\n },\n\n destroy() {\n console.log(\"[HlsAdPlayer] Destroying\");\n destroyed = true;\n \n for (const timeoutId of pendingTimeouts) {\n clearTimeout(timeoutId);\n }\n pendingTimeouts = [];\n \n adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\n contentVideo.volume = Math.max(0, Math.min(1, originalVolume));\n\n if (adHls) {\n adHls.destroy();\n adHls = undefined;\n }\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 preloadedAds.clear();\n preloadingAds.clear();\n },\n\n isAdPlaying() {\n return adPlaying;\n },\n\n resize(width: number, height: number) {\n console.log(`[HlsAdPlayer] 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 console.log(\n `[HlsAdPlayer] updateOriginalMutedState called: { muted: ${originalMutedState} -> ${muted}, volume: ${originalVolume} -> ${nextVolume} }`\n );\n originalMutedState = muted;\n originalVolume = nextVolume;\n },\n\n getOriginalMutedState() {\n return originalMutedState;\n },\n getOriginalVolume() {\n return originalVolume;\n },\n\n setAdVolume(volume: number) {\n if (adVideoElement && adPlaying) {\n const clamped = Math.max(0, Math.min(1, volume));\n adVideoElement.volume = clamped;\n adVideoElement.muted = clamped === 0;\n }\n },\n\n getAdVolume(): number {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n showPlaceholder() {\n contentVideo.style.opacity = \"0\";\n contentVideo.style.visibility = \"hidden\";\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\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\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 \n if (!adPlaying) {\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n }\n },\n getLoadedAdDuration() {\n return currentAd?.duration;\n },\n getLoadedAdId() {\n return currentAd?.id;\n },\n };\n}\n"]}
|
|
@@ -813,6 +813,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
813
813
|
handleAdComplete();
|
|
814
814
|
});
|
|
815
815
|
adVideoElement.addEventListener("error", function(e) {
|
|
816
|
+
if (!adPlaying) return;
|
|
816
817
|
console.error("[HlsAdPlayer] Ad video error:", e);
|
|
817
818
|
if (currentAd) {
|
|
818
819
|
fireTrackingPixels(currentAd.trackingUrls.error);
|
|
@@ -1014,15 +1015,15 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1014
1015
|
adVideoElement.muted = originalMutedState;
|
|
1015
1016
|
console.log("[HlsAdPlayer] Set ad video volume to ".concat(adVideoElement.volume, ", muted: ").concat(adVideoElement.muted, ", originalMutedState: ").concat(originalMutedState, ", contentVolume: ").concat(contentVolume));
|
|
1016
1017
|
}
|
|
1018
|
+
mediaFile = selectBestMediaFile(currentAd.mediaFiles);
|
|
1019
|
+
if (!mediaFile) {
|
|
1020
|
+
throw new Error("No media file available for ad");
|
|
1021
|
+
}
|
|
1017
1022
|
if (adContainerEl) {
|
|
1018
1023
|
adContainerEl.style.display = "flex";
|
|
1019
1024
|
adContainerEl.style.pointerEvents = "auto";
|
|
1020
1025
|
}
|
|
1021
1026
|
emit("content_pause");
|
|
1022
|
-
mediaFile = selectBestMediaFile(currentAd.mediaFiles);
|
|
1023
|
-
if (!mediaFile) {
|
|
1024
|
-
throw new Error("No media file available for ad");
|
|
1025
|
-
}
|
|
1026
1027
|
isHlsAd = isHlsMediaFile(mediaFile);
|
|
1027
1028
|
console.log("[HlsAdPlayer] Loading ".concat(isHlsAd ? "HLS" : "progressive", " ad from: ").concat(mediaFile.url));
|
|
1028
1029
|
if (isHlsAd && import_hls.default.isSupported()) {
|
|
@@ -2310,9 +2311,20 @@ function initializePolyfills() {
|
|
|
2310
2311
|
}
|
|
2311
2312
|
// src/utils/vastEnvironmentSignals.ts
|
|
2312
2313
|
var AIRY_ANDROID_APP_ID = "com.freeairytv.android";
|
|
2314
|
+
var AIRY_WEBOS_APP_ID = "com.freeairytv.webos";
|
|
2315
|
+
var AIRY_TIZEN_APP_ID = "com.freeairytv.samsung";
|
|
2316
|
+
var AIRY_ROKU_APP_ID = "com.freeairytv.roku";
|
|
2313
2317
|
var AIRY_APP_NAME = "AiryTV Movies & TV";
|
|
2314
2318
|
var AIRY_DEFAULT_CONTENT_URL = "https://live.airy.tv";
|
|
2315
2319
|
var CTV_SESSION_STORAGE_KEY = "stormcloud.ctv.sid";
|
|
2320
|
+
function getDefaultAppId() {
|
|
2321
|
+
if (typeof navigator === "undefined") return AIRY_ANDROID_APP_ID;
|
|
2322
|
+
var ua = navigator.userAgent;
|
|
2323
|
+
if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return AIRY_WEBOS_APP_ID;
|
|
2324
|
+
if (/Tizen|Samsung/i.test(ua)) return AIRY_TIZEN_APP_ID;
|
|
2325
|
+
if (/Roku/i.test(ua)) return AIRY_ROKU_APP_ID;
|
|
2326
|
+
return AIRY_ANDROID_APP_ID;
|
|
2327
|
+
}
|
|
2316
2328
|
var DEVICE_ID_STORAGE_KEYS = [
|
|
2317
2329
|
"rdid",
|
|
2318
2330
|
"ifa",
|
|
@@ -2339,7 +2351,7 @@ function resolveVastEnvironmentSignals(isCtv) {
|
|
|
2339
2351
|
return _object_spread_props(_object_spread({
|
|
2340
2352
|
isCtv: true,
|
|
2341
2353
|
contentUrl: bridgeSignals.contentUrl || readStoredString("contentUrl") || AIRY_DEFAULT_CONTENT_URL,
|
|
2342
|
-
appId: bridgeSignals.appId || readStoredString("appId") || readStoredString("msid") ||
|
|
2354
|
+
appId: bridgeSignals.appId || readStoredString("appId") || readStoredString("msid") || getDefaultAppId(),
|
|
2343
2355
|
appName: bridgeSignals.appName || readStoredString("appName") || readStoredString("an") || AIRY_APP_NAME,
|
|
2344
2356
|
sessionId: getOrCreateCtvSessionId()
|
|
2345
2357
|
}, deviceId ? {
|
|
@@ -2636,7 +2648,6 @@ var CTV_UNSUPPORTED_PARAMS = [
|
|
|
2636
2648
|
"max_ad_duration",
|
|
2637
2649
|
"unviewed_position_start",
|
|
2638
2650
|
"impl",
|
|
2639
|
-
"scor",
|
|
2640
2651
|
"vad_type",
|
|
2641
2652
|
"gdpr",
|
|
2642
2653
|
"gdpr_consent",
|
|
@@ -2885,6 +2896,29 @@ function normalizeVastTagUrl(raw) {
|
|
|
2885
2896
|
if (!raw) return raw;
|
|
2886
2897
|
try {
|
|
2887
2898
|
var url = new URL(raw);
|
|
2899
|
+
var anValue = url.searchParams.get("an");
|
|
2900
|
+
if (anValue !== null) {
|
|
2901
|
+
var orphanFragments = [];
|
|
2902
|
+
url.searchParams.forEach(function(_value, key) {
|
|
2903
|
+
if (key && INVALID_VAST_PARAM_KEY.test(key)) {
|
|
2904
|
+
orphanFragments.push(key.trim());
|
|
2905
|
+
}
|
|
2906
|
+
});
|
|
2907
|
+
if (orphanFragments.length > 0) {
|
|
2908
|
+
var reconstructed = [
|
|
2909
|
+
anValue.trimEnd()
|
|
2910
|
+
].concat(_to_consumable_array(orphanFragments)).filter(Boolean).join(" & ");
|
|
2911
|
+
url.searchParams.forEach(function(_value, key) {
|
|
2912
|
+
if (key && INVALID_VAST_PARAM_KEY.test(key)) {
|
|
2913
|
+
url.searchParams.delete(key);
|
|
2914
|
+
}
|
|
2915
|
+
});
|
|
2916
|
+
url.searchParams.set("an", reconstructed);
|
|
2917
|
+
return url.toString().replace(/([?&]an=)([^&]*)/, function(_match, prefix, val) {
|
|
2918
|
+
return prefix + val.replace(/\+/g, "%20");
|
|
2919
|
+
});
|
|
2920
|
+
}
|
|
2921
|
+
}
|
|
2888
2922
|
removeBrokenAppNameOrphans(url.searchParams);
|
|
2889
2923
|
return url.toString();
|
|
2890
2924
|
} catch (unused) {
|
|
@@ -2902,6 +2936,7 @@ function applyVastMacros(baseUrl, ctx) {
|
|
|
2902
2936
|
var params = url.searchParams;
|
|
2903
2937
|
removeBrokenAppNameOrphans(params, ctx.appName);
|
|
2904
2938
|
params.set("correlator", ctx.correlator);
|
|
2939
|
+
params.set("scor", ctx.streamCorrelator);
|
|
2905
2940
|
if (ctx.isCtv) {
|
|
2906
2941
|
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
2907
2942
|
try {
|
|
@@ -2923,8 +2958,6 @@ function applyVastMacros(baseUrl, ctx) {
|
|
|
2923
2958
|
}
|
|
2924
2959
|
}
|
|
2925
2960
|
}
|
|
2926
|
-
} else {
|
|
2927
|
-
params.set("scor", ctx.streamCorrelator);
|
|
2928
2961
|
}
|
|
2929
2962
|
if (ctx.pod != null) {
|
|
2930
2963
|
params.set("pod", String(ctx.pod));
|
|
@@ -4292,7 +4325,7 @@ var AdConfigManager = /*#__PURE__*/ function() {
|
|
|
4292
4325
|
key: "fetchAdConfiguration",
|
|
4293
4326
|
value: function fetchAdConfiguration() {
|
|
4294
4327
|
return _async_to_generator(function() {
|
|
4295
|
-
var _data_response_ima_publisherdeskima, _data_response_ima, _data_response, _data_response_options_vast_cue_tones, _data_response_options_vast, _data_response_options, _data_response1, vastMode, vastEndpoint, apiUrl, headers, response, data, imaPayload, numberAds;
|
|
4328
|
+
var _data_response_ima_publisherdeskima, _data_response_ima, _data_response, _data_response_options_vast_cue_tones, _data_response_options_vast, _data_response_options, _data_response1, vastMode, vastEndpoint, apiUrl, headers, response, data, imaPayload, decodedPayload, numberAds;
|
|
4296
4329
|
return _ts_generator(this, function(_state) {
|
|
4297
4330
|
switch(_state.label){
|
|
4298
4331
|
case 0:
|
|
@@ -4376,9 +4409,16 @@ var AdConfigManager = /*#__PURE__*/ function() {
|
|
|
4376
4409
|
data = _state.sent();
|
|
4377
4410
|
imaPayload = (_data_response = data.response) === null || _data_response === void 0 ? void 0 : (_data_response_ima = _data_response.ima) === null || _data_response_ima === void 0 ? void 0 : (_data_response_ima_publisherdeskima = _data_response_ima["publisherdesk.ima"]) === null || _data_response_ima_publisherdeskima === void 0 ? void 0 : _data_response_ima_publisherdeskima.payload;
|
|
4378
4411
|
if (imaPayload) {
|
|
4379
|
-
|
|
4412
|
+
decodedPayload = imaPayload;
|
|
4413
|
+
try {
|
|
4414
|
+
decodedPayload = decodeURIComponent(imaPayload);
|
|
4415
|
+
} catch (unused) {
|
|
4416
|
+
console.warn("[StormcloudVideoPlayer] imaPayload was not URI-encoded; using as-is:", imaPayload);
|
|
4417
|
+
}
|
|
4418
|
+
console.log("[StormcloudVideoPlayer] Raw VAST tag URL (from API):", decodedPayload);
|
|
4419
|
+
this.apiVastTagUrl = normalizeVastTagUrl(decodedPayload);
|
|
4380
4420
|
if (this.debug) {
|
|
4381
|
-
console.log("[StormcloudVideoPlayer]
|
|
4421
|
+
console.log("[StormcloudVideoPlayer] Normalized VAST tag URL:", this.apiVastTagUrl);
|
|
4382
4422
|
}
|
|
4383
4423
|
} else {
|
|
4384
4424
|
if (this.debug) {
|
|
@@ -4712,7 +4752,9 @@ var AdConfigManager = /*#__PURE__*/ function() {
|
|
|
4712
4752
|
adTest: this.config.adTest,
|
|
4713
4753
|
consent: this.consentSignals
|
|
4714
4754
|
});
|
|
4715
|
-
|
|
4755
|
+
var finalUrl = palNonce.injectNonce(urlWithMacros);
|
|
4756
|
+
console.log("[StormcloudVideoPlayer] Resolved ad request URL (pod=".concat(this.podCounter, ", pos=").concat(this.adRequestPositionInBreak, "):"), finalUrl);
|
|
4757
|
+
urls.push(finalUrl);
|
|
4716
4758
|
}
|
|
4717
4759
|
return urls;
|
|
4718
4760
|
}
|