stormcloud-video-player 0.2.33 → 0.2.35

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.
@@ -222,7 +222,7 @@ function createImaController(video, options) {
222
222
  video.muted = true;
223
223
  video.volume = 0;
224
224
  contentVideoHidden = true;
225
- console.log("[IMA] Content video hidden and muted");
225
+ console.log("[DEBUG-LAYER] \u{1F534} Content video HIDDEN | muted=true, volume=0");
226
226
  }
227
227
  }
228
228
  function showContentVideo() {
@@ -235,7 +235,7 @@ function createImaController(video, options) {
235
235
  video.volume = originalVolume;
236
236
  contentVideoHidden = false;
237
237
  console.log(
238
- `[IMA] Content video restored (muted: ${originalMutedState}, volume: ${originalVolume})`
238
+ `[DEBUG-LAYER] \u{1F7E2} Content video RESTORED | muted=${originalMutedState}, volume=${originalVolume}`
239
239
  );
240
240
  }
241
241
  }
@@ -257,12 +257,12 @@ function createImaController(video, options) {
257
257
  "canplay",
258
258
  () => {
259
259
  adVideo.style.opacity = "1";
260
- console.log("[IMA] Ad video ready to play");
260
+ console.log("[DEBUG-LAYER] \u{1F4FA} Ad video element ready (canplay fired)");
261
261
  },
262
262
  { once: true }
263
263
  );
264
264
  console.log(
265
- `[IMA] Created dedicated ad video element with volume: ${adVideo.volume}, muted: ${adVideo.muted}`
265
+ `[DEBUG-AUDIO] \u{1F50A} Ad video created | volume=${adVideo.volume}, muted=${adVideo.muted}`
266
266
  );
267
267
  return adVideo;
268
268
  }
