stormcloud-video-player 0.2.21 → 0.2.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/stormcloud-vp.min.js +2 -2
- package/lib/index.cjs +43 -4
- package/lib/index.cjs.map +1 -1
- package/lib/index.js +43 -4
- package/lib/index.js.map +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +43 -4
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/players/HlsPlayer.cjs +43 -4
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/index.cjs +43 -4
- package/lib/players/index.cjs.map +1 -1
- package/lib/sdk/hlsAdPlayer.cjs +14 -0
- package/lib/sdk/hlsAdPlayer.cjs.map +1 -1
- package/lib/sdk/ima.cjs +21 -2
- package/lib/sdk/ima.cjs.map +1 -1
- package/lib/ui/StormcloudVideoPlayer.cjs +43 -4
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/package.json +1 -1
package/lib/sdk/hlsAdPlayer.cjs
CHANGED
|
@@ -360,6 +360,18 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
360
360
|
adPlaying = false;
|
|
361
361
|
setAdPlayingFlag(false);
|
|
362
362
|
emit("content_resume");
|
|
363
|
+
setTimeout(() => {
|
|
364
|
+
const stillInPod = contentVideo.dataset.stormcloudAdPlaying === "true";
|
|
365
|
+
if (stillInPod) {
|
|
366
|
+
console.log(
|
|
367
|
+
"[HlsAdPlayer] Still in ad pod - keeping ad container visible (black screen)"
|
|
368
|
+
);
|
|
369
|
+
if (adContainerEl) {
|
|
370
|
+
adContainerEl.style.display = "flex";
|
|
371
|
+
adContainerEl.style.pointerEvents = "auto";
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}, 50);
|
|
363
375
|
}
|
|
364
376
|
function handleAdError() {
|
|
365
377
|
console.log("[HlsAdPlayer] Handling ad error");
|
|
@@ -471,7 +483,9 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
471
483
|
} else {
|
|
472
484
|
console.log("[HlsAdPlayer] Content continues (Live mode)");
|
|
473
485
|
}
|
|
486
|
+
console.log("[HlsAdPlayer] FORCE MUTING main video");
|
|
474
487
|
contentVideo.muted = true;
|
|
488
|
+
contentVideo.volume = 0;
|
|
475
489
|
adPlaying = true;
|
|
476
490
|
setAdPlayingFlag(true);
|
|
477
491
|
if (adVideoElement) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/sdk/hlsAdPlayer.ts"],"sourcesContent":["import type { ImaController } from \"../types\";\nimport Hls from \"hls.js\";\n\ninterface VastMediaFile {\n url: string;\n type: string;\n width: number;\n height: number;\n bitrate?: number | undefined;\n}\n\ninterface VastTrackingUrls {\n impression: string[];\n start: string[];\n firstQuartile: string[];\n midpoint: string[];\n thirdQuartile: string[];\n complete: string[];\n mute: string[];\n unmute: string[];\n pause: string[];\n resume: string[];\n fullscreen: string[];\n exitFullscreen: string[];\n skip: string[];\n error: string[];\n}\n\ninterface VastAd {\n id: string;\n title: string;\n duration: number;\n mediaFiles: VastMediaFile[];\n trackingUrls: VastTrackingUrls;\n clickThrough?: string | undefined;\n}\n\nexport function createHlsAdPlayer(\n contentVideo: HTMLVideoElement,\n options?: {\n continueLiveStreamDuringAds?: boolean;\n licenseKey?: string;\n mainHlsInstance?: Hls;\n }\n): ImaController {\n let adPlaying = false;\n let originalMutedState = false;\n 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\n let trackingFired = {\n impression: false,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false,\n };\n\n function emit(event: string, payload?: any): void {\n const set = listeners.get(event);\n if (!set) return;\n for (const fn of Array.from(set)) {\n try {\n fn(payload);\n } catch (error) {\n console.warn(\n `[HlsAdPlayer] Error in event listener for ${event}:`,\n error\n );\n }\n }\n }\n\n function generateSessionId(): string {\n return `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n\n function fireTrackingPixels(urls: string[]): void {\n if (!urls || urls.length === 0) return;\n\n urls.forEach((url) => {\n try {\n let trackingUrl = url;\n\n if (sessionId) {\n trackingUrl = `${trackingUrl}${\n trackingUrl.includes(\"?\") ? \"&\" : \"?\"\n }session_id=${sessionId}`;\n }\n\n if (licenseKey) {\n trackingUrl = `${trackingUrl}${\n trackingUrl.includes(\"?\") ? \"&\" : \"?\"\n }license_key=${licenseKey}`;\n }\n\n const img = new Image(1, 1);\n img.src = trackingUrl;\n console.log(`[HlsAdPlayer] Fired tracking pixel: ${trackingUrl}`);\n } catch (error) {\n console.warn(`[HlsAdPlayer] Error firing tracking pixel:`, error);\n }\n });\n }\n\n function getMainStreamQuality(): {\n width: number;\n height: number;\n bitrate: number;\n } | null {\n if (!mainHlsInstance || !mainHlsInstance.levels) {\n return null;\n }\n\n const currentLevel = mainHlsInstance.currentLevel;\n if (currentLevel === -1 || !mainHlsInstance.levels[currentLevel]) {\n const autoLevel = mainHlsInstance.loadLevel;\n if (autoLevel !== -1 && mainHlsInstance.levels[autoLevel]) {\n const level = mainHlsInstance.levels[autoLevel];\n return {\n width: level.width || 1920,\n height: level.height || 1080,\n bitrate: level.bitrate || 5000000,\n };\n }\n return null;\n }\n\n const level = mainHlsInstance.levels[currentLevel];\n return {\n width: level.width || 1920,\n height: level.height || 1080,\n bitrate: level.bitrate || 5000000,\n };\n }\n\n function selectBestMediaFile(mediaFiles: VastMediaFile[]): VastMediaFile {\n if (mediaFiles.length === 0) {\n throw new Error(\"No media files available\");\n }\n\n const firstFile = mediaFiles[0];\n if (!firstFile) {\n throw new Error(\"No media files available\");\n }\n\n if (mediaFiles.length === 1) {\n return firstFile;\n }\n\n const mainQuality = getMainStreamQuality();\n if (!mainQuality) {\n console.log(\n \"[HlsAdPlayer] No main stream quality info, using first media file\"\n );\n return firstFile;\n }\n\n console.log(\"[HlsAdPlayer] Main stream quality:\", mainQuality);\n\n const scoredFiles = mediaFiles.map((file) => {\n const widthDiff = Math.abs(file.width - mainQuality.width);\n const heightDiff = Math.abs(file.height - mainQuality.height);\n const resolutionDiff = widthDiff + heightDiff;\n\n const fileBitrate = (file.bitrate || 5000) * 1000;\n const bitrateDiff = Math.abs(fileBitrate - mainQuality.bitrate);\n\n const score = resolutionDiff * 2 + bitrateDiff / 1000;\n\n return { file, score, resolutionDiff, bitrateDiff };\n });\n\n scoredFiles.sort((a, b) => a.score - b.score);\n\n const bestMatch = scoredFiles[0];\n if (!bestMatch) {\n console.log(\"[HlsAdPlayer] No best match found, using first media file\");\n return firstFile;\n }\n\n console.log(\"[HlsAdPlayer] Selected media file:\", {\n url: bestMatch.file.url,\n resolution: `${bestMatch.file.width}x${bestMatch.file.height}`,\n bitrate: bestMatch.file.bitrate,\n score: bestMatch.score,\n resolutionDiff: bestMatch.resolutionDiff,\n bitrateDiff: bestMatch.bitrateDiff,\n });\n\n return bestMatch.file;\n }\n\n function parseVastXml(xmlString: string): VastAd | null {\n try {\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n\n const parserError = xmlDoc.querySelector(\"parsererror\");\n if (parserError) {\n console.error(\n \"[HlsAdPlayer] XML parsing error (malformed VAST XML):\",\n parserError.textContent\n );\n return null;\n }\n\n const adElement = xmlDoc.querySelector(\"Ad\");\n if (!adElement) {\n console.warn(\"[HlsAdPlayer] No Ad element found in VAST XML\");\n return null;\n }\n\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n\n const isNoAdAvailable =\n adId === \"empty\" ||\n title.toLowerCase().includes(\"no ad available\") ||\n title.toLowerCase() === \"no ad available\";\n\n const durationText =\n xmlDoc.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n const durationParts = durationText.split(\":\");\n const duration =\n parseInt(durationParts[0] || \"0\", 10) * 3600 +\n parseInt(durationParts[1] || \"0\", 10) * 60 +\n parseInt(durationParts[2] || \"0\", 10);\n\n const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n const mediaFiles: VastMediaFile[] = [];\n\n console.log(\n `[HlsAdPlayer] Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`\n );\n\n mediaFileElements.forEach((mf, index) => {\n const type = mf.getAttribute(\"type\") || \"\";\n const url = mf.textContent?.trim() || \"\";\n const width = mf.getAttribute(\"width\") || \"\";\n const height = mf.getAttribute(\"height\") || \"\";\n\n console.log(\n `[HlsAdPlayer] MediaFile ${index}: type=\"${type}\", url=\"${url}\", width=\"${width}\", height=\"${height}\"`\n );\n\n 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 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\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 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(vastTagUrl: string) {\n console.log(\"[HlsAdPlayer] Requesting ads:\", vastTagUrl);\n\n if (adPlaying) {\n console.warn(\n \"[HlsAdPlayer] Cannot request new ads while an ad is playing\"\n );\n return Promise.reject(new Error(\"Ad already playing\"));\n }\n\n try {\n sessionId = generateSessionId();\n\n const response = await fetch(vastTagUrl);\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 const ad = parseVastXml(vastXml);\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 // Capture content volume BEFORE muting\n const contentVolume = contentVideo.volume;\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 contentVideo.muted = true;\n adPlaying = true;\n setAdPlayingFlag(true);\n\n if (adVideoElement) {\n const adVolume = originalMutedState ? 0 : contentVolume;\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 adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\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) {\n console.log(\n `[HlsAdPlayer] updateOriginalMutedState called: ${originalMutedState} -> ${muted}`\n );\n originalMutedState = muted;\n },\n\n getOriginalMutedState() {\n return originalMutedState;\n },\n\n setAdVolume(volume: number) {\n if (adVideoElement && adPlaying) {\n adVideoElement.volume = Math.max(0, Math.min(1, volume));\n }\n },\n\n getAdVolume(): number {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n };\n}\n"],"mappings":"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","names":["level","_a","Hls"]}
|
|
1
|
+
{"version":3,"sources":["../../src/sdk/hlsAdPlayer.ts"],"sourcesContent":["import type { ImaController } from \"../types\";\nimport Hls from \"hls.js\";\n\ninterface VastMediaFile {\n url: string;\n type: string;\n width: number;\n height: number;\n bitrate?: number | undefined;\n}\n\ninterface VastTrackingUrls {\n impression: string[];\n start: string[];\n firstQuartile: string[];\n midpoint: string[];\n thirdQuartile: string[];\n complete: string[];\n mute: string[];\n unmute: string[];\n pause: string[];\n resume: string[];\n fullscreen: string[];\n exitFullscreen: string[];\n skip: string[];\n error: string[];\n}\n\ninterface VastAd {\n id: string;\n title: string;\n duration: number;\n mediaFiles: VastMediaFile[];\n trackingUrls: VastTrackingUrls;\n clickThrough?: string | undefined;\n}\n\nexport function createHlsAdPlayer(\n contentVideo: HTMLVideoElement,\n options?: {\n continueLiveStreamDuringAds?: boolean;\n licenseKey?: string;\n mainHlsInstance?: Hls;\n }\n): ImaController {\n let adPlaying = false;\n let originalMutedState = false;\n 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\n let trackingFired = {\n impression: false,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false,\n };\n\n function emit(event: string, payload?: any): void {\n const set = listeners.get(event);\n if (!set) return;\n for (const fn of Array.from(set)) {\n try {\n fn(payload);\n } catch (error) {\n console.warn(\n `[HlsAdPlayer] Error in event listener for ${event}:`,\n error\n );\n }\n }\n }\n\n function generateSessionId(): string {\n return `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n\n function fireTrackingPixels(urls: string[]): void {\n if (!urls || urls.length === 0) return;\n\n urls.forEach((url) => {\n try {\n let trackingUrl = url;\n\n if (sessionId) {\n trackingUrl = `${trackingUrl}${\n trackingUrl.includes(\"?\") ? \"&\" : \"?\"\n }session_id=${sessionId}`;\n }\n\n if (licenseKey) {\n trackingUrl = `${trackingUrl}${\n trackingUrl.includes(\"?\") ? \"&\" : \"?\"\n }license_key=${licenseKey}`;\n }\n\n const img = new Image(1, 1);\n img.src = trackingUrl;\n console.log(`[HlsAdPlayer] Fired tracking pixel: ${trackingUrl}`);\n } catch (error) {\n console.warn(`[HlsAdPlayer] Error firing tracking pixel:`, error);\n }\n });\n }\n\n function getMainStreamQuality(): {\n width: number;\n height: number;\n bitrate: number;\n } | null {\n if (!mainHlsInstance || !mainHlsInstance.levels) {\n return null;\n }\n\n const currentLevel = mainHlsInstance.currentLevel;\n if (currentLevel === -1 || !mainHlsInstance.levels[currentLevel]) {\n const autoLevel = mainHlsInstance.loadLevel;\n if (autoLevel !== -1 && mainHlsInstance.levels[autoLevel]) {\n const level = mainHlsInstance.levels[autoLevel];\n return {\n width: level.width || 1920,\n height: level.height || 1080,\n bitrate: level.bitrate || 5000000,\n };\n }\n return null;\n }\n\n const level = mainHlsInstance.levels[currentLevel];\n return {\n width: level.width || 1920,\n height: level.height || 1080,\n bitrate: level.bitrate || 5000000,\n };\n }\n\n function selectBestMediaFile(mediaFiles: VastMediaFile[]): VastMediaFile {\n if (mediaFiles.length === 0) {\n throw new Error(\"No media files available\");\n }\n\n const firstFile = mediaFiles[0];\n if (!firstFile) {\n throw new Error(\"No media files available\");\n }\n\n if (mediaFiles.length === 1) {\n return firstFile;\n }\n\n const mainQuality = getMainStreamQuality();\n if (!mainQuality) {\n console.log(\n \"[HlsAdPlayer] No main stream quality info, using first media file\"\n );\n return firstFile;\n }\n\n console.log(\"[HlsAdPlayer] Main stream quality:\", mainQuality);\n\n const scoredFiles = mediaFiles.map((file) => {\n const widthDiff = Math.abs(file.width - mainQuality.width);\n const heightDiff = Math.abs(file.height - mainQuality.height);\n const resolutionDiff = widthDiff + heightDiff;\n\n const fileBitrate = (file.bitrate || 5000) * 1000;\n const bitrateDiff = Math.abs(fileBitrate - mainQuality.bitrate);\n\n const score = resolutionDiff * 2 + bitrateDiff / 1000;\n\n return { file, score, resolutionDiff, bitrateDiff };\n });\n\n scoredFiles.sort((a, b) => a.score - b.score);\n\n const bestMatch = scoredFiles[0];\n if (!bestMatch) {\n console.log(\"[HlsAdPlayer] No best match found, using first media file\");\n return firstFile;\n }\n\n console.log(\"[HlsAdPlayer] Selected media file:\", {\n url: bestMatch.file.url,\n resolution: `${bestMatch.file.width}x${bestMatch.file.height}`,\n bitrate: bestMatch.file.bitrate,\n score: bestMatch.score,\n resolutionDiff: bestMatch.resolutionDiff,\n bitrateDiff: bestMatch.bitrateDiff,\n });\n\n return bestMatch.file;\n }\n\n function parseVastXml(xmlString: string): VastAd | null {\n try {\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n\n const parserError = xmlDoc.querySelector(\"parsererror\");\n if (parserError) {\n console.error(\n \"[HlsAdPlayer] XML parsing error (malformed VAST XML):\",\n parserError.textContent\n );\n return null;\n }\n\n const adElement = xmlDoc.querySelector(\"Ad\");\n if (!adElement) {\n console.warn(\"[HlsAdPlayer] No Ad element found in VAST XML\");\n return null;\n }\n\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n\n const isNoAdAvailable =\n adId === \"empty\" ||\n title.toLowerCase().includes(\"no ad available\") ||\n title.toLowerCase() === \"no ad available\";\n\n const durationText =\n xmlDoc.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n const durationParts = durationText.split(\":\");\n const duration =\n parseInt(durationParts[0] || \"0\", 10) * 3600 +\n parseInt(durationParts[1] || \"0\", 10) * 60 +\n parseInt(durationParts[2] || \"0\", 10);\n\n const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n const mediaFiles: VastMediaFile[] = [];\n\n console.log(\n `[HlsAdPlayer] Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`\n );\n\n mediaFileElements.forEach((mf, index) => {\n const type = mf.getAttribute(\"type\") || \"\";\n const url = mf.textContent?.trim() || \"\";\n const width = mf.getAttribute(\"width\") || \"\";\n const height = mf.getAttribute(\"height\") || \"\";\n\n console.log(\n `[HlsAdPlayer] MediaFile ${index}: type=\"${type}\", url=\"${url}\", width=\"${width}\", height=\"${height}\"`\n );\n\n 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 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 setTimeout(() => {\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 }, 50);\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 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(vastTagUrl: string) {\n console.log(\"[HlsAdPlayer] Requesting ads:\", vastTagUrl);\n\n if (adPlaying) {\n console.warn(\n \"[HlsAdPlayer] Cannot request new ads while an ad is playing\"\n );\n return Promise.reject(new Error(\"Ad already playing\"));\n }\n\n try {\n sessionId = generateSessionId();\n\n const response = await fetch(vastTagUrl);\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 const ad = parseVastXml(vastXml);\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 // Capture content volume BEFORE muting\n const contentVolume = contentVideo.volume;\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 : contentVolume;\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 adPlaying = false;\n setAdPlayingFlag(false);\n contentVideo.muted = originalMutedState;\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) {\n console.log(\n `[HlsAdPlayer] updateOriginalMutedState called: ${originalMutedState} -> ${muted}`\n );\n originalMutedState = muted;\n },\n\n getOriginalMutedState() {\n return originalMutedState;\n },\n\n setAdVolume(volume: number) {\n if (adVideoElement && adPlaying) {\n adVideoElement.volume = Math.max(0, Math.min(1, volume));\n }\n },\n\n getAdVolume(): number {\n if (adVideoElement && adPlaying) {\n return adVideoElement.volume;\n }\n return 1;\n },\n };\n}\n"],"mappings":"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","names":["level","_a","Hls"]}
|
package/lib/sdk/ima.cjs
CHANGED
|
@@ -461,7 +461,9 @@ function createImaController(video, options) {
|
|
|
461
461
|
adsManager.addEventListener(
|
|
462
462
|
AdEvent.CONTENT_PAUSE_REQUESTED,
|
|
463
463
|
() => {
|
|
464
|
-
console.log(
|
|
464
|
+
console.log(
|
|
465
|
+
"[IMA] Content pause requested - FORCE MUTING main video"
|
|
466
|
+
);
|
|
465
467
|
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
466
468
|
video.pause();
|
|
467
469
|
console.log("[IMA] Video paused (VOD mode)");
|
|
@@ -471,14 +473,19 @@ function createImaController(video, options) {
|
|
|
471
473
|
);
|
|
472
474
|
}
|
|
473
475
|
video.muted = true;
|
|
476
|
+
video.volume = 0;
|
|
474
477
|
adPlaying = true;
|
|
475
478
|
setAdPlayingFlag(true);
|
|
476
479
|
emit("content_pause");
|
|
477
480
|
}
|
|
478
481
|
);
|
|
479
482
|
adsManager.addEventListener(AdEvent.STARTED, () => {
|
|
480
|
-
console.log(
|
|
483
|
+
console.log(
|
|
484
|
+
"[IMA] Ad started playing - FORCE MUTING main video"
|
|
485
|
+
);
|
|
481
486
|
setAdPlayingFlag(true);
|
|
487
|
+
video.muted = true;
|
|
488
|
+
video.volume = 0;
|
|
482
489
|
if (adContainerEl) {
|
|
483
490
|
adContainerEl.style.pointerEvents = "auto";
|
|
484
491
|
adContainerEl.style.display = "flex";
|
|
@@ -494,6 +501,18 @@ function createImaController(video, options) {
|
|
|
494
501
|
adPlaying = false;
|
|
495
502
|
setAdPlayingFlag(false);
|
|
496
503
|
emit("content_resume");
|
|
504
|
+
setTimeout(() => {
|
|
505
|
+
const stillInPod = video.dataset.stormcloudAdPlaying === "true";
|
|
506
|
+
if (stillInPod) {
|
|
507
|
+
console.log(
|
|
508
|
+
"[IMA] Still in ad pod - keeping ad container visible (black screen)"
|
|
509
|
+
);
|
|
510
|
+
if (adContainerEl) {
|
|
511
|
+
adContainerEl.style.display = "flex";
|
|
512
|
+
adContainerEl.style.pointerEvents = "auto";
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}, 50);
|
|
497
516
|
}
|
|
498
517
|
);
|
|
499
518
|
adsManager.addEventListener(AdEvent.ALL_ADS_COMPLETED, () => {
|
package/lib/sdk/ima.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/sdk/ima.ts","../../src/utils/browserCompat.ts"],"sourcesContent":["import type { ImaController } from \"../types\";\nimport { supportsGoogleIMA } from \"../utils/browserCompat\";\n\ndeclare global {\n interface Window {\n google?: any;\n }\n}\n\nexport function createImaController(\n video: HTMLVideoElement,\n options?: { continueLiveStreamDuringAds?: boolean }\n): ImaController {\n let adPlaying = false;\n let originalMutedState = false;\n const listeners = new Map<string, Set<(payload?: any) => void>>();\n\n function setAdPlayingFlag(isPlaying: boolean): void {\n if (isPlaying) {\n video.dataset.stormcloudAdPlaying = \"true\";\n } else {\n delete video.dataset.stormcloudAdPlaying;\n }\n }\n\n function emit(event: string, payload?: any): void {\n const set = listeners.get(event);\n if (!set) return;\n for (const fn of Array.from(set)) {\n try {\n fn(payload);\n } catch {}\n }\n }\n\n function ensureImaLoaded(): Promise<void> {\n if (!supportsGoogleIMA()) {\n console.warn(\n \"[IMA] Google IMA SDK is not supported on this browser. Please use HLS ad player instead.\"\n );\n return Promise.reject(\n new Error(\"Google IMA SDK not supported on this browser\")\n );\n }\n\n try {\n const frameEl = window.frameElement as HTMLIFrameElement | null;\n const sandboxAttr = frameEl?.getAttribute?.(\"sandbox\") || \"\";\n if (sandboxAttr) {\n const tokens = new Set(\n sandboxAttr\n .split(/\\s+/)\n .map((t) => t.trim())\n .filter((t) => t.length > 0)\n );\n const allowsScripts = tokens.has(\"allow-scripts\");\n if (!allowsScripts) {\n // eslint-disable-next-line no-console\n console.error(\n \"StormcloudVideoPlayer: The host page is inside a sandboxed iframe without 'allow-scripts'. Google IMA cannot run ads within sandboxed frames. Remove the sandbox attribute or include 'allow-scripts allow-same-origin'.\"\n );\n }\n }\n } catch {}\n\n if (typeof window !== \"undefined\" && window.google?.ima)\n return Promise.resolve();\n const existing = document.querySelector(\n 'script[data-ima=\"true\"]'\n ) as HTMLScriptElement | null;\n if (existing) {\n if (window.google?.ima) {\n return Promise.resolve();\n }\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error(\"IMA SDK load timeout\"));\n }, 10000);\n existing.addEventListener(\"load\", () => {\n clearTimeout(timeout);\n resolve();\n });\n existing.addEventListener(\"error\", () => {\n clearTimeout(timeout);\n reject(new Error(\"IMA SDK load failed\"));\n });\n });\n }\n return new Promise((resolve, reject) => {\n const script = document.createElement(\"script\");\n script.src = \"https://imasdk.googleapis.com/js/sdkloader/ima3.js\";\n script.async = true;\n script.defer = true;\n script.setAttribute(\"data-ima\", \"true\");\n script.onload = () => resolve();\n script.onerror = () => reject(new Error(\"IMA SDK load failed\"));\n document.head.appendChild(script);\n });\n }\n\n let adsManager: any | undefined;\n let adsLoader: any | undefined;\n let adDisplayContainer: any | undefined;\n let adContainerEl: HTMLDivElement | undefined;\n let lastAdTagUrl: string | undefined;\n let retryAttempts = 0;\n const maxRetries = 2;\n const backoffBaseMs = 500;\n let adsLoadedPromise: Promise<void> | undefined;\n let adsLoadedResolve: (() => void) | undefined;\n let adsLoadedReject: ((error: Error) => void) | undefined;\n\n function makeAdsRequest(google: any, vastTagUrl: string) {\n const adsRequest = new google.ima.AdsRequest();\n adsRequest.adTagUrl = vastTagUrl;\n\n const videoWidth = video.offsetWidth || video.clientWidth || 640;\n const videoHeight = video.offsetHeight || video.clientHeight || 360;\n\n adsRequest.linearAdSlotWidth = videoWidth;\n adsRequest.linearAdSlotHeight = videoHeight;\n adsRequest.nonLinearAdSlotWidth = videoWidth;\n adsRequest.nonLinearAdSlotHeight = videoHeight;\n\n adsRequest.vastLoadTimeout = 5000;\n\n console.log(`[IMA] Ads request dimensions: ${videoWidth}x${videoHeight}`);\n\n adsLoader.requestAds(adsRequest);\n }\n\n function destroyAdsManager() {\n if (adsManager) {\n try {\n console.log(\"[IMA] Destroying existing ads manager\");\n adsManager.destroy();\n } catch (error) {\n console.warn(\"[IMA] Error destroying ads manager:\", error);\n }\n adsManager = undefined;\n }\n }\n\n return {\n initialize() {\n ensureImaLoaded()\n .then(() => {\n const google = window.google;\n if (!adDisplayContainer) {\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 video.parentElement?.appendChild(container);\n adContainerEl = container;\n adDisplayContainer = new google.ima.AdDisplayContainer(\n container,\n video\n );\n try {\n adDisplayContainer.initialize?.();\n } catch {}\n }\n })\n .catch(() => {});\n },\n async requestAds(vastTagUrl: string) {\n console.log(\"[IMA] Requesting ads:\", vastTagUrl);\n\n if (!vastTagUrl || vastTagUrl.trim() === \"\") {\n const error = new Error(\"VAST tag URL is empty or undefined\");\n console.warn(\"[IMA]\", error.message);\n return Promise.reject(error);\n }\n\n try {\n new URL(vastTagUrl);\n } catch (e) {\n const error = new Error(`Invalid VAST tag URL format: ${vastTagUrl}`);\n console.warn(\"[IMA]\", error.message);\n return Promise.reject(error);\n }\n\n if (adPlaying) {\n console.warn(\n \"[IMA] Cannot request new ads while an ad is playing. Call stop() first.\"\n );\n return Promise.reject(\n new Error(\"Ad already playing - cannot request new ads\")\n );\n }\n\n destroyAdsManager();\n\n adsLoadedReject = undefined;\n adsLoadedResolve = undefined;\n\n let currentReject: ((error: Error) => void) | undefined;\n adsLoadedPromise = new Promise<void>((resolve, reject) => {\n adsLoadedResolve = resolve;\n adsLoadedReject = reject;\n currentReject = reject;\n\n setTimeout(() => {\n if (adsLoadedReject) {\n adsLoadedReject(new Error(\"Ad request timeout\"));\n adsLoadedReject = undefined;\n adsLoadedResolve = undefined;\n }\n }, 10000);\n });\n\n try {\n await ensureImaLoaded();\n const google = window.google;\n lastAdTagUrl = vastTagUrl;\n retryAttempts = 0;\n\n if (!adDisplayContainer) {\n console.log(\"[IMA] Creating ad display container\");\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 if (!video.parentElement) {\n throw new Error(\"Video element has no parent for ad container\");\n }\n\n video.parentElement.appendChild(container);\n adContainerEl = container;\n adDisplayContainer = new google.ima.AdDisplayContainer(\n container,\n video\n );\n\n try {\n adDisplayContainer.initialize();\n console.log(\"[IMA] Ad display container initialized\");\n } catch (error) {\n console.warn(\n \"[IMA] Failed to initialize ad display container:\",\n error\n );\n }\n }\n\n const videoWidth = video.offsetWidth || video.clientWidth;\n const videoHeight = video.offsetHeight || video.clientHeight;\n\n if (\n !videoWidth ||\n !videoHeight ||\n videoWidth === 0 ||\n videoHeight === 0\n ) {\n const error = new Error(\n `Invalid video dimensions: ${videoWidth}x${videoHeight}. Cannot initialize ads.`\n );\n console.warn(\"[IMA]\", error.message);\n currentReject?.(error);\n adsLoadedReject = undefined;\n adsLoadedResolve = undefined;\n return Promise.reject(error);\n }\n\n if (!adsLoader) {\n console.log(\"[IMA] Creating ads loader\");\n const adsLoaderCls = new google.ima.AdsLoader(adDisplayContainer);\n adsLoader = adsLoaderCls;\n\n adsLoader.addEventListener(\n google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,\n (evt: any) => {\n console.log(\"[IMA] Ads manager loaded\");\n try {\n adsManager = evt.getAdsManager(video);\n const AdEvent = google.ima.AdEvent.Type;\n const AdErrorEvent = google.ima.AdErrorEvent.Type;\n\n adsManager.addEventListener(\n AdErrorEvent.AD_ERROR,\n (errorEvent: any) => {\n console.error(\"[IMA] Ad error:\", errorEvent.getError());\n\n destroyAdsManager();\n\n adPlaying = false;\n\n const previousMutedState = video.muted;\n video.muted = originalMutedState;\n setAdPlayingFlag(false);\n console.log(\n `[IMA] Restored mute state after ad error: ${previousMutedState} -> ${originalMutedState}`\n );\n\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n console.log(\"[IMA] Ad container hidden after error\");\n }\n\n if (adsLoadedReject) {\n adsLoadedReject(new Error(\"Ad playback error\"));\n adsLoadedReject = undefined;\n adsLoadedResolve = undefined;\n }\n\n if (lastAdTagUrl && retryAttempts < maxRetries) {\n const delay =\n backoffBaseMs * Math.pow(2, retryAttempts++);\n console.log(\n `[IMA] Retrying ad request in ${delay}ms (attempt ${retryAttempts})`\n );\n window.setTimeout(() => {\n try {\n makeAdsRequest(google, lastAdTagUrl!);\n } catch {}\n }, delay);\n } else {\n console.log(\n \"[IMA] Max retries reached, emitting ad_error\"\n );\n emit(\"ad_error\");\n\n if (!options?.continueLiveStreamDuringAds) {\n if (video.paused) {\n console.log(\n \"[IMA] Resuming paused video after ad error\"\n );\n video.play()?.catch(() => {});\n }\n }\n }\n }\n );\n\n adsManager.addEventListener(\n AdEvent.CONTENT_PAUSE_REQUESTED,\n () => {\n console.log(\"[IMA] Content pause requested\");\n\n if (!options?.continueLiveStreamDuringAds) {\n video.pause();\n console.log(\"[IMA] Video paused (VOD mode)\");\n } else {\n console.log(\n \"[IMA] Video continues playing but muted (Live mode)\"\n );\n }\n\n video.muted = true;\n adPlaying = true;\n setAdPlayingFlag(true);\n emit(\"content_pause\");\n }\n );\n\n adsManager.addEventListener(AdEvent.STARTED, () => {\n console.log(\"[IMA] Ad started playing\");\n setAdPlayingFlag(true);\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"auto\";\n adContainerEl.style.display = \"flex\";\n console.log(\n \"[IMA] Ad container visibility set to flex with pointer events enabled\"\n );\n }\n });\n\n adsManager.addEventListener(\n AdEvent.CONTENT_RESUME_REQUESTED,\n () => {\n console.log(\"[IMA] Content resume requested\");\n adPlaying = false;\n setAdPlayingFlag(false);\n\n emit(\"content_resume\");\n }\n );\n\n adsManager.addEventListener(AdEvent.ALL_ADS_COMPLETED, () => {\n console.log(\"[IMA] All ads completed - notifying parent\");\n adPlaying = false;\n setAdPlayingFlag(false);\n\n emit(\"all_ads_completed\");\n });\n\n console.log(\"[IMA] Ads manager event listeners attached\");\n\n if (adsLoadedResolve) {\n adsLoadedResolve();\n adsLoadedResolve = undefined;\n adsLoadedReject = undefined;\n }\n } catch (e) {\n console.error(\"[IMA] Error setting up ads manager:\", e);\n adPlaying = false;\n video.muted = originalMutedState;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n console.log(\"[IMA] Ad container hidden after setup error\");\n }\n\n if (!options?.continueLiveStreamDuringAds) {\n if (video.paused) {\n console.log(\n \"[IMA] Resuming paused video after setup error\"\n );\n video.play().catch(() => {});\n }\n }\n\n if (adsLoadedReject) {\n adsLoadedReject(new Error(\"Failed to setup ads manager\"));\n adsLoadedReject = undefined;\n adsLoadedResolve = undefined;\n }\n emit(\"ad_error\");\n }\n },\n false\n );\n\n adsLoader.addEventListener(\n google.ima.AdErrorEvent.Type.AD_ERROR,\n (adErrorEvent: any) => {\n console.error(\"[IMA] Ads loader error:\", adErrorEvent.getError());\n\n adPlaying = false;\n\n const previousMutedState = video.muted;\n video.muted = originalMutedState;\n setAdPlayingFlag(false);\n console.log(\n `[IMA] Restored mute state: ${previousMutedState} -> ${originalMutedState}`\n );\n\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n console.log(\"[IMA] Ad container hidden after loader error\");\n }\n\n if (!options?.continueLiveStreamDuringAds) {\n if (video.paused) {\n console.log(\"[IMA] Resuming paused video after loader error\");\n video.play().catch(() => {});\n }\n }\n\n if (adsLoadedReject) {\n adsLoadedReject(new Error(\"Ads loader error\"));\n adsLoadedReject = undefined;\n adsLoadedResolve = undefined;\n }\n emit(\"ad_error\");\n },\n false\n );\n }\n\n console.log(\"[IMA] Making ads request\");\n makeAdsRequest(google, vastTagUrl);\n\n return adsLoadedPromise;\n } catch (error) {\n console.error(\"[IMA] Failed to request ads:\", error);\n\n currentReject?.(error as Error);\n adsLoadedReject = undefined;\n adsLoadedResolve = undefined;\n return Promise.reject(error);\n }\n },\n async play() {\n if (!window.google?.ima || !adDisplayContainer) {\n console.warn(\n \"[IMA] Cannot play ad: IMA SDK or ad container not available\"\n );\n return Promise.reject(new Error(\"IMA SDK not available\"));\n }\n\n if (!adsManager) {\n console.warn(\"[IMA] Cannot play ad: No ads manager available\");\n return Promise.reject(new Error(\"No ads manager\"));\n }\n\n try {\n const width = video.clientWidth || 640;\n const height = video.clientHeight || 360;\n\n console.log(`[IMA] Initializing ads manager (${width}x${height})`);\n adsManager.init(width, height, window.google.ima.ViewMode.NORMAL);\n\n adPlaying = true;\n\n const adVolume = originalMutedState ? 0 : video.volume;\n try {\n adsManager.setVolume(adVolume);\n console.log(`[IMA] Set ad volume to ${adVolume}`);\n } catch (error) {\n console.warn(\"[IMA] Failed to set ad volume:\", error);\n }\n\n console.log(\"[IMA] Starting ad playback\");\n adsManager.start();\n\n return Promise.resolve();\n } catch (error) {\n console.error(\"[IMA] Error starting ad playback:\", error);\n adPlaying = false;\n setAdPlayingFlag(false);\n\n if (!options?.continueLiveStreamDuringAds) {\n video.play()?.catch(() => {});\n }\n return Promise.reject(error);\n }\n },\n async stop() {\n console.log(\"[IMA] Stopping ad playback\");\n adPlaying = false;\n setAdPlayingFlag(false);\n\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n console.log(\"[IMA] Ad container hidden after stop\");\n }\n\n try {\n adsManager?.stop?.();\n } catch {}\n\n destroyAdsManager();\n },\n destroy() {\n destroyAdsManager();\n\n adPlaying = false;\n video.muted = originalMutedState;\n setAdPlayingFlag(false);\n\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n }\n\n try {\n adsLoader?.destroy?.();\n } catch {}\n\n if (adContainerEl?.parentElement) {\n adContainerEl.parentElement.removeChild(adContainerEl);\n }\n\n adContainerEl = undefined;\n adDisplayContainer = undefined;\n adsLoader = undefined;\n },\n isAdPlaying() {\n return adPlaying;\n },\n resize(width: number, height: number) {\n if (!adsManager || !window.google?.ima) {\n console.warn(\n \"[IMA] Cannot resize: No ads manager or IMA SDK available\"\n );\n return;\n }\n\n try {\n console.log(`[IMA] Resizing ads manager to ${width}x${height}`);\n adsManager.resize(width, height, window.google.ima.ViewMode.NORMAL);\n } catch (error) {\n console.warn(\"[IMA] Error resizing ads manager:\", error);\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 off(event: string, listener: (payload?: any) => void) {\n listeners.get(event)?.delete(listener);\n },\n updateOriginalMutedState(muted: boolean) {\n console.log(\n `[IMA] updateOriginalMutedState called: ${originalMutedState} -> ${muted}`\n );\n originalMutedState = muted;\n },\n getOriginalMutedState() {\n return originalMutedState;\n },\n setAdVolume(volume: number) {\n if (adsManager && adPlaying) {\n try {\n adsManager.setVolume(Math.max(0, Math.min(1, volume)));\n } catch (error) {\n console.warn(\"[IMA] Failed to set ad volume:\", error);\n }\n }\n },\n getAdVolume(): number {\n if (adsManager && adPlaying) {\n try {\n return adsManager.getVolume();\n } catch (error) {\n console.warn(\"[IMA] Failed to get ad volume:\", error);\n return 1;\n }\n }\n return 1;\n },\n };\n}\n","interface NavigatorUAData {\n platform?: string;\n brands?: Array<{ brand: string; version: string }>;\n mobile?: boolean;\n}\n\ndeclare global {\n interface Navigator {\n userAgentData?: NavigatorUAData;\n }\n}\n\nexport interface BrowserInfo {\n name: string;\n version: string;\n majorVersion: number;\n isSmartTV: boolean;\n isLegacyTV: boolean;\n platform: string;\n supportsIMA: boolean;\n supportsModernJS: boolean;\n recommendedAdPlayer: 'ima' | 'hls';\n}\n\nfunction getChromeVersion(ua: string): number {\n const match = ua.match(/Chrome\\/(\\d+)/);\n return match && match[1] ? parseInt(match[1], 10) : 0;\n}\n\nfunction getWebKitVersion(ua: string): number {\n const match = ua.match(/AppleWebKit\\/(\\d+)/);\n return match && match[1] ? parseInt(match[1], 10) : 0;\n}\n\nfunction getPlatform(): string {\n if ('userAgentData' in navigator && navigator.userAgentData?.platform) {\n return navigator.userAgentData.platform;\n }\n\n const ua = navigator.userAgent;\n if (/Mac|iPhone|iPad|iPod/i.test(ua)) {\n return /iPhone|iPad|iPod/i.test(ua) ? 'iPhone' : 'MacIntel';\n }\n if (/Win/i.test(ua)) {\n return 'Win32';\n }\n if (/Linux/i.test(ua)) {\n return /Android/i.test(ua) ? 'Linux armv8l' : 'Linux x86_64';\n }\n if (/CrOS/i.test(ua)) {\n return 'CrOS';\n }\n\n // eslint-disable-next-line deprecation/deprecation\n return (navigator as any).platform || 'Unknown';\n}\n\nexport function detectBrowser(): BrowserInfo {\n const ua = navigator.userAgent;\n const platform = getPlatform();\n\n let name = 'Unknown';\n let version = '0';\n let majorVersion = 0;\n let isSmartTV = false;\n let isLegacyTV = false;\n let supportsIMA = true;\n let supportsModernJS = true;\n let recommendedAdPlayer: 'ima' | 'hls' = 'ima';\n\n if (/Web0S|webOS/i.test(ua)) {\n name = 'LG WebOS';\n isSmartTV = true;\n const match = ua.match(/Web0S[/\\s]*([\\d.]+)/i);\n version = match && match[1] ? match[1] : 'Unknown';\n if (version !== 'Unknown') {\n const parts = version.split('.');\n majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n }\n } else if (/Tizen/i.test(ua)) {\n name = 'Samsung Tizen';\n isSmartTV = true;\n const match = ua.match(/Tizen[/\\s]*([\\d.]+)/i);\n version = match && match[1] ? match[1] : 'Unknown';\n if (version !== 'Unknown') {\n const parts = version.split('.');\n majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n }\n } else if (/SMART-TV|SmartTV/i.test(ua)) {\n name = 'Smart TV';\n isSmartTV = true;\n } else if (/NetCast/i.test(ua)) {\n name = 'LG NetCast';\n isSmartTV = true;\n isLegacyTV = true;\n } else if (/BRAVIA/i.test(ua)) {\n name = 'Sony BRAVIA';\n isSmartTV = true;\n }\n\n const chromeVersion = getChromeVersion(ua);\n const webkitVersion = getWebKitVersion(ua);\n\n if (chromeVersion > 0) {\n if (!isSmartTV) {\n name = 'Chrome';\n version = chromeVersion.toString();\n majorVersion = chromeVersion;\n }\n\n if (chromeVersion < 50) {\n supportsIMA = false;\n supportsModernJS = false;\n isLegacyTV = true;\n recommendedAdPlayer = 'hls';\n }\n }\n\n if (webkitVersion > 0 && webkitVersion < 600) {\n supportsModernJS = false;\n if (isSmartTV) {\n isLegacyTV = true;\n supportsIMA = false;\n recommendedAdPlayer = 'hls';\n }\n }\n\n if (typeof Promise === 'undefined' ||\n typeof Map === 'undefined' ||\n typeof Set === 'undefined') {\n supportsModernJS = false;\n supportsIMA = false;\n recommendedAdPlayer = 'hls';\n }\n\n if (typeof URLSearchParams === 'undefined') {\n supportsModernJS = false;\n }\n\n return {\n name,\n version,\n majorVersion,\n isSmartTV,\n isLegacyTV,\n platform,\n supportsIMA,\n supportsModernJS,\n recommendedAdPlayer,\n };\n}\n\nexport function supportsGoogleIMA(): boolean {\n const browser = detectBrowser();\n\n if (browser.isLegacyTV) {\n return false;\n }\n\n if (typeof document === 'undefined' ||\n typeof document.createElement !== 'function') {\n return false;\n }\n\n try {\n const video = document.createElement('video');\n if (!video) {\n return false;\n }\n } catch (e) {\n return false;\n }\n\n if (typeof Promise === 'undefined') {\n return false;\n }\n\n return browser.supportsIMA;\n}\n\nexport function getRecommendedAdPlayer(): 'ima' | 'hls' {\n const browser = detectBrowser();\n return browser.recommendedAdPlayer;\n}\n\nexport function supportsModernJS(): boolean {\n try {\n return (\n typeof Promise !== 'undefined' &&\n typeof Map !== 'undefined' &&\n typeof Set !== 'undefined' &&\n typeof Array.from !== 'undefined' &&\n typeof Object.assign !== 'undefined' &&\n typeof Array.prototype.forEach !== 'undefined' &&\n typeof String.prototype.includes !== 'undefined'\n );\n } catch (e) {\n return false;\n }\n}\n\nexport function logBrowserInfo(debug: boolean = false): void {\n if (!debug) return;\n\n const browser = detectBrowser();\n const imaSupport = supportsGoogleIMA();\n\n console.log('[StormcloudVideoPlayer] Browser Compatibility Info:', {\n browser: `${browser.name} ${browser.version}`,\n platform: browser.platform,\n isSmartTV: browser.isSmartTV,\n isLegacyTV: browser.isLegacyTV,\n supportsIMA: imaSupport,\n supportsModernJS: browser.supportsModernJS,\n recommendedAdPlayer: browser.recommendedAdPlayer,\n userAgent: navigator.userAgent,\n });\n}\n\nexport function getBrowserConfigOverrides(): {\n adPlayerType?: 'ima' | 'hls';\n allowNativeHls?: boolean;\n} {\n const browser = detectBrowser();\n const overrides: any = {};\n\n if (browser.isLegacyTV || !browser.supportsIMA) {\n overrides.adPlayerType = 'hls';\n }\n\n if (browser.isSmartTV) {\n overrides.allowNativeHls = true;\n }\n\n return overrides;\n}\n\nexport function supportsFeature(feature: string): boolean {\n switch (feature) {\n case 'ima':\n return supportsGoogleIMA();\n case 'urlsearchparams':\n return typeof URLSearchParams !== 'undefined';\n case 'textencoder':\n return typeof TextEncoder !== 'undefined';\n case 'promises':\n return typeof Promise !== 'undefined';\n case 'fetch':\n return typeof fetch !== 'undefined';\n case 'crypto':\n return typeof crypto !== 'undefined' && typeof crypto.subtle !== 'undefined';\n default:\n return false;\n }\n}\n\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/sdk/ima.ts","../../src/utils/browserCompat.ts"],"sourcesContent":["import type { ImaController } from \"../types\";\nimport { supportsGoogleIMA } from \"../utils/browserCompat\";\n\ndeclare global {\n interface Window {\n google?: any;\n }\n}\n\nexport function createImaController(\n video: HTMLVideoElement,\n options?: { continueLiveStreamDuringAds?: boolean }\n): ImaController {\n let adPlaying = false;\n let originalMutedState = false;\n const listeners = new Map<string, Set<(payload?: any) => void>>();\n\n function setAdPlayingFlag(isPlaying: boolean): void {\n if (isPlaying) {\n video.dataset.stormcloudAdPlaying = \"true\";\n } else {\n delete video.dataset.stormcloudAdPlaying;\n }\n }\n\n function emit(event: string, payload?: any): void {\n const set = listeners.get(event);\n if (!set) return;\n for (const fn of Array.from(set)) {\n try {\n fn(payload);\n } catch {}\n }\n }\n\n function ensureImaLoaded(): Promise<void> {\n if (!supportsGoogleIMA()) {\n console.warn(\n \"[IMA] Google IMA SDK is not supported on this browser. Please use HLS ad player instead.\"\n );\n return Promise.reject(\n new Error(\"Google IMA SDK not supported on this browser\")\n );\n }\n\n try {\n const frameEl = window.frameElement as HTMLIFrameElement | null;\n const sandboxAttr = frameEl?.getAttribute?.(\"sandbox\") || \"\";\n if (sandboxAttr) {\n const tokens = new Set(\n sandboxAttr\n .split(/\\s+/)\n .map((t) => t.trim())\n .filter((t) => t.length > 0)\n );\n const allowsScripts = tokens.has(\"allow-scripts\");\n if (!allowsScripts) {\n // eslint-disable-next-line no-console\n console.error(\n \"StormcloudVideoPlayer: The host page is inside a sandboxed iframe without 'allow-scripts'. Google IMA cannot run ads within sandboxed frames. Remove the sandbox attribute or include 'allow-scripts allow-same-origin'.\"\n );\n }\n }\n } catch {}\n\n if (typeof window !== \"undefined\" && window.google?.ima)\n return Promise.resolve();\n const existing = document.querySelector(\n 'script[data-ima=\"true\"]'\n ) as HTMLScriptElement | null;\n if (existing) {\n if (window.google?.ima) {\n return Promise.resolve();\n }\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error(\"IMA SDK load timeout\"));\n }, 10000);\n existing.addEventListener(\"load\", () => {\n clearTimeout(timeout);\n resolve();\n });\n existing.addEventListener(\"error\", () => {\n clearTimeout(timeout);\n reject(new Error(\"IMA SDK load failed\"));\n });\n });\n }\n return new Promise((resolve, reject) => {\n const script = document.createElement(\"script\");\n script.src = \"https://imasdk.googleapis.com/js/sdkloader/ima3.js\";\n script.async = true;\n script.defer = true;\n script.setAttribute(\"data-ima\", \"true\");\n script.onload = () => resolve();\n script.onerror = () => reject(new Error(\"IMA SDK load failed\"));\n document.head.appendChild(script);\n });\n }\n\n let adsManager: any | undefined;\n let adsLoader: any | undefined;\n let adDisplayContainer: any | undefined;\n let adContainerEl: HTMLDivElement | undefined;\n let lastAdTagUrl: string | undefined;\n let retryAttempts = 0;\n const maxRetries = 2;\n const backoffBaseMs = 500;\n let adsLoadedPromise: Promise<void> | undefined;\n let adsLoadedResolve: (() => void) | undefined;\n let adsLoadedReject: ((error: Error) => void) | undefined;\n\n function makeAdsRequest(google: any, vastTagUrl: string) {\n const adsRequest = new google.ima.AdsRequest();\n adsRequest.adTagUrl = vastTagUrl;\n\n const videoWidth = video.offsetWidth || video.clientWidth || 640;\n const videoHeight = video.offsetHeight || video.clientHeight || 360;\n\n adsRequest.linearAdSlotWidth = videoWidth;\n adsRequest.linearAdSlotHeight = videoHeight;\n adsRequest.nonLinearAdSlotWidth = videoWidth;\n adsRequest.nonLinearAdSlotHeight = videoHeight;\n\n adsRequest.vastLoadTimeout = 5000;\n\n console.log(`[IMA] Ads request dimensions: ${videoWidth}x${videoHeight}`);\n\n adsLoader.requestAds(adsRequest);\n }\n\n function destroyAdsManager() {\n if (adsManager) {\n try {\n console.log(\"[IMA] Destroying existing ads manager\");\n adsManager.destroy();\n } catch (error) {\n console.warn(\"[IMA] Error destroying ads manager:\", error);\n }\n adsManager = undefined;\n }\n }\n\n return {\n initialize() {\n ensureImaLoaded()\n .then(() => {\n const google = window.google;\n if (!adDisplayContainer) {\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 video.parentElement?.appendChild(container);\n adContainerEl = container;\n adDisplayContainer = new google.ima.AdDisplayContainer(\n container,\n video\n );\n try {\n adDisplayContainer.initialize?.();\n } catch {}\n }\n })\n .catch(() => {});\n },\n async requestAds(vastTagUrl: string) {\n console.log(\"[IMA] Requesting ads:\", vastTagUrl);\n\n if (!vastTagUrl || vastTagUrl.trim() === \"\") {\n const error = new Error(\"VAST tag URL is empty or undefined\");\n console.warn(\"[IMA]\", error.message);\n return Promise.reject(error);\n }\n\n try {\n new URL(vastTagUrl);\n } catch (e) {\n const error = new Error(`Invalid VAST tag URL format: ${vastTagUrl}`);\n console.warn(\"[IMA]\", error.message);\n return Promise.reject(error);\n }\n\n if (adPlaying) {\n console.warn(\n \"[IMA] Cannot request new ads while an ad is playing. Call stop() first.\"\n );\n return Promise.reject(\n new Error(\"Ad already playing - cannot request new ads\")\n );\n }\n\n destroyAdsManager();\n\n adsLoadedReject = undefined;\n adsLoadedResolve = undefined;\n\n let currentReject: ((error: Error) => void) | undefined;\n adsLoadedPromise = new Promise<void>((resolve, reject) => {\n adsLoadedResolve = resolve;\n adsLoadedReject = reject;\n currentReject = reject;\n\n setTimeout(() => {\n if (adsLoadedReject) {\n adsLoadedReject(new Error(\"Ad request timeout\"));\n adsLoadedReject = undefined;\n adsLoadedResolve = undefined;\n }\n }, 10000);\n });\n\n try {\n await ensureImaLoaded();\n const google = window.google;\n lastAdTagUrl = vastTagUrl;\n retryAttempts = 0;\n\n if (!adDisplayContainer) {\n console.log(\"[IMA] Creating ad display container\");\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 if (!video.parentElement) {\n throw new Error(\"Video element has no parent for ad container\");\n }\n\n video.parentElement.appendChild(container);\n adContainerEl = container;\n adDisplayContainer = new google.ima.AdDisplayContainer(\n container,\n video\n );\n\n try {\n adDisplayContainer.initialize();\n console.log(\"[IMA] Ad display container initialized\");\n } catch (error) {\n console.warn(\n \"[IMA] Failed to initialize ad display container:\",\n error\n );\n }\n }\n\n const videoWidth = video.offsetWidth || video.clientWidth;\n const videoHeight = video.offsetHeight || video.clientHeight;\n\n if (\n !videoWidth ||\n !videoHeight ||\n videoWidth === 0 ||\n videoHeight === 0\n ) {\n const error = new Error(\n `Invalid video dimensions: ${videoWidth}x${videoHeight}. Cannot initialize ads.`\n );\n console.warn(\"[IMA]\", error.message);\n currentReject?.(error);\n adsLoadedReject = undefined;\n adsLoadedResolve = undefined;\n return Promise.reject(error);\n }\n\n if (!adsLoader) {\n console.log(\"[IMA] Creating ads loader\");\n const adsLoaderCls = new google.ima.AdsLoader(adDisplayContainer);\n adsLoader = adsLoaderCls;\n\n adsLoader.addEventListener(\n google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,\n (evt: any) => {\n console.log(\"[IMA] Ads manager loaded\");\n try {\n adsManager = evt.getAdsManager(video);\n const AdEvent = google.ima.AdEvent.Type;\n const AdErrorEvent = google.ima.AdErrorEvent.Type;\n\n adsManager.addEventListener(\n AdErrorEvent.AD_ERROR,\n (errorEvent: any) => {\n console.error(\"[IMA] Ad error:\", errorEvent.getError());\n\n destroyAdsManager();\n\n adPlaying = false;\n\n const previousMutedState = video.muted;\n video.muted = originalMutedState;\n setAdPlayingFlag(false);\n console.log(\n `[IMA] Restored mute state after ad error: ${previousMutedState} -> ${originalMutedState}`\n );\n\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n console.log(\"[IMA] Ad container hidden after error\");\n }\n\n if (adsLoadedReject) {\n adsLoadedReject(new Error(\"Ad playback error\"));\n adsLoadedReject = undefined;\n adsLoadedResolve = undefined;\n }\n\n if (lastAdTagUrl && retryAttempts < maxRetries) {\n const delay =\n backoffBaseMs * Math.pow(2, retryAttempts++);\n console.log(\n `[IMA] Retrying ad request in ${delay}ms (attempt ${retryAttempts})`\n );\n window.setTimeout(() => {\n try {\n makeAdsRequest(google, lastAdTagUrl!);\n } catch {}\n }, delay);\n } else {\n console.log(\n \"[IMA] Max retries reached, emitting ad_error\"\n );\n emit(\"ad_error\");\n\n if (!options?.continueLiveStreamDuringAds) {\n if (video.paused) {\n console.log(\n \"[IMA] Resuming paused video after ad error\"\n );\n video.play()?.catch(() => {});\n }\n }\n }\n }\n );\n\n adsManager.addEventListener(\n AdEvent.CONTENT_PAUSE_REQUESTED,\n () => {\n console.log(\n \"[IMA] Content pause requested - FORCE MUTING main video\"\n );\n\n if (!options?.continueLiveStreamDuringAds) {\n video.pause();\n console.log(\"[IMA] Video paused (VOD mode)\");\n } else {\n console.log(\n \"[IMA] Video continues playing but muted (Live mode)\"\n );\n }\n\n video.muted = true;\n video.volume = 0;\n adPlaying = true;\n setAdPlayingFlag(true);\n emit(\"content_pause\");\n }\n );\n\n adsManager.addEventListener(AdEvent.STARTED, () => {\n console.log(\n \"[IMA] Ad started playing - FORCE MUTING main video\"\n );\n setAdPlayingFlag(true);\n\n video.muted = true;\n video.volume = 0;\n\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"auto\";\n adContainerEl.style.display = \"flex\";\n console.log(\n \"[IMA] Ad container visibility set to flex with pointer events enabled\"\n );\n }\n });\n\n adsManager.addEventListener(\n AdEvent.CONTENT_RESUME_REQUESTED,\n () => {\n console.log(\"[IMA] Content resume requested\");\n adPlaying = false;\n setAdPlayingFlag(false);\n\n emit(\"content_resume\");\n\n setTimeout(() => {\n const stillInPod =\n video.dataset.stormcloudAdPlaying === \"true\";\n if (stillInPod) {\n console.log(\n \"[IMA] 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 }, 50);\n }\n );\n\n adsManager.addEventListener(AdEvent.ALL_ADS_COMPLETED, () => {\n console.log(\"[IMA] All ads completed - notifying parent\");\n adPlaying = false;\n setAdPlayingFlag(false);\n\n emit(\"all_ads_completed\");\n });\n\n console.log(\"[IMA] Ads manager event listeners attached\");\n\n if (adsLoadedResolve) {\n adsLoadedResolve();\n adsLoadedResolve = undefined;\n adsLoadedReject = undefined;\n }\n } catch (e) {\n console.error(\"[IMA] Error setting up ads manager:\", e);\n adPlaying = false;\n video.muted = originalMutedState;\n setAdPlayingFlag(false);\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n console.log(\"[IMA] Ad container hidden after setup error\");\n }\n\n if (!options?.continueLiveStreamDuringAds) {\n if (video.paused) {\n console.log(\n \"[IMA] Resuming paused video after setup error\"\n );\n video.play().catch(() => {});\n }\n }\n\n if (adsLoadedReject) {\n adsLoadedReject(new Error(\"Failed to setup ads manager\"));\n adsLoadedReject = undefined;\n adsLoadedResolve = undefined;\n }\n emit(\"ad_error\");\n }\n },\n false\n );\n\n adsLoader.addEventListener(\n google.ima.AdErrorEvent.Type.AD_ERROR,\n (adErrorEvent: any) => {\n console.error(\"[IMA] Ads loader error:\", adErrorEvent.getError());\n\n adPlaying = false;\n\n const previousMutedState = video.muted;\n video.muted = originalMutedState;\n setAdPlayingFlag(false);\n console.log(\n `[IMA] Restored mute state: ${previousMutedState} -> ${originalMutedState}`\n );\n\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n console.log(\"[IMA] Ad container hidden after loader error\");\n }\n\n if (!options?.continueLiveStreamDuringAds) {\n if (video.paused) {\n console.log(\"[IMA] Resuming paused video after loader error\");\n video.play().catch(() => {});\n }\n }\n\n if (adsLoadedReject) {\n adsLoadedReject(new Error(\"Ads loader error\"));\n adsLoadedReject = undefined;\n adsLoadedResolve = undefined;\n }\n emit(\"ad_error\");\n },\n false\n );\n }\n\n console.log(\"[IMA] Making ads request\");\n makeAdsRequest(google, vastTagUrl);\n\n return adsLoadedPromise;\n } catch (error) {\n console.error(\"[IMA] Failed to request ads:\", error);\n\n currentReject?.(error as Error);\n adsLoadedReject = undefined;\n adsLoadedResolve = undefined;\n return Promise.reject(error);\n }\n },\n async play() {\n if (!window.google?.ima || !adDisplayContainer) {\n console.warn(\n \"[IMA] Cannot play ad: IMA SDK or ad container not available\"\n );\n return Promise.reject(new Error(\"IMA SDK not available\"));\n }\n\n if (!adsManager) {\n console.warn(\"[IMA] Cannot play ad: No ads manager available\");\n return Promise.reject(new Error(\"No ads manager\"));\n }\n\n try {\n const width = video.clientWidth || 640;\n const height = video.clientHeight || 360;\n\n console.log(`[IMA] Initializing ads manager (${width}x${height})`);\n adsManager.init(width, height, window.google.ima.ViewMode.NORMAL);\n\n adPlaying = true;\n\n const adVolume = originalMutedState ? 0 : video.volume;\n try {\n adsManager.setVolume(adVolume);\n console.log(`[IMA] Set ad volume to ${adVolume}`);\n } catch (error) {\n console.warn(\"[IMA] Failed to set ad volume:\", error);\n }\n\n console.log(\"[IMA] Starting ad playback\");\n adsManager.start();\n\n return Promise.resolve();\n } catch (error) {\n console.error(\"[IMA] Error starting ad playback:\", error);\n adPlaying = false;\n setAdPlayingFlag(false);\n\n if (!options?.continueLiveStreamDuringAds) {\n video.play()?.catch(() => {});\n }\n return Promise.reject(error);\n }\n },\n async stop() {\n console.log(\"[IMA] Stopping ad playback\");\n adPlaying = false;\n setAdPlayingFlag(false);\n\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n console.log(\"[IMA] Ad container hidden after stop\");\n }\n\n try {\n adsManager?.stop?.();\n } catch {}\n\n destroyAdsManager();\n },\n destroy() {\n destroyAdsManager();\n\n adPlaying = false;\n video.muted = originalMutedState;\n setAdPlayingFlag(false);\n\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n }\n\n try {\n adsLoader?.destroy?.();\n } catch {}\n\n if (adContainerEl?.parentElement) {\n adContainerEl.parentElement.removeChild(adContainerEl);\n }\n\n adContainerEl = undefined;\n adDisplayContainer = undefined;\n adsLoader = undefined;\n },\n isAdPlaying() {\n return adPlaying;\n },\n resize(width: number, height: number) {\n if (!adsManager || !window.google?.ima) {\n console.warn(\n \"[IMA] Cannot resize: No ads manager or IMA SDK available\"\n );\n return;\n }\n\n try {\n console.log(`[IMA] Resizing ads manager to ${width}x${height}`);\n adsManager.resize(width, height, window.google.ima.ViewMode.NORMAL);\n } catch (error) {\n console.warn(\"[IMA] Error resizing ads manager:\", error);\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 off(event: string, listener: (payload?: any) => void) {\n listeners.get(event)?.delete(listener);\n },\n updateOriginalMutedState(muted: boolean) {\n console.log(\n `[IMA] updateOriginalMutedState called: ${originalMutedState} -> ${muted}`\n );\n originalMutedState = muted;\n },\n getOriginalMutedState() {\n return originalMutedState;\n },\n setAdVolume(volume: number) {\n if (adsManager && adPlaying) {\n try {\n adsManager.setVolume(Math.max(0, Math.min(1, volume)));\n } catch (error) {\n console.warn(\"[IMA] Failed to set ad volume:\", error);\n }\n }\n },\n getAdVolume(): number {\n if (adsManager && adPlaying) {\n try {\n return adsManager.getVolume();\n } catch (error) {\n console.warn(\"[IMA] Failed to get ad volume:\", error);\n return 1;\n }\n }\n return 1;\n },\n };\n}\n","interface NavigatorUAData {\n platform?: string;\n brands?: Array<{ brand: string; version: string }>;\n mobile?: boolean;\n}\n\ndeclare global {\n interface Navigator {\n userAgentData?: NavigatorUAData;\n }\n}\n\nexport interface BrowserInfo {\n name: string;\n version: string;\n majorVersion: number;\n isSmartTV: boolean;\n isLegacyTV: boolean;\n platform: string;\n supportsIMA: boolean;\n supportsModernJS: boolean;\n recommendedAdPlayer: 'ima' | 'hls';\n}\n\nfunction getChromeVersion(ua: string): number {\n const match = ua.match(/Chrome\\/(\\d+)/);\n return match && match[1] ? parseInt(match[1], 10) : 0;\n}\n\nfunction getWebKitVersion(ua: string): number {\n const match = ua.match(/AppleWebKit\\/(\\d+)/);\n return match && match[1] ? parseInt(match[1], 10) : 0;\n}\n\nfunction getPlatform(): string {\n if ('userAgentData' in navigator && navigator.userAgentData?.platform) {\n return navigator.userAgentData.platform;\n }\n\n const ua = navigator.userAgent;\n if (/Mac|iPhone|iPad|iPod/i.test(ua)) {\n return /iPhone|iPad|iPod/i.test(ua) ? 'iPhone' : 'MacIntel';\n }\n if (/Win/i.test(ua)) {\n return 'Win32';\n }\n if (/Linux/i.test(ua)) {\n return /Android/i.test(ua) ? 'Linux armv8l' : 'Linux x86_64';\n }\n if (/CrOS/i.test(ua)) {\n return 'CrOS';\n }\n\n // eslint-disable-next-line deprecation/deprecation\n return (navigator as any).platform || 'Unknown';\n}\n\nexport function detectBrowser(): BrowserInfo {\n const ua = navigator.userAgent;\n const platform = getPlatform();\n\n let name = 'Unknown';\n let version = '0';\n let majorVersion = 0;\n let isSmartTV = false;\n let isLegacyTV = false;\n let supportsIMA = true;\n let supportsModernJS = true;\n let recommendedAdPlayer: 'ima' | 'hls' = 'ima';\n\n if (/Web0S|webOS/i.test(ua)) {\n name = 'LG WebOS';\n isSmartTV = true;\n const match = ua.match(/Web0S[/\\s]*([\\d.]+)/i);\n version = match && match[1] ? match[1] : 'Unknown';\n if (version !== 'Unknown') {\n const parts = version.split('.');\n majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n }\n } else if (/Tizen/i.test(ua)) {\n name = 'Samsung Tizen';\n isSmartTV = true;\n const match = ua.match(/Tizen[/\\s]*([\\d.]+)/i);\n version = match && match[1] ? match[1] : 'Unknown';\n if (version !== 'Unknown') {\n const parts = version.split('.');\n majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;\n }\n } else if (/SMART-TV|SmartTV/i.test(ua)) {\n name = 'Smart TV';\n isSmartTV = true;\n } else if (/NetCast/i.test(ua)) {\n name = 'LG NetCast';\n isSmartTV = true;\n isLegacyTV = true;\n } else if (/BRAVIA/i.test(ua)) {\n name = 'Sony BRAVIA';\n isSmartTV = true;\n }\n\n const chromeVersion = getChromeVersion(ua);\n const webkitVersion = getWebKitVersion(ua);\n\n if (chromeVersion > 0) {\n if (!isSmartTV) {\n name = 'Chrome';\n version = chromeVersion.toString();\n majorVersion = chromeVersion;\n }\n\n if (chromeVersion < 50) {\n supportsIMA = false;\n supportsModernJS = false;\n isLegacyTV = true;\n recommendedAdPlayer = 'hls';\n }\n }\n\n if (webkitVersion > 0 && webkitVersion < 600) {\n supportsModernJS = false;\n if (isSmartTV) {\n isLegacyTV = true;\n supportsIMA = false;\n recommendedAdPlayer = 'hls';\n }\n }\n\n if (typeof Promise === 'undefined' ||\n typeof Map === 'undefined' ||\n typeof Set === 'undefined') {\n supportsModernJS = false;\n supportsIMA = false;\n recommendedAdPlayer = 'hls';\n }\n\n if (typeof URLSearchParams === 'undefined') {\n supportsModernJS = false;\n }\n\n return {\n name,\n version,\n majorVersion,\n isSmartTV,\n isLegacyTV,\n platform,\n supportsIMA,\n supportsModernJS,\n recommendedAdPlayer,\n };\n}\n\nexport function supportsGoogleIMA(): boolean {\n const browser = detectBrowser();\n\n if (browser.isLegacyTV) {\n return false;\n }\n\n if (typeof document === 'undefined' ||\n typeof document.createElement !== 'function') {\n return false;\n }\n\n try {\n const video = document.createElement('video');\n if (!video) {\n return false;\n }\n } catch (e) {\n return false;\n }\n\n if (typeof Promise === 'undefined') {\n return false;\n }\n\n return browser.supportsIMA;\n}\n\nexport function getRecommendedAdPlayer(): 'ima' | 'hls' {\n const browser = detectBrowser();\n return browser.recommendedAdPlayer;\n}\n\nexport function supportsModernJS(): boolean {\n try {\n return (\n typeof Promise !== 'undefined' &&\n typeof Map !== 'undefined' &&\n typeof Set !== 'undefined' &&\n typeof Array.from !== 'undefined' &&\n typeof Object.assign !== 'undefined' &&\n typeof Array.prototype.forEach !== 'undefined' &&\n typeof String.prototype.includes !== 'undefined'\n );\n } catch (e) {\n return false;\n }\n}\n\nexport function logBrowserInfo(debug: boolean = false): void {\n if (!debug) return;\n\n const browser = detectBrowser();\n const imaSupport = supportsGoogleIMA();\n\n console.log('[StormcloudVideoPlayer] Browser Compatibility Info:', {\n browser: `${browser.name} ${browser.version}`,\n platform: browser.platform,\n isSmartTV: browser.isSmartTV,\n isLegacyTV: browser.isLegacyTV,\n supportsIMA: imaSupport,\n supportsModernJS: browser.supportsModernJS,\n recommendedAdPlayer: browser.recommendedAdPlayer,\n userAgent: navigator.userAgent,\n });\n}\n\nexport function getBrowserConfigOverrides(): {\n adPlayerType?: 'ima' | 'hls';\n allowNativeHls?: boolean;\n} {\n const browser = detectBrowser();\n const overrides: any = {};\n\n if (browser.isLegacyTV || !browser.supportsIMA) {\n overrides.adPlayerType = 'hls';\n }\n\n if (browser.isSmartTV) {\n overrides.allowNativeHls = true;\n }\n\n return overrides;\n}\n\nexport function supportsFeature(feature: string): boolean {\n switch (feature) {\n case 'ima':\n return supportsGoogleIMA();\n case 'urlsearchparams':\n return typeof URLSearchParams !== 'undefined';\n case 'textencoder':\n return typeof TextEncoder !== 'undefined';\n case 'promises':\n return typeof Promise !== 'undefined';\n case 'fetch':\n return typeof fetch !== 'undefined';\n case 'crypto':\n return typeof crypto !== 'undefined' && typeof crypto.subtle !== 'undefined';\n default:\n return false;\n }\n}\n\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACwBA,SAAS,iBAAiB,IAAoB;AAC5C,QAAM,QAAQ,GAAG,MAAM,eAAe;AACtC,SAAO,SAAS,MAAM,CAAC,IAAI,SAAS,MAAM,CAAC,GAAG,EAAE,IAAI;AACtD;AAEA,SAAS,iBAAiB,IAAoB;AAC5C,QAAM,QAAQ,GAAG,MAAM,oBAAoB;AAC3C,SAAO,SAAS,MAAM,CAAC,IAAI,SAAS,MAAM,CAAC,GAAG,EAAE,IAAI;AACtD;AAEA,SAAS,cAAsB;AAlC/B;AAmCE,MAAI,mBAAmB,eAAa,eAAU,kBAAV,mBAAyB,WAAU;AACrE,WAAO,UAAU,cAAc;AAAA,EACjC;AAEA,QAAM,KAAK,UAAU;AACrB,MAAI,wBAAwB,KAAK,EAAE,GAAG;AACpC,WAAO,oBAAoB,KAAK,EAAE,IAAI,WAAW;AAAA,EACnD;AACA,MAAI,OAAO,KAAK,EAAE,GAAG;AACnB,WAAO;AAAA,EACT;AACA,MAAI,SAAS,KAAK,EAAE,GAAG;AACrB,WAAO,WAAW,KAAK,EAAE,IAAI,iBAAiB;AAAA,EAChD;AACA,MAAI,QAAQ,KAAK,EAAE,GAAG;AACpB,WAAO;AAAA,EACT;AAGA,SAAQ,UAAkB,YAAY;AACxC;AAEO,SAAS,gBAA6B;AAC3C,QAAM,KAAK,UAAU;AACrB,QAAM,WAAW,YAAY;AAE7B,MAAI,OAAO;AACX,MAAI,UAAU;AACd,MAAI,eAAe;AACnB,MAAI,YAAY;AAChB,MAAI,aAAa;AACjB,MAAI,cAAc;AAClB,MAAI,mBAAmB;AACvB,MAAI,sBAAqC;AAEzC,MAAI,eAAe,KAAK,EAAE,GAAG;AAC3B,WAAO;AACP,gBAAY;AACZ,UAAM,QAAQ,GAAG,MAAM,sBAAsB;AAC7C,cAAU,SAAS,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI;AACzC,QAAI,YAAY,WAAW;AACzB,YAAM,QAAQ,QAAQ,MAAM,GAAG;AAC/B,qBAAe,MAAM,CAAC,IAAI,SAAS,MAAM,CAAC,GAAG,EAAE,IAAI;AAAA,IACrD;AAAA,EACF,WAAW,SAAS,KAAK,EAAE,GAAG;AAC5B,WAAO;AACP,gBAAY;AACZ,UAAM,QAAQ,GAAG,MAAM,sBAAsB;AAC7C,cAAU,SAAS,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI;AACzC,QAAI,YAAY,WAAW;AACzB,YAAM,QAAQ,QAAQ,MAAM,GAAG;AAC/B,qBAAe,MAAM,CAAC,IAAI,SAAS,MAAM,CAAC,GAAG,EAAE,IAAI;AAAA,IACrD;AAAA,EACF,WAAW,oBAAoB,KAAK,EAAE,GAAG;AACvC,WAAO;AACP,gBAAY;AAAA,EACd,WAAW,WAAW,KAAK,EAAE,GAAG;AAC9B,WAAO;AACP,gBAAY;AACZ,iBAAa;AAAA,EACf,WAAW,UAAU,KAAK,EAAE,GAAG;AAC7B,WAAO;AACP,gBAAY;AAAA,EACd;AAEA,QAAM,gBAAgB,iBAAiB,EAAE;AACzC,QAAM,gBAAgB,iBAAiB,EAAE;AAEzC,MAAI,gBAAgB,GAAG;AACrB,QAAI,CAAC,WAAW;AACd,aAAO;AACP,gBAAU,cAAc,SAAS;AACjC,qBAAe;AAAA,IACjB;AAEA,QAAI,gBAAgB,IAAI;AACtB,oBAAc;AACd,yBAAmB;AACnB,mBAAa;AACb,4BAAsB;AAAA,IACxB;AAAA,EACF;AAEA,MAAI,gBAAgB,KAAK,gBAAgB,KAAK;AAC5C,uBAAmB;AACnB,QAAI,WAAW;AACb,mBAAa;AACb,oBAAc;AACd,4BAAsB;AAAA,IACxB;AAAA,EACF;AAEA,MAAI,OAAO,YAAY,eACnB,OAAO,QAAQ,eACf,OAAO,QAAQ,aAAa;AAC9B,uBAAmB;AACnB,kBAAc;AACd,0BAAsB;AAAA,EACxB;AAEA,MAAI,OAAO,oBAAoB,aAAa;AAC1C,uBAAmB;AAAA,EACrB;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,oBAA6B;AAC3C,QAAM,UAAU,cAAc;AAE9B,MAAI,QAAQ,YAAY;AACtB,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,aAAa,eACpB,OAAO,SAAS,kBAAkB,YAAY;AAChD,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,QAAI,CAAC,OAAO;AACV,aAAO;AAAA,IACT;AAAA,EACF,SAAS,GAAG;AACV,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,YAAY,aAAa;AAClC,WAAO;AAAA,EACT;AAEA,SAAO,QAAQ;AACjB;;;ADzKO,SAAS,oBACd,OACA,SACe;AACf,MAAI,YAAY;AAChB,MAAI,qBAAqB;AACzB,QAAM,YAAY,oBAAI,IAA0C;AAEhE,WAAS,iBAAiB,WAA0B;AAClD,QAAI,WAAW;AACb,YAAM,QAAQ,sBAAsB;AAAA,IACtC,OAAO;AACL,aAAO,MAAM,QAAQ;AAAA,IACvB;AAAA,EACF;AAEA,WAAS,KAAK,OAAe,SAAqB;AAChD,UAAM,MAAM,UAAU,IAAI,KAAK;AAC/B,QAAI,CAAC,IAAK;AACV,eAAW,MAAM,MAAM,KAAK,GAAG,GAAG;AAChC,UAAI;AACF,WAAG,OAAO;AAAA,MACZ,QAAQ;AAAA,MAAC;AAAA,IACX;AAAA,EACF;AAEA,WAAS,kBAAiC;AAnC5C;AAoCI,QAAI,CAAC,kBAAkB,GAAG;AACxB,cAAQ;AAAA,QACN;AAAA,MACF;AACA,aAAO,QAAQ;AAAA,QACb,IAAI,MAAM,8CAA8C;AAAA,MAC1D;AAAA,IACF;AAEA,QAAI;AACF,YAAM,UAAU,OAAO;AACvB,YAAM,gBAAc,wCAAS,iBAAT,iCAAwB,eAAc;AAC1D,UAAI,aAAa;AACf,cAAM,SAAS,IAAI;AAAA,UACjB,YACG,MAAM,KAAK,EACX,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC;AAAA,QAC/B;AACA,cAAM,gBAAgB,OAAO,IAAI,eAAe;AAChD,YAAI,CAAC,eAAe;AAElB,kBAAQ;AAAA,YACN;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAAC;AAET,QAAI,OAAO,WAAW,iBAAe,YAAO,WAAP,mBAAe;AAClD,aAAO,QAAQ,QAAQ;AACzB,UAAM,WAAW,SAAS;AAAA,MACxB;AAAA,IACF;AACA,QAAI,UAAU;AACZ,WAAI,YAAO,WAAP,mBAAe,KAAK;AACtB,eAAO,QAAQ,QAAQ;AAAA,MACzB;AACA,aAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,cAAM,UAAU,WAAW,MAAM;AAC/B,iBAAO,IAAI,MAAM,sBAAsB,CAAC;AAAA,QAC1C,GAAG,GAAK;AACR,iBAAS,iBAAiB,QAAQ,MAAM;AACtC,uBAAa,OAAO;AACpB,kBAAQ;AAAA,QACV,CAAC;AACD,iBAAS,iBAAiB,SAAS,MAAM;AACvC,uBAAa,OAAO;AACpB,iBAAO,IAAI,MAAM,qBAAqB,CAAC;AAAA,QACzC,CAAC;AAAA,MACH,CAAC;AAAA,IACH;AACA,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,aAAO,MAAM;AACb,aAAO,QAAQ;AACf,aAAO,QAAQ;AACf,aAAO,aAAa,YAAY,MAAM;AACtC,aAAO,SAAS,MAAM,QAAQ;AAC9B,aAAO,UAAU,MAAM,OAAO,IAAI,MAAM,qBAAqB,CAAC;AAC9D,eAAS,KAAK,YAAY,MAAM;AAAA,IAClC,CAAC;AAAA,EACH;AAEA,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI,gBAAgB;AACpB,QAAM,aAAa;AACnB,QAAM,gBAAgB;AACtB,MAAI;AACJ,MAAI;AACJ,MAAI;AAEJ,WAAS,eAAe,QAAa,YAAoB;AACvD,UAAM,aAAa,IAAI,OAAO,IAAI,WAAW;AAC7C,eAAW,WAAW;AAEtB,UAAM,aAAa,MAAM,eAAe,MAAM,eAAe;AAC7D,UAAM,cAAc,MAAM,gBAAgB,MAAM,gBAAgB;AAEhE,eAAW,oBAAoB;AAC/B,eAAW,qBAAqB;AAChC,eAAW,uBAAuB;AAClC,eAAW,wBAAwB;AAEnC,eAAW,kBAAkB;AAE7B,YAAQ,IAAI,iCAAiC,UAAU,IAAI,WAAW,EAAE;AAExE,cAAU,WAAW,UAAU;AAAA,EACjC;AAEA,WAAS,oBAAoB;AAC3B,QAAI,YAAY;AACd,UAAI;AACF,gBAAQ,IAAI,uCAAuC;AACnD,mBAAW,QAAQ;AAAA,MACrB,SAAS,OAAO;AACd,gBAAQ,KAAK,uCAAuC,KAAK;AAAA,MAC3D;AACA,mBAAa;AAAA,IACf;AAAA,EACF;AAEA,SAAO;AAAA,IACL,aAAa;AACX,sBAAgB,EACb,KAAK,MAAM;AAlJpB;AAmJU,cAAM,SAAS,OAAO;AACtB,YAAI,CAAC,oBAAoB;AACvB,gBAAM,YAAY,SAAS,cAAc,KAAK;AAC9C,oBAAU,MAAM,WAAW;AAC3B,oBAAU,MAAM,OAAO;AACvB,oBAAU,MAAM,MAAM;AACtB,oBAAU,MAAM,QAAQ;AACxB,oBAAU,MAAM,SAAS;AACzB,oBAAU,MAAM,UAAU;AAC1B,oBAAU,MAAM,aAAa;AAC7B,oBAAU,MAAM,iBAAiB;AACjC,oBAAU,MAAM,gBAAgB;AAChC,oBAAU,MAAM,SAAS;AACzB,oBAAU,MAAM,kBAAkB;AAClC,sBAAM,kBAAN,mBAAqB,YAAY;AACjC,0BAAgB;AAChB,+BAAqB,IAAI,OAAO,IAAI;AAAA,YAClC;AAAA,YACA;AAAA,UACF;AACA,cAAI;AACF,qCAAmB,eAAnB;AAAA,UACF,QAAQ;AAAA,UAAC;AAAA,QACX;AAAA,MACF,CAAC,EACA,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA,IACnB;AAAA,IACA,MAAM,WAAW,YAAoB;AACnC,cAAQ,IAAI,yBAAyB,UAAU;AAE/C,UAAI,CAAC,cAAc,WAAW,KAAK,MAAM,IAAI;AAC3C,cAAM,QAAQ,IAAI,MAAM,oCAAoC;AAC5D,gBAAQ,KAAK,SAAS,MAAM,OAAO;AACnC,eAAO,QAAQ,OAAO,KAAK;AAAA,MAC7B;AAEA,UAAI;AACF,YAAI,IAAI,UAAU;AAAA,MACpB,SAAS,GAAG;AACV,cAAM,QAAQ,IAAI,MAAM,gCAAgC,UAAU,EAAE;AACpE,gBAAQ,KAAK,SAAS,MAAM,OAAO;AACnC,eAAO,QAAQ,OAAO,KAAK;AAAA,MAC7B;AAEA,UAAI,WAAW;AACb,gBAAQ;AAAA,UACN;AAAA,QACF;AACA,eAAO,QAAQ;AAAA,UACb,IAAI,MAAM,6CAA6C;AAAA,QACzD;AAAA,MACF;AAEA,wBAAkB;AAElB,wBAAkB;AAClB,yBAAmB;AAEnB,UAAI;AACJ,yBAAmB,IAAI,QAAc,CAAC,SAAS,WAAW;AACxD,2BAAmB;AACnB,0BAAkB;AAClB,wBAAgB;AAEhB,mBAAW,MAAM;AACf,cAAI,iBAAiB;AACnB,4BAAgB,IAAI,MAAM,oBAAoB,CAAC;AAC/C,8BAAkB;AAClB,+BAAmB;AAAA,UACrB;AAAA,QACF,GAAG,GAAK;AAAA,MACV,CAAC;AAED,UAAI;AACF,cAAM,gBAAgB;AACtB,cAAM,SAAS,OAAO;AACtB,uBAAe;AACf,wBAAgB;AAEhB,YAAI,CAAC,oBAAoB;AACvB,kBAAQ,IAAI,qCAAqC;AACjD,gBAAM,YAAY,SAAS,cAAc,KAAK;AAC9C,oBAAU,MAAM,WAAW;AAC3B,oBAAU,MAAM,OAAO;AACvB,oBAAU,MAAM,MAAM;AACtB,oBAAU,MAAM,QAAQ;AACxB,oBAAU,MAAM,SAAS;AACzB,oBAAU,MAAM,UAAU;AAC1B,oBAAU,MAAM,aAAa;AAC7B,oBAAU,MAAM,iBAAiB;AACjC,oBAAU,MAAM,gBAAgB;AAChC,oBAAU,MAAM,SAAS;AACzB,oBAAU,MAAM,kBAAkB;AAElC,cAAI,CAAC,MAAM,eAAe;AACxB,kBAAM,IAAI,MAAM,8CAA8C;AAAA,UAChE;AAEA,gBAAM,cAAc,YAAY,SAAS;AACzC,0BAAgB;AAChB,+BAAqB,IAAI,OAAO,IAAI;AAAA,YAClC;AAAA,YACA;AAAA,UACF;AAEA,cAAI;AACF,+BAAmB,WAAW;AAC9B,oBAAQ,IAAI,wCAAwC;AAAA,UACtD,SAAS,OAAO;AACd,oBAAQ;AAAA,cACN;AAAA,cACA;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAEA,cAAM,aAAa,MAAM,eAAe,MAAM;AAC9C,cAAM,cAAc,MAAM,gBAAgB,MAAM;AAEhD,YACE,CAAC,cACD,CAAC,eACD,eAAe,KACf,gBAAgB,GAChB;AACA,gBAAM,QAAQ,IAAI;AAAA,YAChB,6BAA6B,UAAU,IAAI,WAAW;AAAA,UACxD;AACA,kBAAQ,KAAK,SAAS,MAAM,OAAO;AACnC,yDAAgB;AAChB,4BAAkB;AAClB,6BAAmB;AACnB,iBAAO,QAAQ,OAAO,KAAK;AAAA,QAC7B;AAEA,YAAI,CAAC,WAAW;AACd,kBAAQ,IAAI,2BAA2B;AACvC,gBAAM,eAAe,IAAI,OAAO,IAAI,UAAU,kBAAkB;AAChE,sBAAY;AAEZ,oBAAU;AAAA,YACR,OAAO,IAAI,sBAAsB,KAAK;AAAA,YACtC,CAAC,QAAa;AACZ,sBAAQ,IAAI,0BAA0B;AACtC,kBAAI;AACF,6BAAa,IAAI,cAAc,KAAK;AACpC,sBAAM,UAAU,OAAO,IAAI,QAAQ;AACnC,sBAAM,eAAe,OAAO,IAAI,aAAa;AAE7C,2BAAW;AAAA,kBACT,aAAa;AAAA,kBACb,CAAC,eAAoB;AA1SvC;AA2SoB,4BAAQ,MAAM,mBAAmB,WAAW,SAAS,CAAC;AAEtD,sCAAkB;AAElB,gCAAY;AAEZ,0BAAM,qBAAqB,MAAM;AACjC,0BAAM,QAAQ;AACd,qCAAiB,KAAK;AACtB,4BAAQ;AAAA,sBACN,6CAA6C,kBAAkB,OAAO,kBAAkB;AAAA,oBAC1F;AAEA,wBAAI,eAAe;AACjB,oCAAc,MAAM,gBAAgB;AACpC,oCAAc,MAAM,UAAU;AAC9B,8BAAQ,IAAI,uCAAuC;AAAA,oBACrD;AAEA,wBAAI,iBAAiB;AACnB,sCAAgB,IAAI,MAAM,mBAAmB,CAAC;AAC9C,wCAAkB;AAClB,yCAAmB;AAAA,oBACrB;AAEA,wBAAI,gBAAgB,gBAAgB,YAAY;AAC9C,4BAAM,QACJ,gBAAgB,KAAK,IAAI,GAAG,eAAe;AAC7C,8BAAQ;AAAA,wBACN,gCAAgC,KAAK,eAAe,aAAa;AAAA,sBACnE;AACA,6BAAO,WAAW,MAAM;AACtB,4BAAI;AACF,yCAAe,QAAQ,YAAa;AAAA,wBACtC,QAAQ;AAAA,wBAAC;AAAA,sBACX,GAAG,KAAK;AAAA,oBACV,OAAO;AACL,8BAAQ;AAAA,wBACN;AAAA,sBACF;AACA,2BAAK,UAAU;AAEf,0BAAI,EAAC,mCAAS,8BAA6B;AACzC,4BAAI,MAAM,QAAQ;AAChB,kCAAQ;AAAA,4BACN;AAAA,0BACF;AACA,sCAAM,KAAK,MAAX,mBAAc,MAAM,MAAM;AAAA,0BAAC;AAAA,wBAC7B;AAAA,sBACF;AAAA,oBACF;AAAA,kBACF;AAAA,gBACF;AAEA,2BAAW;AAAA,kBACT,QAAQ;AAAA,kBACR,MAAM;AACJ,4BAAQ;AAAA,sBACN;AAAA,oBACF;AAEA,wBAAI,EAAC,mCAAS,8BAA6B;AACzC,4BAAM,MAAM;AACZ,8BAAQ,IAAI,+BAA+B;AAAA,oBAC7C,OAAO;AACL,8BAAQ;AAAA,wBACN;AAAA,sBACF;AAAA,oBACF;AAEA,0BAAM,QAAQ;AACd,0BAAM,SAAS;AACf,gCAAY;AACZ,qCAAiB,IAAI;AACrB,yBAAK,eAAe;AAAA,kBACtB;AAAA,gBACF;AAEA,2BAAW,iBAAiB,QAAQ,SAAS,MAAM;AACjD,0BAAQ;AAAA,oBACN;AAAA,kBACF;AACA,mCAAiB,IAAI;AAErB,wBAAM,QAAQ;AACd,wBAAM,SAAS;AAEf,sBAAI,eAAe;AACjB,kCAAc,MAAM,gBAAgB;AACpC,kCAAc,MAAM,UAAU;AAC9B,4BAAQ;AAAA,sBACN;AAAA,oBACF;AAAA,kBACF;AAAA,gBACF,CAAC;AAED,2BAAW;AAAA,kBACT,QAAQ;AAAA,kBACR,MAAM;AACJ,4BAAQ,IAAI,gCAAgC;AAC5C,gCAAY;AACZ,qCAAiB,KAAK;AAEtB,yBAAK,gBAAgB;AAErB,+BAAW,MAAM;AACf,4BAAM,aACJ,MAAM,QAAQ,wBAAwB;AACxC,0BAAI,YAAY;AACd,gCAAQ;AAAA,0BACN;AAAA,wBACF;AACA,4BAAI,eAAe;AACjB,wCAAc,MAAM,UAAU;AAC9B,wCAAc,MAAM,gBAAgB;AAAA,wBACtC;AAAA,sBACF;AAAA,oBACF,GAAG,EAAE;AAAA,kBACP;AAAA,gBACF;AAEA,2BAAW,iBAAiB,QAAQ,mBAAmB,MAAM;AAC3D,0BAAQ,IAAI,4CAA4C;AACxD,8BAAY;AACZ,mCAAiB,KAAK;AAEtB,uBAAK,mBAAmB;AAAA,gBAC1B,CAAC;AAED,wBAAQ,IAAI,4CAA4C;AAExD,oBAAI,kBAAkB;AACpB,mCAAiB;AACjB,qCAAmB;AACnB,oCAAkB;AAAA,gBACpB;AAAA,cACF,SAAS,GAAG;AACV,wBAAQ,MAAM,uCAAuC,CAAC;AACtD,4BAAY;AACZ,sBAAM,QAAQ;AACd,iCAAiB,KAAK;AACtB,oBAAI,eAAe;AACjB,gCAAc,MAAM,gBAAgB;AACpC,gCAAc,MAAM,UAAU;AAC9B,0BAAQ,IAAI,6CAA6C;AAAA,gBAC3D;AAEA,oBAAI,EAAC,mCAAS,8BAA6B;AACzC,sBAAI,MAAM,QAAQ;AAChB,4BAAQ;AAAA,sBACN;AAAA,oBACF;AACA,0BAAM,KAAK,EAAE,MAAM,MAAM;AAAA,oBAAC,CAAC;AAAA,kBAC7B;AAAA,gBACF;AAEA,oBAAI,iBAAiB;AACnB,kCAAgB,IAAI,MAAM,6BAA6B,CAAC;AACxD,oCAAkB;AAClB,qCAAmB;AAAA,gBACrB;AACA,qBAAK,UAAU;AAAA,cACjB;AAAA,YACF;AAAA,YACA;AAAA,UACF;AAEA,oBAAU;AAAA,YACR,OAAO,IAAI,aAAa,KAAK;AAAA,YAC7B,CAAC,iBAAsB;AACrB,sBAAQ,MAAM,2BAA2B,aAAa,SAAS,CAAC;AAEhE,0BAAY;AAEZ,oBAAM,qBAAqB,MAAM;AACjC,oBAAM,QAAQ;AACd,+BAAiB,KAAK;AACtB,sBAAQ;AAAA,gBACN,8BAA8B,kBAAkB,OAAO,kBAAkB;AAAA,cAC3E;AAEA,kBAAI,eAAe;AACjB,8BAAc,MAAM,gBAAgB;AACpC,8BAAc,MAAM,UAAU;AAC9B,wBAAQ,IAAI,8CAA8C;AAAA,cAC5D;AAEA,kBAAI,EAAC,mCAAS,8BAA6B;AACzC,oBAAI,MAAM,QAAQ;AAChB,0BAAQ,IAAI,gDAAgD;AAC5D,wBAAM,KAAK,EAAE,MAAM,MAAM;AAAA,kBAAC,CAAC;AAAA,gBAC7B;AAAA,cACF;AAEA,kBAAI,iBAAiB;AACnB,gCAAgB,IAAI,MAAM,kBAAkB,CAAC;AAC7C,kCAAkB;AAClB,mCAAmB;AAAA,cACrB;AACA,mBAAK,UAAU;AAAA,YACjB;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAEA,gBAAQ,IAAI,0BAA0B;AACtC,uBAAe,QAAQ,UAAU;AAEjC,eAAO;AAAA,MACT,SAAS,OAAO;AACd,gBAAQ,MAAM,gCAAgC,KAAK;AAEnD,uDAAgB;AAChB,0BAAkB;AAClB,2BAAmB;AACnB,eAAO,QAAQ,OAAO,KAAK;AAAA,MAC7B;AAAA,IACF;AAAA,IACA,MAAM,OAAO;AArgBjB;AAsgBM,UAAI,GAAC,YAAO,WAAP,mBAAe,QAAO,CAAC,oBAAoB;AAC9C,gBAAQ;AAAA,UACN;AAAA,QACF;AACA,eAAO,QAAQ,OAAO,IAAI,MAAM,uBAAuB,CAAC;AAAA,MAC1D;AAEA,UAAI,CAAC,YAAY;AACf,gBAAQ,KAAK,gDAAgD;AAC7D,eAAO,QAAQ,OAAO,IAAI,MAAM,gBAAgB,CAAC;AAAA,MACnD;AAEA,UAAI;AACF,cAAM,QAAQ,MAAM,eAAe;AACnC,cAAM,SAAS,MAAM,gBAAgB;AAErC,gBAAQ,IAAI,mCAAmC,KAAK,IAAI,MAAM,GAAG;AACjE,mBAAW,KAAK,OAAO,QAAQ,OAAO,OAAO,IAAI,SAAS,MAAM;AAEhE,oBAAY;AAEZ,cAAM,WAAW,qBAAqB,IAAI,MAAM;AAChD,YAAI;AACF,qBAAW,UAAU,QAAQ;AAC7B,kBAAQ,IAAI,0BAA0B,QAAQ,EAAE;AAAA,QAClD,SAAS,OAAO;AACd,kBAAQ,KAAK,kCAAkC,KAAK;AAAA,QACtD;AAEA,gBAAQ,IAAI,4BAA4B;AACxC,mBAAW,MAAM;AAEjB,eAAO,QAAQ,QAAQ;AAAA,MACzB,SAAS,OAAO;AACd,gBAAQ,MAAM,qCAAqC,KAAK;AACxD,oBAAY;AACZ,yBAAiB,KAAK;AAEtB,YAAI,EAAC,mCAAS,8BAA6B;AACzC,sBAAM,KAAK,MAAX,mBAAc,MAAM,MAAM;AAAA,UAAC;AAAA,QAC7B;AACA,eAAO,QAAQ,OAAO,KAAK;AAAA,MAC7B;AAAA,IACF;AAAA,IACA,MAAM,OAAO;AAljBjB;AAmjBM,cAAQ,IAAI,4BAA4B;AACxC,kBAAY;AACZ,uBAAiB,KAAK;AAEtB,UAAI,eAAe;AACjB,sBAAc,MAAM,gBAAgB;AACpC,sBAAc,MAAM,UAAU;AAC9B,gBAAQ,IAAI,sCAAsC;AAAA,MACpD;AAEA,UAAI;AACF,uDAAY,SAAZ;AAAA,MACF,QAAQ;AAAA,MAAC;AAET,wBAAkB;AAAA,IACpB;AAAA,IACA,UAAU;AAnkBd;AAokBM,wBAAkB;AAElB,kBAAY;AACZ,YAAM,QAAQ;AACd,uBAAiB,KAAK;AAEtB,UAAI,eAAe;AACjB,sBAAc,MAAM,gBAAgB;AACpC,sBAAc,MAAM,UAAU;AAAA,MAChC;AAEA,UAAI;AACF,qDAAW,YAAX;AAAA,MACF,QAAQ;AAAA,MAAC;AAET,UAAI,+CAAe,eAAe;AAChC,sBAAc,cAAc,YAAY,aAAa;AAAA,MACvD;AAEA,sBAAgB;AAChB,2BAAqB;AACrB,kBAAY;AAAA,IACd;AAAA,IACA,cAAc;AACZ,aAAO;AAAA,IACT;AAAA,IACA,OAAO,OAAe,QAAgB;AA9lB1C;AA+lBM,UAAI,CAAC,cAAc,GAAC,YAAO,WAAP,mBAAe,MAAK;AACtC,gBAAQ;AAAA,UACN;AAAA,QACF;AACA;AAAA,MACF;AAEA,UAAI;AACF,gBAAQ,IAAI,iCAAiC,KAAK,IAAI,MAAM,EAAE;AAC9D,mBAAW,OAAO,OAAO,QAAQ,OAAO,OAAO,IAAI,SAAS,MAAM;AAAA,MACpE,SAAS,OAAO;AACd,gBAAQ,KAAK,qCAAqC,KAAK;AAAA,MACzD;AAAA,IACF;AAAA,IACA,GAAG,OAAe,UAAmC;AACnD,UAAI,CAAC,UAAU,IAAI,KAAK,EAAG,WAAU,IAAI,OAAO,oBAAI,IAAI,CAAC;AACzD,gBAAU,IAAI,KAAK,EAAG,IAAI,QAAQ;AAAA,IACpC;AAAA,IACA,IAAI,OAAe,UAAmC;AAjnB1D;AAknBM,sBAAU,IAAI,KAAK,MAAnB,mBAAsB,OAAO;AAAA,IAC/B;AAAA,IACA,yBAAyB,OAAgB;AACvC,cAAQ;AAAA,QACN,0CAA0C,kBAAkB,OAAO,KAAK;AAAA,MAC1E;AACA,2BAAqB;AAAA,IACvB;AAAA,IACA,wBAAwB;AACtB,aAAO;AAAA,IACT;AAAA,IACA,YAAY,QAAgB;AAC1B,UAAI,cAAc,WAAW;AAC3B,YAAI;AACF,qBAAW,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,MAAM,CAAC,CAAC;AAAA,QACvD,SAAS,OAAO;AACd,kBAAQ,KAAK,kCAAkC,KAAK;AAAA,QACtD;AAAA,MACF;AAAA,IACF;AAAA,IACA,cAAsB;AACpB,UAAI,cAAc,WAAW;AAC3B,YAAI;AACF,iBAAO,WAAW,UAAU;AAAA,QAC9B,SAAS,OAAO;AACd,kBAAQ,KAAK,kCAAkC,KAAK;AACpD,iBAAO;AAAA,QACT;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF;","names":[]}
|
|
@@ -501,7 +501,9 @@ function createImaController(video, options) {
|
|
|
501
501
|
adsManager.addEventListener(
|
|
502
502
|
AdEvent.CONTENT_PAUSE_REQUESTED,
|
|
503
503
|
() => {
|
|
504
|
-
console.log(
|
|
504
|
+
console.log(
|
|
505
|
+
"[IMA] Content pause requested - FORCE MUTING main video"
|
|
506
|
+
);
|
|
505
507
|
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
506
508
|
video.pause();
|
|
507
509
|
console.log("[IMA] Video paused (VOD mode)");
|
|
@@ -511,14 +513,19 @@ function createImaController(video, options) {
|
|
|
511
513
|
);
|
|
512
514
|
}
|
|
513
515
|
video.muted = true;
|
|
516
|
+
video.volume = 0;
|
|
514
517
|
adPlaying = true;
|
|
515
518
|
setAdPlayingFlag(true);
|
|
516
519
|
emit("content_pause");
|
|
517
520
|
}
|
|
518
521
|
);
|
|
519
522
|
adsManager.addEventListener(AdEvent.STARTED, () => {
|
|
520
|
-
console.log(
|
|
523
|
+
console.log(
|
|
524
|
+
"[IMA] Ad started playing - FORCE MUTING main video"
|
|
525
|
+
);
|
|
521
526
|
setAdPlayingFlag(true);
|
|
527
|
+
video.muted = true;
|
|
528
|
+
video.volume = 0;
|
|
522
529
|
if (adContainerEl) {
|
|
523
530
|
adContainerEl.style.pointerEvents = "auto";
|
|
524
531
|
adContainerEl.style.display = "flex";
|
|
@@ -534,6 +541,18 @@ function createImaController(video, options) {
|
|
|
534
541
|
adPlaying = false;
|
|
535
542
|
setAdPlayingFlag(false);
|
|
536
543
|
emit("content_resume");
|
|
544
|
+
setTimeout(() => {
|
|
545
|
+
const stillInPod = video.dataset.stormcloudAdPlaying === "true";
|
|
546
|
+
if (stillInPod) {
|
|
547
|
+
console.log(
|
|
548
|
+
"[IMA] Still in ad pod - keeping ad container visible (black screen)"
|
|
549
|
+
);
|
|
550
|
+
if (adContainerEl) {
|
|
551
|
+
adContainerEl.style.display = "flex";
|
|
552
|
+
adContainerEl.style.pointerEvents = "auto";
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
}, 50);
|
|
537
556
|
}
|
|
538
557
|
);
|
|
539
558
|
adsManager.addEventListener(AdEvent.ALL_ADS_COMPLETED, () => {
|
|
@@ -1083,6 +1102,18 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1083
1102
|
adPlaying = false;
|
|
1084
1103
|
setAdPlayingFlag(false);
|
|
1085
1104
|
emit("content_resume");
|
|
1105
|
+
setTimeout(() => {
|
|
1106
|
+
const stillInPod = contentVideo.dataset.stormcloudAdPlaying === "true";
|
|
1107
|
+
if (stillInPod) {
|
|
1108
|
+
console.log(
|
|
1109
|
+
"[HlsAdPlayer] Still in ad pod - keeping ad container visible (black screen)"
|
|
1110
|
+
);
|
|
1111
|
+
if (adContainerEl) {
|
|
1112
|
+
adContainerEl.style.display = "flex";
|
|
1113
|
+
adContainerEl.style.pointerEvents = "auto";
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
}, 50);
|
|
1086
1117
|
}
|
|
1087
1118
|
function handleAdError() {
|
|
1088
1119
|
console.log("[HlsAdPlayer] Handling ad error");
|
|
@@ -1194,7 +1225,9 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1194
1225
|
} else {
|
|
1195
1226
|
console.log("[HlsAdPlayer] Content continues (Live mode)");
|
|
1196
1227
|
}
|
|
1228
|
+
console.log("[HlsAdPlayer] FORCE MUTING main video");
|
|
1197
1229
|
contentVideo.muted = true;
|
|
1230
|
+
contentVideo.volume = 0;
|
|
1198
1231
|
adPlaying = true;
|
|
1199
1232
|
setAdPlayingFlag(true);
|
|
1200
1233
|
if (adVideoElement) {
|
|
@@ -2139,6 +2172,9 @@ var StormcloudVideoPlayer = class {
|
|
|
2139
2172
|
if (remaining > 500 && this.adPodQueue.length > 0) {
|
|
2140
2173
|
const next = this.adPodQueue.shift();
|
|
2141
2174
|
this.currentAdIndex++;
|
|
2175
|
+
this.video.dataset.stormcloudAdPlaying = "true";
|
|
2176
|
+
this.video.muted = true;
|
|
2177
|
+
this.video.volume = 0;
|
|
2142
2178
|
if (this.config.debugAdTiming) {
|
|
2143
2179
|
console.log(
|
|
2144
2180
|
`[StormcloudVideoPlayer] Playing next ad in pod (${this.currentAdIndex}/${this.totalAdsInBreak}) - main video stays muted, ad layer stays visible`
|
|
@@ -2971,7 +3007,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2971
3007
|
var _a;
|
|
2972
3008
|
if (this.config.debugAdTiming) {
|
|
2973
3009
|
console.log(
|
|
2974
|
-
"[StormcloudVideoPlayer] Handling ad pod completion - resuming content"
|
|
3010
|
+
"[StormcloudVideoPlayer] Handling ad pod completion - resuming content and hiding ad layer"
|
|
2975
3011
|
);
|
|
2976
3012
|
}
|
|
2977
3013
|
this.inAdBreak = false;
|
|
@@ -2984,11 +3020,14 @@ var StormcloudVideoPlayer = class {
|
|
|
2984
3020
|
this.showAds = false;
|
|
2985
3021
|
this.currentAdIndex = 0;
|
|
2986
3022
|
this.totalAdsInBreak = 0;
|
|
3023
|
+
this.ima.stop().catch(() => {
|
|
3024
|
+
});
|
|
2987
3025
|
const originalMutedState = this.ima.getOriginalMutedState();
|
|
2988
3026
|
this.video.muted = originalMutedState;
|
|
3027
|
+
this.video.volume = originalMutedState ? 0 : 1;
|
|
2989
3028
|
if (this.config.debugAdTiming) {
|
|
2990
3029
|
console.log(
|
|
2991
|
-
`[StormcloudVideoPlayer] Restored main video
|
|
3030
|
+
`[StormcloudVideoPlayer] Restored main video - muted: ${originalMutedState}, volume: ${this.video.volume}`
|
|
2992
3031
|
);
|
|
2993
3032
|
}
|
|
2994
3033
|
if (!this.shouldContinueLiveStreamDuringAds() && this.video.paused) {
|