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.
@@ -264,7 +264,7 @@ function createImaController(video, options) {
264
264
  video.muted = true;
265
265
  video.volume = 0;
266
266
  contentVideoHidden = true;
267
- console.log("[IMA] Content video hidden and muted");
267
+ console.log("[DEBUG-LAYER] \u{1F534} Content video HIDDEN | muted=true, volume=0");
268
268
  }
269
269
  }
270
270
  function showContentVideo() {
@@ -277,7 +277,7 @@ function createImaController(video, options) {
277
277
  video.volume = originalVolume;
278
278
  contentVideoHidden = false;
279
279
  console.log(
280
- `[IMA] Content video restored (muted: ${originalMutedState}, volume: ${originalVolume})`
280
+ `[DEBUG-LAYER] \u{1F7E2} Content video RESTORED | muted=${originalMutedState}, volume=${originalVolume}`
281
281
  );
282
282
  }
283
283
  }
@@ -299,12 +299,12 @@ function createImaController(video, options) {
299
299
  "canplay",
300
300
  () => {
301
301
  adVideo.style.opacity = "1";
302
- console.log("[IMA] Ad video ready to play");
302
+ console.log("[DEBUG-LAYER] \u{1F4FA} Ad video element ready (canplay fired)");
303
303
  },
304
304
  { once: true }
305
305
  );
306
306
  console.log(
307
- `[IMA] Created dedicated ad video element with volume: ${adVideo.volume}, muted: ${adVideo.muted}`
307
+ `[DEBUG-AUDIO] \u{1F50A} Ad video created | volume=${adVideo.volume}, muted=${adVideo.muted}`
308
308
  );
309
309
  return adVideo;
310
310
  }
