stormcloud-video-player 0.3.67 → 0.3.68

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.
@@ -367,7 +367,7 @@ function createHlsAdPlayer(contentVideo, options) {
367
367
  }
368
368
  var adElement = xmlDoc.querySelector("Ad");
369
369
  if (!adElement) {
370
- console.warn("[HlsAdPlayer] No Ad element found in VAST XML");
370
+ console.warn("[HlsAdPlayer] No Ad element found in VAST XML (no fill). Content (first 2000 chars):", xmlString.substring(0, 2e3));
371
371
  return null;
372
372
  }
373
373
  var adId = adElement.getAttribute("id") || "unknown";
@@ -463,7 +463,7 @@ function createHlsAdPlayer(contentVideo, options) {
463
463
  }
464
464
  function fetchAndParseVastAd(vastTagUrl) {
465
465
  return _async_to_generator(function() {
466
- var response, vastXml;
466
+ var response, vastXml, trimmedXml;
467
467
  return _ts_generator(this, function(_state) {
468
468
  switch(_state.label){
469
469
  case 0:
@@ -489,8 +489,16 @@ function createHlsAdPlayer(contentVideo, options) {
489
489
  ];
490
490
  case 2:
491
491
  vastXml = _state.sent();
492
- console.log("[HlsAdPlayer] VAST XML received");
492
+ console.log("[HlsAdPlayer] VAST XML received (length=".concat(vastXml.length, ")"));
493
493
  console.log("[HlsAdPlayer] VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
494
+ trimmedXml = vastXml.trim();
495
+ if (trimmedXml.length === 0) {
496
+ console.warn("[HlsAdPlayer] VAST response body is empty (no fill)");
497
+ return [
498
+ 2,
499
+ null
500
+ ];
501
+ }
494
502
  return [
495
503
  2,
496
504
  parseVastXml(vastXml)
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/sdk/hlsAdPlayer.cjs","../../src/sdk/hlsAdPlayer.ts"],"names":["__create","Object","__defProp","create","defineProperty","__getOwnPropNames","getOwnPropertyNames","__getProtoOf","getPrototypeOf","__hasOwnProp","prototype","hasOwnProperty","__export","target","all","name","get","enumerable","__copyProps","to","from","except","desc","key","call","__getOwnPropDesc","hlsAdPlayer_exports","createHlsAdPlayer","mainHlsInstance","__toESM","mod","isNodeMode","__esModule","value","__toCommonJS","module","exports","import_hls","require","contentVideo","options","originalMutedState","originalVolume","Math","max","min","volume","listeners","Map","licenseKey","adVideoElement","adHls","currentAd","sessionId","preloadedAds","preloadingAds","destroyed","pendingTimeouts","trackingFired","impression","start","firstQuartile","midpoint","thirdQuartile","complete","emit","event","payload","set","Array","fn","error","console","warn","generateSessionId","Date","now","random","toString","substr","fireTrackingPixels","urls","length","forEach","url","trackingUrl","includes","src","img","Image","log","getMainStreamQuality","levels","currentLevel","autoLevel","loadLevel","level","width","height","bitrate","selectBestMediaFile","mediaFiles","Error","firstFile","mainQuality","scoredFiles","map","file","widthDiff","abs","heightDiff","resolutionDiff","fileBitrate","bitrateDiff","score","sort","a","b","bestMatch","resolution","isHlsMediaFile","mediaFile","type","toLowerCase","isProgressiveMediaFile","startsWith","endsWith","parseVastXml","xmlString","xmlDoc","parser","DOMParser","parseFromString","parserError","querySelector","textContent","adElement","adId","getAttribute","title","isNoAdAvailable","durationText","durationParts","split","duration","parseInt","mediaFileElements","querySelectorAll","mf","index","trim","bitrateAttr","bitrateValue","push","trackingUrls","mute","unmute","pause","el","resume","fullscreen","exitFullscreen","skip","eventKey","clickThrough","response","vastXml","fetch","vastTagUrl","credentials","headers","referrerPolicy","ok","style","left","progress","statusText","text","substring","createAdVideoElement","video","document","createElement","position","top","backgroundColor","playsInline","muted","setupAdEventListeners","addEventListener","currentTime","handleAdComplete","e","handleAdError","ended","setAdPlayingFlag","isPlaying","dataset","stormcloudAdPlaying","adPlaying","adContainerEl","display","pointerEvents","continueLiveStreamDuringAds","paused","play","catch","initialize","container","right","bottom","alignItems","zIndex","parentElement","appendChild","requestAds","ad","Promise","reject","has","delete","fetchAndParseVastAd","resolve","contentVolume","adVolume","isHlsAd","Hls","isSupported"],"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);\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 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 null;\n }\n const adElement = xmlDoc.querySelector(\"Ad\");\n if (!adElement) {\n console.warn(\"[HlsAdPlayer] No Ad element found in VAST XML\");\n return null;\n }\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n const isNoAdAvailable = adId === \"empty\" || title.toLowerCase().includes(\"no ad available\") || title.toLowerCase() === \"no ad available\";\n const durationText = xmlDoc.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n const durationParts = durationText.split(\":\");\n const duration = parseInt(durationParts[0] || \"0\", 10) * 3600 + parseInt(durationParts[1] || \"0\", 10) * 60 + 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 null;\n }\n const trackingUrls = {\n impression: [],\n start: [],\n firstQuartile: [],\n midpoint: [],\n thirdQuartile: [],\n complete: [],\n mute: [],\n unmute: [],\n pause: [],\n resume: [],\n fullscreen: [],\n exitFullscreen: [],\n skip: [],\n error: []\n };\n xmlDoc.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n xmlDoc.querySelectorAll(\"Tracking\").forEach((el) => {\n const event = el.getAttribute(\"event\");\n const url = el.textContent?.trim();\n if (event && url) {\n const eventKey = event;\n if (trackingUrls[eventKey]) {\n trackingUrls[eventKey].push(url);\n }\n }\n });\n const clickThrough = xmlDoc.querySelector(\"ClickThrough\")?.textContent?.trim();\n return {\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough\n };\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error parsing VAST XML:\", error);\n return null;\n }\n }\n async function fetchAndParseVastAd(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 const vastXml = await response.text();\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 return parseVastXml(vastXml);\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 contentVideo.volume = 0;\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 contentVideo.volume = 0;\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 contentVideo.volume = 0;\n adPlaying = true;\n setAdPlayingFlag(true);\n if (adVideoElement) {\n const adVolume = originalMutedState ? 0 : originalVolume;\n adVideoElement.volume = Math.max(0, Math.min(1, adVolume));\n adVideoElement.muted = false;\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 = originalMutedState ? 0 : originalVolume;\n console.log(\n `[HlsAdPlayer] Restored mute state on stop: ${previousMutedState} -> ${originalMutedState}`\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 = originalMutedState ? 0 : 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 adVideoElement.volume = Math.max(0, Math.min(1, volume));\n }\n },\n getAdVolume() {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n showPlaceholder() {\n contentVideo.style.opacity = \"0\";\n contentVideo.style.visibility = \"hidden\";\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n },\n hidePlaceholder() {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n if (!adPlaying) {\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n }\n }\n };\n}\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n createHlsAdPlayer\n});\n","import type { ImaController } 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\nexport function createHlsAdPlayer(\n contentVideo: HTMLVideoElement,\n options?: {\n continueLiveStreamDuringAds?: boolean;\n licenseKey?: string;\n mainHlsInstance?: Hls;\n }\n): ImaController {\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 parseVastXml(xmlString: string): VastAd | null {\n try {\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n\n const parserError = xmlDoc.querySelector(\"parsererror\");\n if (parserError) {\n console.error(\n \"[HlsAdPlayer] XML parsing error (malformed VAST XML):\",\n parserError.textContent\n );\n return null;\n }\n\n const adElement = xmlDoc.querySelector(\"Ad\");\n if (!adElement) {\n console.warn(\"[HlsAdPlayer] No Ad element found in VAST XML\");\n return null;\n }\n\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n\n const isNoAdAvailable =\n adId === \"empty\" ||\n title.toLowerCase().includes(\"no ad available\") ||\n title.toLowerCase() === \"no ad available\";\n\n const durationText =\n xmlDoc.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n const durationParts = durationText.split(\":\");\n const duration =\n parseInt(durationParts[0] || \"0\", 10) * 3600 +\n parseInt(durationParts[1] || \"0\", 10) * 60 +\n 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 null;\n }\n\n const trackingUrls: VastTrackingUrls = {\n impression: [],\n start: [],\n firstQuartile: [],\n midpoint: [],\n thirdQuartile: [],\n complete: [],\n mute: [],\n unmute: [],\n pause: [],\n resume: [],\n fullscreen: [],\n exitFullscreen: [],\n skip: [],\n error: [],\n };\n\n xmlDoc.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n\n xmlDoc.querySelectorAll(\"Tracking\").forEach((el) => {\n const event = el.getAttribute(\"event\");\n const url = el.textContent?.trim();\n if (event && url) {\n const eventKey = event as keyof VastTrackingUrls;\n if (trackingUrls[eventKey]) {\n trackingUrls[eventKey].push(url);\n }\n }\n });\n\n const clickThrough = xmlDoc\n .querySelector(\"ClickThrough\")\n ?.textContent?.trim();\n\n return {\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough,\n };\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error parsing VAST XML:\", error);\n return null;\n }\n }\n\n async function fetchAndParseVastAd(\n vastTagUrl: string\n ): Promise<VastAd | null> {\n const response = await fetch(vastTagUrl, {\n mode: \"cors\",\n credentials: \"include\",\n headers: {\n \"Accept\": \"application/xml, text/xml, */*\",\n },\n referrerPolicy: \"no-referrer-when-downgrade\",\n });\n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.statusText}`);\n }\n\n const vastXml = await response.text();\n console.log(\"[HlsAdPlayer] VAST XML received\");\n console.log(\n \"[HlsAdPlayer] VAST XML content (first 2000 chars):\",\n vastXml.substring(0, 2000)\n );\n\n return parseVastXml(vastXml);\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 contentVideo.volume = 0;\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 contentVideo.volume = 0;\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 contentVideo.volume = 0;\n adPlaying = true;\n setAdPlayingFlag(true);\n\n if (adVideoElement) {\n const adVolume = originalMutedState ? 0 : originalVolume;\n adVideoElement.volume = Math.max(0, Math.min(1, adVolume));\n adVideoElement.muted = false;\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 = originalMutedState ? 0 : originalVolume;\n console.log(\n `[HlsAdPlayer] Restored mute state on stop: ${previousMutedState} -> ${originalMutedState}`\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 = originalMutedState ? 0 : 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 adVideoElement.volume = Math.max(0, Math.min(1, volume));\n }\n },\n\n getAdVolume(): number {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n 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 };\n}\n"]}
1
+ {"version":3,"sources":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/sdk/hlsAdPlayer.cjs","../../src/sdk/hlsAdPlayer.ts"],"names":["__create","Object","__defProp","create","defineProperty","__getOwnPropNames","getOwnPropertyNames","__getProtoOf","getPrototypeOf","__hasOwnProp","prototype","hasOwnProperty","__export","target","all","name","get","enumerable","__copyProps","to","from","except","desc","key","call","__getOwnPropDesc","createHlsAdPlayer","mainHlsInstance","__toESM","mod","isNodeMode","__esModule","value","__toCommonJS","hlsAdPlayer_exports","module","exports","import_hls","require","contentVideo","options","adPlaying","originalMutedState","originalVolume","Math","max","volume","min","licenseKey","adVideoElement","adHls","adContainerEl","currentAd","sessionId","preloadingAds","Map","destroyed","pendingTimeouts","trackingFired","impression","start","firstQuartile","midpoint","thirdQuartile","complete","emit","event","payload","set","listeners","fn","Array","error","console","warn","generateSessionId","Date","now","random","toString","substr","fireTrackingPixels","urls","length","forEach","url","trackingUrl","includes","img","Image","src","log","getMainStreamQuality","levels","currentLevel","autoLevel","loadLevel","level","width","height","bitrate","firstFile","selectBestMediaFile","mediaFiles","Error","mainQuality","scoredFiles","map","file","widthDiff","abs","heightDiff","resolutionDiff","fileBitrate","bitrateDiff","score","sort","a","b","bestMatch","resolution","isHlsMediaFile","mediaFile","type","toLowerCase","isProgressiveMediaFile","startsWith","endsWith","parseVastXml","xmlString","xmlDoc","parser","DOMParser","parseFromString","parserError","querySelector","textContent","adElement","substring","adId","getAttribute","title","isNoAdAvailable","durationText","durationParts","split","duration","parseInt","mediaFileElements","querySelectorAll","mf","index","trim","bitrateAttr","bitrateValue","push","trackingUrls","mute","unmute","pause","resume","fullscreen","exitFullscreen","skip","el","clickThrough","eventKey","id","fetchAndParseVastAd","vastTagUrl","response","vastXml","trimmedXml","mode","headers","referrerPolicy","statusText","text","style","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","parentElement","appendChild","requestAds","ad","Promise","reject","preloadedAds","has","delete","resolve","contentVolume","adVolume","isHlsAd","Hls","isSupported","destroy"],"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);\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 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 null;\n }\n const adElement = xmlDoc.querySelector(\"Ad\");\n if (!adElement) {\n console.warn(\n \"[HlsAdPlayer] No Ad element found in VAST XML (no fill). Content (first 2000 chars):\",\n xmlString.substring(0, 2e3)\n );\n return null;\n }\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n const isNoAdAvailable = adId === \"empty\" || title.toLowerCase().includes(\"no ad available\") || title.toLowerCase() === \"no ad available\";\n const durationText = xmlDoc.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n const durationParts = durationText.split(\":\");\n const duration = parseInt(durationParts[0] || \"0\", 10) * 3600 + parseInt(durationParts[1] || \"0\", 10) * 60 + 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 null;\n }\n const trackingUrls = {\n impression: [],\n start: [],\n firstQuartile: [],\n midpoint: [],\n thirdQuartile: [],\n complete: [],\n mute: [],\n unmute: [],\n pause: [],\n resume: [],\n fullscreen: [],\n exitFullscreen: [],\n skip: [],\n error: []\n };\n xmlDoc.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n xmlDoc.querySelectorAll(\"Tracking\").forEach((el) => {\n const event = el.getAttribute(\"event\");\n const url = el.textContent?.trim();\n if (event && url) {\n const eventKey = event;\n if (trackingUrls[eventKey]) {\n trackingUrls[eventKey].push(url);\n }\n }\n });\n const clickThrough = xmlDoc.querySelector(\"ClickThrough\")?.textContent?.trim();\n return {\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough\n };\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error parsing VAST XML:\", error);\n return null;\n }\n }\n async function fetchAndParseVastAd(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 const vastXml = await response.text();\n console.log(\n `[HlsAdPlayer] VAST XML received (length=${vastXml.length})`\n );\n console.log(\n \"[HlsAdPlayer] VAST XML content (first 2000 chars):\",\n vastXml.substring(0, 2e3)\n );\n const trimmedXml = vastXml.trim();\n if (trimmedXml.length === 0) {\n console.warn(\"[HlsAdPlayer] VAST response body is empty (no fill)\");\n return null;\n }\n return parseVastXml(vastXml);\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 contentVideo.volume = 0;\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 contentVideo.volume = 0;\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 contentVideo.volume = 0;\n adPlaying = true;\n setAdPlayingFlag(true);\n if (adVideoElement) {\n const adVolume = originalMutedState ? 0 : originalVolume;\n adVideoElement.volume = Math.max(0, Math.min(1, adVolume));\n adVideoElement.muted = false;\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 = originalMutedState ? 0 : originalVolume;\n console.log(\n `[HlsAdPlayer] Restored mute state on stop: ${previousMutedState} -> ${originalMutedState}`\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 = originalMutedState ? 0 : 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 adVideoElement.volume = Math.max(0, Math.min(1, volume));\n }\n },\n getAdVolume() {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n showPlaceholder() {\n contentVideo.style.opacity = \"0\";\n contentVideo.style.visibility = \"hidden\";\n if (!adContainerEl) {\n const container = document.createElement(\"div\");\n container.style.position = \"absolute\";\n container.style.left = \"0\";\n container.style.top = \"0\";\n container.style.right = \"0\";\n container.style.bottom = \"0\";\n container.style.display = \"none\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"10\";\n container.style.backgroundColor = \"#000\";\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n },\n hidePlaceholder() {\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n if (!adPlaying) {\n contentVideo.style.visibility = \"visible\";\n contentVideo.style.opacity = \"1\";\n }\n }\n };\n}\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n createHlsAdPlayer\n});\n","import type { ImaController } 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\nexport function createHlsAdPlayer(\n contentVideo: HTMLVideoElement,\n options?: {\n continueLiveStreamDuringAds?: boolean;\n licenseKey?: string;\n mainHlsInstance?: Hls;\n }\n): ImaController {\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 parseVastXml(xmlString: string): VastAd | null {\n try {\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n\n const parserError = xmlDoc.querySelector(\"parsererror\");\n if (parserError) {\n console.error(\n \"[HlsAdPlayer] XML parsing error (malformed VAST XML):\",\n parserError.textContent\n );\n return null;\n }\n\n const adElement = xmlDoc.querySelector(\"Ad\");\n if (!adElement) {\n console.warn(\n \"[HlsAdPlayer] No Ad element found in VAST XML (no fill). Content (first 2000 chars):\",\n xmlString.substring(0, 2000)\n );\n return null;\n }\n\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n\n const isNoAdAvailable =\n adId === \"empty\" ||\n title.toLowerCase().includes(\"no ad available\") ||\n title.toLowerCase() === \"no ad available\";\n\n const durationText =\n xmlDoc.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n const durationParts = durationText.split(\":\");\n const duration =\n parseInt(durationParts[0] || \"0\", 10) * 3600 +\n parseInt(durationParts[1] || \"0\", 10) * 60 +\n 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 null;\n }\n\n const trackingUrls: VastTrackingUrls = {\n impression: [],\n start: [],\n firstQuartile: [],\n midpoint: [],\n thirdQuartile: [],\n complete: [],\n mute: [],\n unmute: [],\n pause: [],\n resume: [],\n fullscreen: [],\n exitFullscreen: [],\n skip: [],\n error: [],\n };\n\n xmlDoc.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n\n xmlDoc.querySelectorAll(\"Tracking\").forEach((el) => {\n const event = el.getAttribute(\"event\");\n const url = el.textContent?.trim();\n if (event && url) {\n const eventKey = event as keyof VastTrackingUrls;\n if (trackingUrls[eventKey]) {\n trackingUrls[eventKey].push(url);\n }\n }\n });\n\n const clickThrough = xmlDoc\n .querySelector(\"ClickThrough\")\n ?.textContent?.trim();\n\n return {\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough,\n };\n } catch (error) {\n console.error(\"[HlsAdPlayer] Error parsing VAST XML:\", error);\n return null;\n }\n }\n\n async function fetchAndParseVastAd(\n vastTagUrl: string\n ): Promise<VastAd | null> {\n const response = await fetch(vastTagUrl, {\n mode: \"cors\",\n credentials: \"include\",\n headers: {\n \"Accept\": \"application/xml, text/xml, */*\",\n },\n referrerPolicy: \"no-referrer-when-downgrade\",\n });\n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.statusText}`);\n }\n\n const vastXml = await response.text();\n console.log(\n `[HlsAdPlayer] VAST XML received (length=${vastXml.length})`\n );\n console.log(\n \"[HlsAdPlayer] VAST XML content (first 2000 chars):\",\n vastXml.substring(0, 2000)\n );\n\n const trimmedXml = vastXml.trim();\n if (trimmedXml.length === 0) {\n console.warn(\"[HlsAdPlayer] VAST response body is empty (no fill)\");\n return null;\n }\n\n return parseVastXml(vastXml);\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 contentVideo.volume = 0;\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 contentVideo.volume = 0;\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 contentVideo.volume = 0;\n adPlaying = true;\n setAdPlayingFlag(true);\n\n if (adVideoElement) {\n const adVolume = originalMutedState ? 0 : originalVolume;\n adVideoElement.volume = Math.max(0, Math.min(1, adVolume));\n adVideoElement.muted = false;\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 = originalMutedState ? 0 : originalVolume;\n console.log(\n `[HlsAdPlayer] Restored mute state on stop: ${previousMutedState} -> ${originalMutedState}`\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 = originalMutedState ? 0 : 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 adVideoElement.volume = Math.max(0, Math.min(1, volume));\n }\n },\n\n getAdVolume(): number {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n 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 };\n}\n"]}
@@ -1769,7 +1769,7 @@ function createHlsAdPlayer(contentVideo, options) {
1769
1769
  }
1770
1770
  var adElement = xmlDoc.querySelector("Ad");
1771
1771
  if (!adElement) {
1772
- console.warn("[HlsAdPlayer] No Ad element found in VAST XML");
1772
+ console.warn("[HlsAdPlayer] No Ad element found in VAST XML (no fill). Content (first 2000 chars):", xmlString.substring(0, 2e3));
1773
1773
  return null;
1774
1774
  }
1775
1775
  var adId = adElement.getAttribute("id") || "unknown";
@@ -1865,7 +1865,7 @@ function createHlsAdPlayer(contentVideo, options) {
1865
1865
  }
1866
1866
  function fetchAndParseVastAd(vastTagUrl) {
1867
1867
  return _async_to_generator(function() {
1868
- var response, vastXml;
1868
+ var response, vastXml, trimmedXml;
1869
1869
  return _ts_generator(this, function(_state) {
1870
1870
  switch(_state.label){
1871
1871
  case 0:
@@ -1891,8 +1891,16 @@ function createHlsAdPlayer(contentVideo, options) {
1891
1891
  ];
1892
1892
  case 2:
1893
1893
  vastXml = _state.sent();
1894
- console.log("[HlsAdPlayer] VAST XML received");
1894
+ console.log("[HlsAdPlayer] VAST XML received (length=".concat(vastXml.length, ")"));
1895
1895
  console.log("[HlsAdPlayer] VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
1896
+ trimmedXml = vastXml.trim();
1897
+ if (trimmedXml.length === 0) {
1898
+ console.warn("[HlsAdPlayer] VAST response body is empty (no fill)");
1899
+ return [
1900
+ 2,
1901
+ null
1902
+ ];
1903
+ }
1896
1904
  return [
1897
1905
  2,
1898
1906
  parseVastXml(vastXml)
@@ -3332,6 +3340,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3332
3340
  this.preloadPoolActive = false;
3333
3341
  this.preloadPoolLoopRunning = false;
3334
3342
  this.adDetectSentForCurrentBreak = false;
3343
+ this.latencyProfileApplied = false;
3335
3344
  this.continuousFetchLoopRunning = false;
3336
3345
  initializePolyfills();
3337
3346
  var browserOverrides = getBrowserConfigOverrides();
@@ -3448,24 +3457,21 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3448
3457
  2
3449
3458
  ];
3450
3459
  case 7:
3451
- this.hls = new import_hls2.default(_object_spread_props(_object_spread({
3460
+ this.hls = new import_hls2.default({
3452
3461
  enableWorker: true,
3453
3462
  backBufferLength: 30,
3454
3463
  liveDurationInfinity: true,
3455
3464
  lowLatencyMode: !!this.config.lowLatencyMode,
3456
- maxLiveSyncPlaybackRate: this.config.lowLatencyMode ? 1.5 : 1
3457
- }, this.config.lowLatencyMode ? {
3458
- liveSyncDuration: 2
3459
- } : {}), {
3465
+ maxLiveSyncPlaybackRate: 1.1,
3460
3466
  maxBufferLength: 30,
3461
3467
  maxMaxBufferLength: 600,
3462
3468
  maxBufferSize: 60 * 1e3 * 1e3,
3463
- maxBufferHole: 0.5,
3469
+ maxBufferHole: 1,
3464
3470
  highBufferWatchdogPeriod: 2,
3465
- nudgeOffset: 0.1,
3466
- nudgeMaxRetry: 3,
3471
+ nudgeOffset: 0.2,
3472
+ nudgeMaxRetry: 5,
3467
3473
  startPosition: -1
3468
- }));
3474
+ });
3469
3475
  this.hls.on(import_hls2.default.Events.MEDIA_ATTACHED, function() {
3470
3476
  var _this_hls;
3471
3477
  (_this_hls = _this.hls) === null || _this_hls === void 0 ? void 0 : _this_hls.loadSource(_this.config.src);
@@ -3509,6 +3515,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3509
3515
  this.bufferedSegmentsCount = 0;
3510
3516
  this.hasInitialBufferCompleted = false;
3511
3517
  this.shouldAutoplayAfterBuffering = !!this.config.autoplay;
3518
+ this.latencyProfileApplied = false;
3519
+ this.detectedLowLatencyStream = void 0;
3512
3520
  minSegments = (_this_config_minSegmentsBeforePlay = this.config.minSegmentsBeforePlay) !== null && _this_config_minSegmentsBeforePlay !== void 0 ? _this_config_minSegmentsBeforePlay : 2;
3513
3521
  if (this.config.debugAdTiming) {
3514
3522
  console.log("[StormcloudVideoPlayer] Waiting for", minSegments, "segments to buffer before playback");
@@ -3538,6 +3546,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3538
3546
  }).call(_this);
3539
3547
  });
3540
3548
  this.hls.on(import_hls2.default.Events.LEVEL_LOADED, function(_evt, data) {
3549
+ _this.applyStreamLatencyProfile(data === null || data === void 0 ? void 0 : data.details);
3541
3550
  if (_this.inAdBreak || _this.pendingAdBreak) {
3542
3551
  return;
3543
3552
  }
@@ -3817,6 +3826,64 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3817
3826
  }).call(this);
3818
3827
  }
3819
3828
  },
3829
+ {
3830
+ key: "applyStreamLatencyProfile",
3831
+ value: function applyStreamLatencyProfile(details) {
3832
+ if (this.latencyProfileApplied || !this.hls) {
3833
+ return;
3834
+ }
3835
+ if (!details) {
3836
+ return;
3837
+ }
3838
+ if (details.live !== true) {
3839
+ this.latencyProfileApplied = true;
3840
+ this.detectedLowLatencyStream = false;
3841
+ return;
3842
+ }
3843
+ var isLowLatencyManifest = this.isLowLatencyManifest(details);
3844
+ var useLowLatency = isLowLatencyManifest && !!this.config.lowLatencyMode;
3845
+ this.detectedLowLatencyStream = useLowLatency;
3846
+ this.latencyProfileApplied = true;
3847
+ var cfg = this.hls.config;
3848
+ if (useLowLatency) {
3849
+ cfg.maxLiveSyncPlaybackRate = 1.5;
3850
+ cfg.maxBufferHole = 0.5;
3851
+ delete cfg.liveSyncDuration;
3852
+ } else {
3853
+ cfg.maxLiveSyncPlaybackRate = 1.1;
3854
+ cfg.maxBufferHole = 1;
3855
+ delete cfg.liveSyncDuration;
3856
+ cfg.liveSyncDurationCount = 3;
3857
+ }
3858
+ if (this.config.debugAdTiming) {
3859
+ var _details_targetduration;
3860
+ console.log("[StormcloudVideoPlayer] Live latency profile: ".concat(useLowLatency ? "LL-HLS (low latency)" : "standard live (stability)"), {
3861
+ isLowLatencyManifest: isLowLatencyManifest,
3862
+ lowLatencyModeRequested: !!this.config.lowLatencyMode,
3863
+ canBlockReload: details.canBlockReload,
3864
+ partTarget: details.partTarget,
3865
+ partHoldBack: details.partHoldBack,
3866
+ partListLength: Array.isArray(details.partList) ? details.partList.length : 0,
3867
+ targetDuration: (_details_targetduration = details.targetduration) !== null && _details_targetduration !== void 0 ? _details_targetduration : details.targetDuration,
3868
+ maxLiveSyncPlaybackRate: cfg.maxLiveSyncPlaybackRate,
3869
+ maxBufferHole: cfg.maxBufferHole
3870
+ });
3871
+ }
3872
+ }
3873
+ },
3874
+ {
3875
+ key: "isLowLatencyManifest",
3876
+ value: function isLowLatencyManifest(details) {
3877
+ if (!details) {
3878
+ return false;
3879
+ }
3880
+ var hasParts = Array.isArray(details.partList) && details.partList.length > 0;
3881
+ var hasPartTarget = typeof details.partTarget === "number" && details.partTarget > 0;
3882
+ var hasPartHoldBack = typeof details.partHoldBack === "number" && details.partHoldBack > 0;
3883
+ var canBlockReload = details.canBlockReload === true;
3884
+ return hasParts || hasPartTarget || hasPartHoldBack || canBlockReload;
3885
+ }
3886
+ },
3820
3887
  {
3821
3888
  key: "attachImaEventListeners",
3822
3889
  value: function attachImaEventListeners() {
@@ -5805,6 +5872,12 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5805
5872
  return !!(this.config.allowNativeHls && !((_this_config_showCustomControls = this.config.showCustomControls) !== null && _this_config_showCustomControls !== void 0 ? _this_config_showCustomControls : false));
5806
5873
  }
5807
5874
  },
5875
+ {
5876
+ key: "isLowLatencyStream",
5877
+ value: function isLowLatencyStream() {
5878
+ return this.detectedLowLatencyStream;
5879
+ }
5880
+ },
5808
5881
  {
5809
5882
  key: "shouldContinueLiveStreamDuringAds",
5810
5883
  value: function shouldContinueLiveStreamDuringAds() {