stormcloud-video-player 0.2.33 → 0.2.34

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.cjs CHANGED
@@ -289,7 +289,7 @@ function createImaController(video, options) {
289
289
  video.muted = true;
290
290
  video.volume = 0;
291
291
  contentVideoHidden = true;
292
- console.log("[IMA] Content video hidden and muted");
292
+ console.log("[DEBUG-LAYER] \u{1F534} Content video HIDDEN | muted=true, volume=0");
293
293
  }
294
294
  }
295
295
  function showContentVideo() {
@@ -302,7 +302,7 @@ function createImaController(video, options) {
302
302
  video.volume = originalVolume;
303
303
  contentVideoHidden = false;
304
304
  console.log(
305
- `[IMA] Content video restored (muted: ${originalMutedState}, volume: ${originalVolume})`
305
+ `[DEBUG-LAYER] \u{1F7E2} Content video RESTORED | muted=${originalMutedState}, volume=${originalVolume}`
306
306
  );
307
307
  }
308
308
  }
@@ -324,12 +324,12 @@ function createImaController(video, options) {
324
324
  "canplay",
325
325
  () => {
326
326
  adVideo.style.opacity = "1";
327
- console.log("[IMA] Ad video ready to play");
327
+ console.log("[DEBUG-LAYER] \u{1F4FA} Ad video element ready (canplay fired)");
328
328
  },
329
329
  { once: true }
330
330
  );
331
331
  console.log(
332
- `[IMA] Created dedicated ad video element with volume: ${adVideo.volume}, muted: ${adVideo.muted}`
332
+ `[DEBUG-AUDIO] \u{1F50A} Ad video created | volume=${adVideo.volume}, muted=${adVideo.muted}`
333
333
  );
334
334
  return adVideo;
335
335
  }
