stormcloud-video-player 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/ubuntu24/Dev/stormcloud-vp/lib/sdk/hlsAdPlayer.cjs","../../src/sdk/hlsAdPlayer.ts"],"names":["__create","Object","create","__defProp","defineProperty","__getOwnPropDesc","getOwnPropertyDescriptor","__getOwnPropNames","getOwnPropertyNames","__getProtoOf","getPrototypeOf","__hasOwnProp","prototype","hasOwnProperty","__export","target","all","name","get","enumerable","__copyProps","to","from","except","desc","key","call","__toESM","mod","isNodeMode","__esModule","value","__toCommonJS","hlsAdPlayer_exports","createHlsAdPlayer","module","exports","import_hls","require","UNSUPPORTED_VIDEO_EXTENSIONS","getFileExtension","url","pathname","URL","lastDot","lastIndexOf","slice","toLowerCase","originalMutedState","ext","split","isUnsupportedForHls","replaceFlvExtension","replace","contentVideo","options","adPlaying","originalVolume","Math","max","min","volume","listeners","Map","licenseKey","mainHlsInstance","adVideoElement","adHls","currentAd","destroyed","sessionId","pendingTimeouts","trackingFired","impression","start","midpoint","thirdQuartile","complete","emit","event","payload","set","fn","error","console","warn","Date","now","random","toString","substr","buildVastUrl","durationSeconds","baseUrl","metadata","video","width","videoWidth","height","videoHeight","fps","bitrate","profile","pix_fmt","has_b_frames","audio","codec","sample_rate","metadataStr","encodeURIComponent","JSON","stringify","ceil","fireTrackingPixels","urls","length","forEach","trackingUrl","includes","img","Image","src","log","getMainStreamQuality","levels","currentLevel","autoLevel","loadLevel","level","selectBestMediaFile","mediaFiles","Error","firstFile","mainQuality","scoredFiles","map","file","widthDiff","abs","heightDiff","resolutionDiff","fileBitrate","bitrateDiff","score","sort","a","b","bestMatch","resolution","parseVastXml","xmlString","xmlDoc","parser","DOMParser","parseFromString","parserError","querySelector","textContent","adElement","adId","getAttribute","title","isNoAdAvailable","durationText","durationParts","duration","parseInt","mediaFileElements","querySelectorAll","mf","index","type","trim","originalUrl","bitrateAttr","bitrateValue","trackingUrls","firstQuartile","mute","unmute","pause","resume","fullscreen","exitFullscreen","skip","el","push","eventKey","clickThrough","id","fetchAndParseVastAd","response","vastXml","fetch","ok","statusText","text","setupAdEventListeners","handleAdComplete","createAdVideoElement","document","createElement","style","position","left","top","objectFit","backgroundColor","playsInline","muted","addEventListener","progress","e","handleAdError","ended","currentTime","setAdPlayingFlag","isPlaying","dataset","stormcloudAdPlaying","timeoutId","window","setTimeout","stillInPod","adContainerEl","display","pointerEvents","idx","indexOf","splice","previousMutedState","continueLiveStreamDuringAds","paused","play","catch","initialize","container","right","bottom","alignItems","justifyContent","zIndex","parentElement","appendChild","requestAds","parsed","vastUrl","ad","Promise","reject","generateSessionId","isNaN","resolve","contentVolume","adVolume","mediaFile"],"mappings":"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","sourcesContent":["\"use strict\";\nvar __create = Object.create;\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __getProtoOf = Object.getPrototypeOf;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(\n // If the importer is in node compatibility mode or this is not an ESM\n // file that has been converted to a CommonJS file using a Babel-\n // compatible transform (i.e. \"__esModule\" has not been set), then set\n // \"default\" to the CommonJS \"module.exports\" for node compatibility.\n isNodeMode || !mod || !mod.__esModule ? __defProp(target, \"default\", { value: mod, enumerable: true }) : target,\n mod\n));\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n// src/sdk/hlsAdPlayer.ts\nvar hlsAdPlayer_exports = {};\n__export(hlsAdPlayer_exports, {\n createHlsAdPlayer: () => createHlsAdPlayer\n});\nmodule.exports = __toCommonJS(hlsAdPlayer_exports);\nvar import_hls = __toESM(require(\"hls.js\"), 1);\nvar UNSUPPORTED_VIDEO_EXTENSIONS = [\".flv\", \".f4v\", \".swf\", \".wmv\", \".avi\", \".mov\", \".mkv\", \".mp4\", \".webm\"];\nfunction getFileExtension(url) {\n try {\n const pathname = new URL(url, \"http://dummy\").pathname;\n const lastDot = pathname.lastIndexOf(\".\");\n if (lastDot === -1) return \"\";\n return pathname.slice(lastDot).toLowerCase();\n } catch {\n const lastDot = url.lastIndexOf(\".\");\n if (lastDot === -1) return \"\";\n const ext = url.slice(lastDot).split(/[?#]/)[0];\n return (ext || \"\").toLowerCase();\n }\n}\nfunction isUnsupportedForHls(url) {\n const ext = getFileExtension(url);\n return UNSUPPORTED_VIDEO_EXTENSIONS.indexOf(ext) !== -1;\n}\nfunction replaceFlvExtension(url) {\n const ext = getFileExtension(url);\n if (ext === \".flv\") {\n return url.replace(/\\.flv(\\?|$)/i, \".mp4$1\");\n }\n return url;\n}\nfunction 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 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 buildVastUrl(durationSeconds) {\n const baseUrl = `https://adstorm.co/api-adstorm-dev/adstorm/vast/${licenseKey}/pod`;\n const metadata = {\n video: {\n codec: \"h264\",\n width: contentVideo.videoWidth || 1280,\n height: contentVideo.videoHeight || 720,\n fps: 29.97,\n bitrate: 5e3,\n profile: \"high\",\n pix_fmt: \"yuv420p\",\n has_b_frames: 0\n },\n audio: {\n codec: \"aac\",\n sample_rate: 48e3,\n bitrate: 128\n }\n };\n const metadataStr = encodeURIComponent(JSON.stringify(metadata));\n return `${baseUrl}?duration=${Math.ceil(durationSeconds)}&metadata=${metadataStr}`;\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 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 let 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 originalUrl = url;\n url = replaceFlvExtension(url);\n if (url !== originalUrl) {\n console.log(`[HlsAdPlayer] Converted FLV to MP4: ${originalUrl} -> ${url}`);\n }\n if (isUnsupportedForHls(url)) {\n const ext = getFileExtension(url);\n console.log(\n `[HlsAdPlayer] MediaFile ${index} ignored: unsupported format (extension: ${ext}, declared type: ${type})`\n );\n return;\n }\n if (type === \"application/x-mpegURL\" || type.includes(\"m3u8\")) {\n if (!url) {\n console.warn(\n `[HlsAdPlayer] MediaFile ${index} has HLS type but empty URL`\n );\n return;\n }\n const bitrateAttr = mf.getAttribute(\"bitrate\");\n const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;\n mediaFiles.push({\n url,\n type,\n width: parseInt(width || \"1920\", 10),\n height: parseInt(height || \"1080\", 10),\n bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : void 0\n });\n console.log(`[HlsAdPlayer] Added HLS MediaFile: ${url}`);\n } else {\n console.log(\n `[HlsAdPlayer] MediaFile ${index} ignored (type=\"${type}\" is not HLS)`\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 HLS 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(url) {\n const response = await fetch(url);\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 emit(\"content_resume\");\n const timeoutId = window.setTimeout(() => {\n if (destroyed) {\n console.log(\"[HlsAdPlayer] Player destroyed, skipping post-completion check\");\n return;\n }\n const stillInPod = contentVideo.dataset.stormcloudAdPlaying === \"true\";\n if (stillInPod) {\n console.log(\n \"[HlsAdPlayer] Still in ad pod - keeping ad container visible (black screen)\"\n );\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n }\n const idx = pendingTimeouts.indexOf(timeoutId);\n if (idx !== -1) {\n pendingTimeouts.splice(idx, 1);\n }\n }, 50);\n pendingTimeouts.push(timeoutId);\n }\n function handleAdError() {\n console.log(\"[HlsAdPlayer] Handling ad error\");\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: ${previousMutedState} -> ${originalMutedState}`\n );\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n if (!options?.continueLiveStreamDuringAds) {\n if (contentVideo.paused) {\n contentVideo.play().catch(() => {\n });\n }\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 = \"10\";\n container.style.backgroundColor = \"#000\";\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n },\n async requestAds(duration) {\n console.log(\"[HlsAdPlayer] Requesting ads for duration:\", duration);\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 durationSeconds = 30;\n const parsed = parseInt(duration, 10);\n if (!isNaN(parsed) && parsed > 0) {\n durationSeconds = parsed;\n }\n const vastUrl = buildVastUrl(durationSeconds);\n const ad = await fetchAndParseVastAd(vastUrl);\n if (!ad) {\n console.warn(\"[HlsAdPlayer] No ads available from VAST response\");\n emit(\"ad_error\");\n return Promise.resolve();\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 console.log(`[HlsAdPlayer] Loading ad from: ${mediaFile.url}`);\n if (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 (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 {\n throw new Error(\"HLS not supported\");\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 async stop() {\n console.log(\"[HlsAdPlayer] Stopping ad\");\n adPlaying = false;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\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 },\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 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 }\n };\n}\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n createHlsAdPlayer\n});\n","import type { AdController } from \"../types\";\nimport Hls from \"hls.js\";\n\ninterface VastMediaFile {\n url: string;\n type: string;\n width: number;\n height: number;\n bitrate?: number | undefined;\n}\n\nconst UNSUPPORTED_VIDEO_EXTENSIONS = ['.flv', '.f4v', '.swf', '.wmv', '.avi', '.mov', '.mkv', '.mp4', '.webm'];\n\nfunction getFileExtension(url: string): string {\n try {\n const pathname = new URL(url, 'http://dummy').pathname;\n const lastDot = pathname.lastIndexOf('.');\n if (lastDot === -1) return '';\n return pathname.slice(lastDot).toLowerCase();\n } catch {\n const lastDot = url.lastIndexOf('.');\n if (lastDot === -1) return '';\n const ext = url.slice(lastDot).split(/[?#]/)[0];\n return (ext || '').toLowerCase();\n }\n}\n\nfunction isUnsupportedForHls(url: string): boolean {\n const ext = getFileExtension(url);\n return UNSUPPORTED_VIDEO_EXTENSIONS.indexOf(ext) !== -1;\n}\n\nfunction replaceFlvExtension(url: string): string {\n const ext = getFileExtension(url);\n if (ext === '.flv') {\n return url.replace(/\\.flv(\\?|$)/i, '.mp4$1');\n }\n return url;\n}\n\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): AdController {\n let adPlaying = false;\n let originalMutedState = false;\n let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));\n const listeners = new Map<string, Set<(payload?: any) => void>>();\n const licenseKey = options?.licenseKey;\n const mainHlsInstance = options?.mainHlsInstance;\n\n let adVideoElement: HTMLVideoElement | undefined;\n let adHls: Hls | undefined;\n let adContainerEl: HTMLDivElement | undefined;\n let currentAd: VastAd | undefined;\n let sessionId: string | undefined;\n 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 buildVastUrl(durationSeconds: number): string {\n const baseUrl = `https://adstorm.co/api-adstorm-dev/adstorm/vast/${licenseKey}/pod`;\n \n const metadata = {\n video: {\n codec: \"h264\",\n width: contentVideo.videoWidth || 1280,\n height: contentVideo.videoHeight || 720,\n fps: 29.97,\n bitrate: 5000,\n profile: \"high\",\n pix_fmt: \"yuv420p\",\n has_b_frames: 0,\n },\n audio: {\n codec: \"aac\",\n sample_rate: 48000,\n bitrate: 128,\n },\n };\n \n const metadataStr = encodeURIComponent(JSON.stringify(metadata));\n return `${baseUrl}?duration=${Math.ceil(durationSeconds)}&metadata=${metadataStr}`;\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 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 let 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 originalUrl = url;\n url = replaceFlvExtension(url);\n if (url !== originalUrl) {\n console.log(`[HlsAdPlayer] Converted FLV to MP4: ${originalUrl} -> ${url}`);\n }\n\n if (isUnsupportedForHls(url)) {\n const ext = getFileExtension(url);\n console.log(\n `[HlsAdPlayer] MediaFile ${index} ignored: unsupported format (extension: ${ext}, declared type: ${type})`\n );\n return;\n }\n\n if (type === \"application/x-mpegURL\" || type.includes(\"m3u8\")) {\n if (!url) {\n console.warn(\n `[HlsAdPlayer] MediaFile ${index} has HLS type but empty URL`\n );\n return;\n }\n\n const bitrateAttr = mf.getAttribute(\"bitrate\");\n const bitrateValue = bitrateAttr\n ? parseInt(bitrateAttr, 10)\n : undefined;\n\n mediaFiles.push({\n url,\n type,\n width: parseInt(width || \"1920\", 10),\n height: parseInt(height || \"1080\", 10),\n bitrate:\n bitrateValue && bitrateValue > 0 ? bitrateValue : undefined,\n });\n\n console.log(`[HlsAdPlayer] Added HLS MediaFile: ${url}`);\n } else {\n console.log(\n `[HlsAdPlayer] MediaFile ${index} ignored (type=\"${type}\" is not HLS)`\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 HLS 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 url: string\n ): Promise<VastAd | null> {\n const response = await fetch(url);\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 emit(\"content_resume\");\n\n const timeoutId = window.setTimeout(() => {\n if (destroyed) {\n console.log(\"[HlsAdPlayer] Player destroyed, skipping post-completion check\");\n return;\n }\n \n const stillInPod = contentVideo.dataset.stormcloudAdPlaying === \"true\";\n if (stillInPod) {\n console.log(\n \"[HlsAdPlayer] Still in ad pod - keeping ad container visible (black screen)\"\n );\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n }\n \n const idx = pendingTimeouts.indexOf(timeoutId);\n if (idx !== -1) {\n pendingTimeouts.splice(idx, 1);\n }\n }, 50);\n \n pendingTimeouts.push(timeoutId);\n }\n\n function handleAdError(): void {\n console.log(\"[HlsAdPlayer] Handling ad error\");\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: ${previousMutedState} -> ${originalMutedState}`\n );\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 contentVideo.play().catch(() => {});\n }\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 = \"10\";\n container.style.backgroundColor = \"#000\";\n\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n },\n\n async requestAds(duration: string) {\n console.log(\"[HlsAdPlayer] Requesting ads for duration:\", duration);\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 \n let durationSeconds = 30;\n const parsed = parseInt(duration, 10);\n if (!isNaN(parsed) && parsed > 0) {\n durationSeconds = parsed;\n }\n \n const vastUrl = buildVastUrl(durationSeconds);\n const ad = await fetchAndParseVastAd(vastUrl);\n\n if (!ad) {\n console.warn(\"[HlsAdPlayer] No ads available from VAST response\");\n emit(\"ad_error\");\n return Promise.resolve();\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\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 console.log(`[HlsAdPlayer] Loading ad from: ${mediaFile.url}`);\n\n if (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 (\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 {\n throw new Error(\"HLS not supported\");\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\n async stop() {\n console.log(\"[HlsAdPlayer] Stopping ad\");\n adPlaying = false;\n setAdPlayingFlag(false);\n\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\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 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 },\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 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 };\n}\n"]}
1
+ {"version":3,"sources":["/home/ubuntu24/Dev/stormcloud-vp/lib/sdk/hlsAdPlayer.cjs","../../src/sdk/hlsAdPlayer.ts"],"names":["__create","Object","create","__defProp","defineProperty","__getOwnPropDesc","getOwnPropertyDescriptor","__getOwnPropNames","getOwnPropertyNames","__getProtoOf","getPrototypeOf","__hasOwnProp","prototype","hasOwnProperty","__export","target","all","name","get","enumerable","__copyProps","to","from","except","desc","key","call","__toESM","mod","isNodeMode","__esModule","value","__toCommonJS","hlsAdPlayer_exports","createHlsAdPlayer","module","exports","import_hls","require","UNSUPPORTED_VIDEO_EXTENSIONS","getFileExtension","url","pathname","URL","lastDot","lastIndexOf","slice","toLowerCase","Math","max","ext","split","isUnsupportedForHls","indexOf","replaceFlvExtension","replace","contentVideo","options","adPlaying","originalMutedState","originalVolume","min","volume","allowNativeHls","listeners","Map","licenseKey","mainHlsInstance","adVideoElement","adHls","currentAd","destroyed","sessionId","pendingTimeouts","trackingFired","impression","start","midpoint","thirdQuartile","complete","emit","event","payload","set","fn","error","console","warn","Date","now","random","toString","substr","buildVastUrl","durationSeconds","baseUrl","metadata","video","width","videoWidth","height","videoHeight","fps","bitrate","profile","pix_fmt","has_b_frames","audio","codec","sample_rate","metadataStr","encodeURIComponent","JSON","stringify","ceil","fireTrackingPixels","urls","length","forEach","trackingUrl","includes","img","Image","src","log","getMainStreamQuality","levels","currentLevel","autoLevel","loadLevel","level","selectBestMediaFile","mediaFiles","Error","firstFile","mainQuality","scoredFiles","map","file","widthDiff","abs","heightDiff","resolutionDiff","fileBitrate","bitrateDiff","score","sort","a","b","bestMatch","resolution","parseVastXml","xmlString","xmlDoc","parser","DOMParser","parseFromString","parserError","querySelector","textContent","adElement","adId","getAttribute","title","isNoAdAvailable","durationText","durationParts","duration","parseInt","mediaFileElements","querySelectorAll","mf","index","type","trim","originalUrl","bitrateAttr","bitrateValue","trackingUrls","firstQuartile","mute","unmute","pause","resume","fullscreen","exitFullscreen","skip","el","push","eventKey","clickThrough","id","fetchAndParseVastAd","response","vastXml","fetch","ok","statusText","text","setupAdEventListeners","handleAdComplete","createAdVideoElement","document","createElement","style","position","left","top","objectFit","backgroundColor","playsInline","muted","addEventListener","progress","e","handleAdError","ended","currentTime","setAdPlayingFlag","isPlaying","dataset","stormcloudAdPlaying","timeoutId","window","setTimeout","stillInPod","adContainerEl","display","pointerEvents","idx","splice","previousMutedState","continueLiveStreamDuringAds","paused","play","catch","initialize","container","right","bottom","alignItems","justifyContent","zIndex","parentElement","appendChild","requestAds","parsed","vastUrl","ad","Promise","reject","generateSessionId","isNaN","resolve","contentVolume","adVolume","mediaFile"],"mappings":"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","sourcesContent":["\"use strict\";\nvar __create = Object.create;\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __getProtoOf = Object.getPrototypeOf;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(\n // If the importer is in node compatibility mode or this is not an ESM\n // file that has been converted to a CommonJS file using a Babel-\n // compatible transform (i.e. \"__esModule\" has not been set), then set\n // \"default\" to the CommonJS \"module.exports\" for node compatibility.\n isNodeMode || !mod || !mod.__esModule ? __defProp(target, \"default\", { value: mod, enumerable: true }) : target,\n mod\n));\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n// src/sdk/hlsAdPlayer.ts\nvar hlsAdPlayer_exports = {};\n__export(hlsAdPlayer_exports, {\n createHlsAdPlayer: () => createHlsAdPlayer\n});\nmodule.exports = __toCommonJS(hlsAdPlayer_exports);\nvar import_hls = __toESM(require(\"hls.js\"), 1);\nvar UNSUPPORTED_VIDEO_EXTENSIONS = [\".flv\", \".f4v\", \".swf\", \".wmv\", \".avi\", \".mov\", \".mkv\", \".mp4\", \".webm\"];\nfunction getFileExtension(url) {\n try {\n const pathname = new URL(url, \"http://dummy\").pathname;\n const lastDot = pathname.lastIndexOf(\".\");\n if (lastDot === -1) return \"\";\n return pathname.slice(lastDot).toLowerCase();\n } catch {\n const lastDot = url.lastIndexOf(\".\");\n if (lastDot === -1) return \"\";\n const ext = url.slice(lastDot).split(/[?#]/)[0];\n return (ext || \"\").toLowerCase();\n }\n}\nfunction isUnsupportedForHls(url) {\n const ext = getFileExtension(url);\n return UNSUPPORTED_VIDEO_EXTENSIONS.indexOf(ext) !== -1;\n}\nfunction replaceFlvExtension(url) {\n const ext = getFileExtension(url);\n if (ext === \".flv\") {\n return url.replace(/\\.flv(\\?|$)/i, \".mp4$1\");\n }\n return url;\n}\nfunction createHlsAdPlayer(contentVideo, options) {\n let adPlaying = false;\n let originalMutedState = false;\n let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));\n let allowNativeHls = false;\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 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 buildVastUrl(durationSeconds) {\n const baseUrl = `https://adstorm.co/api-adstorm-dev/adstorm/vast/${licenseKey}/pod`;\n const metadata = {\n video: {\n codec: \"h264\",\n width: contentVideo.videoWidth || 1280,\n height: contentVideo.videoHeight || 720,\n fps: 29.97,\n bitrate: 5e3,\n profile: \"high\",\n pix_fmt: \"yuv420p\",\n has_b_frames: 0\n },\n audio: {\n codec: \"aac\",\n sample_rate: 48e3,\n bitrate: 128\n }\n };\n const metadataStr = encodeURIComponent(JSON.stringify(metadata));\n return `${baseUrl}?duration=${Math.ceil(durationSeconds)}&metadata=${metadataStr}`;\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 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 let 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 originalUrl = url;\n url = replaceFlvExtension(url);\n if (url !== originalUrl) {\n console.log(`[HlsAdPlayer] Converted FLV to MP4: ${originalUrl} -> ${url}`);\n }\n if (isUnsupportedForHls(url)) {\n const ext = getFileExtension(url);\n console.log(\n `[HlsAdPlayer] MediaFile ${index} ignored: unsupported format (extension: ${ext}, declared type: ${type})`\n );\n return;\n }\n if (type === \"application/x-mpegURL\" || type.includes(\"m3u8\")) {\n if (!url) {\n console.warn(\n `[HlsAdPlayer] MediaFile ${index} has HLS type but empty URL`\n );\n return;\n }\n const bitrateAttr = mf.getAttribute(\"bitrate\");\n const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;\n mediaFiles.push({\n url,\n type,\n width: parseInt(width || \"1920\", 10),\n height: parseInt(height || \"1080\", 10),\n bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : void 0\n });\n console.log(`[HlsAdPlayer] Added HLS MediaFile: ${url}`);\n } else {\n console.log(\n `[HlsAdPlayer] MediaFile ${index} ignored (type=\"${type}\" is not HLS)`\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 HLS 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(url) {\n const response = await fetch(url);\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 emit(\"content_resume\");\n const timeoutId = window.setTimeout(() => {\n if (destroyed) {\n console.log(\"[HlsAdPlayer] Player destroyed, skipping post-completion check\");\n return;\n }\n const stillInPod = contentVideo.dataset.stormcloudAdPlaying === \"true\";\n if (stillInPod) {\n console.log(\n \"[HlsAdPlayer] Still in ad pod - keeping ad container visible (black screen)\"\n );\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n }\n const idx = pendingTimeouts.indexOf(timeoutId);\n if (idx !== -1) {\n pendingTimeouts.splice(idx, 1);\n }\n }, 50);\n pendingTimeouts.push(timeoutId);\n }\n function handleAdError() {\n console.log(\"[HlsAdPlayer] Handling ad error\");\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: ${previousMutedState} -> ${originalMutedState}`\n );\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\n }\n if (!options?.continueLiveStreamDuringAds) {\n if (contentVideo.paused) {\n contentVideo.play().catch(() => {\n });\n }\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 = \"10\";\n container.style.backgroundColor = \"#000\";\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n },\n async requestAds(duration) {\n console.log(\"[HlsAdPlayer] Requesting ads for duration:\", duration);\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 durationSeconds = 30;\n const parsed = parseInt(duration, 10);\n if (!isNaN(parsed) && parsed > 0) {\n durationSeconds = parsed;\n }\n const vastUrl = buildVastUrl(durationSeconds);\n const ad = await fetchAndParseVastAd(vastUrl);\n if (!ad) {\n console.warn(\"[HlsAdPlayer] No ads available from VAST response\");\n emit(\"ad_error\");\n return Promise.resolve();\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 console.log(`[HlsAdPlayer] Loading ad from: ${mediaFile.url}`);\n if (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 (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 {\n throw new Error(\"HLS not supported\");\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 async stop() {\n console.log(\"[HlsAdPlayer] Stopping ad\");\n adPlaying = false;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\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 },\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 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 },\n setAllowNativeHls(value) {\n allowNativeHls = value;\n }\n };\n}\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n createHlsAdPlayer\n});\n","import type { AdController } from \"../types\";\nimport Hls from \"hls.js\";\n\ninterface VastMediaFile {\n url: string;\n type: string;\n width: number;\n height: number;\n bitrate?: number | undefined;\n}\n\nconst UNSUPPORTED_VIDEO_EXTENSIONS = ['.flv', '.f4v', '.swf', '.wmv', '.avi', '.mov', '.mkv', '.mp4', '.webm'];\n\nfunction getFileExtension(url: string): string {\n try {\n const pathname = new URL(url, 'http://dummy').pathname;\n const lastDot = pathname.lastIndexOf('.');\n if (lastDot === -1) return '';\n return pathname.slice(lastDot).toLowerCase();\n } catch {\n const lastDot = url.lastIndexOf('.');\n if (lastDot === -1) return '';\n const ext = url.slice(lastDot).split(/[?#]/)[0];\n return (ext || '').toLowerCase();\n }\n}\n\nfunction isUnsupportedForHls(url: string): boolean {\n const ext = getFileExtension(url);\n return UNSUPPORTED_VIDEO_EXTENSIONS.indexOf(ext) !== -1;\n}\n\nfunction replaceFlvExtension(url: string): string {\n const ext = getFileExtension(url);\n if (ext === '.flv') {\n return url.replace(/\\.flv(\\?|$)/i, '.mp4$1');\n }\n return url;\n}\n\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): AdController {\n let adPlaying = false;\n let originalMutedState = false;\n let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));\n let allowNativeHls = false;\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 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 buildVastUrl(durationSeconds: number): string {\n const baseUrl = `https://adstorm.co/api-adstorm-dev/adstorm/vast/${licenseKey}/pod`;\n \n const metadata = {\n video: {\n codec: \"h264\",\n width: contentVideo.videoWidth || 1280,\n height: contentVideo.videoHeight || 720,\n fps: 29.97,\n bitrate: 5000,\n profile: \"high\",\n pix_fmt: \"yuv420p\",\n has_b_frames: 0,\n },\n audio: {\n codec: \"aac\",\n sample_rate: 48000,\n bitrate: 128,\n },\n };\n \n const metadataStr = encodeURIComponent(JSON.stringify(metadata));\n return `${baseUrl}?duration=${Math.ceil(durationSeconds)}&metadata=${metadataStr}`;\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 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 let 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 originalUrl = url;\n url = replaceFlvExtension(url);\n if (url !== originalUrl) {\n console.log(`[HlsAdPlayer] Converted FLV to MP4: ${originalUrl} -> ${url}`);\n }\n\n if (isUnsupportedForHls(url)) {\n const ext = getFileExtension(url);\n console.log(\n `[HlsAdPlayer] MediaFile ${index} ignored: unsupported format (extension: ${ext}, declared type: ${type})`\n );\n return;\n }\n\n if (type === \"application/x-mpegURL\" || type.includes(\"m3u8\")) {\n if (!url) {\n console.warn(\n `[HlsAdPlayer] MediaFile ${index} has HLS type but empty URL`\n );\n return;\n }\n\n const bitrateAttr = mf.getAttribute(\"bitrate\");\n const bitrateValue = bitrateAttr\n ? parseInt(bitrateAttr, 10)\n : undefined;\n\n mediaFiles.push({\n url,\n type,\n width: parseInt(width || \"1920\", 10),\n height: parseInt(height || \"1080\", 10),\n bitrate:\n bitrateValue && bitrateValue > 0 ? bitrateValue : undefined,\n });\n\n console.log(`[HlsAdPlayer] Added HLS MediaFile: ${url}`);\n } else {\n console.log(\n `[HlsAdPlayer] MediaFile ${index} ignored (type=\"${type}\" is not HLS)`\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 HLS 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 url: string\n ): Promise<VastAd | null> {\n const response = await fetch(url);\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 emit(\"content_resume\");\n\n const timeoutId = window.setTimeout(() => {\n if (destroyed) {\n console.log(\"[HlsAdPlayer] Player destroyed, skipping post-completion check\");\n return;\n }\n \n const stillInPod = contentVideo.dataset.stormcloudAdPlaying === \"true\";\n if (stillInPod) {\n console.log(\n \"[HlsAdPlayer] Still in ad pod - keeping ad container visible (black screen)\"\n );\n if (adContainerEl) {\n adContainerEl.style.display = \"flex\";\n adContainerEl.style.pointerEvents = \"auto\";\n }\n }\n \n const idx = pendingTimeouts.indexOf(timeoutId);\n if (idx !== -1) {\n pendingTimeouts.splice(idx, 1);\n }\n }, 50);\n \n pendingTimeouts.push(timeoutId);\n }\n\n function handleAdError(): void {\n console.log(\"[HlsAdPlayer] Handling ad error\");\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: ${previousMutedState} -> ${originalMutedState}`\n );\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 contentVideo.play().catch(() => {});\n }\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 = \"10\";\n container.style.backgroundColor = \"#000\";\n\n contentVideo.parentElement?.appendChild(container);\n adContainerEl = container;\n }\n },\n\n async requestAds(duration: string) {\n console.log(\"[HlsAdPlayer] Requesting ads for duration:\", duration);\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 \n let durationSeconds = 30;\n const parsed = parseInt(duration, 10);\n if (!isNaN(parsed) && parsed > 0) {\n durationSeconds = parsed;\n }\n \n const vastUrl = buildVastUrl(durationSeconds);\n const ad = await fetchAndParseVastAd(vastUrl);\n\n if (!ad) {\n console.warn(\"[HlsAdPlayer] No ads available from VAST response\");\n emit(\"ad_error\");\n return Promise.resolve();\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\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 console.log(`[HlsAdPlayer] Loading ad from: ${mediaFile.url}`);\n\n if (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 (\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 {\n throw new Error(\"HLS not supported\");\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\n async stop() {\n console.log(\"[HlsAdPlayer] Stopping ad\");\n adPlaying = false;\n setAdPlayingFlag(false);\n\n if (adContainerEl) {\n adContainerEl.style.display = \"none\";\n adContainerEl.style.pointerEvents = \"none\";\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 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 },\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 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 setAllowNativeHls(value: boolean) {\n allowNativeHls = value;\n },\n };\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { A as AdController } from '../types-Ca4ZDaWw.cjs';
1
+ import { A as AdController } from '../types-2vzNGNdf.cjs';
2
2
  import Hls from 'hls.js';
3
3
 
4
4
  declare function createHlsAdPlayer(contentVideo: HTMLVideoElement, options?: {
@@ -36,6 +36,7 @@ interface AdController {
36
36
  getAdVolume: () => number;
37
37
  showPlaceholder: () => void;
38
38
  hidePlaceholder: () => void;
39
+ setAllowNativeHls: (allowNativeHls: boolean) => void;
39
40
  }
40
41
  interface ClientInfo {
41
42
  brand: string;
@@ -419,6 +419,7 @@ function createAdStormPlayer(contentVideo, options) {
419
419
  var adContainerEl;
420
420
  var currentAd;
421
421
  var destroyed = false;
422
+ var allowNativeHls = false;
422
423
  var trackingFired = {
423
424
  impression: false,
424
425
  start: false,
@@ -876,7 +877,9 @@ function createAdStormPlayer(contentVideo, options) {
876
877
  }, 300);
877
878
  contentVideo.muted = true;
878
879
  contentVideo.volume = 0;
879
- contentVideo.pause();
880
+ if (allowNativeHls) {
881
+ contentVideo.pause();
882
+ }
880
883
  adPlaying = true;
881
884
  setAdPlayingFlag(true);
882
885
  if (adVideoElement) {
@@ -1052,6 +1055,10 @@ function createAdStormPlayer(contentVideo, options) {
1052
1055
  }
1053
1056
  }, 300);
1054
1057
  }
1058
+ },
1059
+ setAllowNativeHls: function setAllowNativeHls(value) {
1060
+ allowNativeHls = value;
1061
+ log("allowNativeHls set to: ".concat(value));
1055
1062
  }
1056
1063
  };
1057
1064
  }
@@ -1484,6 +1491,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
1484
1491
  });
1485
1492
  }
1486
1493
  this.adPlayer.initialize();
1494
+ this.adPlayer.setAllowNativeHls(!!this.config.allowNativeHls);
1487
1495
  if (!this.config.autoplay) return [
1488
1496
  3,
1489
1497
  2
@@ -1538,6 +1546,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
1538
1546
  });
1539
1547
  }
1540
1548
  this.adPlayer.initialize();
1549
+ this.adPlayer.setAllowNativeHls(!!this.config.allowNativeHls);
1541
1550
  this.bufferedSegmentsCount = 0;
1542
1551
  this.hasInitialBufferCompleted = false;
1543
1552
  this.shouldAutoplayAfterBuffering = !!this.config.autoplay;