stormcloud-video-player 0.2.10 → 0.2.11

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/lib/sdk/ima.cjs CHANGED
@@ -254,8 +254,11 @@ function createImaController(video, options) {
254
254
  );
255
255
  emit("ad_error");
256
256
  if (!options?.continueLiveStreamDuringAds) {
257
- video.play()?.catch(() => {
258
- });
257
+ if (video.paused) {
258
+ console.log("[IMA] Resuming paused video after ad error");
259
+ video.play()?.catch(() => {
260
+ });
261
+ }
259
262
  }
260
263
  }
261
264
  }
@@ -346,10 +349,17 @@ function createImaController(video, options) {
346
349
  console.error("[IMA] Error setting up ads manager:", e);
347
350
  adPlaying = false;
348
351
  video.muted = originalMutedState;
349
- if (adContainerEl) adContainerEl.style.pointerEvents = "none";
352
+ if (adContainerEl) {
353
+ adContainerEl.style.pointerEvents = "none";
354
+ adContainerEl.style.display = "none";
355
+ console.log("[IMA] Ad container hidden after setup error");
356
+ }
350
357
  if (!options?.continueLiveStreamDuringAds) {
351
- video.play().catch(() => {
352
- });
358
+ if (video.paused) {
359
+ console.log("[IMA] Resuming paused video after setup error");
360
+ video.play().catch(() => {
361
+ });
362
+ }
353
363
  }
354
364
  if (adsLoadedReject) {
355
365
  adsLoadedReject(new Error("Failed to setup ads manager"));
@@ -367,10 +377,17 @@ function createImaController(video, options) {
367
377
  console.error("[IMA] Ads loader error:", adErrorEvent.getError());
368
378
  adPlaying = false;
369
379
  video.muted = originalMutedState;
370
- if (adContainerEl) adContainerEl.style.pointerEvents = "none";
380
+ if (adContainerEl) {
381
+ adContainerEl.style.pointerEvents = "none";
382
+ adContainerEl.style.display = "none";
383
+ console.log("[IMA] Ad container hidden after loader error");
384
+ }
371
385
  if (!options?.continueLiveStreamDuringAds) {
372
- video.play().catch(() => {
373
- });
386
+ if (video.paused) {
387
+ console.log("[IMA] Resuming paused video after loader error");
388
+ video.play().catch(() => {
389
+ });
390
+ }
374
391
  }
375
392
  if (adsLoadedReject) {
376
393
  adsLoadedReject(new Error("Ads loader error"));
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/sdk/ima.ts"],"sourcesContent":["import type { ImaController } from \"../types\";\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 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 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 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 = \"flex\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"2\";\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 (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 = \"2\";\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 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 video.muted = originalMutedState;\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 video.play()?.catch(() => {});\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 emit(\"content_pause\");\n }\n );\n\n adsManager.addEventListener(AdEvent.STARTED, () => {\n console.log(\"[IMA] Ad started playing\");\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 video.muted = originalMutedState;\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n console.log(\n \"[IMA] Ad container hidden - pointer events disabled\"\n );\n }\n\n if (!options?.continueLiveStreamDuringAds) {\n video.play()?.catch(() => {});\n console.log(\"[IMA] Video resumed (VOD mode)\");\n } else {\n console.log(\n \"[IMA] Video unmuted (Live mode - was never paused)\"\n );\n }\n\n emit(\"content_resume\");\n }\n );\n\n adsManager.addEventListener(AdEvent.ALL_ADS_COMPLETED, () => {\n console.log(\"[IMA] All ads completed\");\n adPlaying = false;\n video.muted = originalMutedState;\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n console.log(\n \"[IMA] Ad container hidden after all ads completed\"\n );\n }\n\n if (!options?.continueLiveStreamDuringAds) {\n video.play().catch(() => {});\n console.log(\n \"[IMA] Video resumed after all ads completed (VOD mode)\"\n );\n } else {\n console.log(\n \"[IMA] Video unmuted after all ads completed (Live mode)\"\n );\n }\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 if (adContainerEl) adContainerEl.style.pointerEvents = \"none\";\n\n if (!options?.continueLiveStreamDuringAds) {\n video.play().catch(() => {});\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 video.muted = originalMutedState;\n if (adContainerEl) adContainerEl.style.pointerEvents = \"none\";\n\n if (!options?.continueLiveStreamDuringAds) {\n video.play().catch(() => {});\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 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\n if (!options?.continueLiveStreamDuringAds) {\n video.play()?.catch(() => {});\n }\n return Promise.reject(error);\n }\n },\n async stop() {\n adPlaying = false;\n video.muted = originalMutedState;\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 if (!options?.continueLiveStreamDuringAds) {\n video.play().catch(() => {});\n console.log(\"[IMA] Video resumed after stop (VOD mode)\");\n } else {\n console.log(\"[IMA] Video unmuted after stop (Live mode)\");\n }\n },\n destroy() {\n destroyAdsManager();\n\n adPlaying = false;\n video.muted = originalMutedState;\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 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"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/sdk/ima.ts"],"sourcesContent":["import type { ImaController } from \"../types\";\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 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 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 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 = \"flex\";\n container.style.alignItems = \"center\";\n container.style.justifyContent = \"center\";\n container.style.pointerEvents = \"none\";\n container.style.zIndex = \"2\";\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 (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 = \"2\";\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 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 video.muted = originalMutedState;\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(\"[IMA] Resuming paused video after ad error\");\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 emit(\"content_pause\");\n }\n );\n\n adsManager.addEventListener(AdEvent.STARTED, () => {\n console.log(\"[IMA] Ad started playing\");\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 video.muted = originalMutedState;\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n console.log(\n \"[IMA] Ad container hidden - pointer events disabled\"\n );\n }\n\n if (!options?.continueLiveStreamDuringAds) {\n video.play()?.catch(() => {});\n console.log(\"[IMA] Video resumed (VOD mode)\");\n } else {\n console.log(\n \"[IMA] Video unmuted (Live mode - was never paused)\"\n );\n }\n\n emit(\"content_resume\");\n }\n );\n\n adsManager.addEventListener(AdEvent.ALL_ADS_COMPLETED, () => {\n console.log(\"[IMA] All ads completed\");\n adPlaying = false;\n video.muted = originalMutedState;\n if (adContainerEl) {\n adContainerEl.style.pointerEvents = \"none\";\n adContainerEl.style.display = \"none\";\n console.log(\n \"[IMA] Ad container hidden after all ads completed\"\n );\n }\n\n if (!options?.continueLiveStreamDuringAds) {\n video.play().catch(() => {});\n console.log(\n \"[IMA] Video resumed after all ads completed (VOD mode)\"\n );\n } else {\n console.log(\n \"[IMA] Video unmuted after all ads completed (Live mode)\"\n );\n }\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 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(\"[IMA] Resuming paused video after setup error\");\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 video.muted = originalMutedState;\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 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\n if (!options?.continueLiveStreamDuringAds) {\n video.play()?.catch(() => {});\n }\n return Promise.reject(error);\n }\n },\n async stop() {\n adPlaying = false;\n video.muted = originalMutedState;\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 if (!options?.continueLiveStreamDuringAds) {\n video.play().catch(() => {});\n console.log(\"[IMA] Video resumed after stop (VOD mode)\");\n } else {\n console.log(\"[IMA] Video unmuted after stop (Live mode)\");\n }\n },\n destroy() {\n destroyAdsManager();\n\n adPlaying = false;\n video.muted = originalMutedState;\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 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"],"mappings":"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","names":[]}
@@ -270,8 +270,11 @@ function createImaController(video, options) {
270
270
  );
271
271
  emit("ad_error");
272
272
  if (!options?.continueLiveStreamDuringAds) {
273
- video.play()?.catch(() => {
274
- });
273
+ if (video.paused) {
274
+ console.log("[IMA] Resuming paused video after ad error");
275
+ video.play()?.catch(() => {
276
+ });
277
+ }
275
278
  }
276
279
  }
277
280
  }