@@ -415,17 +415,12 @@ function createImaController(video, options) {
415
415
  let adsLoadedResolve;
416
416
  let adsLoadedReject;
417
417
  function makeAdsRequest(google, vastTagUrl) {
418
- console.log("[IMA] \u{1F4CB} === makeAdsRequest() - Building IMA request ===");
419
418
  const adsRequest = new google.ima.AdsRequest();
420
419
  const preloadedResponse = preloadedVast.get(vastTagUrl);
421
420
  if (preloadedResponse) {
422
421
  adsRequest.adsResponse = preloadedResponse;
423
- console.log(
424
- "[IMA] \u26A1 Using preloaded VAST response for immediate ad request"
425
- );
426
422
  } else {
427
423
  adsRequest.adTagUrl = vastTagUrl;
428
- console.log("[IMA] \u{1F310} Will fetch VAST from URL:", vastTagUrl);
429
424
  }
430
425
  const videoWidth = video.offsetWidth || video.clientWidth || 640;
431
426
  const videoHeight = video.offsetHeight || video.clientHeight || 360;
@@ -437,7 +432,6 @@ function createImaController(video, options) {
437
432
  try {
438
433
  const willAutoPlay = !video.paused || video.autoplay;
439
434
  adsRequest.setAdWillAutoPlay(willAutoPlay);
440
- console.log(`[IMA] Ad will autoplay: ${willAutoPlay}`);
441
435
  } catch (error) {
442
436
  console.warn("[IMA] Failed to call setAdWillAutoPlay:", error);
443
437
  }
@@ -446,17 +440,12 @@ function createImaController(video, options) {
446
440
  try {
447
441
  const willPlayMuted = video.muted || video.volume === 0;
448
442
  adsRequest.setAdWillPlayMuted(willPlayMuted);
449
- console.log(`[IMA] Ad will play muted: ${willPlayMuted}`);
450
443
  } catch (error) {
451
444
  console.warn("[IMA] Failed to call setAdWillPlayMuted:", error);
452
445
  }
453
446
  }
454
447
  adsRequest.vastLoadTimeout = 5e3;
455
- console.log(`[IMA] \u{1F4D0} Ads request dimensions: ${videoWidth}x${videoHeight}`);
456
- console.log("[IMA] \u23F1\uFE0F VAST load timeout: 5000ms");
457
- console.log("[IMA] \u{1F680} Calling adsLoader.requestAds()...");
458
448
  adsLoader.requestAds(adsRequest);
459
- console.log("[IMA] \u23F3 Waiting for ADS_MANAGER_LOADED or AD_ERROR event...");
460
449
  if (preloadedResponse) {
461
450
  preloadedVast.delete(vastTagUrl);
462
451
  }
@@ -641,85 +630,29 @@ function createImaController(video, options) {
641
630
  adsLoader.addEventListener(
642
631
  google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,
643
632
  (evt) => {
644
- console.log("[IMA] \u2705 ADS_MANAGER_LOADED - Ads fetched successfully!");
645
- console.log("[IMA] Setting up ads manager with preloading enabled");
646
- console.log("[IMA] ========================================");
647
- console.log("[IMA] EXPECTED EVENT FLOW:");
648
- console.log("[IMA] 1. requestAds() \u2192 fetch VAST");
649
- console.log("[IMA] 2. ADS_MANAGER_LOADED \u2192 ads ready");
650
- console.log("[IMA] 3. play() \u2192 start playback");
651
- console.log("[IMA] 4. CONTENT_PAUSE_REQUESTED \u2192 show ad layer \u2728");
652
- console.log("[IMA] 5. STARTED \u2192 ad is playing");
653
- console.log("[IMA] 6. CONTENT_RESUME_REQUESTED \u2192 ad done");
654
- console.log("[IMA] 7. ALL_ADS_COMPLETED \u2192 hide ad layer");
655
- console.log("[IMA] ========================================");
633
+ console.log("[DEBUG-FLOW] \u2705 ADS_MANAGER_LOADED - Setting up manager");
656
634
  try {
657
635
  const adsRenderingSettings = new google.ima.AdsRenderingSettings();
658
636
  adsRenderingSettings.enablePreloading = true;
659
637
  adsManager = evt.getAdsManager(video, adsRenderingSettings);
660
638
  const AdEvent = google.ima.AdEvent.Type;
661
639
  const AdErrorEvent = google.ima.AdErrorEvent.Type;
662
- console.log("[IMA] ========== IMA EVENT LOGGING ENABLED ==========");
663
- console.log("[IMA] All IMA SDK events will be logged below");
664
- const allAdEvents = [
665
- "AD_BREAK_READY",
666
- "AD_METADATA",
667
- "ALL_ADS_COMPLETED",
668
- "CLICK",
669
- "COMPLETE",
670
- "CONTENT_PAUSE_REQUESTED",
671
- "CONTENT_RESUME_REQUESTED",
672
- "DURATION_CHANGE",
673
- "FIRST_QUARTILE",
674
- "IMPRESSION",
675
- "INTERACTION",
676
- "LINEAR_CHANGED",
677
- "LOADED",
678
- "LOG",
679
- "MIDPOINT",
680
- "PAUSED",
681
- "RESUMED",
682
- "SKIPPABLE_STATE_CHANGED",
683
- "SKIPPED",
684
- "STARTED",
685
- "THIRD_QUARTILE",
686
- "USER_CLOSE",
687
- "VOLUME_CHANGED",
688
- "VOLUME_MUTED"
689
- ];
690
- allAdEvents.forEach((eventType) => {
640
+ const keyEvents = ["STARTED", "COMPLETE", "CONTENT_PAUSE_REQUESTED", "CONTENT_RESUME_REQUESTED", "ALL_ADS_COMPLETED"];
641
+ keyEvents.forEach((eventType) => {
691
642
  if (AdEvent[eventType]) {
692
643
  adsManager.addEventListener(AdEvent[eventType], (e) => {
693
- var _a, _b, _c, _d, _e, _f;
644
+ var _a, _b;
694
645
  const ad = (_a = e.getAd) == null ? void 0 : _a.call(e);
695
- const adData = ad ? {
696
- adId: (_b = ad.getAdId) == null ? void 0 : _b.call(ad),
697
- title: (_c = ad.getTitle) == null ? void 0 : _c.call(ad),
698
- duration: (_d = ad.getDuration) == null ? void 0 : _d.call(ad),
699
- isLinear: (_e = ad.isLinear) == null ? void 0 : _e.call(ad),
700
- contentType: (_f = ad.getContentType) == null ? void 0 : _f.call(ad)
701
- } : null;
702
- console.log(`[IMA EVENT] ${eventType}`, {
703
- eventType,
704
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
705
- adData
706
- });
646
+ console.log(`[DEBUG-FLOW] \u{1F3AC} ${eventType} | title=${((_b = ad == null ? void 0 : ad.getTitle) == null ? void 0 : _b.call(ad)) || "N/A"}`);
707
647
  });
708
648
  }
709
649
  });
710
- console.log("[IMA] ========== EVENT LISTENERS ATTACHED ==========");
711
650
  adsManager.addEventListener(
712
651
  AdErrorEvent.AD_ERROR,
713
652
  (errorEvent) => {
714
- var _a, _b, _c, _d, _e, _f;
653
+ var _a, _b;
715
654
  const error = errorEvent.getError();
716
- console.error("[IMA] \u274C AD_ERROR Event:", {
717
- message: (_a = error.getMessage) == null ? void 0 : _a.call(error),
718
- errorCode: (_b = error.getErrorCode) == null ? void 0 : _b.call(error),
719
- type: (_c = error.getType) == null ? void 0 : _c.call(error),
720
- vastErrorCode: (_d = error.getVastErrorCode) == null ? void 0 : _d.call(error),
721
- innerError: (_e = error.getInnerError) == null ? void 0 : _e.call(error)
722
- });
655
+ console.error("[DEBUG-ERROR] \u274C AD_ERROR:", (_a = error.getMessage) == null ? void 0 : _a.call(error));
723
656
  destroyAdsManager();
724
657
  adPlaying = false;
725
658
  setAdPlayingFlag(false);
@@ -730,7 +663,7 @@ function createImaController(video, options) {
730
663
  if (adContainerEl) {
731
664
  adContainerEl.style.pointerEvents = "none";
732
665
  adContainerEl.style.display = "none";
733
- console.log("[IMA] Ad container hidden after error");
666
+ console.log("[DEBUG-LAYER] \u274C Ad container HIDDEN (error)");
734
667
  }
735
668
  }, 300);
736
669
  }
@@ -742,9 +675,6 @@ function createImaController(video, options) {
742
675
  }
743
676
  if (lastAdTagUrl && retryAttempts < maxRetries) {
744
677
  const delay = backoffBaseMs * Math.pow(2, retryAttempts++);
745
- console.log(
746
- `[IMA] Retrying ad request in ${delay}ms (attempt ${retryAttempts})`
747
- );
748
678
  window.setTimeout(() => {
749
679
  try {
750
680
  makeAdsRequest(google, lastAdTagUrl);
@@ -752,16 +682,10 @@ function createImaController(video, options) {
752
682
  }
753
683
  }, delay);
754
684
  } else {
755
- console.log(
756
- "[IMA] Max retries reached, emitting ad_error"
757
- );
758
685
  emit("ad_error");
759
686
  if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
760
687
  if (video.paused) {
761
- console.log(
762
- "[IMA] Resuming paused video after ad error"
763
- );
764
- (_f = video.play()) == null ? void 0 : _f.catch(() => {
688
+ (_b = video.play()) == null ? void 0 : _b.catch(() => {
765
689
  });
766
690
  }
767
691
  }
@@ -771,15 +695,9 @@ function createImaController(video, options) {
771
695
  adsManager.addEventListener(
772
696
  AdEvent.CONTENT_PAUSE_REQUESTED,
773
697
  () => {
774
- console.log("[IMA] \u2705 CONTENT_PAUSE_REQUESTED - Ad is ready to play!");
775
- console.log("[IMA] This is the event that triggers the ad layer to appear");
698
+ console.log("[DEBUG-FLOW] \u{1F3AF} CONTENT_PAUSE_REQUESTED - Ad starting");
776
699
  if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
777
700
  video.pause();
778
- console.log("[IMA] Content video paused (VOD mode)");
779
- } else {
780
- console.log(
781
- "[IMA] Content video continues in background (Live mode)"
782
- );
783
701
  }
784
702
  hideContentVideo();
785
703
  if (adContainerEl) {
@@ -788,23 +706,22 @@ function createImaController(video, options) {
788
706
  adContainerEl.style.backgroundColor = "#000";
789
707
  adContainerEl.offsetHeight;
790
708
  adContainerEl.style.opacity = "1";
791
- console.log("[IMA] \u2728 Ad container NOW VISIBLE (after content pause)");
709
+ console.log("[DEBUG-LAYER] \u{1F7E1} Ad container VISIBLE");
792
710
  }
793
711
  adPlaying = true;
794
712
  setAdPlayingFlag(true);
795
- console.log("[IMA] Emitting 'content_pause' event to player");
796
713
  emit("content_pause");
797
714
  }
798
715
  );
799
716
  adsManager.addEventListener(AdEvent.STARTED, () => {
800
- console.log("[IMA] \u25B6\uFE0F STARTED - Ad playback has begun");
717
+ console.log("[DEBUG-FLOW] \u25B6\uFE0F STARTED - Ad playing now");
801
718
  setAdPlayingFlag(true);
802
719
  hideContentVideo();
803
720
  if (adVideoElement) {
804
721
  adVideoElement.volume = originalMutedState ? 0 : originalVolume;
805
722
  adVideoElement.muted = originalMutedState;
806
723
  console.log(
807
- `[IMA] Ad video volume: ${adVideoElement.volume}, muted: ${adVideoElement.muted}`
724
+ `[DEBUG-AUDIO] \u{1F50A} Ad audio set | volume=${adVideoElement.volume}, muted=${adVideoElement.muted}`
808
725
  );
809
726
  }
810
727
  if (adContainerEl) {
@@ -813,21 +730,20 @@ function createImaController(video, options) {
813
730
  adContainerEl.style.backgroundColor = "#000";
814
731
  adContainerEl.offsetHeight;
815
732
  adContainerEl.style.opacity = "1";
816
- console.log("[IMA] Ad container now visible (STARTED event)");
817
733
  }
818
734
  });
819
735
  adsManager.addEventListener(
820
736
  AdEvent.CONTENT_RESUME_REQUESTED,
821
737
  () => {
822
- console.log("[IMA] \u23F8\uFE0F CONTENT_RESUME_REQUESTED - Single ad completed");
738
+ console.log("[DEBUG-FLOW] \u23F8\uFE0F CONTENT_RESUME - Single ad done");
823
739
  adPlaying = false;
824
740
  setAdPlayingFlag(false);
825
- console.log("[IMA] Emitting 'content_resume' event to player");
741
+ console.log("[DEBUG-LAYER] \u26A0\uFE0F Waiting for pod manager decision (more ads or done)");
826
742
  emit("content_resume");
827
743
  }
828
744
  );
829
745
  adsManager.addEventListener(AdEvent.ALL_ADS_COMPLETED, () => {
830
- console.log("[IMA] \u{1F3C1} ALL_ADS_COMPLETED - All ads in break finished");
746
+ console.log("[DEBUG-FLOW] \u{1F3C1} ALL_ADS_COMPLETED - Pod finished");
831
747
  adPlaying = false;
832
748
  setAdPlayingFlag(false);
833
749
  if (adContainerEl) {
@@ -837,18 +753,16 @@ function createImaController(video, options) {
837
753
  if (adContainerEl) {
838
754
  adContainerEl.style.pointerEvents = "none";
839
755
  adContainerEl.style.display = "none";
840
- console.log("[IMA] \u{1F648} Ad container hidden (ALL_ADS_COMPLETED)");
756
+ console.log("[DEBUG-LAYER] \u26AB Ad container HIDDEN (pod done)");
841
757
  }
842
758
  }, 300);
843
759
  }
844
760
  showContentVideo();
845
761
  if (!(options == null ? void 0 : options.continueLiveStreamDuringAds) && video.paused) {
846
- console.log("[IMA] Resuming content video playback");
847
762
  video.play().catch((e) => {
848
- console.warn("[IMA] Failed to resume content video:", e);
763
+ console.warn("[DEBUG-ERROR] Failed to resume video:", e);
849
764
  });
850
765
  }
851
- console.log("[IMA] Emitting 'all_ads_completed' event to player");
852
766
  emit("all_ads_completed");
853
767
  });
854
768
  console.log("[IMA] Ads manager event listeners attached");
@@ -868,18 +782,12 @@ function createImaController(video, options) {
868
782
  if (adContainerEl) {
869
783
  adContainerEl.style.pointerEvents = "none";
870
784
  adContainerEl.style.display = "none";
871
- console.log(
872
- "[IMA] Ad container hidden after setup error"
873
- );
874
785
  }
875
786
  }, 300);
876
787
  }
877
788
  showContentVideo();
878
789
  if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
879
790
  if (video.paused) {
880
- console.log(
881
- "[IMA] Resuming paused video after setup error"
882
- );
883
791
  video.play().catch(() => {
884
792
  });
885
793
  }
@@ -897,17 +805,9 @@ function createImaController(video, options) {
897
805
  adsLoader.addEventListener(
898
806
  google.ima.AdErrorEvent.Type.AD_ERROR,
899
807
  (adErrorEvent) => {
900
- var _a, _b, _c, _d;
808
+ var _a;
901
809
  const error = adErrorEvent.getError();
902
- console.error("[IMA] \u274C ADS_LOADER ERROR - Ad request failed!", {
903
- message: (_a = error.getMessage) == null ? void 0 : _a.call(error),
904
- errorCode: (_b = error.getErrorCode) == null ? void 0 : _b.call(error),
905
- type: (_c = error.getType) == null ? void 0 : _c.call(error),
906
- vastErrorCode: (_d = error.getVastErrorCode) == null ? void 0 : _d.call(error)
907
- });
908
- console.error("[IMA] This means the ad server didn't return valid ads");
909
- console.error("[IMA] Ad layer will NOT appear (no flicker)");
910
- console.error("[IMA] Full error object:", adErrorEvent.getError());
810
+ console.error("[DEBUG-ERROR] \u274C ADS_LOADER ERROR:", (_a = error.getMessage) == null ? void 0 : _a.call(error));
911
811
  adPlaying = false;
912
812
  setAdPlayingFlag(false);
913
813
  if (adContainerEl) {
@@ -917,14 +817,12 @@ function createImaController(video, options) {
917
817
  if (adContainerEl) {
918
818
  adContainerEl.style.pointerEvents = "none";
919
819
  adContainerEl.style.display = "none";
920
- console.log("[IMA] Ad container hidden after loader error");
921
820
  }
922
821
  }, 300);
923
822
  }
924
823
  showContentVideo();
925
824
  if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
926
825
  if (video.paused) {
927
- console.log("[IMA] Resuming paused video after loader error");
928
826
  video.play().catch(() => {
929
827
  });
930
828
  }
@@ -939,10 +837,7 @@ function createImaController(video, options) {
939
837
  false
940
838
  );
941
839
  }
942
- console.log("[IMA] \u{1F680} Making ads request to IMA SDK");
943
- console.log("[IMA] Waiting for IMA SDK response (LOADED or ERROR event)...");
944
840
  makeAdsRequest(google, vastTagUrl);
945
- console.log("[IMA] \u23F3 Returning promise that will resolve when ads are loaded");
946
841
  return adsLoadedPromise;
947
842
  } catch (error) {
948
843
  console.error("[IMA] Failed to request ads:", error);
@@ -980,23 +875,16 @@ function createImaController(video, options) {
980
875
  },
981
876
  async play() {
982
877
  var _a, _b;
983
- console.log("[IMA] \u25B6\uFE0F === play() called ===");
984
- console.log("[IMA] This initializes and starts the ad");
985
- console.log("[IMA] Ad layer will appear when CONTENT_PAUSE_REQUESTED fires");
878
+ console.log("[DEBUG-FLOW] \u25B6\uFE0F play() - Starting ad playback");
986
879
  if (!((_a = window.google) == null ? void 0 : _a.ima) || !adDisplayContainer) {
987
- console.warn(
988
- "[IMA] \u274C Cannot play ad: IMA SDK or ad container not available"
989
- );
990
880
  return Promise.reject(new Error("IMA SDK not available"));
991
881
  }
992
882
  if (!adsManager) {
993
- console.warn("[IMA] \u274C Cannot play ad: No ads manager available");
994
883
  return Promise.reject(new Error("No ads manager"));
995
884
  }
996
885
  try {
997
886
  const width = video.clientWidth || 640;
998
887
  const height = video.clientHeight || 360;
999
- console.log(`[IMA] \u{1F3AC} Initializing ads manager (${width}x${height})`);
1000
888
  adsManager.init(width, height, window.google.ima.ViewMode.NORMAL);
1001
889
  adPlaying = true;
1002
890
  const adVolume = originalMutedState ? 0 : originalVolume;
@@ -1004,22 +892,18 @@ function createImaController(video, options) {
1004
892
  adVideoElement.volume = adVolume;
1005
893
  adVideoElement.muted = originalMutedState;
1006
894
  console.log(
1007
- `[IMA] \u{1F50A} Set dedicated ad video volume to ${adVolume}, muted: ${originalMutedState}`
895
+ `[DEBUG-AUDIO] \u{1F50A} Pre-start ad audio | volume=${adVolume}, muted=${originalMutedState}`
1008
896
  );
1009
897
  }
1010
898
  try {
1011
899
  adsManager.setVolume(adVolume);
1012
- console.log(`[IMA] Set IMA manager volume to ${adVolume}`);
1013
900
  } catch (error) {
1014
- console.warn("[IMA] Failed to set IMA manager volume:", error);
901
+ console.warn("[DEBUG-ERROR] Failed to set IMA manager volume:", error);
1015
902
  }
1016
- console.log("[IMA] \u{1F3AF} Calling adsManager.start()");
1017
- console.log("[IMA] If successful, IMA will fire CONTENT_PAUSE_REQUESTED");
1018
903
  adsManager.start();
1019
- console.log("[IMA] \u2705 play() completed successfully");
1020
904
  return Promise.resolve();
1021
905
  } catch (error) {
1022
- console.error("[IMA] \u274C Error starting ad playback:", error);
906
+ console.error("[DEBUG-ERROR] \u274C Error starting ad:", error);
1023
907
  adPlaying = false;
1024
908
  setAdPlayingFlag(false);
1025
909
  if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
@@ -1031,7 +915,7 @@ function createImaController(video, options) {
1031
915
  },
1032
916
  async stop() {
1033
917
  var _a;
1034
- console.log("[IMA] Stopping ad playback");
918
+ console.log("[DEBUG-FLOW] \u23F9\uFE0F stop() - Stopping ad playback");
1035
919
  adPlaying = false;
1036
920
  setAdPlayingFlag(false);
1037
921
  if (adContainerEl) {
@@ -1041,7 +925,7 @@ function createImaController(video, options) {
1041
925
  if (adContainerEl) {
1042
926
  adContainerEl.style.pointerEvents = "none";
1043
927
  adContainerEl.style.display = "none";
1044
- console.log("[IMA] Ad container hidden after stop");
928
+ console.log("[DEBUG-LAYER] \u26AB Ad container HIDDEN (stop)");
1045
929
  }
1046
930
  }, 300);
1047
931
  }
@@ -1112,7 +996,7 @@ function createImaController(video, options) {
1112
996
  updateOriginalMutedState(muted, volume) {
1113
997
  const nextVolume = typeof volume === "number" && !Number.isNaN(volume) ? Math.max(0, Math.min(1, volume)) : originalVolume;
1114
998
  console.log(
1115
- `[IMA] updateOriginalMutedState called: { muted: ${originalMutedState} -> ${muted}, volume: ${originalVolume} -> ${nextVolume} }`
999
+ `[DEBUG-AUDIO] \u{1F4BE} Saved original state | muted: ${originalMutedState}->${muted}, volume: ${originalVolume}->${nextVolume}`
1116
1000
  );
1117
1001
  originalMutedState = muted;
1118
1002
  originalVolume = nextVolume;
@@ -1129,14 +1013,14 @@ function createImaController(video, options) {
1129
1013
  adVideoElement.volume = clampedVolume;
1130
1014
  adVideoElement.muted = clampedVolume === 0;
1131
1015
  console.log(
1132
- `[IMA] Set dedicated ad video volume to ${clampedVolume}, muted: ${clampedVolume === 0}`
1016
+ `[DEBUG-AUDIO] \u{1F50A} Ad volume changed | volume=${clampedVolume}, muted=${clampedVolume === 0}`
1133
1017
  );
1134
1018
  }
1135
1019
  if (adsManager && adPlaying) {
1136
1020
  try {
1137
1021
  adsManager.setVolume(clampedVolume);
1138
1022
  } catch (error) {
1139
- console.warn("[IMA] Failed to set IMA manager volume:", error);
1023
+ console.warn("[DEBUG-ERROR] Failed to set IMA manager volume:", error);
1140
1024
  }
1141
1025
  }
1142
1026
  },
@@ -2347,6 +2231,10 @@ var StormcloudVideoPlayer = class {
2347
2231
  this.vastToMediaUrlMap = /* @__PURE__ */ new Map();
2348
2232
  this.preloadedMediaUrls = /* @__PURE__ */ new Set();
2349
2233
  this.preloadingMediaUrls = /* @__PURE__ */ new Set();
2234
+ this.adRequestTokenCounter = 0;
2235
+ this.activeAdRequestToken = null;
2236
+ this.adRequestWatchdogToken = null;
2237
+ this.adFailsafeToken = null;
2350
2238
  initializePolyfills();
2351
2239
  const browserOverrides = getBrowserConfigOverrides();
2352
2240
  this.config = { ...config, ...browserOverrides };
@@ -2660,29 +2548,21 @@ var StormcloudVideoPlayer = class {
2660
2548
  }
2661
2549
  });
2662
2550
  this.ima.on("content_pause", () => {
2663
- if (this.config.debugAdTiming) {
2664
- console.log("[StormcloudVideoPlayer] IMA content_pause event received");
2665
- }
2551
+ console.log(`[DEBUG-POD] \u{1F3AF} content_pause | ad ${this.currentAdIndex}/${this.totalAdsInBreak}, queue=${this.adPodQueue.length}`);
2666
2552
  this.clearAdFailsafeTimer();
2553
+ this.clearAdRequestWatchdog();
2554
+ this.activeAdRequestToken = null;
2555
+ this.showAds = true;
2667
2556
  this.enforceAdHoldState();
2668
2557
  });
2669
2558
  this.ima.on("content_resume", () => {
2670
- if (this.config.debugAdTiming) {
2671
- console.log(
2672
- "[StormcloudVideoPlayer] IMA content_resume event received",
2673
- {
2674
- inAdBreak: this.inAdBreak,
2675
- pendingAds: this.adPodQueue.length
2676
- }
2677
- );
2678
- }
2559
+ console.log(`[DEBUG-POD] \u23F8\uFE0F content_resume | ad ${this.currentAdIndex}/${this.totalAdsInBreak}, queue=${this.adPodQueue.length}, remaining=${this.getRemainingAdMs()}ms`);
2679
2560
  this.clearAdFailsafeTimer();
2561
+ this.clearAdRequestWatchdog();
2562
+ this.activeAdRequestToken = null;
2563
+ this.showAds = false;
2680
2564
  if (!this.inAdBreak) {
2681
- if (this.config.debugAdTiming) {
2682
- console.log(
2683
- "[StormcloudVideoPlayer] Not in ad break - this shouldn't happen during pod"
2684
- );
2685
- }
2565
+ console.warn("[DEBUG-POD] \u26A0\uFE0F Not in ad break - shouldn't happen");
2686
2566
  return;
2687
2567
  }
2688
2568
  const remaining = this.getRemainingAdMs();
@@ -2690,33 +2570,17 @@ var StormcloudVideoPlayer = class {
2690
2570
  const nextPreloaded = this.findNextPreloadedAd();
2691
2571
  if (nextPreloaded) {
2692
2572
  this.currentAdIndex++;
2693
- if (this.config.debugAdTiming) {
2694
- console.log(
2695
- `[StormcloudVideoPlayer] Playing next preloaded ad in pod (${this.currentAdIndex}/${this.totalAdsInBreak}) - layer will stay visible if ad loads`
2696
- );
2697
- }
2573
+ console.log(`[DEBUG-POD] \u27A1\uFE0F Playing next ad ${this.currentAdIndex}/${this.totalAdsInBreak} (preloaded)`);
2698
2574
  this.playSingleAd(nextPreloaded).catch(() => {
2699
- if (this.config.debugAdTiming) {
2700
- console.error(
2701
- "[StormcloudVideoPlayer] Failed to play next ad in pod"
2702
- );
2703
- }
2575
+ console.error("[DEBUG-POD] \u274C Failed to play next ad");
2704
2576
  this.handleAdPodComplete();
2705
2577
  });
2706
2578
  } else {
2707
- if (this.config.debugAdTiming) {
2708
- console.log(
2709
- "[StormcloudVideoPlayer] No preloaded ads available - completing ad break"
2710
- );
2711
- }
2579
+ console.log("[DEBUG-POD] \u26A0\uFE0F No preloaded ads - ending pod");
2712
2580
  this.handleAdPodComplete();
2713
2581
  }
2714
2582
  } else {
2715
- if (this.config.debugAdTiming) {
2716
- console.log(
2717
- "[StormcloudVideoPlayer] No more ads in pod - completing ad break"
2718
- );
2719
- }
2583
+ console.log("[DEBUG-POD] \u2705 Pod complete (no more ads or time expired)");
2720
2584
  this.handleAdPodComplete();
2721
2585
  }
2722
2586
  });
@@ -3291,52 +3155,27 @@ var StormcloudVideoPlayer = class {
3291
3155
  let vastTagUrls = [];
3292
3156
  if (this.apiVastTagUrl) {
3293
3157
  vastTagUrls = [this.apiVastTagUrl];
3294
- if (this.config.debugAdTiming) {
3295
- console.log(
3296
- "[StormcloudVideoPlayer] Using VAST endpoint:",
3297
- this.apiVastTagUrl
3298
- );
3299
- }
3300
3158
  } else if (tags && tags.length > 0) {
3301
3159
  vastTagUrls = tags;
3302
- if (this.config.debugAdTiming) {
3303
- console.log(
3304
- "[StormcloudVideoPlayer] Using scheduled VAST tags (count: " + tags.length + "):",
3305
- tags
3306
- );
3307
- }
3308
3160
  } else {
3309
- if (this.config.debugAdTiming) {
3310
- console.log("[StormcloudVideoPlayer] No VAST tag available for ad");
3311
- }
3161
+ console.log("[DEBUG-POD] \u26A0\uFE0F No VAST tag available");
3312
3162
  return;
3313
3163
  }
3314
3164
  if (vastTagUrls.length > 0) {
3165
+ console.log(`[DEBUG-POD] \u{1F3AF} Starting ad break with ${vastTagUrls.length} ads`);
3315
3166
  this.adPodAllUrls = [...vastTagUrls];
3316
3167
  this.preloadingAdUrls.clear();
3317
3168
  this.vastToMediaUrlMap.clear();
3318
3169
  this.preloadedMediaUrls.clear();
3319
3170
  this.preloadingMediaUrls.clear();
3320
- this.logQueuedAdUrls(this.adPodAllUrls);
3321
- if (this.config.debugAdTiming) {
3322
- console.log(
3323
- `[StormcloudVideoPlayer] Capturing original audio state before ad break:`,
3324
- {
3325
- videoMuted: this.video.muted,
3326
- videoVolume: this.video.volume
3327
- }
3328
- );
3329
- }
3171
+ console.log(
3172
+ `[DEBUG-AUDIO] \u{1F4BE} Capturing original state | muted=${this.video.muted}, volume=${this.video.volume}`
3173
+ );
3330
3174
  this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);
3331
3175
  this.inAdBreak = true;
3332
3176
  this.currentAdIndex = 0;
3333
3177
  this.totalAdsInBreak = vastTagUrls.length;
3334
3178
  this.adPodQueue = [...vastTagUrls];
3335
- if (this.config.debugAdTiming) {
3336
- console.log(
3337
- `[StormcloudVideoPlayer] Starting ad pod with ${vastTagUrls.length} ads - preloading all ads in parallel (ad layer will show after ad loads)`
3338
- );
3339
- }
3340
3179
  this.preloadAllAdsInBackground().catch((error) => {
3341
3180
  if (this.config.debugAdTiming) {
3342
3181
  console.warn(
@@ -3348,12 +3187,7 @@ var StormcloudVideoPlayer = class {
3348
3187
  try {
3349
3188
  await this.playAdPod();
3350
3189
  } catch (error) {
3351
- if (this.config.debugAdTiming) {
3352
- console.error(
3353
- "[StormcloudVideoPlayer] Ad pod playback failed:",
3354
- error
3355
- );
3356
- }
3190
+ console.error("[DEBUG-POD] \u274C Pod playback failed:", error);
3357
3191
  this.handleAdFailure();
3358
3192
  }
3359
3193
  }
@@ -3365,19 +3199,13 @@ var StormcloudVideoPlayer = class {
3365
3199
  }
3366
3200
  async playAdPod() {
3367
3201
  if (this.adPodQueue.length === 0) {
3368
- if (this.config.debugAdTiming) {
3369
- console.log("[StormcloudVideoPlayer] No ads in pod to play");
3370
- }
3202
+ console.log("[DEBUG-POD] \u26A0\uFE0F No ads in pod");
3371
3203
  return;
3372
3204
  }
3373
3205
  await new Promise((resolve) => setTimeout(resolve, 500));
3374
3206
  const firstPreloaded = this.findNextPreloadedAd();
3375
3207
  if (!firstPreloaded) {
3376
- if (this.config.debugAdTiming) {
3377
- console.log(
3378
- "[StormcloudVideoPlayer] No preloaded ads available after waiting, trying first ad anyway"
3379
- );
3380
- }
3208
+ console.log("[DEBUG-POD] \u26A0\uFE0F No preloaded ads after wait, trying first ad");
3381
3209
  const firstAd = this.adPodQueue.shift();
3382
3210
  if (firstAd) {
3383
3211
  this.currentAdIndex++;
@@ -3386,11 +3214,7 @@ var StormcloudVideoPlayer = class {
3386
3214
  return;
3387
3215
  }
3388
3216
  this.currentAdIndex++;
3389
- if (this.config.debugAdTiming) {
3390
- console.log(
3391
- `[StormcloudVideoPlayer] Playing first preloaded ad ${this.currentAdIndex}/${this.totalAdsInBreak}`
3392
- );
3393
- }
3217
+ console.log(`[DEBUG-POD] \u{1F680} Starting pod with ad ${this.currentAdIndex}/${this.totalAdsInBreak}`);
3394
3218
  await this.playSingleAd(firstPreloaded);
3395
3219
  }
3396
3220
  findCurrentOrNextBreak(nowMs) {
@@ -3527,62 +3351,56 @@ var StormcloudVideoPlayer = class {
3527
3351
  this.ptsDriftEmaMs = this.ptsDriftEmaMs * (1 - alpha) + sampleMs * alpha;
3528
3352
  }
3529
3353
  async playSingleAd(vastTagUrl) {
3530
- if (this.config.debugAdTiming) {
3531
- console.log("[StormcloudVideoPlayer] Attempting to play ad:", vastTagUrl);
3532
- }
3354
+ console.log(`[DEBUG-POD] \u{1F3AC} playSingleAd | url=${vastTagUrl.substring(0, 60)}...`);
3533
3355
  if (this.ima.isAdPlaying()) {
3534
- if (this.config.debugAdTiming) {
3535
- console.warn(
3536
- "[StormcloudVideoPlayer] Ad already playing - skipping new ad request"
3537
- );
3538
- }
3356
+ console.warn("[DEBUG-POD] \u26A0\uFE0F Ad already playing - skipping request");
3539
3357
  return;
3540
3358
  }
3359
+ const requestToken = ++this.adRequestTokenCounter;
3541
3360
  const wasPreloaded = this.ima.hasPreloadedAd(vastTagUrl);
3542
- if (wasPreloaded && this.config.debugAdTiming) {
3543
- console.log(
3544
- `[StormcloudVideoPlayer] IMA SDK preloaded this ad already: ${vastTagUrl}`
3545
- );
3546
- }
3547
- this.startAdFailsafeTimer();
3361
+ this.activeAdRequestToken = requestToken;
3362
+ console.log(`[DEBUG-POD] \u{1F4DD} Request token=${requestToken}, preloaded=${wasPreloaded}`);
3363
+ this.startAdRequestWatchdog(requestToken);
3548
3364
  try {
3549
3365
  await this.ima.requestAds(vastTagUrl);
3366
+ this.clearAdRequestWatchdog();
3367
+ if (this.activeAdRequestToken !== requestToken) {
3368
+ console.warn(`[DEBUG-POD] \u26A0\uFE0F Token mismatch after requestAds (stale request)`);
3369
+ return;
3370
+ }
3550
3371
  try {
3551
- if (this.config.debugAdTiming) {
3552
- console.log(
3553
- "[StormcloudVideoPlayer] Ad request completed, attempting playback (ad layer will show when IMA triggers content pause)"
3554
- );
3555
- }
3372
+ this.startAdFailsafeTimer(requestToken);
3556
3373
  await this.ima.play();
3557
- this.showAds = true;
3558
- if (this.config.debugAdTiming) {
3559
- console.log(
3560
- "[StormcloudVideoPlayer] Ad playback started successfully, showAds = true"
3561
- );
3374
+ if (this.activeAdRequestToken === requestToken) {
3375
+ console.log(`[DEBUG-POD] \u2705 Ad play initiated (token=${requestToken})`);
3376
+ } else {
3377
+ console.warn(`[DEBUG-POD] \u26A0\uFE0F Token mismatch after play (stale request)`);
3562
3378
  }
3563
3379
  } catch (playError) {
3564
- if (this.config.debugAdTiming) {
3565
- console.log(
3566
- "[StormcloudVideoPlayer] No ads available, skipping playback"
3567
- );
3380
+ console.log("[DEBUG-POD] \u26A0\uFE0F No ads available from play()");
3381
+ this.clearAdFailsafeTimer();
3382
+ if (this.activeAdRequestToken === requestToken) {
3383
+ this.activeAdRequestToken = null;
3568
3384
  }
3569
3385
  this.handleAdFailure();
3570
3386
  return;
3571
3387
  }
3572
3388
  } catch (error) {
3573
- if (this.config.debugAdTiming) {
3574
- console.error("[StormcloudVideoPlayer] Ad playback failed:", error);
3389
+ console.error("[DEBUG-POD] \u274C Ad request failed:", error == null ? void 0 : error.message);
3390
+ this.clearAdRequestWatchdog();
3391
+ this.clearAdFailsafeTimer();
3392
+ if (this.activeAdRequestToken === requestToken) {
3393
+ this.activeAdRequestToken = null;
3575
3394
  }
3576
3395
  this.handleAdFailure();
3577
3396
  }
3578
3397
  }
3579
3398
  handleAdPodComplete() {
3580
3399
  var _a;
3581
- if (this.config.debugAdTiming) {
3582
- console.log(
3583
- "[StormcloudVideoPlayer] Handling ad pod completion - resuming content and hiding ad layer"
3584
- );
3585
- }
3400
+ console.log("[DEBUG-POD] \u{1F3C1} handleAdPodComplete - Ending ad break, restoring content");
3401
+ this.clearAdRequestWatchdog();
3402
+ this.clearAdFailsafeTimer();
3403
+ this.activeAdRequestToken = null;
3586
3404
  this.releaseAdHoldState();
3587
3405
  this.preloadingAdUrls.clear();
3588
3406
  this.vastToMediaUrlMap.clear();
@@ -3593,7 +3411,6 @@ var StormcloudVideoPlayer = class {
3593
3411
  this.currentAdBreakStartWallClockMs = void 0;
3594
3412
  this.clearAdStartTimer();
3595
3413
  this.clearAdStopTimer();
3596
- this.clearAdFailsafeTimer();
3597
3414
  this.adPodQueue = [];
3598
3415
  this.adPodAllUrls = [];
3599
3416
  this.showAds = false;
@@ -3605,70 +3422,84 @@ var StormcloudVideoPlayer = class {
3605
3422
  const originalVolume = typeof this.ima.getOriginalVolume === "function" ? this.ima.getOriginalVolume() : this.video.volume;
3606
3423
  this.video.muted = originalMutedState;
3607
3424
  this.video.volume = originalVolume;
3608
- if (this.config.debugAdTiming) {
3609
- console.log(
3610
- `[StormcloudVideoPlayer] Restored main video - muted: ${originalMutedState}, volume: ${this.video.volume}`
3611
- );
3612
- }
3425
+ console.log(
3426
+ `[DEBUG-AUDIO] \u{1F50A} Main video restored | muted=${originalMutedState}, volume=${originalVolume}`
3427
+ );
3613
3428
  if (!this.shouldContinueLiveStreamDuringAds() && this.video.paused) {
3614
- if (this.config.debugAdTiming) {
3615
- console.log("[StormcloudVideoPlayer] Resuming paused video");
3616
- }
3429
+ console.log("[DEBUG-FLOW] \u25B6\uFE0F Resuming main video playback");
3617
3430
  (_a = this.video.play()) == null ? void 0 : _a.catch((error) => {
3618
- if (this.config.debugAdTiming) {
3619
- console.error(
3620
- "[StormcloudVideoPlayer] Failed to resume video:",
3621
- error
3622
- );
3623
- }
3431
+ console.error("[DEBUG-ERROR] Failed to resume video:", error);
3624
3432
  });
3625
3433
  }
3626
3434
  }
3627
3435
  handleAdFailure() {
3628
- if (this.config.debugAdTiming) {
3629
- console.log(
3630
- "[StormcloudVideoPlayer] Handling ad failure - resuming content",
3631
- {
3632
- inAdBreak: this.inAdBreak,
3633
- showAds: this.showAds,
3634
- videoPaused: this.video.paused,
3635
- adPlaying: this.ima.isAdPlaying()
3636
- }
3637
- );
3638
- }
3436
+ console.log(
3437
+ `[DEBUG-POD] \u274C handleAdFailure | inBreak=${this.inAdBreak}, showAds=${this.showAds}, paused=${this.video.paused}`
3438
+ );
3639
3439
  this.handleAdPodComplete();
3640
3440
  }
3641
- startAdFailsafeTimer() {
3441
+ startAdRequestWatchdog(token) {
3442
+ var _a;
3443
+ this.clearAdRequestWatchdog();
3444
+ const timeoutMs = (_a = this.config.adFailsafeTimeoutMs) != null ? _a : 1e4;
3445
+ this.adRequestWatchdogToken = token;
3446
+ this.adRequestWatchdogId = window.setTimeout(() => {
3447
+ if (this.adRequestWatchdogToken !== token) {
3448
+ return;
3449
+ }
3450
+ this.adRequestWatchdogId = void 0;
3451
+ this.adRequestWatchdogToken = null;
3452
+ if (this.activeAdRequestToken === token) {
3453
+ this.activeAdRequestToken = null;
3454
+ }
3455
+ this.logAdState("ad_request_timeout", { token, timeoutMs });
3456
+ this.handleAdFailure();
3457
+ }, timeoutMs);
3458
+ this.logAdState("ad_request_watchdog_started", { token, timeoutMs });
3459
+ }
3460
+ clearAdRequestWatchdog() {
3461
+ if (this.adRequestWatchdogId != null) {
3462
+ clearTimeout(this.adRequestWatchdogId);
3463
+ this.adRequestWatchdogId = void 0;
3464
+ }
3465
+ if (this.adRequestWatchdogToken != null) {
3466
+ this.logAdState("ad_request_watchdog_cleared", {
3467
+ token: this.adRequestWatchdogToken
3468
+ });
3469
+ this.adRequestWatchdogToken = null;
3470
+ }
3471
+ }
3472
+ startAdFailsafeTimer(token) {
3642
3473
  var _a;
3643
3474
  this.clearAdFailsafeTimer();
3644
3475
  const failsafeMs = (_a = this.config.adFailsafeTimeoutMs) != null ? _a : 1e4;
3645
- if (this.config.debugAdTiming) {
3646
- console.log(
3647
- `[StormcloudVideoPlayer] Starting failsafe timer (${failsafeMs}ms)`
3648
- );
3649
- }
3476
+ this.adFailsafeToken = token;
3650
3477
  this.adFailsafeTimerId = window.setTimeout(() => {
3651
- const shouldTrigger = this.video.paused || this.showAds && !this.ima.isAdPlaying();
3652
- if (shouldTrigger) {
3653
- if (this.config.debugAdTiming) {
3654
- console.warn(
3655
- "[StormcloudVideoPlayer] Failsafe timer triggered - forcing video resume",
3656
- {
3657
- paused: this.video.paused,
3658
- showAds: this.showAds,
3659
- adPlaying: this.ima.isAdPlaying()
3660
- }
3661
- );
3662
- }
3663
- this.handleAdFailure();
3478
+ if (this.adFailsafeToken !== token) {
3479
+ return;
3664
3480
  }
3481
+ this.adFailsafeTimerId = void 0;
3482
+ this.adFailsafeToken = null;
3483
+ if (this.activeAdRequestToken === token) {
3484
+ this.activeAdRequestToken = null;
3485
+ }
3486
+ this.logAdState("ad_failsafe_triggered", {
3487
+ token,
3488
+ failsafeMs,
3489
+ videoPaused: this.video.paused,
3490
+ imaAdPlaying: this.ima.isAdPlaying()
3491
+ });
3492
+ this.handleAdFailure();
3665
3493
  }, failsafeMs);
3494
+ this.logAdState("ad_failsafe_started", { token, failsafeMs });
3666
3495
  }
3667
3496
  clearAdFailsafeTimer() {
3668
3497
  if (this.adFailsafeTimerId != null) {
3669
3498
  clearTimeout(this.adFailsafeTimerId);
3499
+ this.logAdState("ad_failsafe_cleared", { token: this.adFailsafeToken });
3670
3500
  this.adFailsafeTimerId = void 0;
3671
3501
  }
3502
+ this.adFailsafeToken = null;
3672
3503
  }
3673
3504
  selectVastTagsForBreak(b) {
3674
3505
  if (!b || !b.vastTagUrl) return void 0;
@@ -3683,16 +3514,32 @@ var StormcloudVideoPlayer = class {
3683
3514
  }
3684
3515
  console.log("[StormcloudVideoPlayer] ALL ad URLs queued:", urls);
3685
3516
  }
3517
+ logAdState(event, extra = {}) {
3518
+ if (!this.config.debugAdTiming) {
3519
+ return;
3520
+ }
3521
+ console.log("[StormcloudVideoPlayer][AdState]", {
3522
+ event,
3523
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
3524
+ showAds: this.showAds,
3525
+ adPlaying: this.ima.isAdPlaying(),
3526
+ inAdBreak: this.inAdBreak,
3527
+ activeAdRequestToken: this.activeAdRequestToken,
3528
+ ...extra
3529
+ });
3530
+ }
3686
3531
  enforceAdHoldState() {
3687
3532
  this.video.dataset.stormcloudAdPlaying = "true";
3688
3533
  this.video.muted = true;
3689
3534
  this.video.volume = 0;
3535
+ console.log("[DEBUG-LAYER] \u{1F512} Enforced ad hold state (main video muted)");
3690
3536
  if (typeof this.ima.showPlaceholder === "function") {
3691
3537
  this.ima.showPlaceholder();
3692
3538
  }
3693
3539
  }
3694
3540
  releaseAdHoldState() {
3695
3541
  delete this.video.dataset.stormcloudAdPlaying;
3542
+ console.log("[DEBUG-LAYER] \u{1F513} Released ad hold state");
3696
3543
  if (typeof this.ima.hidePlaceholder === "function") {
3697
3544
  this.ima.hidePlaceholder();
3698
3545
  }