@@ -348,17 +348,12 @@ function createImaController(video, options) {
348
348
  let adsLoadedResolve;
349
349
  let adsLoadedReject;
350
350
  function makeAdsRequest(google, vastTagUrl) {
351
- console.log("[IMA] \u{1F4CB} === makeAdsRequest() - Building IMA request ===");
352
351
  const adsRequest = new google.ima.AdsRequest();
353
352
  const preloadedResponse = preloadedVast.get(vastTagUrl);
354
353
  if (preloadedResponse) {
355
354
  adsRequest.adsResponse = preloadedResponse;
356
- console.log(
357
- "[IMA] \u26A1 Using preloaded VAST response for immediate ad request"
358
- );
359
355
  } else {
360
356
  adsRequest.adTagUrl = vastTagUrl;
361
- console.log("[IMA] \u{1F310} Will fetch VAST from URL:", vastTagUrl);
362
357
  }
363
358
  const videoWidth = video.offsetWidth || video.clientWidth || 640;
364
359
  const videoHeight = video.offsetHeight || video.clientHeight || 360;
@@ -370,7 +365,6 @@ function createImaController(video, options) {
370
365
  try {
371
366
  const willAutoPlay = !video.paused || video.autoplay;
372
367
  adsRequest.setAdWillAutoPlay(willAutoPlay);
373
- console.log(`[IMA] Ad will autoplay: ${willAutoPlay}`);
374
368
  } catch (error) {
375
369
  console.warn("[IMA] Failed to call setAdWillAutoPlay:", error);
376
370
  }
@@ -379,17 +373,12 @@ function createImaController(video, options) {
379
373
  try {
380
374
  const willPlayMuted = video.muted || video.volume === 0;
381
375
  adsRequest.setAdWillPlayMuted(willPlayMuted);
382
- console.log(`[IMA] Ad will play muted: ${willPlayMuted}`);
383
376
  } catch (error) {
384
377
  console.warn("[IMA] Failed to call setAdWillPlayMuted:", error);
385
378
  }
386
379
  }
387
380
  adsRequest.vastLoadTimeout = 5e3;
388
- console.log(`[IMA] \u{1F4D0} Ads request dimensions: ${videoWidth}x${videoHeight}`);
389
- console.log("[IMA] \u23F1\uFE0F VAST load timeout: 5000ms");
390
- console.log("[IMA] \u{1F680} Calling adsLoader.requestAds()...");
391
381
  adsLoader.requestAds(adsRequest);
392
- console.log("[IMA] \u23F3 Waiting for ADS_MANAGER_LOADED or AD_ERROR event...");
393
382
  if (preloadedResponse) {
394
383
  preloadedVast.delete(vastTagUrl);
395
384
  }
@@ -574,85 +563,29 @@ function createImaController(video, options) {
574
563
  adsLoader.addEventListener(
575
564
  google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,
576
565
  (evt) => {
577
- console.log("[IMA] \u2705 ADS_MANAGER_LOADED - Ads fetched successfully!");
578
- console.log("[IMA] Setting up ads manager with preloading enabled");
579
- console.log("[IMA] ========================================");
580
- console.log("[IMA] EXPECTED EVENT FLOW:");
581
- console.log("[IMA] 1. requestAds() \u2192 fetch VAST");
582
- console.log("[IMA] 2. ADS_MANAGER_LOADED \u2192 ads ready");
583
- console.log("[IMA] 3. play() \u2192 start playback");
584
- console.log("[IMA] 4. CONTENT_PAUSE_REQUESTED \u2192 show ad layer \u2728");
585
- console.log("[IMA] 5. STARTED \u2192 ad is playing");
586
- console.log("[IMA] 6. CONTENT_RESUME_REQUESTED \u2192 ad done");
587
- console.log("[IMA] 7. ALL_ADS_COMPLETED \u2192 hide ad layer");
588
- console.log("[IMA] ========================================");
566
+ console.log("[DEBUG-FLOW] \u2705 ADS_MANAGER_LOADED - Setting up manager");
589
567
  try {
590
568
  const adsRenderingSettings = new google.ima.AdsRenderingSettings();
591
569
  adsRenderingSettings.enablePreloading = true;
592
570
  adsManager = evt.getAdsManager(video, adsRenderingSettings);
593
571
  const AdEvent = google.ima.AdEvent.Type;
594
572
  const AdErrorEvent = google.ima.AdErrorEvent.Type;
595
- console.log("[IMA] ========== IMA EVENT LOGGING ENABLED ==========");
596
- console.log("[IMA] All IMA SDK events will be logged below");
597
- const allAdEvents = [
598
- "AD_BREAK_READY",
599
- "AD_METADATA",
600
- "ALL_ADS_COMPLETED",
601
- "CLICK",
602
- "COMPLETE",
603
- "CONTENT_PAUSE_REQUESTED",
604
- "CONTENT_RESUME_REQUESTED",
605
- "DURATION_CHANGE",
606
- "FIRST_QUARTILE",
607
- "IMPRESSION",
608
- "INTERACTION",
609
- "LINEAR_CHANGED",
610
- "LOADED",
611
- "LOG",
612
- "MIDPOINT",
613
- "PAUSED",
614
- "RESUMED",
615
- "SKIPPABLE_STATE_CHANGED",
616
- "SKIPPED",
617
- "STARTED",
618
- "THIRD_QUARTILE",
619
- "USER_CLOSE",
620
- "VOLUME_CHANGED",
621
- "VOLUME_MUTED"
622
- ];
623
- allAdEvents.forEach((eventType) => {
573
+ const keyEvents = ["STARTED", "COMPLETE", "CONTENT_PAUSE_REQUESTED", "CONTENT_RESUME_REQUESTED", "ALL_ADS_COMPLETED"];
574
+ keyEvents.forEach((eventType) => {
624
575
  if (AdEvent[eventType]) {
625
576
  adsManager.addEventListener(AdEvent[eventType], (e) => {
626
- var _a, _b, _c, _d, _e, _f;
577
+ var _a, _b;
627
578
  const ad = (_a = e.getAd) == null ? void 0 : _a.call(e);
628
- const adData = ad ? {
629
- adId: (_b = ad.getAdId) == null ? void 0 : _b.call(ad),
630
- title: (_c = ad.getTitle) == null ? void 0 : _c.call(ad),
631
- duration: (_d = ad.getDuration) == null ? void 0 : _d.call(ad),
632
- isLinear: (_e = ad.isLinear) == null ? void 0 : _e.call(ad),
633
- contentType: (_f = ad.getContentType) == null ? void 0 : _f.call(ad)
634
- } : null;
635
- console.log(`[IMA EVENT] ${eventType}`, {
636
- eventType,
637
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
638
- adData
639
- });
579
+ console.log(`[DEBUG-FLOW] \u{1F3AC} ${eventType} | title=${((_b = ad == null ? void 0 : ad.getTitle) == null ? void 0 : _b.call(ad)) || "N/A"}`);
640
580
  });
641
581
  }
642
582
  });
643
- console.log("[IMA] ========== EVENT LISTENERS ATTACHED ==========");
644
583
  adsManager.addEventListener(
645
584
  AdErrorEvent.AD_ERROR,
646
585
  (errorEvent) => {
647
- var _a, _b, _c, _d, _e, _f;
586
+ var _a, _b;
648
587
  const error = errorEvent.getError();
649
- console.error("[IMA] \u274C AD_ERROR Event:", {
650
- message: (_a = error.getMessage) == null ? void 0 : _a.call(error),
651
- errorCode: (_b = error.getErrorCode) == null ? void 0 : _b.call(error),
652
- type: (_c = error.getType) == null ? void 0 : _c.call(error),
653
- vastErrorCode: (_d = error.getVastErrorCode) == null ? void 0 : _d.call(error),
654
- innerError: (_e = error.getInnerError) == null ? void 0 : _e.call(error)
655
- });
588
+ console.error("[DEBUG-ERROR] \u274C AD_ERROR:", (_a = error.getMessage) == null ? void 0 : _a.call(error));
656
589
  destroyAdsManager();
657
590
  adPlaying = false;
658
591
  setAdPlayingFlag(false);
@@ -663,7 +596,7 @@ function createImaController(video, options) {
663
596
  if (adContainerEl) {
664
597
  adContainerEl.style.pointerEvents = "none";
665
598
  adContainerEl.style.display = "none";
666
- console.log("[IMA] Ad container hidden after error");
599
+ console.log("[DEBUG-LAYER] \u274C Ad container HIDDEN (error)");
667
600
  }
668
601
  }, 300);
669
602
  }
@@ -675,9 +608,6 @@ function createImaController(video, options) {
675
608
  }
676
609
  if (lastAdTagUrl && retryAttempts < maxRetries) {
677
610
  const delay = backoffBaseMs * Math.pow(2, retryAttempts++);
678
- console.log(
679
- `[IMA] Retrying ad request in ${delay}ms (attempt ${retryAttempts})`
680
- );
681
611
  window.setTimeout(() => {
682
612
  try {
683
613
  makeAdsRequest(google, lastAdTagUrl);
@@ -685,16 +615,10 @@ function createImaController(video, options) {
685
615
  }
686
616
  }, delay);
687
617
  } else {
688
- console.log(
689
- "[IMA] Max retries reached, emitting ad_error"
690
- );
691
618
  emit("ad_error");
692
619
  if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
693
620
  if (video.paused) {
694
- console.log(
695
- "[IMA] Resuming paused video after ad error"
696
- );
697
- (_f = video.play()) == null ? void 0 : _f.catch(() => {
621
+ (_b = video.play()) == null ? void 0 : _b.catch(() => {
698
622
  });
699
623
  }
700
624
  }
@@ -704,15 +628,9 @@ function createImaController(video, options) {
704
628
  adsManager.addEventListener(
705
629
  AdEvent.CONTENT_PAUSE_REQUESTED,
706
630
  () => {
707
- console.log("[IMA] \u2705 CONTENT_PAUSE_REQUESTED - Ad is ready to play!");
708
- console.log("[IMA] This is the event that triggers the ad layer to appear");
631
+ console.log("[DEBUG-FLOW] \u{1F3AF} CONTENT_PAUSE_REQUESTED - Ad starting");
709
632
  if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
710
633
  video.pause();
711
- console.log("[IMA] Content video paused (VOD mode)");
712
- } else {
713
- console.log(
714
- "[IMA] Content video continues in background (Live mode)"
715
- );
716
634
  }
717
635
  hideContentVideo();
718
636
  if (adContainerEl) {
@@ -721,23 +639,22 @@ function createImaController(video, options) {
721
639
  adContainerEl.style.backgroundColor = "#000";
722
640
  adContainerEl.offsetHeight;
723
641
  adContainerEl.style.opacity = "1";
724
- console.log("[IMA] \u2728 Ad container NOW VISIBLE (after content pause)");
642
+ console.log("[DEBUG-LAYER] \u{1F7E1} Ad container VISIBLE");
725
643
  }
726
644
  adPlaying = true;
727
645
  setAdPlayingFlag(true);
728
- console.log("[IMA] Emitting 'content_pause' event to player");
729
646
  emit("content_pause");
730
647
  }
731
648
  );
732
649
  adsManager.addEventListener(AdEvent.STARTED, () => {
733
- console.log("[IMA] \u25B6\uFE0F STARTED - Ad playback has begun");
650
+ console.log("[DEBUG-FLOW] \u25B6\uFE0F STARTED - Ad playing now");
734
651
  setAdPlayingFlag(true);
735
652
  hideContentVideo();
736
653
  if (adVideoElement) {
737
654
  adVideoElement.volume = originalMutedState ? 0 : originalVolume;
738
655
  adVideoElement.muted = originalMutedState;
739
656
  console.log(
740
- `[IMA] Ad video volume: ${adVideoElement.volume}, muted: ${adVideoElement.muted}`
657
+ `[DEBUG-AUDIO] \u{1F50A} Ad audio set | volume=${adVideoElement.volume}, muted=${adVideoElement.muted}`
741
658
  );
742
659
  }
743
660
  if (adContainerEl) {
@@ -746,21 +663,20 @@ function createImaController(video, options) {
746
663
  adContainerEl.style.backgroundColor = "#000";
747
664
  adContainerEl.offsetHeight;
748
665
  adContainerEl.style.opacity = "1";
749
- console.log("[IMA] Ad container now visible (STARTED event)");
750
666
  }
751
667
  });
752
668
  adsManager.addEventListener(
753
669
  AdEvent.CONTENT_RESUME_REQUESTED,
754
670
  () => {
755
- console.log("[IMA] \u23F8\uFE0F CONTENT_RESUME_REQUESTED - Single ad completed");
671
+ console.log("[DEBUG-FLOW] \u23F8\uFE0F CONTENT_RESUME - Single ad done");
756
672
  adPlaying = false;
757
673
  setAdPlayingFlag(false);
758
- console.log("[IMA] Emitting 'content_resume' event to player");
674
+ console.log("[DEBUG-LAYER] \u26A0\uFE0F Waiting for pod manager (more ads, placeholder, or done)");
759
675
  emit("content_resume");
760
676
  }
761
677
  );
762
678
  adsManager.addEventListener(AdEvent.ALL_ADS_COMPLETED, () => {
763
- console.log("[IMA] \u{1F3C1} ALL_ADS_COMPLETED - All ads in break finished");
679
+ console.log("[DEBUG-FLOW] \u{1F3C1} ALL_ADS_COMPLETED - Pod finished");
764
680
  adPlaying = false;
765
681
  setAdPlayingFlag(false);
766
682
  if (adContainerEl) {
@@ -770,18 +686,16 @@ function createImaController(video, options) {
770
686
  if (adContainerEl) {
771
687
  adContainerEl.style.pointerEvents = "none";
772
688
  adContainerEl.style.display = "none";
773
- console.log("[IMA] \u{1F648} Ad container hidden (ALL_ADS_COMPLETED)");
689
+ console.log("[DEBUG-LAYER] \u26AB Ad container HIDDEN (pod done)");
774
690
  }
775
691
  }, 300);
776
692
  }
777
693
  showContentVideo();
778
694
  if (!(options == null ? void 0 : options.continueLiveStreamDuringAds) && video.paused) {
779
- console.log("[IMA] Resuming content video playback");
780
695
  video.play().catch((e) => {
781
- console.warn("[IMA] Failed to resume content video:", e);
696
+ console.warn("[DEBUG-ERROR] Failed to resume video:", e);
782
697
  });
783
698
  }
784
- console.log("[IMA] Emitting 'all_ads_completed' event to player");
785
699
  emit("all_ads_completed");
786
700
  });
787
701
  console.log("[IMA] Ads manager event listeners attached");
@@ -801,18 +715,12 @@ function createImaController(video, options) {
801
715
  if (adContainerEl) {
802
716
  adContainerEl.style.pointerEvents = "none";
803
717
  adContainerEl.style.display = "none";
804
- console.log(
805
- "[IMA] Ad container hidden after setup error"
806
- );
807
718
  }
808
719
  }, 300);
809
720
  }
810
721
  showContentVideo();
811
722
  if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
812
723
  if (video.paused) {
813
- console.log(
814
- "[IMA] Resuming paused video after setup error"
815
- );
816
724
  video.play().catch(() => {
817
725
  });
818
726
  }
@@ -830,17 +738,9 @@ function createImaController(video, options) {
830
738
  adsLoader.addEventListener(
831
739
  google.ima.AdErrorEvent.Type.AD_ERROR,
832
740
  (adErrorEvent) => {
833
- var _a, _b, _c, _d;
741
+ var _a;
834
742
  const error = adErrorEvent.getError();
835
- console.error("[IMA] \u274C ADS_LOADER ERROR - Ad request failed!", {
836
- message: (_a = error.getMessage) == null ? void 0 : _a.call(error),
837
- errorCode: (_b = error.getErrorCode) == null ? void 0 : _b.call(error),
838
- type: (_c = error.getType) == null ? void 0 : _c.call(error),
839
- vastErrorCode: (_d = error.getVastErrorCode) == null ? void 0 : _d.call(error)
840
- });
841
- console.error("[IMA] This means the ad server didn't return valid ads");
842
- console.error("[IMA] Ad layer will NOT appear (no flicker)");
843
- console.error("[IMA] Full error object:", adErrorEvent.getError());
743
+ console.error("[DEBUG-ERROR] \u274C ADS_LOADER ERROR:", (_a = error.getMessage) == null ? void 0 : _a.call(error));
844
744
  adPlaying = false;
845
745
  setAdPlayingFlag(false);
846
746
  if (adContainerEl) {
@@ -850,14 +750,12 @@ function createImaController(video, options) {
850
750
  if (adContainerEl) {
851
751
  adContainerEl.style.pointerEvents = "none";
852
752
  adContainerEl.style.display = "none";
853
- console.log("[IMA] Ad container hidden after loader error");
854
753
  }
855
754
  }, 300);
856
755
  }
857
756
  showContentVideo();
858
757
  if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
859
758
  if (video.paused) {
860
- console.log("[IMA] Resuming paused video after loader error");
861
759
  video.play().catch(() => {
862
760
  });
863
761
  }
@@ -872,10 +770,7 @@ function createImaController(video, options) {
872
770
  false
873
771
  );
874
772
  }
875
- console.log("[IMA] \u{1F680} Making ads request to IMA SDK");
876
- console.log("[IMA] Waiting for IMA SDK response (LOADED or ERROR event)...");
877
773
  makeAdsRequest(google, vastTagUrl);
878
- console.log("[IMA] \u23F3 Returning promise that will resolve when ads are loaded");
879
774
  return adsLoadedPromise;
880
775
  } catch (error) {
881
776
  console.error("[IMA] Failed to request ads:", error);
@@ -913,23 +808,16 @@ function createImaController(video, options) {
913
808
  },
914
809
  async play() {
915
810
  var _a, _b;
916
- console.log("[IMA] \u25B6\uFE0F === play() called ===");
917
- console.log("[IMA] This initializes and starts the ad");
918
- console.log("[IMA] Ad layer will appear when CONTENT_PAUSE_REQUESTED fires");
811
+ console.log("[DEBUG-FLOW] \u25B6\uFE0F play() - Starting ad playback");
919
812
  if (!((_a = window.google) == null ? void 0 : _a.ima) || !adDisplayContainer) {
920
- console.warn(
921
- "[IMA] \u274C Cannot play ad: IMA SDK or ad container not available"
922
- );
923
813
  return Promise.reject(new Error("IMA SDK not available"));
924
814
  }
925
815
  if (!adsManager) {
926
- console.warn("[IMA] \u274C Cannot play ad: No ads manager available");
927
816
  return Promise.reject(new Error("No ads manager"));
928
817
  }
929
818
  try {
930
819
  const width = video.clientWidth || 640;
931
820
  const height = video.clientHeight || 360;
932
- console.log(`[IMA] \u{1F3AC} Initializing ads manager (${width}x${height})`);
933
821
  adsManager.init(width, height, window.google.ima.ViewMode.NORMAL);
934
822
  adPlaying = true;
935
823
  const adVolume = originalMutedState ? 0 : originalVolume;
@@ -937,22 +825,18 @@ function createImaController(video, options) {
937
825
  adVideoElement.volume = adVolume;
938
826
  adVideoElement.muted = originalMutedState;
939
827
  console.log(
940
- `[IMA] \u{1F50A} Set dedicated ad video volume to ${adVolume}, muted: ${originalMutedState}`
828
+ `[DEBUG-AUDIO] \u{1F50A} Pre-start ad audio | volume=${adVolume}, muted=${originalMutedState}`
941
829
  );
942
830
  }
943
831
  try {
944
832
  adsManager.setVolume(adVolume);
945
- console.log(`[IMA] Set IMA manager volume to ${adVolume}`);
946
833
  } catch (error) {
947
- console.warn("[IMA] Failed to set IMA manager volume:", error);
834
+ console.warn("[DEBUG-ERROR] Failed to set IMA manager volume:", error);
948
835
  }
949
- console.log("[IMA] \u{1F3AF} Calling adsManager.start()");
950
- console.log("[IMA] If successful, IMA will fire CONTENT_PAUSE_REQUESTED");
951
836
  adsManager.start();
952
- console.log("[IMA] \u2705 play() completed successfully");
953
837
  return Promise.resolve();
954
838
  } catch (error) {
955
- console.error("[IMA] \u274C Error starting ad playback:", error);
839
+ console.error("[DEBUG-ERROR] \u274C Error starting ad:", error);
956
840
  adPlaying = false;
957
841
  setAdPlayingFlag(false);
958
842
  if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
@@ -964,7 +848,7 @@ function createImaController(video, options) {
964
848
  },
965
849
  async stop() {
966
850
  var _a;
967
- console.log("[IMA] Stopping ad playback");
851
+ console.log("[DEBUG-FLOW] \u23F9\uFE0F stop() - Stopping ad playback");
968
852
  adPlaying = false;
969
853
  setAdPlayingFlag(false);
970
854
  if (adContainerEl) {
@@ -974,7 +858,7 @@ function createImaController(video, options) {
974
858
  if (adContainerEl) {
975
859
  adContainerEl.style.pointerEvents = "none";
976
860
  adContainerEl.style.display = "none";
977
- console.log("[IMA] Ad container hidden after stop");
861
+ console.log("[DEBUG-LAYER] \u26AB Ad container HIDDEN (stop)");
978
862
  }
979
863
  }, 300);
980
864
  }
@@ -1045,7 +929,7 @@ function createImaController(video, options) {
1045
929
  updateOriginalMutedState(muted, volume) {
1046
930
  const nextVolume = typeof volume === "number" && !Number.isNaN(volume) ? Math.max(0, Math.min(1, volume)) : originalVolume;
1047
931
  console.log(
1048
- `[IMA] updateOriginalMutedState called: { muted: ${originalMutedState} -> ${muted}, volume: ${originalVolume} -> ${nextVolume} }`
932
+ `[DEBUG-AUDIO] \u{1F4BE} Saved original state | muted: ${originalMutedState}->${muted}, volume: ${originalVolume}->${nextVolume}`
1049
933
  );
1050
934
  originalMutedState = muted;
1051
935
  originalVolume = nextVolume;
@@ -1062,14 +946,14 @@ function createImaController(video, options) {
1062
946
  adVideoElement.volume = clampedVolume;
1063
947
  adVideoElement.muted = clampedVolume === 0;
1064
948
  console.log(
1065
- `[IMA] Set dedicated ad video volume to ${clampedVolume}, muted: ${clampedVolume === 0}`
949
+ `[DEBUG-AUDIO] \u{1F50A} Ad volume changed | volume=${clampedVolume}, muted=${clampedVolume === 0}`
1066
950
  );
1067
951
  }
1068
952
  if (adsManager && adPlaying) {
1069
953
  try {
1070
954
  adsManager.setVolume(clampedVolume);
1071
955
  } catch (error) {
1072
- console.warn("[IMA] Failed to set IMA manager volume:", error);
956
+ console.warn("[DEBUG-ERROR] Failed to set IMA manager volume:", error);
1073
957
  }
1074
958
  }
1075
959
  },
@@ -2280,6 +2164,10 @@ var StormcloudVideoPlayer = class {
2280
2164
  this.vastToMediaUrlMap = /* @__PURE__ */ new Map();
2281
2165
  this.preloadedMediaUrls = /* @__PURE__ */ new Set();
2282
2166
  this.preloadingMediaUrls = /* @__PURE__ */ new Set();
2167
+ this.adRequestTokenCounter = 0;
2168
+ this.activeAdRequestToken = null;
2169
+ this.adRequestWatchdogToken = null;
2170
+ this.adFailsafeToken = null;
2283
2171
  initializePolyfills();
2284
2172
  const browserOverrides = getBrowserConfigOverrides();
2285
2173
  this.config = { ...config, ...browserOverrides };
@@ -2551,71 +2439,50 @@ var StormcloudVideoPlayer = class {
2551
2439
  }
2552
2440
  });
2553
2441
  this.ima.on("ad_error", () => {
2554
- if (this.config.debugAdTiming) {
2555
- console.log("[StormcloudVideoPlayer] IMA ad_error event received", {
2556
- showAds: this.showAds,
2557
- inAdBreak: this.inAdBreak,
2558
- remainingAds: this.adPodQueue.length
2559
- });
2560
- }
2442
+ const remaining = this.getRemainingAdMs();
2443
+ console.log(
2444
+ `[DEBUG-POD] \u274C ad_error event | inBreak=${this.inAdBreak}, queue=${this.adPodQueue.length}, remaining=${remaining}ms`
2445
+ );
2561
2446
  if (this.inAdBreak) {
2562
- const remaining = this.getRemainingAdMs();
2563
2447
  if (remaining > 500 && this.adPodQueue.length > 0) {
2564
2448
  const nextPreloaded = this.findNextPreloadedAd();
2565
2449
  if (nextPreloaded) {
2566
2450
  this.currentAdIndex++;
2567
- if (this.config.debugAdTiming) {
2568
- console.log(
2569
- `[StormcloudVideoPlayer] Skipping to next preloaded ad after error`
2570
- );
2571
- }
2451
+ console.log(
2452
+ `[DEBUG-POD] \u27A1\uFE0F Trying next ad after error (${this.currentAdIndex}/${this.totalAdsInBreak})`
2453
+ );
2572
2454
  this.playSingleAd(nextPreloaded).catch(() => {
2573
2455
  this.handleAdFailure();
2574
2456
  });
2575
2457
  } else {
2576
- if (this.config.debugAdTiming) {
2577
- console.log(
2578
- "[StormcloudVideoPlayer] No preloaded ads available, ending ad break"
2579
- );
2580
- }
2458
+ console.log("[DEBUG-POD] \u26A0\uFE0F No more preloaded ads - calling handleAdFailure");
2581
2459
  this.handleAdFailure();
2582
2460
  }
2583
2461
  } else {
2462
+ console.log("[DEBUG-POD] \u26A0\uFE0F No more ads or time - calling handleAdFailure");
2584
2463
  this.handleAdFailure();
2585
2464
  }
2586
2465
  } else {
2587
- if (this.config.debugAdTiming) {
2588
- console.log(
2589
- "[StormcloudVideoPlayer] Ad error before ad break established - cleaning up"
2590
- );
2591
- }
2466
+ console.log("[DEBUG-POD] \u26A0\uFE0F Error before ad break established");
2592
2467
  this.handleAdFailure();
2593
2468
  }
2594
2469
  });
2595
2470
  this.ima.on("content_pause", () => {
2596
- if (this.config.debugAdTiming) {
2597
- console.log("[StormcloudVideoPlayer] IMA content_pause event received");
2598
- }
2471
+ console.log(`[DEBUG-POD] \u{1F3AF} content_pause | ad ${this.currentAdIndex}/${this.totalAdsInBreak}, queue=${this.adPodQueue.length}`);
2599
2472
  this.clearAdFailsafeTimer();
2473
+ this.clearAdRequestWatchdog();
2474
+ this.activeAdRequestToken = null;
2475
+ this.showAds = true;
2600
2476
  this.enforceAdHoldState();
2601
2477
  });
2602
2478
  this.ima.on("content_resume", () => {
2603
- if (this.config.debugAdTiming) {
2604
- console.log(
2605
- "[StormcloudVideoPlayer] IMA content_resume event received",
2606
- {
2607
- inAdBreak: this.inAdBreak,
2608
- pendingAds: this.adPodQueue.length
2609
- }
2610
- );
2611
- }
2479
+ console.log(`[DEBUG-POD] \u23F8\uFE0F content_resume | ad ${this.currentAdIndex}/${this.totalAdsInBreak}, queue=${this.adPodQueue.length}, remaining=${this.getRemainingAdMs()}ms`);
2612
2480
  this.clearAdFailsafeTimer();
2481
+ this.clearAdRequestWatchdog();
2482
+ this.activeAdRequestToken = null;
2483
+ this.showAds = false;
2613
2484
  if (!this.inAdBreak) {
2614
- if (this.config.debugAdTiming) {
2615
- console.log(
2616
- "[StormcloudVideoPlayer] Not in ad break - this shouldn't happen during pod"
2617
- );
2618
- }
2485
+ console.warn("[DEBUG-POD] \u26A0\uFE0F Not in ad break - shouldn't happen");
2619
2486
  return;
2620
2487
  }
2621
2488
  const remaining = this.getRemainingAdMs();
@@ -2623,33 +2490,17 @@ var StormcloudVideoPlayer = class {
2623
2490
  const nextPreloaded = this.findNextPreloadedAd();
2624
2491
  if (nextPreloaded) {
2625
2492
  this.currentAdIndex++;
2626
- if (this.config.debugAdTiming) {
2627
- console.log(
2628
- `[StormcloudVideoPlayer] Playing next preloaded ad in pod (${this.currentAdIndex}/${this.totalAdsInBreak}) - layer will stay visible if ad loads`
2629
- );
2630
- }
2493
+ console.log(`[DEBUG-POD] \u27A1\uFE0F Playing next ad ${this.currentAdIndex}/${this.totalAdsInBreak} (preloaded)`);
2631
2494
  this.playSingleAd(nextPreloaded).catch(() => {
2632
- if (this.config.debugAdTiming) {
2633
- console.error(
2634
- "[StormcloudVideoPlayer] Failed to play next ad in pod"
2635
- );
2636
- }
2495
+ console.error("[DEBUG-POD] \u274C Failed to play next ad");
2637
2496
  this.handleAdPodComplete();
2638
2497
  });
2639
2498
  } else {
2640
- if (this.config.debugAdTiming) {
2641
- console.log(
2642
- "[StormcloudVideoPlayer] No preloaded ads available - completing ad break"
2643
- );
2644
- }
2499
+ console.log("[DEBUG-POD] \u26A0\uFE0F No preloaded ads - ending pod");
2645
2500
  this.handleAdPodComplete();
2646
2501
  }
2647
2502
  } else {
2648
- if (this.config.debugAdTiming) {
2649
- console.log(
2650
- "[StormcloudVideoPlayer] No more ads in pod - completing ad break"
2651
- );
2652
- }
2503
+ console.log("[DEBUG-POD] \u2705 Pod complete (no more ads or time expired)");
2653
2504
  this.handleAdPodComplete();
2654
2505
  }
2655
2506
  });
@@ -3224,52 +3075,27 @@ var StormcloudVideoPlayer = class {
3224
3075
  let vastTagUrls = [];
3225
3076
  if (this.apiVastTagUrl) {
3226
3077
  vastTagUrls = [this.apiVastTagUrl];
3227
- if (this.config.debugAdTiming) {
3228
- console.log(
3229
- "[StormcloudVideoPlayer] Using VAST endpoint:",
3230
- this.apiVastTagUrl
3231
- );
3232
- }
3233
3078
  } else if (tags && tags.length > 0) {
3234
3079
  vastTagUrls = tags;
3235
- if (this.config.debugAdTiming) {
3236
- console.log(
3237
- "[StormcloudVideoPlayer] Using scheduled VAST tags (count: " + tags.length + "):",
3238
- tags
3239
- );
3240
- }
3241
3080
  } else {
3242
- if (this.config.debugAdTiming) {
3243
- console.log("[StormcloudVideoPlayer] No VAST tag available for ad");
3244
- }
3081
+ console.log("[DEBUG-POD] \u26A0\uFE0F No VAST tag available");
3245
3082
  return;
3246
3083
  }
3247
3084
  if (vastTagUrls.length > 0) {
3085
+ console.log(`[DEBUG-POD] \u{1F3AF} Starting ad break with ${vastTagUrls.length} ads`);
3248
3086
  this.adPodAllUrls = [...vastTagUrls];
3249
3087
  this.preloadingAdUrls.clear();
3250
3088
  this.vastToMediaUrlMap.clear();
3251
3089
  this.preloadedMediaUrls.clear();
3252
3090
  this.preloadingMediaUrls.clear();
3253
- this.logQueuedAdUrls(this.adPodAllUrls);
3254
- if (this.config.debugAdTiming) {
3255
- console.log(
3256
- `[StormcloudVideoPlayer] Capturing original audio state before ad break:`,
3257
- {
3258
- videoMuted: this.video.muted,
3259
- videoVolume: this.video.volume
3260
- }
3261
- );
3262
- }
3091
+ console.log(
3092
+ `[DEBUG-AUDIO] \u{1F4BE} Capturing original state | muted=${this.video.muted}, volume=${this.video.volume}`
3093
+ );
3263
3094
  this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);
3264
3095
  this.inAdBreak = true;
3265
3096
  this.currentAdIndex = 0;
3266
3097
  this.totalAdsInBreak = vastTagUrls.length;
3267
3098
  this.adPodQueue = [...vastTagUrls];
3268
- if (this.config.debugAdTiming) {
3269
- console.log(
3270
- `[StormcloudVideoPlayer] Starting ad pod with ${vastTagUrls.length} ads - preloading all ads in parallel (ad layer will show after ad loads)`
3271
- );
3272
- }
3273
3099
  this.preloadAllAdsInBackground().catch((error) => {
3274
3100
  if (this.config.debugAdTiming) {
3275
3101
  console.warn(
@@ -3281,12 +3107,7 @@ var StormcloudVideoPlayer = class {
3281
3107
  try {
3282
3108
  await this.playAdPod();
3283
3109
  } catch (error) {
3284
- if (this.config.debugAdTiming) {
3285
- console.error(
3286
- "[StormcloudVideoPlayer] Ad pod playback failed:",
3287
- error
3288
- );
3289
- }
3110
+ console.error("[DEBUG-POD] \u274C Pod playback failed:", error);
3290
3111
  this.handleAdFailure();
3291
3112
  }
3292
3113
  }
@@ -3298,19 +3119,13 @@ var StormcloudVideoPlayer = class {
3298
3119
  }
3299
3120
  async playAdPod() {
3300
3121
  if (this.adPodQueue.length === 0) {
3301
- if (this.config.debugAdTiming) {
3302
- console.log("[StormcloudVideoPlayer] No ads in pod to play");
3303
- }
3122
+ console.log("[DEBUG-POD] \u26A0\uFE0F No ads in pod");
3304
3123
  return;
3305
3124
  }
3306
3125
  await new Promise((resolve) => setTimeout(resolve, 500));
3307
3126
  const firstPreloaded = this.findNextPreloadedAd();
3308
3127
  if (!firstPreloaded) {
3309
- if (this.config.debugAdTiming) {
3310
- console.log(
3311
- "[StormcloudVideoPlayer] No preloaded ads available after waiting, trying first ad anyway"
3312
- );
3313
- }
3128
+ console.log("[DEBUG-POD] \u26A0\uFE0F No preloaded ads after wait, trying first ad");
3314
3129
  const firstAd = this.adPodQueue.shift();
3315
3130
  if (firstAd) {
3316
3131
  this.currentAdIndex++;
@@ -3319,11 +3134,7 @@ var StormcloudVideoPlayer = class {
3319
3134
  return;
3320
3135
  }
3321
3136
  this.currentAdIndex++;
3322
- if (this.config.debugAdTiming) {
3323
- console.log(
3324
- `[StormcloudVideoPlayer] Playing first preloaded ad ${this.currentAdIndex}/${this.totalAdsInBreak}`
3325
- );
3326
- }
3137
+ console.log(`[DEBUG-POD] \u{1F680} Starting pod with ad ${this.currentAdIndex}/${this.totalAdsInBreak}`);
3327
3138
  await this.playSingleAd(firstPreloaded);
3328
3139
  }
3329
3140
  findCurrentOrNextBreak(nowMs) {
@@ -3403,31 +3214,15 @@ var StormcloudVideoPlayer = class {
3403
3214
  const overrunMs = Math.max(0, elapsedSinceStartMs - expectedDurationMs);
3404
3215
  const shouldExtendAdBreak = (adPlaying || pendingAds || this.showAds) && overrunMs < maxExtensionMs;
3405
3216
  if (shouldExtendAdBreak) {
3406
- if (this.config.debugAdTiming) {
3407
- console.log(
3408
- "[StormcloudVideoPlayer] Extending ad break beyond scheduled duration",
3409
- {
3410
- adPlaying,
3411
- pendingAds,
3412
- showAds: this.showAds,
3413
- overrunMs,
3414
- checkIntervalMs,
3415
- maxExtensionMs
3416
- }
3417
- );
3418
- }
3217
+ console.log(
3218
+ `[DEBUG-POD] \u23F3 Extending ad break | elapsed=${elapsedSinceStartMs}ms, expected=${expectedDurationMs}ms, overrun=${overrunMs}ms`
3219
+ );
3419
3220
  this.scheduleAdStopCountdown(checkIntervalMs);
3420
3221
  return;
3421
3222
  }
3422
- if (this.config.debugAdTiming) {
3423
- console.log("[StormcloudVideoPlayer] Ending ad break via timer", {
3424
- adPlaying,
3425
- pendingAds,
3426
- showAds: this.showAds,
3427
- overrunMs,
3428
- maxExtensionMs
3429
- });
3430
- }
3223
+ console.log(
3224
+ `[DEBUG-POD] \u23F1\uFE0F Ad break duration expired | elapsed=${elapsedSinceStartMs}ms, expected=${expectedDurationMs}ms`
3225
+ );
3431
3226
  if (adPlaying) {
3432
3227
  this.ima.stop().catch(() => {
3433
3228
  });
@@ -3460,62 +3255,56 @@ var StormcloudVideoPlayer = class {
3460
3255
  this.ptsDriftEmaMs = this.ptsDriftEmaMs * (1 - alpha) + sampleMs * alpha;
3461
3256
  }
3462
3257
  async playSingleAd(vastTagUrl) {
3463
- if (this.config.debugAdTiming) {
3464
- console.log("[StormcloudVideoPlayer] Attempting to play ad:", vastTagUrl);
3465
- }
3258
+ console.log(`[DEBUG-POD] \u{1F3AC} playSingleAd | url=${vastTagUrl.substring(0, 60)}...`);
3466
3259
  if (this.ima.isAdPlaying()) {
3467
- if (this.config.debugAdTiming) {
3468
- console.warn(
3469
- "[StormcloudVideoPlayer] Ad already playing - skipping new ad request"
3470
- );
3471
- }
3260
+ console.warn("[DEBUG-POD] \u26A0\uFE0F Ad already playing - skipping request");
3472
3261
  return;
3473
3262
  }
3263
+ const requestToken = ++this.adRequestTokenCounter;
3474
3264
  const wasPreloaded = this.ima.hasPreloadedAd(vastTagUrl);
3475
- if (wasPreloaded && this.config.debugAdTiming) {
3476
- console.log(
3477
- `[StormcloudVideoPlayer] IMA SDK preloaded this ad already: ${vastTagUrl}`
3478
- );
3479
- }
3480
- this.startAdFailsafeTimer();
3265
+ this.activeAdRequestToken = requestToken;
3266
+ console.log(`[DEBUG-POD] \u{1F4DD} Request token=${requestToken}, preloaded=${wasPreloaded}`);
3267
+ this.startAdRequestWatchdog(requestToken);
3481
3268
  try {
3482
3269
  await this.ima.requestAds(vastTagUrl);
3270
+ this.clearAdRequestWatchdog();
3271
+ if (this.activeAdRequestToken !== requestToken) {
3272
+ console.warn(`[DEBUG-POD] \u26A0\uFE0F Token mismatch after requestAds (stale request)`);
3273
+ return;
3274
+ }
3483
3275
  try {
3484
- if (this.config.debugAdTiming) {
3485
- console.log(
3486
- "[StormcloudVideoPlayer] Ad request completed, attempting playback (ad layer will show when IMA triggers content pause)"
3487
- );
3488
- }
3276
+ this.startAdFailsafeTimer(requestToken);
3489
3277
  await this.ima.play();
3490
- this.showAds = true;
3491
- if (this.config.debugAdTiming) {
3492
- console.log(
3493
- "[StormcloudVideoPlayer] Ad playback started successfully, showAds = true"
3494
- );
3278
+ if (this.activeAdRequestToken === requestToken) {
3279
+ console.log(`[DEBUG-POD] \u2705 Ad play initiated (token=${requestToken})`);
3280
+ } else {
3281
+ console.warn(`[DEBUG-POD] \u26A0\uFE0F Token mismatch after play (stale request)`);
3495
3282
  }
3496
3283
  } catch (playError) {
3497
- if (this.config.debugAdTiming) {
3498
- console.log(
3499
- "[StormcloudVideoPlayer] No ads available, skipping playback"
3500
- );
3284
+ console.log("[DEBUG-POD] \u26A0\uFE0F No ads available from play()");
3285
+ this.clearAdFailsafeTimer();
3286
+ if (this.activeAdRequestToken === requestToken) {
3287
+ this.activeAdRequestToken = null;
3501
3288
  }
3502
3289
  this.handleAdFailure();
3503
3290
  return;
3504
3291
  }
3505
3292
  } catch (error) {
3506
- if (this.config.debugAdTiming) {
3507
- console.error("[StormcloudVideoPlayer] Ad playback failed:", error);
3293
+ console.error("[DEBUG-POD] \u274C Ad request failed:", error == null ? void 0 : error.message);
3294
+ this.clearAdRequestWatchdog();
3295
+ this.clearAdFailsafeTimer();
3296
+ if (this.activeAdRequestToken === requestToken) {
3297
+ this.activeAdRequestToken = null;
3508
3298
  }
3509
3299
  this.handleAdFailure();
3510
3300
  }
3511
3301
  }
3512
3302
  handleAdPodComplete() {
3513
3303
  var _a;
3514
- if (this.config.debugAdTiming) {
3515
- console.log(
3516
- "[StormcloudVideoPlayer] Handling ad pod completion - resuming content and hiding ad layer"
3517
- );
3518
- }
3304
+ console.log("[DEBUG-POD] \u{1F3C1} handleAdPodComplete - Ending ad break, restoring content");
3305
+ this.clearAdRequestWatchdog();
3306
+ this.clearAdFailsafeTimer();
3307
+ this.activeAdRequestToken = null;
3519
3308
  this.releaseAdHoldState();
3520
3309
  this.preloadingAdUrls.clear();
3521
3310
  this.vastToMediaUrlMap.clear();
@@ -3526,7 +3315,6 @@ var StormcloudVideoPlayer = class {
3526
3315
  this.currentAdBreakStartWallClockMs = void 0;
3527
3316
  this.clearAdStartTimer();
3528
3317
  this.clearAdStopTimer();
3529
- this.clearAdFailsafeTimer();
3530
3318
  this.adPodQueue = [];
3531
3319
  this.adPodAllUrls = [];
3532
3320
  this.showAds = false;
@@ -3538,70 +3326,95 @@ var StormcloudVideoPlayer = class {
3538
3326
  const originalVolume = typeof this.ima.getOriginalVolume === "function" ? this.ima.getOriginalVolume() : this.video.volume;
3539
3327
  this.video.muted = originalMutedState;
3540
3328
  this.video.volume = originalVolume;
3541
- if (this.config.debugAdTiming) {
3542
- console.log(
3543
- `[StormcloudVideoPlayer] Restored main video - muted: ${originalMutedState}, volume: ${this.video.volume}`
3544
- );
3545
- }
3329
+ console.log(
3330
+ `[DEBUG-AUDIO] \u{1F50A} Main video restored | muted=${originalMutedState}, volume=${originalVolume}`
3331
+ );
3546
3332
  if (!this.shouldContinueLiveStreamDuringAds() && this.video.paused) {
3547
- if (this.config.debugAdTiming) {
3548
- console.log("[StormcloudVideoPlayer] Resuming paused video");
3549
- }
3333
+ console.log("[DEBUG-FLOW] \u25B6\uFE0F Resuming main video playback");
3550
3334
  (_a = this.video.play()) == null ? void 0 : _a.catch((error) => {
3551
- if (this.config.debugAdTiming) {
3552
- console.error(
3553
- "[StormcloudVideoPlayer] Failed to resume video:",
3554
- error
3555
- );
3556
- }
3335
+ console.error("[DEBUG-ERROR] Failed to resume video:", error);
3557
3336
  });
3558
3337
  }
3559
3338
  }
3560
3339
  handleAdFailure() {
3561
- if (this.config.debugAdTiming) {
3340
+ const remaining = this.getRemainingAdMs();
3341
+ console.log(
3342
+ `[DEBUG-POD] \u274C handleAdFailure | inBreak=${this.inAdBreak}, showAds=${this.showAds}, remaining=${remaining}ms`
3343
+ );
3344
+ if (remaining > 500 && this.inAdBreak) {
3562
3345
  console.log(
3563
- "[StormcloudVideoPlayer] Handling ad failure - resuming content",
3564
- {
3565
- inAdBreak: this.inAdBreak,
3566
- showAds: this.showAds,
3567
- videoPaused: this.video.paused,
3568
- adPlaying: this.ima.isAdPlaying()
3569
- }
3346
+ `[DEBUG-POD] \u23F3 Ad failed but ${remaining}ms remaining - showing placeholder until duration expires`
3570
3347
  );
3348
+ this.showAds = true;
3349
+ this.ima.showPlaceholder();
3350
+ this.enforceAdHoldState();
3351
+ return;
3571
3352
  }
3353
+ console.log("[DEBUG-POD] \u23F9\uFE0F No remaining time - ending ad break now");
3572
3354
  this.handleAdPodComplete();
3573
3355
  }
3574
- startAdFailsafeTimer() {
3356
+ startAdRequestWatchdog(token) {
3357
+ var _a;
3358
+ this.clearAdRequestWatchdog();
3359
+ const timeoutMs = (_a = this.config.adFailsafeTimeoutMs) != null ? _a : 1e4;
3360
+ this.adRequestWatchdogToken = token;
3361
+ this.adRequestWatchdogId = window.setTimeout(() => {
3362
+ if (this.adRequestWatchdogToken !== token) {
3363
+ return;
3364
+ }
3365
+ this.adRequestWatchdogId = void 0;
3366
+ this.adRequestWatchdogToken = null;
3367
+ if (this.activeAdRequestToken === token) {
3368
+ this.activeAdRequestToken = null;
3369
+ }
3370
+ this.logAdState("ad_request_timeout", { token, timeoutMs });
3371
+ this.handleAdFailure();
3372
+ }, timeoutMs);
3373
+ this.logAdState("ad_request_watchdog_started", { token, timeoutMs });
3374
+ }
3375
+ clearAdRequestWatchdog() {
3376
+ if (this.adRequestWatchdogId != null) {
3377
+ clearTimeout(this.adRequestWatchdogId);
3378
+ this.adRequestWatchdogId = void 0;
3379
+ }
3380
+ if (this.adRequestWatchdogToken != null) {
3381
+ this.logAdState("ad_request_watchdog_cleared", {
3382
+ token: this.adRequestWatchdogToken
3383
+ });
3384
+ this.adRequestWatchdogToken = null;
3385
+ }
3386
+ }
3387
+ startAdFailsafeTimer(token) {
3575
3388
  var _a;
3576
3389
  this.clearAdFailsafeTimer();
3577
3390
  const failsafeMs = (_a = this.config.adFailsafeTimeoutMs) != null ? _a : 1e4;
3578
- if (this.config.debugAdTiming) {
3579
- console.log(
3580
- `[StormcloudVideoPlayer] Starting failsafe timer (${failsafeMs}ms)`
3581
- );
3582
- }
3391
+ this.adFailsafeToken = token;
3583
3392
  this.adFailsafeTimerId = window.setTimeout(() => {
3584
- const shouldTrigger = this.video.paused || this.showAds && !this.ima.isAdPlaying();
3585
- if (shouldTrigger) {
3586
- if (this.config.debugAdTiming) {
3587
- console.warn(
3588
- "[StormcloudVideoPlayer] Failsafe timer triggered - forcing video resume",
3589
- {
3590
- paused: this.video.paused,
3591
- showAds: this.showAds,
3592
- adPlaying: this.ima.isAdPlaying()
3593
- }
3594
- );
3595
- }
3596
- this.handleAdFailure();
3393
+ if (this.adFailsafeToken !== token) {
3394
+ return;
3597
3395
  }
3396
+ this.adFailsafeTimerId = void 0;
3397
+ this.adFailsafeToken = null;
3398
+ if (this.activeAdRequestToken === token) {
3399
+ this.activeAdRequestToken = null;
3400
+ }
3401
+ this.logAdState("ad_failsafe_triggered", {
3402
+ token,
3403
+ failsafeMs,
3404
+ videoPaused: this.video.paused,
3405
+ imaAdPlaying: this.ima.isAdPlaying()
3406
+ });
3407
+ this.handleAdFailure();
3598
3408
  }, failsafeMs);
3409
+ this.logAdState("ad_failsafe_started", { token, failsafeMs });
3599
3410
  }
3600
3411
  clearAdFailsafeTimer() {
3601
3412
  if (this.adFailsafeTimerId != null) {
3602
3413
  clearTimeout(this.adFailsafeTimerId);
3414
+ this.logAdState("ad_failsafe_cleared", { token: this.adFailsafeToken });
3603
3415
  this.adFailsafeTimerId = void 0;
3604
3416
  }
3417
+ this.adFailsafeToken = null;
3605
3418
  }
3606
3419
  selectVastTagsForBreak(b) {
3607
3420
  if (!b || !b.vastTagUrl) return void 0;
@@ -3616,16 +3429,32 @@ var StormcloudVideoPlayer = class {
3616
3429
  }
3617
3430
  console.log("[StormcloudVideoPlayer] ALL ad URLs queued:", urls);
3618
3431
  }
3432
+ logAdState(event, extra = {}) {
3433
+ if (!this.config.debugAdTiming) {
3434
+ return;
3435
+ }
3436
+ console.log("[StormcloudVideoPlayer][AdState]", {
3437
+ event,
3438
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
3439
+ showAds: this.showAds,
3440
+ adPlaying: this.ima.isAdPlaying(),
3441
+ inAdBreak: this.inAdBreak,
3442
+ activeAdRequestToken: this.activeAdRequestToken,
3443
+ ...extra
3444
+ });
3445
+ }
3619
3446
  enforceAdHoldState() {
3620
3447
  this.video.dataset.stormcloudAdPlaying = "true";
3621
3448
  this.video.muted = true;
3622
3449
  this.video.volume = 0;
3450
+ console.log("[DEBUG-LAYER] \u{1F512} Enforced ad hold state (main video muted)");
3623
3451
  if (typeof this.ima.showPlaceholder === "function") {
3624
3452
  this.ima.showPlaceholder();
3625
3453
  }
3626
3454
  }
3627
3455
  releaseAdHoldState() {
3628
3456
  delete this.video.dataset.stormcloudAdPlaying;
3457
+ console.log("[DEBUG-LAYER] \u{1F513} Released ad hold state");
3629
3458
  if (typeof this.ima.hidePlaceholder === "function") {
3630
3459
  this.ima.hidePlaceholder();
3631
3460
  }