@@ -362,10 +365,17 @@ function createImaController(video, options) {
362
365
  console.error("[IMA] Error setting up ads manager:", e);
363
366
  adPlaying = false;
364
367
  video.muted = originalMutedState;
365
- if (adContainerEl) adContainerEl.style.pointerEvents = "none";
368
+ if (adContainerEl) {
369
+ adContainerEl.style.pointerEvents = "none";
370
+ adContainerEl.style.display = "none";
371
+ console.log("[IMA] Ad container hidden after setup error");
372
+ }
366
373
  if (!options?.continueLiveStreamDuringAds) {
367
- video.play().catch(() => {
368
- });
374
+ if (video.paused) {
375
+ console.log("[IMA] Resuming paused video after setup error");
376
+ video.play().catch(() => {
377
+ });
378
+ }
369
379
  }
370
380
  if (adsLoadedReject) {
371
381
  adsLoadedReject(new Error("Failed to setup ads manager"));
@@ -383,10 +393,17 @@ function createImaController(video, options) {
383
393
  console.error("[IMA] Ads loader error:", adErrorEvent.getError());
384
394
  adPlaying = false;
385
395
  video.muted = originalMutedState;
386
- if (adContainerEl) adContainerEl.style.pointerEvents = "none";
396
+ if (adContainerEl) {
397
+ adContainerEl.style.pointerEvents = "none";
398
+ adContainerEl.style.display = "none";
399
+ console.log("[IMA] Ad container hidden after loader error");
400
+ }
387
401
  if (!options?.continueLiveStreamDuringAds) {
388
- video.play().catch(() => {
389
- });
402
+ if (video.paused) {
403
+ console.log("[IMA] Resuming paused video after loader error");
404
+ video.play().catch(() => {
405
+ });
406
+ }
390
407
  }
391
408
  if (adsLoadedReject) {
392
409
  adsLoadedReject(new Error("Ads loader error"));
@@ -963,15 +980,25 @@ var StormcloudVideoPlayer = class {
963
980
  if (this.config.debugAdTiming) {
964
981
  console.log("[StormcloudVideoPlayer] IMA ad_error event received");
965
982
  }
966
- if (!this.inAdBreak) return;
967
- const remaining = this.getRemainingAdMs();
968
- if (remaining > 500 && this.adPodQueue.length > 0) {
969
- const next = this.adPodQueue.shift();
970
- this.currentAdIndex++;
971
- this.playSingleAd(next).catch(() => {
972
- });
973
- } else {
974
- this.handleAdFailure();
983
+ if (this.showAds) {
984
+ if (this.inAdBreak) {
985
+ const remaining = this.getRemainingAdMs();
986
+ if (remaining > 500 && this.adPodQueue.length > 0) {
987
+ const next = this.adPodQueue.shift();
988
+ this.currentAdIndex++;
989
+ this.playSingleAd(next).catch(() => {
990
+ });
991
+ } else {
992
+ this.handleAdFailure();
993
+ }
994
+ } else {
995
+ if (this.config.debugAdTiming) {
996
+ console.log(
997
+ "[StormcloudVideoPlayer] Ad error before ad break established - cleaning up"
998
+ );
999
+ }
1000
+ this.handleAdFailure();
1001
+ }
975
1002
  }
976
1003
  });
977
1004
  this.ima.on("content_pause", () => {
@@ -1552,9 +1579,20 @@ var StormcloudVideoPlayer = class {
1552
1579
  return;
1553
1580
  }
1554
1581
  if (vastTagUrl) {
1582
+ this.inAdBreak = true;
1555
1583
  this.showAds = true;
1556
1584
  this.currentAdIndex++;
1557
- await this.playSingleAd(vastTagUrl);
1585
+ try {
1586
+ await this.playSingleAd(vastTagUrl);
1587
+ } catch (error) {
1588
+ if (this.config.debugAdTiming) {
1589
+ console.error(
1590
+ "[StormcloudVideoPlayer] Ad playback failed in handleAdStart:",
1591
+ error
1592
+ );
1593
+ }
1594
+ this.handleAdFailure();
1595
+ }
1558
1596
  }
1559
1597
  if (this.expectedAdBreakDurationMs == null && scheduled?.durationMs != null) {
1560
1598
  this.expectedAdBreakDurationMs = scheduled.durationMs;
@@ -1685,7 +1723,13 @@ var StormcloudVideoPlayer = class {
1685
1723
  handleAdFailure() {
1686
1724
  if (this.config.debugAdTiming) {
1687
1725
  console.log(
1688
- "[StormcloudVideoPlayer] Handling ad failure - resuming content"
1726
+ "[StormcloudVideoPlayer] Handling ad failure - resuming content",
1727
+ {
1728
+ inAdBreak: this.inAdBreak,
1729
+ showAds: this.showAds,
1730
+ videoPaused: this.video.paused,
1731
+ adPlaying: this.ima.isAdPlaying()
1732
+ }
1689
1733
  );
1690
1734
  }
1691
1735
  this.inAdBreak = false;
@@ -1706,13 +1750,21 @@ var StormcloudVideoPlayer = class {
1706
1750
  );
1707
1751
  }
1708
1752
  if (this.video.paused) {
1709
- this.video.play()?.catch(() => {
1753
+ if (this.config.debugAdTiming) {
1754
+ console.log("[StormcloudVideoPlayer] Resuming paused video");
1755
+ }
1756
+ this.video.play()?.catch((error) => {
1710
1757
  if (this.config.debugAdTiming) {
1711
1758
  console.error(
1712
- "[StormcloudVideoPlayer] Failed to resume video after ad failure"
1759
+ "[StormcloudVideoPlayer] Failed to resume video after ad failure:",
1760
+ error
1713
1761
  );
1714
1762
  }
1715
1763
  });
1764
+ } else {
1765
+ if (this.config.debugAdTiming) {
1766
+ console.log("[StormcloudVideoPlayer] Video is already playing, no resume needed");
1767
+ }
1716
1768
  }
1717
1769
  }
1718
1770
  startAdFailsafeTimer() {
@@ -1724,10 +1776,12 @@ var StormcloudVideoPlayer = class {
1724
1776
  );
1725
1777
  }
1726
1778
  this.adFailsafeTimerId = window.setTimeout(() => {
1727
- if (this.video.paused) {
1779
+ const shouldTrigger = this.video.paused || this.showAds && !this.ima.isAdPlaying();
1780
+ if (shouldTrigger) {
1728
1781
  if (this.config.debugAdTiming) {
1729
1782
  console.warn(
1730
- "[StormcloudVideoPlayer] Failsafe timer triggered - forcing video resume"
1783
+ "[StormcloudVideoPlayer] Failsafe timer triggered - forcing video resume",
1784
+ { paused: this.video.paused, showAds: this.showAds, adPlaying: this.ima.isAdPlaying() }
1731
1785
  );
1732
1786
  }
1733
1787
  this.handleAdFailure();