@@ -390,17 +390,12 @@ function createImaController(video, options) {
390
390
  let adsLoadedResolve;
391
391
  let adsLoadedReject;
392
392
  function makeAdsRequest(google, vastTagUrl) {
393
- console.log("[IMA] \u{1F4CB} === makeAdsRequest() - Building IMA request ===");
394
393
  const adsRequest = new google.ima.AdsRequest();
395
394
  const preloadedResponse = preloadedVast.get(vastTagUrl);
396
395
  if (preloadedResponse) {
397
396
  adsRequest.adsResponse = preloadedResponse;
398
- console.log(
399
- "[IMA] \u26A1 Using preloaded VAST response for immediate ad request"
400
- );
401
397
  } else {
402
398
  adsRequest.adTagUrl = vastTagUrl;
403
- console.log("[IMA] \u{1F310} Will fetch VAST from URL:", vastTagUrl);
404
399
  }
405
400
  const videoWidth = video.offsetWidth || video.clientWidth || 640;
406
401
  const videoHeight = video.offsetHeight || video.clientHeight || 360;
@@ -412,7 +407,6 @@ function createImaController(video, options) {
412
407
  try {
413
408
  const willAutoPlay = !video.paused || video.autoplay;
414
409
  adsRequest.setAdWillAutoPlay(willAutoPlay);
415
- console.log(`[IMA] Ad will autoplay: ${willAutoPlay}`);
416
410
  } catch (error) {
417
411
  console.warn("[IMA] Failed to call setAdWillAutoPlay:", error);
418
412
  }
@@ -421,17 +415,12 @@ function createImaController(video, options) {
421
415
  try {
422
416
  const willPlayMuted = video.muted || video.volume === 0;
423
417
  adsRequest.setAdWillPlayMuted(willPlayMuted);
424
- console.log(`[IMA] Ad will play muted: ${willPlayMuted}`);
425
418
  } catch (error) {
426
419
  console.warn("[IMA] Failed to call setAdWillPlayMuted:", error);
427
420
  }
428
421
  }
429
422
  adsRequest.vastLoadTimeout = 5e3;
430
- console.log(`[IMA] \u{1F4D0} Ads request dimensions: ${videoWidth}x${videoHeight}`);
431
- console.log("[IMA] \u23F1\uFE0F VAST load timeout: 5000ms");
432
- console.log("[IMA] \u{1F680} Calling adsLoader.requestAds()...");
433
423
  adsLoader.requestAds(adsRequest);
434
- console.log("[IMA] \u23F3 Waiting for ADS_MANAGER_LOADED or AD_ERROR event...");
435
424
  if (preloadedResponse) {
436
425
  preloadedVast.delete(vastTagUrl);
437
426
  }
@@ -616,85 +605,29 @@ function createImaController(video, options) {
616
605
  adsLoader.addEventListener(
617
606
  google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,
618
607
  (evt) => {
619
- console.log("[IMA] \u2705 ADS_MANAGER_LOADED - Ads fetched successfully!");
620
- console.log("[IMA] Setting up ads manager with preloading enabled");
621
- console.log("[IMA] ========================================");
622
- console.log("[IMA] EXPECTED EVENT FLOW:");
623
- console.log("[IMA] 1. requestAds() \u2192 fetch VAST");
624
- console.log("[IMA] 2. ADS_MANAGER_LOADED \u2192 ads ready");
625
- console.log("[IMA] 3. play() \u2192 start playback");
626
- console.log("[IMA] 4. CONTENT_PAUSE_REQUESTED \u2192 show ad layer \u2728");
627
- console.log("[IMA] 5. STARTED \u2192 ad is playing");
628
- console.log("[IMA] 6. CONTENT_RESUME_REQUESTED \u2192 ad done");
629
- console.log("[IMA] 7. ALL_ADS_COMPLETED \u2192 hide ad layer");
630
- console.log("[IMA] ========================================");
608
+ console.log("[DEBUG-FLOW] \u2705 ADS_MANAGER_LOADED - Setting up manager");
631
609
  try {
632
610
  const adsRenderingSettings = new google.ima.AdsRenderingSettings();
633
611
  adsRenderingSettings.enablePreloading = true;
634
612
  adsManager = evt.getAdsManager(video, adsRenderingSettings);
635
613
  const AdEvent = google.ima.AdEvent.Type;
636
614
  const AdErrorEvent = google.ima.AdErrorEvent.Type;
637
- console.log("[IMA] ========== IMA EVENT LOGGING ENABLED ==========");
638
- console.log("[IMA] All IMA SDK events will be logged below");
639
- const allAdEvents = [
640
- "AD_BREAK_READY",
641
- "AD_METADATA",
642
- "ALL_ADS_COMPLETED",
643
- "CLICK",
644
- "COMPLETE",
645
- "CONTENT_PAUSE_REQUESTED",
646
- "CONTENT_RESUME_REQUESTED",
647
- "DURATION_CHANGE",
648
- "FIRST_QUARTILE",
649
- "IMPRESSION",
650
- "INTERACTION",
651
- "LINEAR_CHANGED",
652
- "LOADED",
653
- "LOG",
654
- "MIDPOINT",
655
- "PAUSED",
656
- "RESUMED",
657
- "SKIPPABLE_STATE_CHANGED",
658
- "SKIPPED",
659
- "STARTED",
660
- "THIRD_QUARTILE",
661
- "USER_CLOSE",
662
- "VOLUME_CHANGED",
663
- "VOLUME_MUTED"
664
- ];
665
- allAdEvents.forEach((eventType) => {
615
+ const keyEvents = ["STARTED", "COMPLETE", "CONTENT_PAUSE_REQUESTED", "CONTENT_RESUME_REQUESTED", "ALL_ADS_COMPLETED"];
616
+ keyEvents.forEach((eventType) => {
666
617
  if (AdEvent[eventType]) {
667
618
  adsManager.addEventListener(AdEvent[eventType], (e) => {
668
- var _a, _b, _c, _d, _e, _f;
619
+ var _a, _b;
669
620
  const ad = (_a = e.getAd) == null ? void 0 : _a.call(e);
670
- const adData = ad ? {
671
- adId: (_b = ad.getAdId) == null ? void 0 : _b.call(ad),
672
- title: (_c = ad.getTitle) == null ? void 0 : _c.call(ad),
673
- duration: (_d = ad.getDuration) == null ? void 0 : _d.call(ad),
674
- isLinear: (_e = ad.isLinear) == null ? void 0 : _e.call(ad),
675
- contentType: (_f = ad.getContentType) == null ? void 0 : _f.call(ad)
676
- } : null;
677
- console.log(`[IMA EVENT] ${eventType}`, {
678
- eventType,
679
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
680
- adData
681
- });
621
+ console.log(`[DEBUG-FLOW] \u{1F3AC} ${eventType} | title=${((_b = ad == null ? void 0 : ad.getTitle) == null ? void 0 : _b.call(ad)) || "N/A"}`);
682
622
  });
683
623
  }
684
624
  });
685
- console.log("[IMA] ========== EVENT LISTENERS ATTACHED ==========");
686
625
  adsManager.addEventListener(
687
626
  AdErrorEvent.AD_ERROR,
688
627
  (errorEvent) => {
689
- var _a, _b, _c, _d, _e, _f;
628
+ var _a, _b;
690
629
  const error = errorEvent.getError();
691
- console.error("[IMA] \u274C AD_ERROR Event:", {
692
- message: (_a = error.getMessage) == null ? void 0 : _a.call(error),
693
- errorCode: (_b = error.getErrorCode) == null ? void 0 : _b.call(error),
694
- type: (_c = error.getType) == null ? void 0 : _c.call(error),
695
- vastErrorCode: (_d = error.getVastErrorCode) == null ? void 0 : _d.call(error),
696
- innerError: (_e = error.getInnerError) == null ? void 0 : _e.call(error)
697
- });
630
+ console.error("[DEBUG-ERROR] \u274C AD_ERROR:", (_a = error.getMessage) == null ? void 0 : _a.call(error));
698
631
  destroyAdsManager();
699
632
  adPlaying = false;
700
633
  setAdPlayingFlag(false);
@@ -705,7 +638,7 @@ function createImaController(video, options) {
705
638
  if (adContainerEl) {
706
639
  adContainerEl.style.pointerEvents = "none";
707
640
  adContainerEl.style.display = "none";
708
- console.log("[IMA] Ad container hidden after error");
641
+ console.log("[DEBUG-LAYER] \u274C Ad container HIDDEN (error)");
709
642
  }
710
643
  }, 300);
711
644
  }
@@ -717,9 +650,6 @@ function createImaController(video, options) {
717
650
  }
718
651
  if (lastAdTagUrl && retryAttempts < maxRetries) {
719
652
  const delay = backoffBaseMs * Math.pow(2, retryAttempts++);
720
- console.log(
721
- `[IMA] Retrying ad request in ${delay}ms (attempt ${retryAttempts})`
722
- );
723
653
  window.setTimeout(() => {
724
654
  try {
725
655
  makeAdsRequest(google, lastAdTagUrl);
@@ -727,16 +657,10 @@ function createImaController(video, options) {
727
657
  }
728
658
  }, delay);
729
659
  } else {
730
- console.log(
731
- "[IMA] Max retries reached, emitting ad_error"
732
- );
733
660
  emit("ad_error");
734
661
  if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
735
662
  if (video.paused) {
736
- console.log(
737
- "[IMA] Resuming paused video after ad error"
738
- );
739
- (_f = video.play()) == null ? void 0 : _f.catch(() => {
663
+ (_b = video.play()) == null ? void 0 : _b.catch(() => {
740
664
  });
741
665
  }
742
666
  }
@@ -746,15 +670,9 @@ function createImaController(video, options) {
746
670
  adsManager.addEventListener(
747
671
  AdEvent.CONTENT_PAUSE_REQUESTED,
748
672
  () => {
749
- console.log("[IMA] \u2705 CONTENT_PAUSE_REQUESTED - Ad is ready to play!");
750
- console.log("[IMA] This is the event that triggers the ad layer to appear");
673
+ console.log("[DEBUG-FLOW] \u{1F3AF} CONTENT_PAUSE_REQUESTED - Ad starting");
751
674
  if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
752
675
  video.pause();
753
- console.log("[IMA] Content video paused (VOD mode)");
754
- } else {
755
- console.log(
756
- "[IMA] Content video continues in background (Live mode)"
757
- );
758
676
  }
759
677
  hideContentVideo();
760
678
  if (adContainerEl) {
@@ -763,23 +681,22 @@ function createImaController(video, options) {
763
681
  adContainerEl.style.backgroundColor = "#000";
764
682
  adContainerEl.offsetHeight;
765
683
  adContainerEl.style.opacity = "1";
766
- console.log("[IMA] \u2728 Ad container NOW VISIBLE (after content pause)");
684
+ console.log("[DEBUG-LAYER] \u{1F7E1} Ad container VISIBLE");
767
685
  }
768
686
  adPlaying = true;
769
687
  setAdPlayingFlag(true);
770
- console.log("[IMA] Emitting 'content_pause' event to player");
771
688
  emit("content_pause");
772
689
  }
773
690
  );
774
691
  adsManager.addEventListener(AdEvent.STARTED, () => {
775
- console.log("[IMA] \u25B6\uFE0F STARTED - Ad playback has begun");
692
+ console.log("[DEBUG-FLOW] \u25B6\uFE0F STARTED - Ad playing now");
776
693
  setAdPlayingFlag(true);
777
694
  hideContentVideo();
778
695
  if (adVideoElement) {
779
696
  adVideoElement.volume = originalMutedState ? 0 : originalVolume;
780
697
  adVideoElement.muted = originalMutedState;
781
698
  console.log(
782
- `[IMA] Ad video volume: ${adVideoElement.volume}, muted: ${adVideoElement.muted}`
699
+ `[DEBUG-AUDIO] \u{1F50A} Ad audio set | volume=${adVideoElement.volume}, muted=${adVideoElement.muted}`
783
700
  );
784
701
  }
785
702
  if (adContainerEl) {
@@ -788,21 +705,20 @@ function createImaController(video, options) {
788
705
  adContainerEl.style.backgroundColor = "#000";
789
706
  adContainerEl.offsetHeight;
790
707
  adContainerEl.style.opacity = "1";
791
- console.log("[IMA] Ad container now visible (STARTED event)");
792
708
  }
793
709
  });
794
710
  adsManager.addEventListener(
795
711
  AdEvent.CONTENT_RESUME_REQUESTED,
796
712
  () => {
797
- console.log("[IMA] \u23F8\uFE0F CONTENT_RESUME_REQUESTED - Single ad completed");
713
+ console.log("[DEBUG-FLOW] \u23F8\uFE0F CONTENT_RESUME - Single ad done");
798
714
  adPlaying = false;
799
715
  setAdPlayingFlag(false);
800
- console.log("[IMA] Emitting 'content_resume' event to player");
716
+ console.log("[DEBUG-LAYER] \u26A0\uFE0F Waiting for pod manager (more ads, placeholder, or done)");
801
717
  emit("content_resume");
802
718
  }
803
719
  );
804
720
  adsManager.addEventListener(AdEvent.ALL_ADS_COMPLETED, () => {
805
- console.log("[IMA] \u{1F3C1} ALL_ADS_COMPLETED - All ads in break finished");
721
+ console.log("[DEBUG-FLOW] \u{1F3C1} ALL_ADS_COMPLETED - Pod finished");
806
722
  adPlaying = false;
807
723
  setAdPlayingFlag(false);
808
724
  if (adContainerEl) {
@@ -812,18 +728,16 @@ function createImaController(video, options) {
812
728
  if (adContainerEl) {
813
729
  adContainerEl.style.pointerEvents = "none";
814
730
  adContainerEl.style.display = "none";
815
- console.log("[IMA] \u{1F648} Ad container hidden (ALL_ADS_COMPLETED)");
731
+ console.log("[DEBUG-LAYER] \u26AB Ad container HIDDEN (pod done)");
816
732
  }
817
733
  }, 300);
818
734
  }
819
735
  showContentVideo();
820
736
  if (!(options == null ? void 0 : options.continueLiveStreamDuringAds) && video.paused) {
821
- console.log("[IMA] Resuming content video playback");
822
737
  video.play().catch((e) => {
823
- console.warn("[IMA] Failed to resume content video:", e);
738
+ console.warn("[DEBUG-ERROR] Failed to resume video:", e);
824
739
  });
825
740
  }
826
- console.log("[IMA] Emitting 'all_ads_completed' event to player");
827
741
  emit("all_ads_completed");
828
742
  });
829
743
  console.log("[IMA] Ads manager event listeners attached");
@@ -843,18 +757,12 @@ function createImaController(video, options) {
843
757
  if (adContainerEl) {
844
758
  adContainerEl.style.pointerEvents = "none";
845
759
  adContainerEl.style.display = "none";
846
- console.log(
847
- "[IMA] Ad container hidden after setup error"
848
- );
849
760
  }
850
761
  }, 300);
851
762
  }
852
763
  showContentVideo();
853
764
  if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
854
765
  if (video.paused) {
855
- console.log(
856
- "[IMA] Resuming paused video after setup error"
857
- );
858
766
  video.play().catch(() => {
859
767
  });
860
768
  }
@@ -872,17 +780,9 @@ function createImaController(video, options) {
872
780
  adsLoader.addEventListener(
873
781
  google.ima.AdErrorEvent.Type.AD_ERROR,
874
782
  (adErrorEvent) => {
875
- var _a, _b, _c, _d;
783
+ var _a;
876
784
  const error = adErrorEvent.getError();
877
- console.error("[IMA] \u274C ADS_LOADER ERROR - Ad request failed!", {
878
- message: (_a = error.getMessage) == null ? void 0 : _a.call(error),
879
- errorCode: (_b = error.getErrorCode) == null ? void 0 : _b.call(error),
880
- type: (_c = error.getType) == null ? void 0 : _c.call(error),
881
- vastErrorCode: (_d = error.getVastErrorCode) == null ? void 0 : _d.call(error)
882
- });
883
- console.error("[IMA] This means the ad server didn't return valid ads");
884
- console.error("[IMA] Ad layer will NOT appear (no flicker)");
885
- console.error("[IMA] Full error object:", adErrorEvent.getError());
785
+ console.error("[DEBUG-ERROR] \u274C ADS_LOADER ERROR:", (_a = error.getMessage) == null ? void 0 : _a.call(error));
886
786
  adPlaying = false;
887
787
  setAdPlayingFlag(false);
888
788
  if (adContainerEl) {
@@ -892,14 +792,12 @@ function createImaController(video, options) {
892
792
  if (adContainerEl) {
893
793
  adContainerEl.style.pointerEvents = "none";
894
794
  adContainerEl.style.display = "none";
895
- console.log("[IMA] Ad container hidden after loader error");
896
795
  }
897
796
  }, 300);
898
797
  }
899
798
  showContentVideo();
900
799
  if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
901
800
  if (video.paused) {
902
- console.log("[IMA] Resuming paused video after loader error");
903
801
  video.play().catch(() => {
904
802
  });
905
803
  }
@@ -914,10 +812,7 @@ function createImaController(video, options) {
914
812
  false
915
813
  );
916
814
  }
917
- console.log("[IMA] \u{1F680} Making ads request to IMA SDK");
918
- console.log("[IMA] Waiting for IMA SDK response (LOADED or ERROR event)...");
919
815
  makeAdsRequest(google, vastTagUrl);
920
- console.log("[IMA] \u23F3 Returning promise that will resolve when ads are loaded");
921
816
  return adsLoadedPromise;
922
817
  } catch (error) {
923
818
  console.error("[IMA] Failed to request ads:", error);
@@ -955,23 +850,16 @@ function createImaController(video, options) {
955
850
  },
956
851
  async play() {
957
852
  var _a, _b;
958
- console.log("[IMA] \u25B6\uFE0F === play() called ===");
959
- console.log("[IMA] This initializes and starts the ad");
960
- console.log("[IMA] Ad layer will appear when CONTENT_PAUSE_REQUESTED fires");
853
+ console.log("[DEBUG-FLOW] \u25B6\uFE0F play() - Starting ad playback");
961
854
  if (!((_a = window.google) == null ? void 0 : _a.ima) || !adDisplayContainer) {
962
- console.warn(
963
- "[IMA] \u274C Cannot play ad: IMA SDK or ad container not available"
964
- );
965
855
  return Promise.reject(new Error("IMA SDK not available"));
966
856
  }
967
857
  if (!adsManager) {
968
- console.warn("[IMA] \u274C Cannot play ad: No ads manager available");
969
858
  return Promise.reject(new Error("No ads manager"));
970
859
  }
971
860
  try {
972
861
  const width = video.clientWidth || 640;
973
862
  const height = video.clientHeight || 360;
974
- console.log(`[IMA] \u{1F3AC} Initializing ads manager (${width}x${height})`);
975
863
  adsManager.init(width, height, window.google.ima.ViewMode.NORMAL);
976
864
  adPlaying = true;
977
865
  const adVolume = originalMutedState ? 0 : originalVolume;
@@ -979,22 +867,18 @@ function createImaController(video, options) {
979
867
  adVideoElement.volume = adVolume;
980
868
  adVideoElement.muted = originalMutedState;
981
869
  console.log(
982
- `[IMA] \u{1F50A} Set dedicated ad video volume to ${adVolume}, muted: ${originalMutedState}`
870
+ `[DEBUG-AUDIO] \u{1F50A} Pre-start ad audio | volume=${adVolume}, muted=${originalMutedState}`
983
871
  );
984
872
  }
985
873
  try {
986
874
  adsManager.setVolume(adVolume);
987
- console.log(`[IMA] Set IMA manager volume to ${adVolume}`);
988
875
  } catch (error) {
989
- console.warn("[IMA] Failed to set IMA manager volume:", error);
876
+ console.warn("[DEBUG-ERROR] Failed to set IMA manager volume:", error);
990
877
  }
991
- console.log("[IMA] \u{1F3AF} Calling adsManager.start()");
992
- console.log("[IMA] If successful, IMA will fire CONTENT_PAUSE_REQUESTED");
993
878
  adsManager.start();
994
- console.log("[IMA] \u2705 play() completed successfully");
995
879
  return Promise.resolve();
996
880
  } catch (error) {
997
- console.error("[IMA] \u274C Error starting ad playback:", error);
881
+ console.error("[DEBUG-ERROR] \u274C Error starting ad:", error);
998
882
  adPlaying = false;
999
883
  setAdPlayingFlag(false);
1000
884
  if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
@@ -1006,7 +890,7 @@ function createImaController(video, options) {
1006
890
  },
1007
891
  async stop() {
1008
892
  var _a;
1009
- console.log("[IMA] Stopping ad playback");
893
+ console.log("[DEBUG-FLOW] \u23F9\uFE0F stop() - Stopping ad playback");
1010
894
  adPlaying = false;
1011
895
  setAdPlayingFlag(false);
1012
896
  if (adContainerEl) {
@@ -1016,7 +900,7 @@ function createImaController(video, options) {
1016
900
  if (adContainerEl) {
1017
901
  adContainerEl.style.pointerEvents = "none";
1018
902
  adContainerEl.style.display = "none";
1019
- console.log("[IMA] Ad container hidden after stop");
903
+ console.log("[DEBUG-LAYER] \u26AB Ad container HIDDEN (stop)");
1020
904
  }
1021
905
  }, 300);
1022
906
  }
@@ -1087,7 +971,7 @@ function createImaController(video, options) {
1087
971
  updateOriginalMutedState(muted, volume) {
1088
972
  const nextVolume = typeof volume === "number" && !Number.isNaN(volume) ? Math.max(0, Math.min(1, volume)) : originalVolume;
1089
973
  console.log(
1090
- `[IMA] updateOriginalMutedState called: { muted: ${originalMutedState} -> ${muted}, volume: ${originalVolume} -> ${nextVolume} }`
974
+ `[DEBUG-AUDIO] \u{1F4BE} Saved original state | muted: ${originalMutedState}->${muted}, volume: ${originalVolume}->${nextVolume}`
1091
975
  );
1092
976
  originalMutedState = muted;
1093
977
  originalVolume = nextVolume;
@@ -1104,14 +988,14 @@ function createImaController(video, options) {
1104
988
  adVideoElement.volume = clampedVolume;
1105
989
  adVideoElement.muted = clampedVolume === 0;
1106
990
  console.log(
1107
- `[IMA] Set dedicated ad video volume to ${clampedVolume}, muted: ${clampedVolume === 0}`
991
+ `[DEBUG-AUDIO] \u{1F50A} Ad volume changed | volume=${clampedVolume}, muted=${clampedVolume === 0}`
1108
992
  );
1109
993
  }
1110
994
  if (adsManager && adPlaying) {
1111
995
  try {
1112
996
  adsManager.setVolume(clampedVolume);
1113
997
  } catch (error) {
1114
- console.warn("[IMA] Failed to set IMA manager volume:", error);
998
+ console.warn("[DEBUG-ERROR] Failed to set IMA manager volume:", error);
1115
999
  }
1116
1000
  }
1117
1001
  },
@@ -2322,6 +2206,10 @@ var StormcloudVideoPlayer = class {
2322
2206
  this.vastToMediaUrlMap = /* @__PURE__ */ new Map();
2323
2207
  this.preloadedMediaUrls = /* @__PURE__ */ new Set();
2324
2208
  this.preloadingMediaUrls = /* @__PURE__ */ new Set();
2209
+ this.adRequestTokenCounter = 0;
2210
+ this.activeAdRequestToken = null;
2211
+ this.adRequestWatchdogToken = null;
2212
+ this.adFailsafeToken = null;
2325
2213
  initializePolyfills();
2326
2214
  const browserOverrides = getBrowserConfigOverrides();
2327
2215
  this.config = { ...config, ...browserOverrides };
@@ -2593,71 +2481,50 @@ var StormcloudVideoPlayer = class {
2593
2481
  }
2594
2482
  });
2595
2483
  this.ima.on("ad_error", () => {
2596
- if (this.config.debugAdTiming) {
2597
- console.log("[StormcloudVideoPlayer] IMA ad_error event received", {
2598
- showAds: this.showAds,
2599
- inAdBreak: this.inAdBreak,
2600
- remainingAds: this.adPodQueue.length
2601
- });
2602
- }
2484
+ const remaining = this.getRemainingAdMs();
2485
+ console.log(
2486
+ `[DEBUG-POD] \u274C ad_error event | inBreak=${this.inAdBreak}, queue=${this.adPodQueue.length}, remaining=${remaining}ms`
2487
+ );
2603
2488
  if (this.inAdBreak) {
2604
- const remaining = this.getRemainingAdMs();
2605
2489
  if (remaining > 500 && this.adPodQueue.length > 0) {
2606
2490
  const nextPreloaded = this.findNextPreloadedAd();
2607
2491
  if (nextPreloaded) {
2608
2492
  this.currentAdIndex++;
2609
- if (this.config.debugAdTiming) {
2610
- console.log(
2611
- `[StormcloudVideoPlayer] Skipping to next preloaded ad after error`
2612
- );
2613
- }
2493
+ console.log(
2494
+ `[DEBUG-POD] \u27A1\uFE0F Trying next ad after error (${this.currentAdIndex}/${this.totalAdsInBreak})`
2495
+ );
2614
2496
  this.playSingleAd(nextPreloaded).catch(() => {
2615
2497
  this.handleAdFailure();
2616
2498
  });
2617
2499
  } else {
2618
- if (this.config.debugAdTiming) {
2619
- console.log(
2620
- "[StormcloudVideoPlayer] No preloaded ads available, ending ad break"
2621
- );
2622
- }
2500
+ console.log("[DEBUG-POD] \u26A0\uFE0F No more preloaded ads - calling handleAdFailure");
2623
2501
  this.handleAdFailure();
2624
2502
  }
2625
2503
  } else {
2504
+ console.log("[DEBUG-POD] \u26A0\uFE0F No more ads or time - calling handleAdFailure");
2626
2505
  this.handleAdFailure();
2627
2506
  }
2628
2507
  } else {
2629
- if (this.config.debugAdTiming) {
2630
- console.log(
2631
- "[StormcloudVideoPlayer] Ad error before ad break established - cleaning up"
2632
- );
2633
- }
2508
+ console.log("[DEBUG-POD] \u26A0\uFE0F Error before ad break established");
2634
2509
  this.handleAdFailure();
2635
2510
  }
2636
2511
  });
2637
2512
  this.ima.on("content_pause", () => {
2638
- if (this.config.debugAdTiming) {
2639
- console.log("[StormcloudVideoPlayer] IMA content_pause event received");
2640
- }
2513
+ console.log(`[DEBUG-POD] \u{1F3AF} content_pause | ad ${this.currentAdIndex}/${this.totalAdsInBreak}, queue=${this.adPodQueue.length}`);
2641
2514
  this.clearAdFailsafeTimer();
2515
+ this.clearAdRequestWatchdog();
2516
+ this.activeAdRequestToken = null;
2517
+ this.showAds = true;
2642
2518
  this.enforceAdHoldState();
2643
2519
  });
2644
2520
  this.ima.on("content_resume", () => {
2645
- if (this.config.debugAdTiming) {
2646
- console.log(
2647
- "[StormcloudVideoPlayer] IMA content_resume event received",
2648
- {
2649
- inAdBreak: this.inAdBreak,
2650
- pendingAds: this.adPodQueue.length
2651
- }
2652
- );
2653
- }
2521
+ console.log(`[DEBUG-POD] \u23F8\uFE0F content_resume | ad ${this.currentAdIndex}/${this.totalAdsInBreak}, queue=${this.adPodQueue.length}, remaining=${this.getRemainingAdMs()}ms`);
2654
2522
  this.clearAdFailsafeTimer();
2523
+ this.clearAdRequestWatchdog();
2524
+ this.activeAdRequestToken = null;
2525
+ this.showAds = false;
2655
2526
  if (!this.inAdBreak) {
2656
- if (this.config.debugAdTiming) {
2657
- console.log(
2658
- "[StormcloudVideoPlayer] Not in ad break - this shouldn't happen during pod"
2659
- );
2660
- }
2527
+ console.warn("[DEBUG-POD] \u26A0\uFE0F Not in ad break - shouldn't happen");
2661
2528
  return;
2662
2529
  }
2663
2530
  const remaining = this.getRemainingAdMs();
@@ -2665,33 +2532,17 @@ var StormcloudVideoPlayer = class {
2665
2532
  const nextPreloaded = this.findNextPreloadedAd();
2666
2533
  if (nextPreloaded) {
2667
2534
  this.currentAdIndex++;
2668
- if (this.config.debugAdTiming) {
2669
- console.log(
2670
- `[StormcloudVideoPlayer] Playing next preloaded ad in pod (${this.currentAdIndex}/${this.totalAdsInBreak}) - layer will stay visible if ad loads`
2671
- );
2672
- }
2535
+ console.log(`[DEBUG-POD] \u27A1\uFE0F Playing next ad ${this.currentAdIndex}/${this.totalAdsInBreak} (preloaded)`);
2673
2536
  this.playSingleAd(nextPreloaded).catch(() => {
2674
- if (this.config.debugAdTiming) {
2675
- console.error(
2676
- "[StormcloudVideoPlayer] Failed to play next ad in pod"
2677
- );
2678
- }
2537
+ console.error("[DEBUG-POD] \u274C Failed to play next ad");
2679
2538
  this.handleAdPodComplete();
2680
2539
  });
2681
2540
  } else {
2682
- if (this.config.debugAdTiming) {
2683
- console.log(
2684
- "[StormcloudVideoPlayer] No preloaded ads available - completing ad break"
2685
- );
2686
- }
2541
+ console.log("[DEBUG-POD] \u26A0\uFE0F No preloaded ads - ending pod");
2687
2542
  this.handleAdPodComplete();
2688
2543
  }
2689
2544
  } else {
2690
- if (this.config.debugAdTiming) {
2691
- console.log(
2692
- "[StormcloudVideoPlayer] No more ads in pod - completing ad break"
2693
- );
2694
- }
2545
+ console.log("[DEBUG-POD] \u2705 Pod complete (no more ads or time expired)");
2695
2546
  this.handleAdPodComplete();
2696
2547
  }
2697
2548
  });
@@ -3266,52 +3117,27 @@ var StormcloudVideoPlayer = class {
3266
3117
  let vastTagUrls = [];
3267
3118
  if (this.apiVastTagUrl) {
3268
3119
  vastTagUrls = [this.apiVastTagUrl];
3269
- if (this.config.debugAdTiming) {
3270
- console.log(
3271
- "[StormcloudVideoPlayer] Using VAST endpoint:",
3272
- this.apiVastTagUrl
3273
- );
3274
- }
3275
3120
  } else if (tags && tags.length > 0) {
3276
3121
  vastTagUrls = tags;
3277
- if (this.config.debugAdTiming) {
3278
- console.log(
3279
- "[StormcloudVideoPlayer] Using scheduled VAST tags (count: " + tags.length + "):",
3280
- tags
3281
- );
3282
- }
3283
3122
  } else {
3284
- if (this.config.debugAdTiming) {
3285
- console.log("[StormcloudVideoPlayer] No VAST tag available for ad");
3286
- }
3123
+ console.log("[DEBUG-POD] \u26A0\uFE0F No VAST tag available");
3287
3124
  return;
3288
3125
  }
3289
3126
  if (vastTagUrls.length > 0) {
3127
+ console.log(`[DEBUG-POD] \u{1F3AF} Starting ad break with ${vastTagUrls.length} ads`);
3290
3128
  this.adPodAllUrls = [...vastTagUrls];
3291
3129
  this.preloadingAdUrls.clear();
3292
3130
  this.vastToMediaUrlMap.clear();
3293
3131
  this.preloadedMediaUrls.clear();
3294
3132
  this.preloadingMediaUrls.clear();
3295
- this.logQueuedAdUrls(this.adPodAllUrls);
3296
- if (this.config.debugAdTiming) {
3297
- console.log(
3298
- `[StormcloudVideoPlayer] Capturing original audio state before ad break:`,
3299
- {
3300
- videoMuted: this.video.muted,
3301
- videoVolume: this.video.volume
3302
- }
3303
- );
3304
- }
3133
+ console.log(
3134
+ `[DEBUG-AUDIO] \u{1F4BE} Capturing original state | muted=${this.video.muted}, volume=${this.video.volume}`
3135
+ );
3305
3136
  this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);
3306
3137
  this.inAdBreak = true;
3307
3138
  this.currentAdIndex = 0;
3308
3139
  this.totalAdsInBreak = vastTagUrls.length;
3309
3140
  this.adPodQueue = [...vastTagUrls];
3310
- if (this.config.debugAdTiming) {
3311
- console.log(
3312
- `[StormcloudVideoPlayer] Starting ad pod with ${vastTagUrls.length} ads - preloading all ads in parallel (ad layer will show after ad loads)`
3313
- );
3314
- }
3315
3141
  this.preloadAllAdsInBackground().catch((error) => {
3316
3142
  if (this.config.debugAdTiming) {
3317
3143
  console.warn(
@@ -3323,12 +3149,7 @@ var StormcloudVideoPlayer = class {
3323
3149
  try {
3324
3150
  await this.playAdPod();
3325
3151
  } catch (error) {
3326
- if (this.config.debugAdTiming) {
3327
- console.error(
3328
- "[StormcloudVideoPlayer] Ad pod playback failed:",
3329
- error
3330
- );
3331
- }
3152
+ console.error("[DEBUG-POD] \u274C Pod playback failed:", error);
3332
3153
  this.handleAdFailure();
3333
3154
  }
3334
3155
  }
@@ -3340,19 +3161,13 @@ var StormcloudVideoPlayer = class {
3340
3161
  }
3341
3162
  async playAdPod() {
3342
3163
  if (this.adPodQueue.length === 0) {
3343
- if (this.config.debugAdTiming) {
3344
- console.log("[StormcloudVideoPlayer] No ads in pod to play");
3345
- }
3164
+ console.log("[DEBUG-POD] \u26A0\uFE0F No ads in pod");
3346
3165
  return;
3347
3166
  }
3348
3167
  await new Promise((resolve) => setTimeout(resolve, 500));
3349
3168
  const firstPreloaded = this.findNextPreloadedAd();
3350
3169
  if (!firstPreloaded) {
3351
- if (this.config.debugAdTiming) {
3352
- console.log(
3353
- "[StormcloudVideoPlayer] No preloaded ads available after waiting, trying first ad anyway"
3354
- );
3355
- }
3170
+ console.log("[DEBUG-POD] \u26A0\uFE0F No preloaded ads after wait, trying first ad");
3356
3171
  const firstAd = this.adPodQueue.shift();
3357
3172
  if (firstAd) {
3358
3173
  this.currentAdIndex++;
@@ -3361,11 +3176,7 @@ var StormcloudVideoPlayer = class {
3361
3176
  return;
3362
3177
  }
3363
3178
  this.currentAdIndex++;
3364
- if (this.config.debugAdTiming) {
3365
- console.log(
3366
- `[StormcloudVideoPlayer] Playing first preloaded ad ${this.currentAdIndex}/${this.totalAdsInBreak}`
3367
- );
3368
- }
3179
+ console.log(`[DEBUG-POD] \u{1F680} Starting pod with ad ${this.currentAdIndex}/${this.totalAdsInBreak}`);
3369
3180
  await this.playSingleAd(firstPreloaded);
3370
3181
  }
3371
3182
  findCurrentOrNextBreak(nowMs) {
@@ -3445,31 +3256,15 @@ var StormcloudVideoPlayer = class {
3445
3256
  const overrunMs = Math.max(0, elapsedSinceStartMs - expectedDurationMs);
3446
3257
  const shouldExtendAdBreak = (adPlaying || pendingAds || this.showAds) && overrunMs < maxExtensionMs;
3447
3258
  if (shouldExtendAdBreak) {
3448
- if (this.config.debugAdTiming) {
3449
- console.log(
3450
- "[StormcloudVideoPlayer] Extending ad break beyond scheduled duration",
3451
- {
3452
- adPlaying,
3453
- pendingAds,
3454
- showAds: this.showAds,
3455
- overrunMs,
3456
- checkIntervalMs,
3457
- maxExtensionMs
3458
- }
3459
- );
3460
- }
3259
+ console.log(
3260
+ `[DEBUG-POD] \u23F3 Extending ad break | elapsed=${elapsedSinceStartMs}ms, expected=${expectedDurationMs}ms, overrun=${overrunMs}ms`
3261
+ );
3461
3262
  this.scheduleAdStopCountdown(checkIntervalMs);
3462
3263
  return;
3463
3264
  }
3464
- if (this.config.debugAdTiming) {
3465
- console.log("[StormcloudVideoPlayer] Ending ad break via timer", {
3466
- adPlaying,
3467
- pendingAds,
3468
- showAds: this.showAds,
3469
- overrunMs,
3470
- maxExtensionMs
3471
- });
3472
- }
3265
+ console.log(
3266
+ `[DEBUG-POD] \u23F1\uFE0F Ad break duration expired | elapsed=${elapsedSinceStartMs}ms, expected=${expectedDurationMs}ms`
3267
+ );
3473
3268
  if (adPlaying) {
3474
3269
  this.ima.stop().catch(() => {
3475
3270
  });
@@ -3502,62 +3297,56 @@ var StormcloudVideoPlayer = class {
3502
3297
  this.ptsDriftEmaMs = this.ptsDriftEmaMs * (1 - alpha) + sampleMs * alpha;
3503
3298
  }
3504
3299
  async playSingleAd(vastTagUrl) {
3505
- if (this.config.debugAdTiming) {
3506
- console.log("[StormcloudVideoPlayer] Attempting to play ad:", vastTagUrl);
3507
- }
3300
+ console.log(`[DEBUG-POD] \u{1F3AC} playSingleAd | url=${vastTagUrl.substring(0, 60)}...`);
3508
3301
  if (this.ima.isAdPlaying()) {
3509
- if (this.config.debugAdTiming) {
3510
- console.warn(
3511
- "[StormcloudVideoPlayer] Ad already playing - skipping new ad request"
3512
- );
3513
- }
3302
+ console.warn("[DEBUG-POD] \u26A0\uFE0F Ad already playing - skipping request");
3514
3303
  return;
3515
3304
  }
3305
+ const requestToken = ++this.adRequestTokenCounter;
3516
3306
  const wasPreloaded = this.ima.hasPreloadedAd(vastTagUrl);
3517
- if (wasPreloaded && this.config.debugAdTiming) {
3518
- console.log(
3519
- `[StormcloudVideoPlayer] IMA SDK preloaded this ad already: ${vastTagUrl}`
3520
- );
3521
- }
3522
- this.startAdFailsafeTimer();
3307
+ this.activeAdRequestToken = requestToken;
3308
+ console.log(`[DEBUG-POD] \u{1F4DD} Request token=${requestToken}, preloaded=${wasPreloaded}`);
3309
+ this.startAdRequestWatchdog(requestToken);
3523
3310
  try {
3524
3311
  await this.ima.requestAds(vastTagUrl);
3312
+ this.clearAdRequestWatchdog();
3313
+ if (this.activeAdRequestToken !== requestToken) {
3314
+ console.warn(`[DEBUG-POD] \u26A0\uFE0F Token mismatch after requestAds (stale request)`);
3315
+ return;
3316
+ }
3525
3317
  try {
3526
- if (this.config.debugAdTiming) {
3527
- console.log(
3528
- "[StormcloudVideoPlayer] Ad request completed, attempting playback (ad layer will show when IMA triggers content pause)"
3529
- );
3530
- }
3318
+ this.startAdFailsafeTimer(requestToken);
3531
3319
  await this.ima.play();
3532
- this.showAds = true;
3533
- if (this.config.debugAdTiming) {
3534
- console.log(
3535
- "[StormcloudVideoPlayer] Ad playback started successfully, showAds = true"
3536
- );
3320
+ if (this.activeAdRequestToken === requestToken) {
3321
+ console.log(`[DEBUG-POD] \u2705 Ad play initiated (token=${requestToken})`);
3322
+ } else {
3323
+ console.warn(`[DEBUG-POD] \u26A0\uFE0F Token mismatch after play (stale request)`);
3537
3324
  }
3538
3325
  } catch (playError) {
3539
- if (this.config.debugAdTiming) {
3540
- console.log(
3541
- "[StormcloudVideoPlayer] No ads available, skipping playback"
3542
- );
3326
+ console.log("[DEBUG-POD] \u26A0\uFE0F No ads available from play()");
3327
+ this.clearAdFailsafeTimer();
3328
+ if (this.activeAdRequestToken === requestToken) {
3329
+ this.activeAdRequestToken = null;
3543
3330
  }
3544
3331
  this.handleAdFailure();
3545
3332
  return;
3546
3333
  }
3547
3334
  } catch (error) {
3548
- if (this.config.debugAdTiming) {
3549
- console.error("[StormcloudVideoPlayer] Ad playback failed:", error);
3335
+ console.error("[DEBUG-POD] \u274C Ad request failed:", error == null ? void 0 : error.message);
3336
+ this.clearAdRequestWatchdog();
3337
+ this.clearAdFailsafeTimer();
3338
+ if (this.activeAdRequestToken === requestToken) {
3339
+ this.activeAdRequestToken = null;
3550
3340
  }
3551
3341
  this.handleAdFailure();
3552
3342
  }
3553
3343
  }
3554
3344
  handleAdPodComplete() {
3555
3345
  var _a;
3556
- if (this.config.debugAdTiming) {
3557
- console.log(
3558
- "[StormcloudVideoPlayer] Handling ad pod completion - resuming content and hiding ad layer"
3559
- );
3560
- }
3346
+ console.log("[DEBUG-POD] \u{1F3C1} handleAdPodComplete - Ending ad break, restoring content");
3347
+ this.clearAdRequestWatchdog();
3348
+ this.clearAdFailsafeTimer();
3349
+ this.activeAdRequestToken = null;
3561
3350
  this.releaseAdHoldState();
3562
3351
  this.preloadingAdUrls.clear();
3563
3352
  this.vastToMediaUrlMap.clear();
@@ -3568,7 +3357,6 @@ var StormcloudVideoPlayer = class {
3568
3357
  this.currentAdBreakStartWallClockMs = void 0;
3569
3358
  this.clearAdStartTimer();
3570
3359
  this.clearAdStopTimer();
3571
- this.clearAdFailsafeTimer();
3572
3360
  this.adPodQueue = [];
3573
3361
  this.adPodAllUrls = [];
3574
3362
  this.showAds = false;
@@ -3580,70 +3368,95 @@ var StormcloudVideoPlayer = class {
3580
3368
  const originalVolume = typeof this.ima.getOriginalVolume === "function" ? this.ima.getOriginalVolume() : this.video.volume;
3581
3369
  this.video.muted = originalMutedState;
3582
3370
  this.video.volume = originalVolume;
3583
- if (this.config.debugAdTiming) {
3584
- console.log(
3585
- `[StormcloudVideoPlayer] Restored main video - muted: ${originalMutedState}, volume: ${this.video.volume}`
3586
- );
3587
- }
3371
+ console.log(
3372
+ `[DEBUG-AUDIO] \u{1F50A} Main video restored | muted=${originalMutedState}, volume=${originalVolume}`
3373
+ );
3588
3374
  if (!this.shouldContinueLiveStreamDuringAds() && this.video.paused) {
3589
- if (this.config.debugAdTiming) {
3590
- console.log("[StormcloudVideoPlayer] Resuming paused video");
3591
- }
3375
+ console.log("[DEBUG-FLOW] \u25B6\uFE0F Resuming main video playback");
3592
3376
  (_a = this.video.play()) == null ? void 0 : _a.catch((error) => {
3593
- if (this.config.debugAdTiming) {
3594
- console.error(
3595
- "[StormcloudVideoPlayer] Failed to resume video:",
3596
- error
3597
- );
3598
- }
3377
+ console.error("[DEBUG-ERROR] Failed to resume video:", error);
3599
3378
  });
3600
3379
  }
3601
3380
  }
3602
3381
  handleAdFailure() {
3603
- if (this.config.debugAdTiming) {
3382
+ const remaining = this.getRemainingAdMs();
3383
+ console.log(
3384
+ `[DEBUG-POD] \u274C handleAdFailure | inBreak=${this.inAdBreak}, showAds=${this.showAds}, remaining=${remaining}ms`
3385
+ );
3386
+ if (remaining > 500 && this.inAdBreak) {
3604
3387
  console.log(
3605
- "[StormcloudVideoPlayer] Handling ad failure - resuming content",
3606
- {
3607
- inAdBreak: this.inAdBreak,
3608
- showAds: this.showAds,
3609
- videoPaused: this.video.paused,
3610
- adPlaying: this.ima.isAdPlaying()
3611
- }
3388
+ `[DEBUG-POD] \u23F3 Ad failed but ${remaining}ms remaining - showing placeholder until duration expires`
3612
3389
  );
3390
+ this.showAds = true;
3391
+ this.ima.showPlaceholder();
3392
+ this.enforceAdHoldState();
3393
+ return;
3613
3394
  }
3395
+ console.log("[DEBUG-POD] \u23F9\uFE0F No remaining time - ending ad break now");
3614
3396
  this.handleAdPodComplete();
3615
3397
  }
3616
- startAdFailsafeTimer() {
3398
+ startAdRequestWatchdog(token) {
3399
+ var _a;
3400
+ this.clearAdRequestWatchdog();
3401
+ const timeoutMs = (_a = this.config.adFailsafeTimeoutMs) != null ? _a : 1e4;
3402
+ this.adRequestWatchdogToken = token;
3403
+ this.adRequestWatchdogId = window.setTimeout(() => {
3404
+ if (this.adRequestWatchdogToken !== token) {
3405
+ return;
3406
+ }
3407
+ this.adRequestWatchdogId = void 0;
3408
+ this.adRequestWatchdogToken = null;
3409
+ if (this.activeAdRequestToken === token) {
3410
+ this.activeAdRequestToken = null;
3411
+ }
3412
+ this.logAdState("ad_request_timeout", { token, timeoutMs });
3413
+ this.handleAdFailure();
3414
+ }, timeoutMs);
3415
+ this.logAdState("ad_request_watchdog_started", { token, timeoutMs });
3416
+ }
3417
+ clearAdRequestWatchdog() {
3418
+ if (this.adRequestWatchdogId != null) {
3419
+ clearTimeout(this.adRequestWatchdogId);
3420
+ this.adRequestWatchdogId = void 0;
3421
+ }
3422
+ if (this.adRequestWatchdogToken != null) {
3423
+ this.logAdState("ad_request_watchdog_cleared", {
3424
+ token: this.adRequestWatchdogToken
3425
+ });
3426
+ this.adRequestWatchdogToken = null;
3427
+ }
3428
+ }
3429
+ startAdFailsafeTimer(token) {
3617
3430
  var _a;
3618
3431
  this.clearAdFailsafeTimer();
3619
3432
  const failsafeMs = (_a = this.config.adFailsafeTimeoutMs) != null ? _a : 1e4;
3620
- if (this.config.debugAdTiming) {
3621
- console.log(
3622
- `[StormcloudVideoPlayer] Starting failsafe timer (${failsafeMs}ms)`
3623
- );
3624
- }
3433
+ this.adFailsafeToken = token;
3625
3434
  this.adFailsafeTimerId = window.setTimeout(() => {
3626
- const shouldTrigger = this.video.paused || this.showAds && !this.ima.isAdPlaying();
3627
- if (shouldTrigger) {
3628
- if (this.config.debugAdTiming) {
3629
- console.warn(
3630
- "[StormcloudVideoPlayer] Failsafe timer triggered - forcing video resume",
3631
- {
3632
- paused: this.video.paused,
3633
- showAds: this.showAds,
3634
- adPlaying: this.ima.isAdPlaying()
3635
- }
3636
- );
3637
- }
3638
- this.handleAdFailure();
3435
+ if (this.adFailsafeToken !== token) {
3436
+ return;
3639
3437
  }
3438
+ this.adFailsafeTimerId = void 0;
3439
+ this.adFailsafeToken = null;
3440
+ if (this.activeAdRequestToken === token) {
3441
+ this.activeAdRequestToken = null;
3442
+ }
3443
+ this.logAdState("ad_failsafe_triggered", {
3444
+ token,
3445
+ failsafeMs,
3446
+ videoPaused: this.video.paused,
3447
+ imaAdPlaying: this.ima.isAdPlaying()
3448
+ });
3449
+ this.handleAdFailure();
3640
3450
  }, failsafeMs);
3451
+ this.logAdState("ad_failsafe_started", { token, failsafeMs });
3641
3452
  }
3642
3453
  clearAdFailsafeTimer() {
3643
3454
  if (this.adFailsafeTimerId != null) {
3644
3455
  clearTimeout(this.adFailsafeTimerId);
3456
+ this.logAdState("ad_failsafe_cleared", { token: this.adFailsafeToken });
3645
3457
  this.adFailsafeTimerId = void 0;
3646
3458
  }
3459
+ this.adFailsafeToken = null;
3647
3460
  }
3648
3461
  selectVastTagsForBreak(b) {
3649
3462
  if (!b || !b.vastTagUrl) return void 0;
@@ -3658,16 +3471,32 @@ var StormcloudVideoPlayer = class {
3658
3471
  }
3659
3472
  console.log("[StormcloudVideoPlayer] ALL ad URLs queued:", urls);
3660
3473
  }
3474
+ logAdState(event, extra = {}) {
3475
+ if (!this.config.debugAdTiming) {
3476
+ return;
3477
+ }
3478
+ console.log("[StormcloudVideoPlayer][AdState]", {
3479
+ event,
3480
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
3481
+ showAds: this.showAds,
3482
+ adPlaying: this.ima.isAdPlaying(),
3483
+ inAdBreak: this.inAdBreak,
3484
+ activeAdRequestToken: this.activeAdRequestToken,
3485
+ ...extra
3486
+ });
3487
+ }
3661
3488
  enforceAdHoldState() {
3662
3489
  this.video.dataset.stormcloudAdPlaying = "true";
3663
3490
  this.video.muted = true;
3664
3491
  this.video.volume = 0;
3492
+ console.log("[DEBUG-LAYER] \u{1F512} Enforced ad hold state (main video muted)");
3665
3493
  if (typeof this.ima.showPlaceholder === "function") {
3666
3494
  this.ima.showPlaceholder();
3667
3495
  }
3668
3496
  }
3669
3497
  releaseAdHoldState() {
3670
3498
  delete this.video.dataset.stormcloudAdPlaying;
3499
+ console.log("[DEBUG-LAYER] \u{1F513} Released ad hold state");
3671
3500
  if (typeof this.ima.hidePlaceholder === "function") {
3672
3501
  this.ima.hidePlaceholder();
3673
3502
  }