stormcloud-video-player 0.3.6 → 0.3.8

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,6 @@ function createImaController(video, options) {
289
289
  video.muted = true;
290
290
  video.volume = 0;
291
291
  contentVideoHidden = true;
292
- console.log("[DEBUG-LAYER] \u{1F534} Content video HIDDEN | muted=true, volume=0");
293
292
  }
294
293
  }
295
294
  function showContentVideo() {
@@ -301,9 +300,6 @@ function createImaController(video, options) {
301
300
  video.muted = originalMutedState;
302
301
  video.volume = originalVolume;
303
302
  contentVideoHidden = false;
304
- console.log(
305
- `[DEBUG-LAYER] \u{1F7E2} Content video RESTORED | muted=${originalMutedState}, volume=${originalVolume}`
306
- );
307
303
  }
308
304
  }
309
305
  function createAdVideoElement() {
@@ -324,13 +320,9 @@ function createImaController(video, options) {
324
320
  "canplay",
325
321
  () => {
326
322
  adVideo.style.opacity = "1";
327
- console.log("[DEBUG-LAYER] \u{1F4FA} Ad video element ready (canplay fired)");
328
323
  },
329
324
  { once: true }
330
325
  );
331
- console.log(
332
- `[DEBUG-AUDIO] \u{1F50A} Ad video created | volume=${adVideo.volume}, muted=${adVideo.muted}`
333
- );
334
326
  return adVideo;
335
327
  }
