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