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