336
328
  function emit(event, payload) {
@@ -482,10 +474,8 @@ function createImaController(video, options) {
482
474
  function destroyAdsManager() {
483
475
  if (adsManager) {
484
476
  try {
485
- console.log("[IMA] Destroying existing ads manager");
486
477
  adsManager.destroy();
487
- } catch (error) {
488
- console.warn("[IMA] Error destroying ads manager:", error);
478
+ } catch {
489
479
  }
490
480
  adsManager = void 0;
491
481
  }
@@ -503,9 +493,6 @@ function createImaController(video, options) {
503
493
  if (!adVideoElement) {
504
494
  adVideoElement = createAdVideoElement();
505
495
  adContainerEl.appendChild(adVideoElement);
506
- console.log(
507
- "[IMA] Dedicated ad video element added to container"
508
- );
509
496
  }
510
497
  adDisplayContainer = new google.ima.AdDisplayContainer(
511
498
  adContainerEl,
@@ -513,9 +500,6 @@ function createImaController(video, options) {
513
500
  );
514
501
  try {
515
502
  (_a = adDisplayContainer.initialize) == null ? void 0 : _a.call(adDisplayContainer);
516
- console.log(
517
- "[IMA] AdDisplayContainer initialized with dedicated ad video"
518
- );
519
503
  } catch {
520
504
  }
521
505
  }
@@ -523,9 +507,6 @@ function createImaController(video, options) {
523
507
  });
524
508
  },
525
509
  async requestAds(vastTagUrl) {
526
- console.log("[IMA] \u{1F4E1} === requestAds() called ===");
527
- console.log("[IMA] VAST URL:", vastTagUrl);
528
- console.log("[IMA] This will fetch the ad from the server - no visual change yet");
529
510
  if (!vastTagUrl || vastTagUrl.trim() === "") {
530
511
  const error = new Error("VAST tag URL is empty or undefined");
531
512
  console.warn("[IMA] \u274C", error.message);
@@ -568,7 +549,6 @@ function createImaController(video, options) {
568
549
  lastAdTagUrl = vastTagUrl;
569
550
  retryAttempts = 0;
570
551
  if (!adDisplayContainer) {
571
- console.log("[IMA] Creating ad display container");
572
552
  const container = document.createElement("div");
573
553
  container.style.position = "absolute";
574
554
  container.style.left = "0";
@@ -591,25 +571,11 @@ function createImaController(video, options) {
591
571
  if (!adVideoElement) {
592
572
  adVideoElement = createAdVideoElement();
593
573
  adContainerEl.appendChild(adVideoElement);
594
- console.log(
595
- "[IMA] Dedicated ad video element created and added to container"
596
- );
597
574
  }
598
575
  adDisplayContainer = new google.ima.AdDisplayContainer(
599
576
  container,
600
577
  adVideoElement
601
578
  );
602
- try {
603
- adDisplayContainer.initialize();
604
- console.log(
605
- "[IMA] Ad display container initialized with dedicated ad video"
606
- );
607
- } catch (error) {
608
- console.warn(
609
- "[IMA] Failed to initialize ad display container:",
610
- error
611
- );
612
- }
613
579
  }
614
580
  const videoWidth = video.offsetWidth || video.clientWidth;
615
581
  const videoHeight = video.offsetHeight || video.clientHeight;
@@ -624,29 +590,17 @@ function createImaController(video, options) {
624
590
  return Promise.reject(error);
625
591
  }
626
592
  if (!adsLoader) {
627
- console.log("[IMA] Creating ads loader");
628
593
  const adsLoaderCls = new google.ima.AdsLoader(adDisplayContainer);
629
594
  adsLoader = adsLoaderCls;
630
595
  adsLoader.addEventListener(
631
596
  google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,
632
597
  (evt) => {
633
- console.log("[DEBUG-FLOW] \u2705 ADS_MANAGER_LOADED - Setting up manager");
634
598
  try {
635
599
  const adsRenderingSettings = new google.ima.AdsRenderingSettings();
636
600
  adsRenderingSettings.enablePreloading = true;
637
601
  adsManager = evt.getAdsManager(video, adsRenderingSettings);
638
602
  const AdEvent = google.ima.AdEvent.Type;
639
603
  const AdErrorEvent = google.ima.AdErrorEvent.Type;
640
- const keyEvents = ["STARTED", "COMPLETE", "CONTENT_PAUSE_REQUESTED", "CONTENT_RESUME_REQUESTED", "ALL_ADS_COMPLETED"];
641
- keyEvents.forEach((eventType) => {
642
- if (AdEvent[eventType]) {
643
- adsManager.addEventListener(AdEvent[eventType], (e) => {
644
- var _a, _b;
645
- const ad = (_a = e.getAd) == null ? void 0 : _a.call(e);
646
- console.log(`[DEBUG-FLOW] \u{1F3AC} ${eventType} | title=${((_b = ad == null ? void 0 : ad.getTitle) == null ? void 0 : _b.call(ad)) || "N/A"}`);
647
- });
648
- }
649
- });
650
604
  adsManager.addEventListener(
651
605
  AdErrorEvent.AD_ERROR,
652
606
  (errorEvent) => {
@@ -663,7 +617,6 @@ function createImaController(video, options) {
663
617
  if (adContainerEl) {
664
618
  adContainerEl.style.pointerEvents = "none";
665
619
  adContainerEl.style.display = "none";
666
- console.log("[DEBUG-LAYER] \u274C Ad container HIDDEN (error)");
667
620
  }
668
621
  }, 300);
669
622
  }
@@ -695,7 +648,6 @@ function createImaController(video, options) {
695
648
  adsManager.addEventListener(
696
649
  AdEvent.CONTENT_PAUSE_REQUESTED,
697
650
  () => {
698
- console.log("[DEBUG-FLOW] \u{1F3AF} CONTENT_PAUSE_REQUESTED - Ad request accepted");
699
651
  if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
700
652
  video.pause();
701
653
  }
@@ -705,15 +657,11 @@ function createImaController(video, options) {
705
657
  }
706
658
  );
707
659
  adsManager.addEventListener(AdEvent.STARTED, () => {
708
- console.log("[DEBUG-FLOW] \u25B6\uFE0F STARTED - Ad playing now");
709
660
  setAdPlayingFlag(true);
710
661
  hideContentVideo();
711
662
  if (adVideoElement) {
712
663
  adVideoElement.volume = originalMutedState ? 0 : originalVolume;
713
664
  adVideoElement.muted = originalMutedState;
714
- console.log(
715
- `[DEBUG-AUDIO] \u{1F50A} Ad audio set | volume=${adVideoElement.volume}, muted=${adVideoElement.muted}`
716
- );
717
665
  }
718
666
  if (adContainerEl) {
719
667
  adContainerEl.style.pointerEvents = "auto";
@@ -726,15 +674,12 @@ function createImaController(video, options) {
726
674
  adsManager.addEventListener(
727
675
  AdEvent.CONTENT_RESUME_REQUESTED,
728
676
  () => {
729
- console.log("[DEBUG-FLOW] \u23F8\uFE0F CONTENT_RESUME - Single ad done");
730
677
  adPlaying = false;
731
678
  setAdPlayingFlag(false);
732
- console.log("[DEBUG-LAYER] \u26A0\uFE0F Waiting for pod manager (more ads, placeholder, or done)");
733
679
  emit("content_resume");
734
680
  }
735
681
  );
736
682
  adsManager.addEventListener(AdEvent.ALL_ADS_COMPLETED, () => {
737
- console.log("[DEBUG-FLOW] \u{1F3C1} ALL_ADS_COMPLETED - Pod finished");
738
683
  adPlaying = false;
739
684
  setAdPlayingFlag(false);
740
685
  if (adContainerEl) {
@@ -744,19 +689,16 @@ function createImaController(video, options) {
744
689
  if (adContainerEl) {
745
690
  adContainerEl.style.pointerEvents = "none";
746
691
  adContainerEl.style.display = "none";
747
- console.log("[DEBUG-LAYER] \u26AB Ad container HIDDEN (pod done)");
748
692
  }
749
693
  }, 300);
750
694
  }
751
695
  showContentVideo();
752
696
  if (!(options == null ? void 0 : options.continueLiveStreamDuringAds) && video.paused) {
753
- video.play().catch((e) => {
754
- console.warn("[DEBUG-ERROR] Failed to resume video:", e);
697
+ video.play().catch(() => {
755
698
  });
756
699
  }
757
700
  emit("all_ads_completed");
758
701
  });
759
- console.log("[IMA] Ads manager event listeners attached");
760
702
  if (adsLoadedResolve) {
761
703
  adsLoadedResolve();
762
704
  adsLoadedResolve = void 0;
@@ -851,9 +793,7 @@ function createImaController(video, options) {
851
793
  }
852
794
  const preloadPromise = fetchVastDocument(vastTagUrl).then((xml) => {
853
795
  preloadedVast.set(vastTagUrl, xml);
854
- console.log("[IMA] Cached VAST response for preloading:", vastTagUrl);
855
- }).catch((error) => {
856
- console.warn("[IMA] Failed to preload VAST response:", error);
796
+ }).catch(() => {
857
797
  preloadedVast.delete(vastTagUrl);
858
798
  }).finally(() => {
859
799
  preloadingVast.delete(vastTagUrl);
@@ -866,7 +806,6 @@ function createImaController(video, options) {
866
806
  },
867
807
  async play() {
868
808
  var _a, _b;
869
- console.log("[DEBUG-FLOW] \u25B6\uFE0F play() - Starting ad playback");
870
809
  if (!((_a = window.google) == null ? void 0 : _a.ima) || !adDisplayContainer) {
871
810
  return Promise.reject(new Error("IMA SDK not available"));
872
811
  }
@@ -882,19 +821,15 @@ function createImaController(video, options) {
882
821
  if (adVideoElement) {
883
822
  adVideoElement.volume = adVolume;
884
823
  adVideoElement.muted = originalMutedState;
885
- console.log(
886
- `[DEBUG-AUDIO] \u{1F50A} Pre-start ad audio | volume=${adVolume}, muted=${originalMutedState}`
887
- );
888
824
  }
889
825
  try {
890
826
  adsManager.setVolume(adVolume);
891
- } catch (error) {
892
- console.warn("[DEBUG-ERROR] Failed to set IMA manager volume:", error);
827
+ } catch {
893
828
  }
894
829
  adsManager.start();
895
830
  return Promise.resolve();
896
831
  } catch (error) {
897
- console.error("[DEBUG-ERROR] \u274C Error starting ad:", error);
832
+ console.error("[IMA] \u274C Error starting ad:", error);
898
833
  adPlaying = false;
899
834
  setAdPlayingFlag(false);
900
835
  if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
@@ -906,7 +841,6 @@ function createImaController(video, options) {
906
841
  },
907
842
  async stop() {
908
843
  var _a;
909
- console.log("[DEBUG-FLOW] \u23F9\uFE0F stop() - Stopping ad playback");
910
844
  adPlaying = false;
911
845
  setAdPlayingFlag(false);
912
846
  if (adContainerEl) {
@@ -916,7 +850,6 @@ function createImaController(video, options) {
916
850
  if (adContainerEl) {
917
851
  adContainerEl.style.pointerEvents = "none";
918
852
  adContainerEl.style.display = "none";
919
- console.log("[DEBUG-LAYER] \u26AB Ad container HIDDEN (stop)");
920
853
  }
921
854
  }, 300);
922
855
  }
@@ -986,9 +919,6 @@ function createImaController(video, options) {
986
919
  },
987
920
  updateOriginalMutedState(muted, volume) {
988
921
  const nextVolume = typeof volume === "number" && !Number.isNaN(volume) ? Math.max(0, Math.min(1, volume)) : originalVolume;
989
- console.log(
990
- `[DEBUG-AUDIO] \u{1F4BE} Saved original state | muted: ${originalMutedState}->${muted}, volume: ${originalVolume}->${nextVolume}`
991
- );
992
922
  originalMutedState = muted;
993
923
  originalVolume = nextVolume;
994
924
  },
@@ -1003,15 +933,11 @@ function createImaController(video, options) {
1003
933
  if (adVideoElement && adPlaying) {
1004
934
  adVideoElement.volume = clampedVolume;
1005
935
  adVideoElement.muted = clampedVolume === 0;
1006
- console.log(
1007
- `[DEBUG-AUDIO] \u{1F50A} Ad volume changed | volume=${clampedVolume}, muted=${clampedVolume === 0}`
1008
- );
1009
936
  }
1010
937
  if (adsManager && adPlaying) {
1011
938
  try {
1012
939
  adsManager.setVolume(clampedVolume);
1013
- } catch (error) {
1014
- console.warn("[DEBUG-ERROR] Failed to set IMA manager volume:", error);
940
+ } catch {
1015
941
  }
1016
942
  }
1017
943
  },
@@ -2229,6 +2155,7 @@ var StormcloudVideoPlayer = class {
2229
2155
  this.fetchedAdDurations = /* @__PURE__ */ new Map();
2230
2156
  this.targetAdBreakDurationMs = null;
2231
2157
  this.isAdaptiveMode = false;
2158
+ this.failedVastUrls = /* @__PURE__ */ new Set();
2232
2159
  initializePolyfills();
2233
2160
  const browserOverrides = getBrowserConfigOverrides();
2234
2161
  this.config = { ...config, ...browserOverrides };
@@ -2501,51 +2428,37 @@ var StormcloudVideoPlayer = class {
2501
2428
  });
2502
2429
  this.ima.on("ad_error", (errorPayload) => {
2503
2430
  const remaining = this.getRemainingAdMs();
2504
- console.error(
2505
- `[DEBUG-POD] \u274C ad_error event | inBreak=${this.inAdBreak}, queue=${this.adPodQueue.length}, remaining=${remaining}ms`,
2506
- errorPayload ? `
2507
- Error details: ${JSON.stringify(errorPayload)}` : ""
2508
- );
2431
+ console.error("[AD-ERROR] Ad playback failed", errorPayload || "");
2509
2432
  if (this.inAdBreak) {
2510
2433
  if (remaining > 500 && this.adPodQueue.length > 0) {
2511
2434
  const nextPreloaded = this.findNextPreloadedAd();
2512
2435
  if (nextPreloaded) {
2513
2436
  this.currentAdIndex++;
2514
- console.log(
2515
- `[DEBUG-POD] \u27A1\uFE0F Trying next ad after error (${this.currentAdIndex}/${this.totalAdsInBreak})`
2516
- );
2517
2437
  this.playSingleAd(nextPreloaded).catch(() => {
2518
2438
  this.handleAdFailure();
2519
2439
  });
2520
2440
  } else {
2521
- console.log("[DEBUG-POD] \u26A0\uFE0F No more preloaded ads - calling handleAdFailure");
2522
2441
  this.handleAdFailure();
2523
2442
  }
2524
2443
  } else {
2525
- console.log("[DEBUG-POD] \u26A0\uFE0F No more ads or time - calling handleAdFailure");
2526
2444
  this.handleAdFailure();
2527
2445
  }
2528
2446
  } else {
2529
- console.log("[DEBUG-POD] \u26A0\uFE0F Error before ad break established");
2530
2447
  this.handleAdFailure();
2531
2448
  }
2532
2449
  });
2533
2450
  this.ima.on("content_pause", () => {
2534
- console.log(`[DEBUG-POD] \u{1F3AF} content_pause (AD STARTING!) | ad ${this.currentAdIndex}/${this.totalAdsInBreak}, queue=${this.adPodQueue.length}`);
2535
2451
  this.clearAdFailsafeTimer();
2536
2452
  this.clearAdRequestWatchdog();
2537
2453
  this.activeAdRequestToken = null;
2538
2454
  this.showAds = true;
2539
- console.log("[DEBUG-LAYER] \u{1F3AC} Layers: Main=hidden, Ad=visible, Placeholder=no");
2540
2455
  });
2541
2456
  this.ima.on("content_resume", () => {
2542
- console.log(`[DEBUG-POD] \u23F8\uFE0F content_resume | ad ${this.currentAdIndex}/${this.totalAdsInBreak}, queue=${this.adPodQueue.length}, remaining=${this.getRemainingAdMs()}ms`);
2543
2457
  this.clearAdFailsafeTimer();
2544
2458
  this.clearAdRequestWatchdog();
2545
2459
  this.activeAdRequestToken = null;
2546
2460
  this.showAds = false;
2547
2461
  if (!this.inAdBreak) {
2548
- console.warn("[DEBUG-POD] \u26A0\uFE0F Not in ad break - shouldn't happen");
2549
2462
  return;
2550
2463
  }
2551
2464
  const remaining = this.getRemainingAdMs();
@@ -2553,17 +2466,13 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
2553
2466
  const nextPreloaded = this.findNextPreloadedAd();
2554
2467
  if (nextPreloaded) {
2555
2468
  this.currentAdIndex++;
2556
- console.log(`[DEBUG-POD] \u27A1\uFE0F Playing next ad ${this.currentAdIndex}/${this.totalAdsInBreak} (preloaded)`);
2557
2469
  this.playSingleAd(nextPreloaded).catch(() => {
2558
- console.error("[DEBUG-POD] \u274C Failed to play next ad");
2559
2470
  this.handleAdPodComplete();
2560
2471
  });
2561
2472
  } else {
2562
- console.log("[DEBUG-POD] \u26A0\uFE0F No preloaded ads - ending pod");
2563
2473
  this.handleAdPodComplete();
2564
2474
  }
2565
2475
  } else {
2566
- console.log("[DEBUG-POD] \u2705 Pod complete (no more ads or time expired)");
2567
2476
  this.handleAdPodComplete();
2568
2477
  }
2569
2478
  });
@@ -2717,9 +2626,6 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
2717
2626
  }
2718
2627
  if (marker.type === "start") {
2719
2628
  if (this.inAdBreak) {
2720
- console.log(
2721
- `[DEBUG-POD] \u26A0\uFE0F SCTE-35 start marker ignored - already in ad break (currentTime: ${this.video.currentTime})`
2722
- );
2723
2629
  return;
2724
2630
  }
2725
2631
  this.inAdBreak = true;
@@ -2788,9 +2694,6 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
2788
2694
  return;
2789
2695
  }
2790
2696
  if (marker.type === "progress" && this.inAdBreak) {
2791
- console.log(
2792
- `[DEBUG-POD] \u{1F4CA} SCTE-35 progress marker (currentTime: ${this.video.currentTime})`
2793
- );
2794
2697
  if (marker.durationSeconds != null) {
2795
2698
  this.expectedAdBreakDurationMs = marker.durationSeconds * 1e3;
2796
2699
  }
@@ -2803,7 +2706,6 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
2803
2706
  this.scheduleAdStopCountdown(remainingMs);
2804
2707
  }
2805
2708
  if (!this.ima.isAdPlaying() && this.activeAdRequestToken === null) {
2806
- console.log("[DEBUG-POD] \u{1F4CA} Progress marker: no ad playing, attempting to start");
2807
2709
  const scheduled = this.findCurrentOrNextBreak(
2808
2710
  this.video.currentTime * 1e3
2809
2711
  );
@@ -2815,24 +2717,16 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
2815
2717
  this.playSingleAd(first).catch(() => {
2816
2718
  });
2817
2719
  }
2818
- } else {
2819
- console.log(
2820
- `[DEBUG-POD] \u{1F4CA} Progress marker: ad playing or request active (playing=${this.ima.isAdPlaying()}, token=${this.activeAdRequestToken})`
2821
- );
2822
2720
  }
2823
2721
  return;
2824
2722
  }
2825
2723
  if (marker.type === "end") {
2826
- console.log(
2827
- `[DEBUG-POD] \u{1F3C1} SCTE-35 end marker received (currentTime: ${this.video.currentTime})`
2828
- );
2829
2724
  this.inAdBreak = false;
2830
2725
  this.expectedAdBreakDurationMs = void 0;
2831
2726
  this.currentAdBreakStartWallClockMs = void 0;
2832
2727
  this.clearAdStartTimer();
2833
2728
  this.clearAdStopTimer();
2834
2729
  if (this.ima.isAdPlaying()) {
2835
- console.log("[DEBUG-POD] \u{1F6D1} Stopping ad due to SCTE-35 end marker");
2836
2730
  this.ima.stop().catch(() => {
2837
2731
  });
2838
2732
  }
@@ -3233,21 +3127,17 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
3233
3127
  } else if (tags && tags.length > 0) {
3234
3128
  vastTagUrls = tags;
3235
3129
  } else {
3236
- console.log("[DEBUG-POD] \u26A0\uFE0F No VAST tag available");
3237
3130
  return;
3238
3131
  }
3239
3132
  if (vastTagUrls.length > 0) {
3240
- console.log(`[DEBUG-POD] \u{1F3AF} Starting ad break with ${vastTagUrls.length} ads`);
3241
3133
  this.adPodAllUrls = [...vastTagUrls];
3242
3134
  this.preloadingAdUrls.clear();
3243
3135
  this.vastToMediaUrlMap.clear();
3244
3136
  this.preloadedMediaUrls.clear();
3245
3137
  this.preloadingMediaUrls.clear();
3138
+ this.failedVastUrls.clear();
3246
3139
  const currentMuted = this.video.muted;
3247
3140
  const currentVolume = this.video.volume;
3248
- console.log(
3249
- `[DEBUG-AUDIO] \u{1F4BE} Capturing ORIGINAL state (once) | muted=${currentMuted}, volume=${currentVolume}`
3250
- );
3251
3141
  this.ima.updateOriginalMutedState(currentMuted, currentVolume);
3252
3142
  this.inAdBreak = true;
3253
3143
  this.currentAdIndex = 0;
@@ -3308,40 +3198,27 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
3308
3198
  }
3309
3199
  async playAdPod() {
3310
3200
  if (this.adPodQueue.length === 0) {
3311
- console.log("[DEBUG-POD] \u26A0\uFE0F No ads in pod");
3312
3201
  return;
3313
3202
  }
3314
3203
  const waitTime = this.isAdaptiveMode ? 50 : 500;
3315
3204
  await new Promise((resolve) => setTimeout(resolve, waitTime));
3316
- if (this.config.debugAdTiming) {
3317
- console.log(
3318
- `[DEBUG-POD] \u{1F50D} Looking for preloaded ad in queue of ${this.adPodQueue.length} URLs`
3319
- );
3320
- }
3321
3205
  const firstPreloaded = this.findNextPreloadedAd();
3322
3206
  if (!firstPreloaded) {
3323
- console.log("[DEBUG-POD] \u26A0\uFE0F No preloaded ads found, trying first ad from queue");
3324
3207
  const firstAd = this.adPodQueue.shift();
3325
3208
  if (firstAd) {
3326
3209
  this.currentAdIndex++;
3327
- console.log(`[DEBUG-POD] \u{1F3AC} Attempting to play first ad (not preloaded): ${firstAd.substring(0, 60)}...`);
3328
3210
  try {
3329
3211
  await this.playSingleAd(firstAd);
3330
3212
  } catch (error) {
3331
- console.log("[DEBUG-POD] \u26A0\uFE0F First ad failed, error handler will retry");
3332
3213
  return;
3333
3214
  }
3334
- } else {
3335
- console.log("[DEBUG-POD] \u274C No ads available in queue");
3336
3215
  }
3337
3216
  return;
3338
3217
  }
3339
3218
  this.currentAdIndex++;
3340
- console.log(`[DEBUG-POD] \u{1F680} Starting pod with ad ${this.currentAdIndex}/${this.totalAdsInBreak}`);
3341
3219
  try {
3342
3220
  await this.playSingleAd(firstPreloaded);
3343
3221
  } catch (error) {
3344
- console.log("[DEBUG-POD] \u26A0\uFE0F First ad failed, error handler will retry");
3345
3222
  }
3346
3223
  }
3347
3224
  findCurrentOrNextBreak(nowMs) {
@@ -3421,15 +3298,9 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
3421
3298
  const overrunMs = Math.max(0, elapsedSinceStartMs - expectedDurationMs);
3422
3299
  const shouldExtendAdBreak = (adPlaying || pendingAds || this.showAds) && overrunMs < maxExtensionMs;
3423
3300
  if (shouldExtendAdBreak) {
3424
- console.log(
3425
- `[DEBUG-POD] \u23F3 Extending ad break | elapsed=${elapsedSinceStartMs}ms, expected=${expectedDurationMs}ms, overrun=${overrunMs}ms`
3426
- );
3427
3301
  this.scheduleAdStopCountdown(checkIntervalMs);
3428
3302
  return;
3429
3303
  }
3430
- console.log(
3431
- `[DEBUG-POD] \u23F1\uFE0F Ad break duration expired | elapsed=${elapsedSinceStartMs}ms, expected=${expectedDurationMs}ms`
3432
- );
3433
3304
  if (adPlaying) {
3434
3305
  this.ima.stop().catch(() => {
3435
3306
  });
@@ -3462,42 +3333,29 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
3462
3333
  this.ptsDriftEmaMs = this.ptsDriftEmaMs * (1 - alpha) + sampleMs * alpha;
3463
3334
  }
3464
3335
  async playSingleAd(vastTagUrl) {
3465
- console.log(`[DEBUG-POD] \u{1F3AC} playSingleAd | url=${vastTagUrl.substring(0, 60)}...`);
3466
3336
  if (this.ima.isAdPlaying()) {
3467
- console.warn("[DEBUG-POD] \u26A0\uFE0F Ad already playing - skipping request");
3337
+ return;
3338
+ }
3339
+ if (this.failedVastUrls.has(vastTagUrl)) {
3340
+ console.warn("[AD-ERROR] Skipping already-failed VAST URL:", vastTagUrl.substring(0, 60));
3341
+ this.handleAdFailure();
3468
3342
  return;
3469
3343
  }
3470
3344
  const requestToken = ++this.adRequestTokenCounter;
3471
- const wasPreloaded = this.ima.hasPreloadedAd(vastTagUrl);
3472
3345
  this.activeAdRequestToken = requestToken;
3473
- console.log(`[DEBUG-POD] \u{1F4DD} Request token=${requestToken}, preloaded=${wasPreloaded}`);
3474
3346
  this.startAdRequestWatchdog(requestToken);
3475
3347
  try {
3476
- console.log(`[DEBUG-POD] \u{1F4E1} Calling ima.requestAds() for token=${requestToken}...`);
3477
3348
  await this.ima.requestAds(vastTagUrl);
3478
- console.log(`[DEBUG-POD] \u2705 ima.requestAds() completed successfully`);
3479
3349
  this.clearAdRequestWatchdog();
3480
3350
  if (this.activeAdRequestToken !== requestToken) {
3481
- console.warn(`[DEBUG-POD] \u26A0\uFE0F Token mismatch after requestAds (stale request)`);
3482
3351
  return;
3483
3352
  }
3484
- console.log(`[DEBUG-POD] \u{1F4FA} Calling ima.play() to start ad playback...`);
3485
- console.log(`[DEBUG-POD] \u{1F4CA} Video element state: paused=${this.video.paused}, muted=${this.video.muted}, readyState=${this.video.readyState}`);
3486
3353
  try {
3487
3354
  this.startAdFailsafeTimer(requestToken);
3488
3355
  await this.ima.play();
3489
- if (this.activeAdRequestToken === requestToken) {
3490
- console.log(`[DEBUG-POD] \u2705 Ad play initiated successfully (token=${requestToken})`);
3491
- } else {
3492
- console.warn(`[DEBUG-POD] \u26A0\uFE0F Token mismatch after play (stale request)`);
3493
- }
3494
3356
  } catch (playError) {
3495
- console.error(
3496
- "[DEBUG-POD] \u274C Failed to play ad:",
3497
- playError instanceof Error ? playError.message : playError,
3498
- "\nFull error:",
3499
- playError
3500
- );
3357
+ console.error("[AD-ERROR] Failed to play ad:", playError);
3358
+ this.failedVastUrls.add(vastTagUrl);
3501
3359
  this.clearAdFailsafeTimer();
3502
3360
  if (this.activeAdRequestToken === requestToken) {
3503
3361
  this.activeAdRequestToken = null;
@@ -3506,7 +3364,8 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
3506
3364
  return;
3507
3365
  }
3508
3366
  } catch (error) {
3509
- console.error("[DEBUG-POD] \u274C Ad request failed:", error == null ? void 0 : error.message);
3367
+ console.error("[AD-ERROR] Ad request failed:", error == null ? void 0 : error.message);
3368
+ this.failedVastUrls.add(vastTagUrl);
3510
3369
  this.clearAdRequestWatchdog();
3511
3370
  this.clearAdFailsafeTimer();
3512
3371
  if (this.activeAdRequestToken === requestToken) {
@@ -3517,7 +3376,6 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
3517
3376
  }
3518
3377
  handleAdPodComplete() {
3519
3378
  var _a;
3520
- console.log("[DEBUG-POD] \u{1F3C1} handleAdPodComplete - Ending ad break, restoring content");
3521
3379
  this.clearAdRequestWatchdog();
3522
3380
  this.clearAdFailsafeTimer();
3523
3381
  this.activeAdRequestToken = null;
@@ -3539,10 +3397,6 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
3539
3397
  });
3540
3398
  const restoredMuted = this.ima.getOriginalMutedState();
3541
3399
  const restoredVolume = this.ima.getOriginalVolume();
3542
- console.log(
3543
- `[DEBUG-AUDIO] \u{1F50A} Audio restored by IMA | muted=${restoredMuted}, volume=${restoredVolume}`
3544
- );
3545
- console.log("[DEBUG-LAYER] \u{1F3AC} Layers: Main=visible, Ad=hidden, Placeholder=no");
3546
3400
  if (this.video.muted !== restoredMuted) {
3547
3401
  this.video.muted = restoredMuted;
3548
3402
  }
@@ -3550,16 +3404,14 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
3550
3404
  this.video.volume = restoredVolume;
3551
3405
  }
3552
3406
  if (!this.shouldContinueLiveStreamDuringAds() && this.video.paused) {
3553
- console.log("[DEBUG-FLOW] \u25B6\uFE0F Resuming main video playback");
3554
- (_a = this.video.play()) == null ? void 0 : _a.catch((error) => {
3555
- console.error("[DEBUG-ERROR] Failed to resume video:", error);
3407
+ (_a = this.video.play()) == null ? void 0 : _a.catch(() => {
3556
3408
  });
3557
3409
  }
3558
3410
  }
3559
3411
  handleAdFailure() {
3560
- console.log("[DEBUG-POD] \u274C handleAdFailure - skipping to next ad or ending break");
3561
3412
  const remaining = this.getRemainingAdMs();
3562
- if (remaining > 500 && this.adPodQueue.length > 0) {
3413
+ const availableAds = this.adPodQueue.filter((url) => !this.failedVastUrls.has(url)).length;
3414
+ if (remaining > 500 && availableAds > 0) {
3563
3415
  if (this.isAdaptiveMode && this.currentAdIndex <= 1) {
3564
3416
  console.log("[ADAPTIVE-POD] \u23F3 First ad failed, waiting for sequential preload to catch up...");
3565
3417
  setTimeout(() => {
@@ -3570,14 +3422,13 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
3570
3422
  const nextPreloaded = this.findNextPreloadedAd();
3571
3423
  if (nextPreloaded) {
3572
3424
  this.currentAdIndex++;
3573
- console.log(`[DEBUG-POD] \u27A1\uFE0F Trying next ad after failure (${this.currentAdIndex}/${this.totalAdsInBreak})`);
3574
3425
  this.playSingleAd(nextPreloaded).catch(() => {
3575
3426
  this.handleAdPodComplete();
3576
3427
  });
3577
3428
  return;
3578
3429
  }
3579
3430
  }
3580
- console.log("[DEBUG-POD] \u23F9\uFE0F Ending ad break after failure");
3431
+ console.error("[AD-ERROR] All ads failed or time expired. Failed URLs:", this.failedVastUrls.size);
3581
3432
  this.handleAdPodComplete();
3582
3433
  }
3583
3434
  tryNextAdWithRetry(retryCount) {
@@ -4030,37 +3881,21 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
4030
3881
  }
4031
3882
  findNextPreloadedAd() {
4032
3883
  var _a, _b, _c;
4033
- if (this.config.debugAdTiming) {
4034
- console.log(
4035
- `[DEBUG-POD] \u{1F50E} Searching for preloaded ad in queue (${this.adPodQueue.length} URLs, ${this.preloadedMediaUrls.size} media preloaded, ${this.vastToMediaUrlMap.size} VAST mappings)`
4036
- );
4037
- }
4038
3884
  for (let i = 0; i < this.adPodQueue.length; i++) {
4039
3885
  const vastTagUrl = this.adPodQueue[i];
4040
3886
  if (!vastTagUrl) continue;
3887
+ if (this.failedVastUrls.has(vastTagUrl)) {
3888
+ console.warn("[AD-ERROR] Skipping failed URL in queue");
3889
+ continue;
3890
+ }
4041
3891
  const hasImaPreload = (_c = (_b = (_a = this.ima).hasPreloadedAd) == null ? void 0 : _b.call(_a, vastTagUrl)) != null ? _c : false;
4042
3892
  const mediaUrls = this.vastToMediaUrlMap.get(vastTagUrl);
4043
3893
  const hasMediaPreload = mediaUrls && mediaUrls.length > 0 ? this.preloadedMediaUrls.has(mediaUrls[0]) : false;
4044
- if (this.config.debugAdTiming) {
4045
- console.log(
4046
- `[DEBUG-POD] Ad ${i}: IMA=${hasImaPreload}, Media=${hasMediaPreload}, MediaURLs=${(mediaUrls == null ? void 0 : mediaUrls.length) || 0}, URL=${vastTagUrl.substring(0, 60)}...`
4047
- );
4048
- }
4049
3894
  if (hasImaPreload || hasMediaPreload) {
4050
- if (this.config.debugAdTiming) {
4051
- console.log(
4052
- `[DEBUG-POD] \u2705 Found preloaded ad at index ${i}`
4053
- );
4054
- }
4055
3895
  this.adPodQueue.splice(0, i + 1);
4056
3896
  return vastTagUrl;
4057
3897
  }
4058
3898
  }
4059
- if (this.config.debugAdTiming) {
4060
- console.log(
4061
- `[DEBUG-POD] \u274C No preloaded ads found in queue`
4062
- );
4063
- }
4064
3899
  return void 0;
4065
3900
  }
4066
3901
  getRemainingAdMs() {