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/dist/stormcloud-vp.min.js +2 -2
- package/lib/index.cjs +26 -191
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +26 -191
- package/lib/index.js.map +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +26 -191
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/player/StormcloudVideoPlayer.d.cts +1 -0
- package/lib/players/HlsPlayer.cjs +26 -191
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/index.cjs +26 -191
- package/lib/players/index.cjs.map +1 -1
- package/lib/sdk/ima.cjs +6 -80
- package/lib/sdk/ima.cjs.map +1 -1
- package/lib/ui/StormcloudVideoPlayer.cjs +26 -191
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/package.json +1 -1
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
|
|
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((
|
|
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
|
-
|
|
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
|
|
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("[
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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("[
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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() {
|