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/players/index.cjs
CHANGED
|
@@ -264,7 +264,6 @@ function createImaController(video, options) {
|
|
|
264
264
|
video.muted = true;
|
|
265
265
|
video.volume = 0;
|
|
266
266
|
contentVideoHidden = true;
|
|
267
|
-
console.log("[DEBUG-LAYER] \u{1F534} Content video HIDDEN | muted=true, volume=0");
|
|
268
267
|
}
|
|
269
268
|
}
|
|
270
269
|
function showContentVideo() {
|
|
@@ -276,9 +275,6 @@ function createImaController(video, options) {
|
|
|
276
275
|
video.muted = originalMutedState;
|
|
277
276
|
video.volume = originalVolume;
|
|
278
277
|
contentVideoHidden = false;
|
|
279
|
-
console.log(
|
|
280
|
-
`[DEBUG-LAYER] \u{1F7E2} Content video RESTORED | muted=${originalMutedState}, volume=${originalVolume}`
|
|
281
|
-
);
|
|
282
278
|
}
|
|
283
279
|
}
|
|
284
280
|
function createAdVideoElement() {
|
|
@@ -299,13 +295,9 @@ function createImaController(video, options) {
|
|
|
299
295
|
"canplay",
|
|
300
296
|
() => {
|
|
301
297
|
adVideo.style.opacity = "1";
|
|
302
|
-
console.log("[DEBUG-LAYER] \u{1F4FA} Ad video element ready (canplay fired)");
|
|
303
298
|
},
|
|
304
299
|
{ once: true }
|
|
305
300
|
);
|
|
306
|
-
console.log(
|
|
307
|
-
`[DEBUG-AUDIO] \u{1F50A} Ad video created | volume=${adVideo.volume}, muted=${adVideo.muted}`
|
|
308
|
-
);
|
|
309
301
|
return adVideo;
|
|
310
302
|
}
|
|
311
303
|
function emit(event, payload) {
|
|
@@ -457,10 +449,8 @@ function createImaController(video, options) {
|
|
|
457
449
|
function destroyAdsManager() {
|
|
458
450
|
if (adsManager) {
|
|
459
451
|
try {
|
|
460
|
-
console.log("[IMA] Destroying existing ads manager");
|
|
461
452
|
adsManager.destroy();
|
|
462
|
-
} catch
|
|
463
|
-
console.warn("[IMA] Error destroying ads manager:", error);
|
|
453
|
+
} catch {
|
|
464
454
|
}
|
|
465
455
|
adsManager = void 0;
|
|
466
456
|
}
|
|
@@ -478,9 +468,6 @@ function createImaController(video, options) {
|
|
|
478
468
|
if (!adVideoElement) {
|
|
479
469
|
adVideoElement = createAdVideoElement();
|
|
480
470
|
adContainerEl.appendChild(adVideoElement);
|
|
481
|
-
console.log(
|
|
482
|
-
"[IMA] Dedicated ad video element added to container"
|
|
483
|
-
);
|
|
484
471
|
}
|
|
485
472
|
adDisplayContainer = new google.ima.AdDisplayContainer(
|
|
486
473
|
adContainerEl,
|
|
@@ -488,9 +475,6 @@ function createImaController(video, options) {
|
|
|
488
475
|
);
|
|
489
476
|
try {
|
|
490
477
|
(_a = adDisplayContainer.initialize) == null ? void 0 : _a.call(adDisplayContainer);
|
|
491
|
-
console.log(
|
|
492
|
-
"[IMA] AdDisplayContainer initialized with dedicated ad video"
|
|
493
|
-
);
|
|
494
478
|
} catch {
|
|
495
479
|
}
|
|
496
480
|
}
|
|
@@ -498,9 +482,6 @@ function createImaController(video, options) {
|
|
|
498
482
|
});
|
|
499
483
|
},
|
|
500
484
|
async requestAds(vastTagUrl) {
|
|
501
|
-
console.log("[IMA] \u{1F4E1} === requestAds() called ===");
|
|
502
|
-
console.log("[IMA] VAST URL:", vastTagUrl);
|
|
503
|
-
console.log("[IMA] This will fetch the ad from the server - no visual change yet");
|
|
504
485
|
if (!vastTagUrl || vastTagUrl.trim() === "") {
|
|
505
486
|
const error = new Error("VAST tag URL is empty or undefined");
|
|
506
487
|
console.warn("[IMA] \u274C", error.message);
|
|
@@ -543,7 +524,6 @@ function createImaController(video, options) {
|
|
|
543
524
|
lastAdTagUrl = vastTagUrl;
|
|
544
525
|
retryAttempts = 0;
|
|
545
526
|
if (!adDisplayContainer) {
|
|
546
|
-
console.log("[IMA] Creating ad display container");
|
|
547
527
|
const container = document.createElement("div");
|
|
548
528
|
container.style.position = "absolute";
|
|
549
529
|
container.style.left = "0";
|
|
@@ -566,25 +546,11 @@ function createImaController(video, options) {
|
|
|
566
546
|
if (!adVideoElement) {
|
|
567
547
|
adVideoElement = createAdVideoElement();
|
|
568
548
|
adContainerEl.appendChild(adVideoElement);
|
|
569
|
-
console.log(
|
|
570
|
-
"[IMA] Dedicated ad video element created and added to container"
|
|
571
|
-
);
|
|
572
549
|
}
|
|
573
550
|
adDisplayContainer = new google.ima.AdDisplayContainer(
|
|
574
551
|
container,
|
|
575
552
|
adVideoElement
|
|
576
553
|
);
|
|
577
|
-
try {
|
|
578
|
-
adDisplayContainer.initialize();
|
|
579
|
-
console.log(
|
|
580
|
-
"[IMA] Ad display container initialized with dedicated ad video"
|
|
581
|
-
);
|
|
582
|
-
} catch (error) {
|
|
583
|
-
console.warn(
|
|
584
|
-
"[IMA] Failed to initialize ad display container:",
|
|
585
|
-
error
|
|
586
|
-
);
|
|
587
|
-
}
|
|
588
554
|
}
|
|
589
555
|
const videoWidth = video.offsetWidth || video.clientWidth;
|
|
590
556
|
const videoHeight = video.offsetHeight || video.clientHeight;
|
|
@@ -599,29 +565,17 @@ function createImaController(video, options) {
|
|
|
599
565
|
return Promise.reject(error);
|
|
600
566
|
}
|
|
601
567
|
if (!adsLoader) {
|
|
602
|
-
console.log("[IMA] Creating ads loader");
|
|
603
568
|
const adsLoaderCls = new google.ima.AdsLoader(adDisplayContainer);
|
|
604
569
|
adsLoader = adsLoaderCls;
|
|
605
570
|
adsLoader.addEventListener(
|
|
606
571
|
google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,
|
|
607
572
|
(evt) => {
|
|
608
|
-
console.log("[DEBUG-FLOW] \u2705 ADS_MANAGER_LOADED - Setting up manager");
|
|
609
573
|
try {
|
|
610
574
|
const adsRenderingSettings = new google.ima.AdsRenderingSettings();
|
|
611
575
|
adsRenderingSettings.enablePreloading = true;
|
|
612
576
|
adsManager = evt.getAdsManager(video, adsRenderingSettings);
|
|
613
577
|
const AdEvent = google.ima.AdEvent.Type;
|
|
614
578
|
const AdErrorEvent = google.ima.AdErrorEvent.Type;
|
|
615
|
-
const keyEvents = ["STARTED", "COMPLETE", "CONTENT_PAUSE_REQUESTED", "CONTENT_RESUME_REQUESTED", "ALL_ADS_COMPLETED"];
|
|
616
|
-
keyEvents.forEach((eventType) => {
|
|
617
|
-
if (AdEvent[eventType]) {
|
|
618
|
-
adsManager.addEventListener(AdEvent[eventType], (e) => {
|
|
619
|
-
var _a, _b;
|
|
620
|
-
const ad = (_a = e.getAd) == null ? void 0 : _a.call(e);
|
|
621
|
-
console.log(`[DEBUG-FLOW] \u{1F3AC} ${eventType} | title=${((_b = ad == null ? void 0 : ad.getTitle) == null ? void 0 : _b.call(ad)) || "N/A"}`);
|
|
622
|
-
});
|
|
623
|
-
}
|
|
624
|
-
});
|
|
625
579
|
adsManager.addEventListener(
|
|
626
580
|
AdErrorEvent.AD_ERROR,
|
|
627
581
|
(errorEvent) => {
|
|
@@ -638,7 +592,6 @@ function createImaController(video, options) {
|
|
|
638
592
|
if (adContainerEl) {
|
|
639
593
|
adContainerEl.style.pointerEvents = "none";
|
|
640
594
|
adContainerEl.style.display = "none";
|
|
641
|
-
console.log("[DEBUG-LAYER] \u274C Ad container HIDDEN (error)");
|
|
642
595
|
}
|
|
643
596
|
}, 300);
|
|
644
597
|
}
|
|
@@ -670,7 +623,6 @@ function createImaController(video, options) {
|
|
|
670
623
|
adsManager.addEventListener(
|
|
671
624
|
AdEvent.CONTENT_PAUSE_REQUESTED,
|
|
672
625
|
() => {
|
|
673
|
-
console.log("[DEBUG-FLOW] \u{1F3AF} CONTENT_PAUSE_REQUESTED - Ad request accepted");
|
|
674
626
|
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
675
627
|
video.pause();
|
|
676
628
|
}
|
|
@@ -680,15 +632,11 @@ function createImaController(video, options) {
|
|
|
680
632
|
}
|
|
681
633
|
);
|
|
682
634
|
adsManager.addEventListener(AdEvent.STARTED, () => {
|
|
683
|
-
console.log("[DEBUG-FLOW] \u25B6\uFE0F STARTED - Ad playing now");
|
|
684
635
|
setAdPlayingFlag(true);
|
|
685
636
|
hideContentVideo();
|
|
686
637
|
if (adVideoElement) {
|
|
687
638
|
adVideoElement.volume = originalMutedState ? 0 : originalVolume;
|
|
688
639
|
adVideoElement.muted = originalMutedState;
|
|
689
|
-
console.log(
|
|
690
|
-
`[DEBUG-AUDIO] \u{1F50A} Ad audio set | volume=${adVideoElement.volume}, muted=${adVideoElement.muted}`
|
|
691
|
-
);
|
|
692
640
|
}
|
|
693
641
|
if (adContainerEl) {
|
|
694
642
|
adContainerEl.style.pointerEvents = "auto";
|
|
@@ -701,15 +649,12 @@ function createImaController(video, options) {
|
|
|
701
649
|
adsManager.addEventListener(
|
|
702
650
|
AdEvent.CONTENT_RESUME_REQUESTED,
|
|
703
651
|
() => {
|
|
704
|
-
console.log("[DEBUG-FLOW] \u23F8\uFE0F CONTENT_RESUME - Single ad done");
|
|
705
652
|
adPlaying = false;
|
|
706
653
|
setAdPlayingFlag(false);
|
|
707
|
-
console.log("[DEBUG-LAYER] \u26A0\uFE0F Waiting for pod manager (more ads, placeholder, or done)");
|
|
708
654
|
emit("content_resume");
|
|
709
655
|
}
|
|
710
656
|
);
|
|
711
657
|
adsManager.addEventListener(AdEvent.ALL_ADS_COMPLETED, () => {
|
|
712
|
-
console.log("[DEBUG-FLOW] \u{1F3C1} ALL_ADS_COMPLETED - Pod finished");
|
|
713
658
|
adPlaying = false;
|
|
714
659
|
setAdPlayingFlag(false);
|
|
715
660
|
if (adContainerEl) {
|
|
@@ -719,19 +664,16 @@ function createImaController(video, options) {
|
|
|
719
664
|
if (adContainerEl) {
|
|
720
665
|
adContainerEl.style.pointerEvents = "none";
|
|
721
666
|
adContainerEl.style.display = "none";
|
|
722
|
-
console.log("[DEBUG-LAYER] \u26AB Ad container HIDDEN (pod done)");
|
|
723
667
|
}
|
|
724
668
|
}, 300);
|
|
725
669
|
}
|
|
726
670
|
showContentVideo();
|
|
727
671
|
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds) && video.paused) {
|
|
728
|
-
video.play().catch((
|
|
729
|
-
console.warn("[DEBUG-ERROR] Failed to resume video:", e);
|
|
672
|
+
video.play().catch(() => {
|
|
730
673
|
});
|
|
731
674
|
}
|
|
732
675
|
emit("all_ads_completed");
|
|
733
676
|
});
|
|
734
|
-
console.log("[IMA] Ads manager event listeners attached");
|
|
735
677
|
if (adsLoadedResolve) {
|
|
736
678
|
adsLoadedResolve();
|
|
737
679
|
adsLoadedResolve = void 0;
|
|
@@ -826,9 +768,7 @@ function createImaController(video, options) {
|
|
|
826
768
|
}
|
|
827
769
|
const preloadPromise = fetchVastDocument(vastTagUrl).then((xml) => {
|
|
828
770
|
preloadedVast.set(vastTagUrl, xml);
|
|
829
|
-
|
|
830
|
-
}).catch((error) => {
|
|
831
|
-
console.warn("[IMA] Failed to preload VAST response:", error);
|
|
771
|
+
}).catch(() => {
|
|
832
772
|
preloadedVast.delete(vastTagUrl);
|
|
833
773
|
}).finally(() => {
|
|
834
774
|
preloadingVast.delete(vastTagUrl);
|
|
@@ -841,7 +781,6 @@ function createImaController(video, options) {
|
|
|
841
781
|
},
|
|
842
782
|
async play() {
|
|
843
783
|
var _a, _b;
|
|
844
|
-
console.log("[DEBUG-FLOW] \u25B6\uFE0F play() - Starting ad playback");
|
|
845
784
|
if (!((_a = window.google) == null ? void 0 : _a.ima) || !adDisplayContainer) {
|
|
846
785
|
return Promise.reject(new Error("IMA SDK not available"));
|
|
847
786
|
}
|
|
@@ -857,19 +796,15 @@ function createImaController(video, options) {
|
|
|
857
796
|
if (adVideoElement) {
|
|
858
797
|
adVideoElement.volume = adVolume;
|
|
859
798
|
adVideoElement.muted = originalMutedState;
|
|
860
|
-
console.log(
|
|
861
|
-
`[DEBUG-AUDIO] \u{1F50A} Pre-start ad audio | volume=${adVolume}, muted=${originalMutedState}`
|
|
862
|
-
);
|
|
863
799
|
}
|
|
864
800
|
try {
|
|
865
801
|
adsManager.setVolume(adVolume);
|
|
866
|
-
} catch
|
|
867
|
-
console.warn("[DEBUG-ERROR] Failed to set IMA manager volume:", error);
|
|
802
|
+
} catch {
|
|
868
803
|
}
|
|
869
804
|
adsManager.start();
|
|
870
805
|
return Promise.resolve();
|
|
871
806
|
} catch (error) {
|
|
872
|
-
console.error("[
|
|
807
|
+
console.error("[IMA] \u274C Error starting ad:", error);
|
|
873
808
|
adPlaying = false;
|
|
874
809
|
setAdPlayingFlag(false);
|
|
875
810
|
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
@@ -881,7 +816,6 @@ function createImaController(video, options) {
|
|
|
881
816
|
},
|
|
882
817
|
async stop() {
|
|
883
818
|
var _a;
|
|
884
|
-
console.log("[DEBUG-FLOW] \u23F9\uFE0F stop() - Stopping ad playback");
|
|
885
819
|
adPlaying = false;
|
|
886
820
|
setAdPlayingFlag(false);
|
|
887
821
|
if (adContainerEl) {
|
|
@@ -891,7 +825,6 @@ function createImaController(video, options) {
|
|
|
891
825
|
if (adContainerEl) {
|
|
892
826
|
adContainerEl.style.pointerEvents = "none";
|
|
893
827
|
adContainerEl.style.display = "none";
|
|
894
|
-
console.log("[DEBUG-LAYER] \u26AB Ad container HIDDEN (stop)");
|
|
895
828
|
}
|
|
896
829
|
}, 300);
|
|
897
830
|
}
|
|
@@ -961,9 +894,6 @@ function createImaController(video, options) {
|
|
|
961
894
|
},
|
|
962
895
|
updateOriginalMutedState(muted, volume) {
|
|
963
896
|
const nextVolume = typeof volume === "number" && !Number.isNaN(volume) ? Math.max(0, Math.min(1, volume)) : originalVolume;
|
|
964
|
-
console.log(
|
|
965
|
-
`[DEBUG-AUDIO] \u{1F4BE} Saved original state | muted: ${originalMutedState}->${muted}, volume: ${originalVolume}->${nextVolume}`
|
|
966
|
-
);
|
|
967
897
|
originalMutedState = muted;
|
|
968
898
|
originalVolume = nextVolume;
|
|
969
899
|
},
|
|
@@ -978,15 +908,11 @@ function createImaController(video, options) {
|
|
|
978
908
|
if (adVideoElement && adPlaying) {
|
|
979
909
|
adVideoElement.volume = clampedVolume;
|
|
980
910
|
adVideoElement.muted = clampedVolume === 0;
|
|
981
|
-
console.log(
|
|
982
|
-
`[DEBUG-AUDIO] \u{1F50A} Ad volume changed | volume=${clampedVolume}, muted=${clampedVolume === 0}`
|
|
983
|
-
);
|
|
984
911
|
}
|
|
985
912
|
if (adsManager && adPlaying) {
|
|
986
913
|
try {
|
|
987
914
|
adsManager.setVolume(clampedVolume);
|
|
988
|
-
} catch
|
|
989
|
-
console.warn("[DEBUG-ERROR] Failed to set IMA manager volume:", error);
|
|
915
|
+
} catch {
|
|
990
916
|
}
|
|
991
917
|
}
|
|
992
918
|
},
|
|
@@ -2204,6 +2130,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2204
2130
|
this.fetchedAdDurations = /* @__PURE__ */ new Map();
|
|
2205
2131
|
this.targetAdBreakDurationMs = null;
|
|
2206
2132
|
this.isAdaptiveMode = false;
|
|
2133
|
+
this.failedVastUrls = /* @__PURE__ */ new Set();
|
|
2207
2134
|
initializePolyfills();
|
|
2208
2135
|
const browserOverrides = getBrowserConfigOverrides();
|
|
2209
2136
|
this.config = { ...config, ...browserOverrides };
|
|
@@ -2476,51 +2403,37 @@ var StormcloudVideoPlayer = class {
|
|
|
2476
2403
|
});
|
|
2477
2404
|
this.ima.on("ad_error", (errorPayload) => {
|
|
2478
2405
|
const remaining = this.getRemainingAdMs();
|
|
2479
|
-
console.error(
|
|
2480
|
-
`[DEBUG-POD] \u274C ad_error event | inBreak=${this.inAdBreak}, queue=${this.adPodQueue.length}, remaining=${remaining}ms`,
|
|
2481
|
-
errorPayload ? `
|
|
2482
|
-
Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
2483
|
-
);
|
|
2406
|
+
console.error("[AD-ERROR] Ad playback failed", errorPayload || "");
|
|
2484
2407
|
if (this.inAdBreak) {
|
|
2485
2408
|
if (remaining > 500 && this.adPodQueue.length > 0) {
|
|
2486
2409
|
const nextPreloaded = this.findNextPreloadedAd();
|
|
2487
2410
|
if (nextPreloaded) {
|
|
2488
2411
|
this.currentAdIndex++;
|
|
2489
|
-
console.log(
|
|
2490
|
-
`[DEBUG-POD] \u27A1\uFE0F Trying next ad after error (${this.currentAdIndex}/${this.totalAdsInBreak})`
|
|
2491
|
-
);
|
|
2492
2412
|
this.playSingleAd(nextPreloaded).catch(() => {
|
|
2493
2413
|
this.handleAdFailure();
|
|
2494
2414
|
});
|
|
2495
2415
|
} else {
|
|
2496
|
-
console.log("[DEBUG-POD] \u26A0\uFE0F No more preloaded ads - calling handleAdFailure");
|
|
2497
2416
|
this.handleAdFailure();
|
|
2498
2417
|
}
|
|
2499
2418
|
} else {
|
|
2500
|
-
console.log("[DEBUG-POD] \u26A0\uFE0F No more ads or time - calling handleAdFailure");
|
|
2501
2419
|
this.handleAdFailure();
|
|
2502
2420
|
}
|
|
2503
2421
|
} else {
|
|
2504
|
-
console.log("[DEBUG-POD] \u26A0\uFE0F Error before ad break established");
|
|
2505
2422
|
this.handleAdFailure();
|
|
2506
2423
|
}
|
|
2507
2424
|
});
|
|
2508
2425
|
this.ima.on("content_pause", () => {
|
|
2509
|
-
console.log(`[DEBUG-POD] \u{1F3AF} content_pause (AD STARTING!) | ad ${this.currentAdIndex}/${this.totalAdsInBreak}, queue=${this.adPodQueue.length}`);
|
|
2510
2426
|
this.clearAdFailsafeTimer();
|
|
2511
2427
|
this.clearAdRequestWatchdog();
|
|
2512
2428
|
this.activeAdRequestToken = null;
|
|
2513
2429
|
this.showAds = true;
|
|
2514
|
-
console.log("[DEBUG-LAYER] \u{1F3AC} Layers: Main=hidden, Ad=visible, Placeholder=no");
|
|
2515
2430
|
});
|
|
2516
2431
|
this.ima.on("content_resume", () => {
|
|
2517
|
-
console.log(`[DEBUG-POD] \u23F8\uFE0F content_resume | ad ${this.currentAdIndex}/${this.totalAdsInBreak}, queue=${this.adPodQueue.length}, remaining=${this.getRemainingAdMs()}ms`);
|
|
2518
2432
|
this.clearAdFailsafeTimer();
|
|
2519
2433
|
this.clearAdRequestWatchdog();
|
|
2520
2434
|
this.activeAdRequestToken = null;
|
|
2521
2435
|
this.showAds = false;
|
|
2522
2436
|
if (!this.inAdBreak) {
|
|
2523
|
-
console.warn("[DEBUG-POD] \u26A0\uFE0F Not in ad break - shouldn't happen");
|
|
2524
2437
|
return;
|
|
2525
2438
|
}
|
|
2526
2439
|
const remaining = this.getRemainingAdMs();
|
|
@@ -2528,17 +2441,13 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
|
2528
2441
|
const nextPreloaded = this.findNextPreloadedAd();
|
|
2529
2442
|
if (nextPreloaded) {
|
|
2530
2443
|
this.currentAdIndex++;
|
|
2531
|
-
console.log(`[DEBUG-POD] \u27A1\uFE0F Playing next ad ${this.currentAdIndex}/${this.totalAdsInBreak} (preloaded)`);
|
|
2532
2444
|
this.playSingleAd(nextPreloaded).catch(() => {
|
|
2533
|
-
console.error("[DEBUG-POD] \u274C Failed to play next ad");
|
|
2534
2445
|
this.handleAdPodComplete();
|
|
2535
2446
|
});
|
|
2536
2447
|
} else {
|
|
2537
|
-
console.log("[DEBUG-POD] \u26A0\uFE0F No preloaded ads - ending pod");
|
|
2538
2448
|
this.handleAdPodComplete();
|
|
2539
2449
|
}
|
|
2540
2450
|
} else {
|
|
2541
|
-
console.log("[DEBUG-POD] \u2705 Pod complete (no more ads or time expired)");
|
|
2542
2451
|
this.handleAdPodComplete();
|
|
2543
2452
|
}
|
|
2544
2453
|
});
|
|
@@ -2692,9 +2601,6 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
|
2692
2601
|
}
|
|
2693
2602
|
if (marker.type === "start") {
|
|
2694
2603
|
if (this.inAdBreak) {
|
|
2695
|
-
console.log(
|
|
2696
|
-
`[DEBUG-POD] \u26A0\uFE0F SCTE-35 start marker ignored - already in ad break (currentTime: ${this.video.currentTime})`
|
|
2697
|
-
);
|
|
2698
2604
|
return;
|
|
2699
2605
|
}
|
|
2700
2606
|
this.inAdBreak = true;
|
|
@@ -2763,9 +2669,6 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
|
2763
2669
|
return;
|
|
2764
2670
|
}
|
|
2765
2671
|
if (marker.type === "progress" && this.inAdBreak) {
|
|
2766
|
-
console.log(
|
|
2767
|
-
`[DEBUG-POD] \u{1F4CA} SCTE-35 progress marker (currentTime: ${this.video.currentTime})`
|
|
2768
|
-
);
|
|
2769
2672
|
if (marker.durationSeconds != null) {
|
|
2770
2673
|
this.expectedAdBreakDurationMs = marker.durationSeconds * 1e3;
|
|
2771
2674
|
}
|
|
@@ -2778,7 +2681,6 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
|
2778
2681
|
this.scheduleAdStopCountdown(remainingMs);
|
|
2779
2682
|
}
|
|
2780
2683
|
if (!this.ima.isAdPlaying() && this.activeAdRequestToken === null) {
|
|
2781
|
-
console.log("[DEBUG-POD] \u{1F4CA} Progress marker: no ad playing, attempting to start");
|
|
2782
2684
|
const scheduled = this.findCurrentOrNextBreak(
|
|
2783
2685
|
this.video.currentTime * 1e3
|
|
2784
2686
|
);
|
|
@@ -2790,24 +2692,16 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
|
2790
2692
|
this.playSingleAd(first).catch(() => {
|
|
2791
2693
|
});
|
|
2792
2694
|
}
|
|
2793
|
-
} else {
|
|
2794
|
-
console.log(
|
|
2795
|
-
`[DEBUG-POD] \u{1F4CA} Progress marker: ad playing or request active (playing=${this.ima.isAdPlaying()}, token=${this.activeAdRequestToken})`
|
|
2796
|
-
);
|
|
2797
2695
|
}
|
|
2798
2696
|
return;
|
|
2799
2697
|
}
|
|
2800
2698
|
if (marker.type === "end") {
|
|
2801
|
-
console.log(
|
|
2802
|
-
`[DEBUG-POD] \u{1F3C1} SCTE-35 end marker received (currentTime: ${this.video.currentTime})`
|
|
2803
|
-
);
|
|
2804
2699
|
this.inAdBreak = false;
|
|
2805
2700
|
this.expectedAdBreakDurationMs = void 0;
|
|
2806
2701
|
this.currentAdBreakStartWallClockMs = void 0;
|
|
2807
2702
|
this.clearAdStartTimer();
|
|
2808
2703
|
this.clearAdStopTimer();
|
|
2809
2704
|
if (this.ima.isAdPlaying()) {
|
|
2810
|
-
console.log("[DEBUG-POD] \u{1F6D1} Stopping ad due to SCTE-35 end marker");
|
|
2811
2705
|
this.ima.stop().catch(() => {
|
|
2812
2706
|
});
|
|
2813
2707
|
}
|
|
@@ -3208,21 +3102,17 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
|
3208
3102
|
} else if (tags && tags.length > 0) {
|
|
3209
3103
|
vastTagUrls = tags;
|
|
3210
3104
|
} else {
|
|
3211
|
-
console.log("[DEBUG-POD] \u26A0\uFE0F No VAST tag available");
|
|
3212
3105
|
return;
|
|
3213
3106
|
}
|
|
3214
3107
|
if (vastTagUrls.length > 0) {
|
|
3215
|
-
console.log(`[DEBUG-POD] \u{1F3AF} Starting ad break with ${vastTagUrls.length} ads`);
|
|
3216
3108
|
this.adPodAllUrls = [...vastTagUrls];
|
|
3217
3109
|
this.preloadingAdUrls.clear();
|
|
3218
3110
|
this.vastToMediaUrlMap.clear();
|
|
3219
3111
|
this.preloadedMediaUrls.clear();
|
|
3220
3112
|
this.preloadingMediaUrls.clear();
|
|
3113
|
+
this.failedVastUrls.clear();
|
|
3221
3114
|
const currentMuted = this.video.muted;
|
|
3222
3115
|
const currentVolume = this.video.volume;
|
|
3223
|
-
console.log(
|
|
3224
|
-
`[DEBUG-AUDIO] \u{1F4BE} Capturing ORIGINAL state (once) | muted=${currentMuted}, volume=${currentVolume}`
|
|
3225
|
-
);
|
|
3226
3116
|
this.ima.updateOriginalMutedState(currentMuted, currentVolume);
|
|
3227
3117
|
this.inAdBreak = true;
|
|
3228
3118
|
this.currentAdIndex = 0;
|
|
@@ -3283,40 +3173,27 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
|
3283
3173
|
}
|
|
3284
3174
|
async playAdPod() {
|
|
3285
3175
|
if (this.adPodQueue.length === 0) {
|
|
3286
|
-
console.log("[DEBUG-POD] \u26A0\uFE0F No ads in pod");
|
|
3287
3176
|
return;
|
|
3288
3177
|
}
|
|
3289
3178
|
const waitTime = this.isAdaptiveMode ? 50 : 500;
|
|
3290
3179
|
await new Promise((resolve) => setTimeout(resolve, waitTime));
|
|
3291
|
-
if (this.config.debugAdTiming) {
|
|
3292
|
-
console.log(
|
|
3293
|
-
`[DEBUG-POD] \u{1F50D} Looking for preloaded ad in queue of ${this.adPodQueue.length} URLs`
|
|
3294
|
-
);
|
|
3295
|
-
}
|
|
3296
3180
|
const firstPreloaded = this.findNextPreloadedAd();
|
|
3297
3181
|
if (!firstPreloaded) {
|
|
3298
|
-
console.log("[DEBUG-POD] \u26A0\uFE0F No preloaded ads found, trying first ad from queue");
|
|
3299
3182
|
const firstAd = this.adPodQueue.shift();
|
|
3300
3183
|
if (firstAd) {
|
|
3301
3184
|
this.currentAdIndex++;
|
|
3302
|
-
console.log(`[DEBUG-POD] \u{1F3AC} Attempting to play first ad (not preloaded): ${firstAd.substring(0, 60)}...`);
|
|
3303
3185
|
try {
|
|
3304
3186
|
await this.playSingleAd(firstAd);
|
|
3305
3187
|
} catch (error) {
|
|
3306
|
-
console.log("[DEBUG-POD] \u26A0\uFE0F First ad failed, error handler will retry");
|
|
3307
3188
|
return;
|
|
3308
3189
|
}
|
|
3309
|
-
} else {
|
|
3310
|
-
console.log("[DEBUG-POD] \u274C No ads available in queue");
|
|
3311
3190
|
}
|
|
3312
3191
|
return;
|
|
3313
3192
|
}
|
|
3314
3193
|
this.currentAdIndex++;
|
|
3315
|
-
console.log(`[DEBUG-POD] \u{1F680} Starting pod with ad ${this.currentAdIndex}/${this.totalAdsInBreak}`);
|
|
3316
3194
|
try {
|
|
3317
3195
|
await this.playSingleAd(firstPreloaded);
|
|
3318
3196
|
} catch (error) {
|
|
3319
|
-
console.log("[DEBUG-POD] \u26A0\uFE0F First ad failed, error handler will retry");
|
|
3320
3197
|
}
|
|
3321
3198
|
}
|
|
3322
3199
|
findCurrentOrNextBreak(nowMs) {
|
|
@@ -3396,15 +3273,9 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
|
3396
3273
|
const overrunMs = Math.max(0, elapsedSinceStartMs - expectedDurationMs);
|
|
3397
3274
|
const shouldExtendAdBreak = (adPlaying || pendingAds || this.showAds) && overrunMs < maxExtensionMs;
|
|
3398
3275
|
if (shouldExtendAdBreak) {
|
|
3399
|
-
console.log(
|
|
3400
|
-
`[DEBUG-POD] \u23F3 Extending ad break | elapsed=${elapsedSinceStartMs}ms, expected=${expectedDurationMs}ms, overrun=${overrunMs}ms`
|
|
3401
|
-
);
|
|
3402
3276
|
this.scheduleAdStopCountdown(checkIntervalMs);
|
|
3403
3277
|
return;
|
|
3404
3278
|
}
|
|
3405
|
-
console.log(
|
|
3406
|
-
`[DEBUG-POD] \u23F1\uFE0F Ad break duration expired | elapsed=${elapsedSinceStartMs}ms, expected=${expectedDurationMs}ms`
|
|
3407
|
-
);
|
|
3408
3279
|
if (adPlaying) {
|
|
3409
3280
|
this.ima.stop().catch(() => {
|
|
3410
3281
|
});
|
|
@@ -3437,42 +3308,29 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
|
3437
3308
|
this.ptsDriftEmaMs = this.ptsDriftEmaMs * (1 - alpha) + sampleMs * alpha;
|
|
3438
3309
|
}
|
|
3439
3310
|
async playSingleAd(vastTagUrl) {
|
|
3440
|
-
console.log(`[DEBUG-POD] \u{1F3AC} playSingleAd | url=${vastTagUrl.substring(0, 60)}...`);
|
|
3441
3311
|
if (this.ima.isAdPlaying()) {
|
|
3442
|
-
|
|
3312
|
+
return;
|
|
3313
|
+
}
|
|
3314
|
+
if (this.failedVastUrls.has(vastTagUrl)) {
|
|
3315
|
+
console.warn("[AD-ERROR] Skipping already-failed VAST URL:", vastTagUrl.substring(0, 60));
|
|
3316
|
+
this.handleAdFailure();
|
|
3443
3317
|
return;
|
|
3444
3318
|
}
|
|
3445
3319
|
const requestToken = ++this.adRequestTokenCounter;
|
|
3446
|
-
const wasPreloaded = this.ima.hasPreloadedAd(vastTagUrl);
|
|
3447
3320
|
this.activeAdRequestToken = requestToken;
|
|
3448
|
-
console.log(`[DEBUG-POD] \u{1F4DD} Request token=${requestToken}, preloaded=${wasPreloaded}`);
|
|
3449
3321
|
this.startAdRequestWatchdog(requestToken);
|
|
3450
3322
|
try {
|
|
3451
|
-
console.log(`[DEBUG-POD] \u{1F4E1} Calling ima.requestAds() for token=${requestToken}...`);
|
|
3452
3323
|
await this.ima.requestAds(vastTagUrl);
|
|
3453
|
-
console.log(`[DEBUG-POD] \u2705 ima.requestAds() completed successfully`);
|
|
3454
3324
|
this.clearAdRequestWatchdog();
|
|
3455
3325
|
if (this.activeAdRequestToken !== requestToken) {
|
|
3456
|
-
console.warn(`[DEBUG-POD] \u26A0\uFE0F Token mismatch after requestAds (stale request)`);
|
|
3457
3326
|
return;
|
|
3458
3327
|
}
|
|
3459
|
-
console.log(`[DEBUG-POD] \u{1F4FA} Calling ima.play() to start ad playback...`);
|
|
3460
|
-
console.log(`[DEBUG-POD] \u{1F4CA} Video element state: paused=${this.video.paused}, muted=${this.video.muted}, readyState=${this.video.readyState}`);
|
|
3461
3328
|
try {
|
|
3462
3329
|
this.startAdFailsafeTimer(requestToken);
|
|
3463
3330
|
await this.ima.play();
|
|
3464
|
-
if (this.activeAdRequestToken === requestToken) {
|
|
3465
|
-
console.log(`[DEBUG-POD] \u2705 Ad play initiated successfully (token=${requestToken})`);
|
|
3466
|
-
} else {
|
|
3467
|
-
console.warn(`[DEBUG-POD] \u26A0\uFE0F Token mismatch after play (stale request)`);
|
|
3468
|
-
}
|
|
3469
3331
|
} catch (playError) {
|
|
3470
|
-
console.error(
|
|
3471
|
-
|
|
3472
|
-
playError instanceof Error ? playError.message : playError,
|
|
3473
|
-
"\nFull error:",
|
|
3474
|
-
playError
|
|
3475
|
-
);
|
|
3332
|
+
console.error("[AD-ERROR] Failed to play ad:", playError);
|
|
3333
|
+
this.failedVastUrls.add(vastTagUrl);
|
|
3476
3334
|
this.clearAdFailsafeTimer();
|
|
3477
3335
|
if (this.activeAdRequestToken === requestToken) {
|
|
3478
3336
|
this.activeAdRequestToken = null;
|
|
@@ -3481,7 +3339,8 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
|
3481
3339
|
return;
|
|
3482
3340
|
}
|
|
3483
3341
|
} catch (error) {
|
|
3484
|
-
console.error("[
|
|
3342
|
+
console.error("[AD-ERROR] Ad request failed:", error == null ? void 0 : error.message);
|
|
3343
|
+
this.failedVastUrls.add(vastTagUrl);
|
|
3485
3344
|
this.clearAdRequestWatchdog();
|
|
3486
3345
|
this.clearAdFailsafeTimer();
|
|
3487
3346
|
if (this.activeAdRequestToken === requestToken) {
|
|
@@ -3492,7 +3351,6 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
|
3492
3351
|
}
|
|
3493
3352
|
handleAdPodComplete() {
|
|
3494
3353
|
var _a;
|
|
3495
|
-
console.log("[DEBUG-POD] \u{1F3C1} handleAdPodComplete - Ending ad break, restoring content");
|
|
3496
3354
|
this.clearAdRequestWatchdog();
|
|
3497
3355
|
this.clearAdFailsafeTimer();
|
|
3498
3356
|
this.activeAdRequestToken = null;
|
|
@@ -3514,10 +3372,6 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
|
3514
3372
|
});
|
|
3515
3373
|
const restoredMuted = this.ima.getOriginalMutedState();
|
|
3516
3374
|
const restoredVolume = this.ima.getOriginalVolume();
|
|
3517
|
-
console.log(
|
|
3518
|
-
`[DEBUG-AUDIO] \u{1F50A} Audio restored by IMA | muted=${restoredMuted}, volume=${restoredVolume}`
|
|
3519
|
-
);
|
|
3520
|
-
console.log("[DEBUG-LAYER] \u{1F3AC} Layers: Main=visible, Ad=hidden, Placeholder=no");
|
|
3521
3375
|
if (this.video.muted !== restoredMuted) {
|
|
3522
3376
|
this.video.muted = restoredMuted;
|
|
3523
3377
|
}
|
|
@@ -3525,16 +3379,14 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
|
3525
3379
|
this.video.volume = restoredVolume;
|
|
3526
3380
|
}
|
|
3527
3381
|
if (!this.shouldContinueLiveStreamDuringAds() && this.video.paused) {
|
|
3528
|
-
|
|
3529
|
-
(_a = this.video.play()) == null ? void 0 : _a.catch((error) => {
|
|
3530
|
-
console.error("[DEBUG-ERROR] Failed to resume video:", error);
|
|
3382
|
+
(_a = this.video.play()) == null ? void 0 : _a.catch(() => {
|
|
3531
3383
|
});
|
|
3532
3384
|
}
|
|
3533
3385
|
}
|
|
3534
3386
|
handleAdFailure() {
|
|
3535
|
-
console.log("[DEBUG-POD] \u274C handleAdFailure - skipping to next ad or ending break");
|
|
3536
3387
|
const remaining = this.getRemainingAdMs();
|
|
3537
|
-
|
|
3388
|
+
const availableAds = this.adPodQueue.filter((url) => !this.failedVastUrls.has(url)).length;
|
|
3389
|
+
if (remaining > 500 && availableAds > 0) {
|
|
3538
3390
|
if (this.isAdaptiveMode && this.currentAdIndex <= 1) {
|
|
3539
3391
|
console.log("[ADAPTIVE-POD] \u23F3 First ad failed, waiting for sequential preload to catch up...");
|
|
3540
3392
|
setTimeout(() => {
|
|
@@ -3545,14 +3397,13 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
|
3545
3397
|
const nextPreloaded = this.findNextPreloadedAd();
|
|
3546
3398
|
if (nextPreloaded) {
|
|
3547
3399
|
this.currentAdIndex++;
|
|
3548
|
-
console.log(`[DEBUG-POD] \u27A1\uFE0F Trying next ad after failure (${this.currentAdIndex}/${this.totalAdsInBreak})`);
|
|
3549
3400
|
this.playSingleAd(nextPreloaded).catch(() => {
|
|
3550
3401
|
this.handleAdPodComplete();
|
|
3551
3402
|
});
|
|
3552
3403
|
return;
|
|
3553
3404
|
}
|
|
3554
3405
|
}
|
|
3555
|
-
console.
|
|
3406
|
+
console.error("[AD-ERROR] All ads failed or time expired. Failed URLs:", this.failedVastUrls.size);
|
|
3556
3407
|
this.handleAdPodComplete();
|
|
3557
3408
|
}
|
|
3558
3409
|
tryNextAdWithRetry(retryCount) {
|
|
@@ -4005,37 +3856,21 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
|
4005
3856
|
}
|
|
4006
3857
|
findNextPreloadedAd() {
|
|
4007
3858
|
var _a, _b, _c;
|
|
4008
|
-
if (this.config.debugAdTiming) {
|
|
4009
|
-
console.log(
|
|
4010
|
-
`[DEBUG-POD] \u{1F50E} Searching for preloaded ad in queue (${this.adPodQueue.length} URLs, ${this.preloadedMediaUrls.size} media preloaded, ${this.vastToMediaUrlMap.size} VAST mappings)`
|
|
4011
|
-
);
|
|
4012
|
-
}
|
|
4013
3859
|
for (let i = 0; i < this.adPodQueue.length; i++) {
|
|
4014
3860
|
const vastTagUrl = this.adPodQueue[i];
|
|
4015
3861
|
if (!vastTagUrl) continue;
|
|
3862
|
+
if (this.failedVastUrls.has(vastTagUrl)) {
|
|
3863
|
+
console.warn("[AD-ERROR] Skipping failed URL in queue");
|
|
3864
|
+
continue;
|
|
3865
|
+
}
|
|
4016
3866
|
const hasImaPreload = (_c = (_b = (_a = this.ima).hasPreloadedAd) == null ? void 0 : _b.call(_a, vastTagUrl)) != null ? _c : false;
|
|
4017
3867
|
const mediaUrls = this.vastToMediaUrlMap.get(vastTagUrl);
|
|
4018
3868
|
const hasMediaPreload = mediaUrls && mediaUrls.length > 0 ? this.preloadedMediaUrls.has(mediaUrls[0]) : false;
|
|
4019
|
-
if (this.config.debugAdTiming) {
|
|
4020
|
-
console.log(
|
|
4021
|
-
`[DEBUG-POD] Ad ${i}: IMA=${hasImaPreload}, Media=${hasMediaPreload}, MediaURLs=${(mediaUrls == null ? void 0 : mediaUrls.length) || 0}, URL=${vastTagUrl.substring(0, 60)}...`
|
|
4022
|
-
);
|
|
4023
|
-
}
|
|
4024
3869
|
if (hasImaPreload || hasMediaPreload) {
|
|
4025
|
-
if (this.config.debugAdTiming) {
|
|
4026
|
-
console.log(
|
|
4027
|
-
`[DEBUG-POD] \u2705 Found preloaded ad at index ${i}`
|
|
4028
|
-
);
|
|
4029
|
-
}
|
|
4030
3870
|
this.adPodQueue.splice(0, i + 1);
|
|
4031
3871
|
return vastTagUrl;
|
|
4032
3872
|
}
|
|
4033
3873
|
}
|
|
4034
|
-
if (this.config.debugAdTiming) {
|
|
4035
|
-
console.log(
|
|
4036
|
-
`[DEBUG-POD] \u274C No preloaded ads found in queue`
|
|
4037
|
-
);
|
|
4038
|
-
}
|
|
4039
3874
|
return void 0;
|
|
4040
3875
|
}
|
|
4041
3876
|
getRemainingAdMs() {
|