stormcloud-video-player 0.2.31 → 0.2.33
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 +414 -99
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +9 -1
- package/lib/index.d.ts +9 -1
- package/lib/index.js +414 -99
- package/lib/index.js.map +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +414 -99
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/player/StormcloudVideoPlayer.d.cts +9 -1
- package/lib/players/HlsPlayer.cjs +414 -99
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/index.cjs +414 -99
- package/lib/players/index.cjs.map +1 -1
- package/lib/sdk/ima.cjs +130 -26
- package/lib/sdk/ima.cjs.map +1 -1
- package/lib/ui/StormcloudVideoPlayer.cjs +414 -99
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/package.json +2 -2
|
@@ -348,15 +348,17 @@ function createImaController(video, options) {
|
|
|
348
348
|
let adsLoadedResolve;
|
|
349
349
|
let adsLoadedReject;
|
|
350
350
|
function makeAdsRequest(google, vastTagUrl) {
|
|
351
|
+
console.log("[IMA] \u{1F4CB} === makeAdsRequest() - Building IMA request ===");
|
|
351
352
|
const adsRequest = new google.ima.AdsRequest();
|
|
352
353
|
const preloadedResponse = preloadedVast.get(vastTagUrl);
|
|
353
354
|
if (preloadedResponse) {
|
|
354
355
|
adsRequest.adsResponse = preloadedResponse;
|
|
355
356
|
console.log(
|
|
356
|
-
"[IMA] Using preloaded VAST response for immediate ad request"
|
|
357
|
+
"[IMA] \u26A1 Using preloaded VAST response for immediate ad request"
|
|
357
358
|
);
|
|
358
359
|
} else {
|
|
359
360
|
adsRequest.adTagUrl = vastTagUrl;
|
|
361
|
+
console.log("[IMA] \u{1F310} Will fetch VAST from URL:", vastTagUrl);
|
|
360
362
|
}
|
|
361
363
|
const videoWidth = video.offsetWidth || video.clientWidth || 640;
|
|
362
364
|
const videoHeight = video.offsetHeight || video.clientHeight || 360;
|
|
@@ -368,6 +370,7 @@ function createImaController(video, options) {
|
|
|
368
370
|
try {
|
|
369
371
|
const willAutoPlay = !video.paused || video.autoplay;
|
|
370
372
|
adsRequest.setAdWillAutoPlay(willAutoPlay);
|
|
373
|
+
console.log(`[IMA] Ad will autoplay: ${willAutoPlay}`);
|
|
371
374
|
} catch (error) {
|
|
372
375
|
console.warn("[IMA] Failed to call setAdWillAutoPlay:", error);
|
|
373
376
|
}
|
|
@@ -376,13 +379,17 @@ function createImaController(video, options) {
|
|
|
376
379
|
try {
|
|
377
380
|
const willPlayMuted = video.muted || video.volume === 0;
|
|
378
381
|
adsRequest.setAdWillPlayMuted(willPlayMuted);
|
|
382
|
+
console.log(`[IMA] Ad will play muted: ${willPlayMuted}`);
|
|
379
383
|
} catch (error) {
|
|
380
384
|
console.warn("[IMA] Failed to call setAdWillPlayMuted:", error);
|
|
381
385
|
}
|
|
382
386
|
}
|
|
383
387
|
adsRequest.vastLoadTimeout = 5e3;
|
|
384
|
-
console.log(`[IMA] Ads request dimensions: ${videoWidth}x${videoHeight}`);
|
|
388
|
+
console.log(`[IMA] \u{1F4D0} Ads request dimensions: ${videoWidth}x${videoHeight}`);
|
|
389
|
+
console.log("[IMA] \u23F1\uFE0F VAST load timeout: 5000ms");
|
|
390
|
+
console.log("[IMA] \u{1F680} Calling adsLoader.requestAds()...");
|
|
385
391
|
adsLoader.requestAds(adsRequest);
|
|
392
|
+
console.log("[IMA] \u23F3 Waiting for ADS_MANAGER_LOADED or AD_ERROR event...");
|
|
386
393
|
if (preloadedResponse) {
|
|
387
394
|
preloadedVast.delete(vastTagUrl);
|
|
388
395
|
}
|
|
@@ -460,22 +467,24 @@ function createImaController(video, options) {
|
|
|
460
467
|
});
|
|
461
468
|
},
|
|
462
469
|
async requestAds(vastTagUrl) {
|
|
463
|
-
console.log("[IMA]
|
|
470
|
+
console.log("[IMA] \u{1F4E1} === requestAds() called ===");
|
|
471
|
+
console.log("[IMA] VAST URL:", vastTagUrl);
|
|
472
|
+
console.log("[IMA] This will fetch the ad from the server - no visual change yet");
|
|
464
473
|
if (!vastTagUrl || vastTagUrl.trim() === "") {
|
|
465
474
|
const error = new Error("VAST tag URL is empty or undefined");
|
|
466
|
-
console.warn("[IMA]", error.message);
|
|
475
|
+
console.warn("[IMA] \u274C", error.message);
|
|
467
476
|
return Promise.reject(error);
|
|
468
477
|
}
|
|
469
478
|
try {
|
|
470
479
|
new URL(vastTagUrl);
|
|
471
480
|
} catch (e) {
|
|
472
481
|
const error = new Error(`Invalid VAST tag URL format: ${vastTagUrl}`);
|
|
473
|
-
console.warn("[IMA]", error.message);
|
|
482
|
+
console.warn("[IMA] \u274C", error.message);
|
|
474
483
|
return Promise.reject(error);
|
|
475
484
|
}
|
|
476
485
|
if (adPlaying) {
|
|
477
486
|
console.warn(
|
|
478
|
-
"[IMA] Cannot request new ads while an ad is playing. Call stop() first."
|
|
487
|
+
"[IMA] \u26A0\uFE0F Cannot request new ads while an ad is playing. Call stop() first."
|
|
479
488
|
);
|
|
480
489
|
return Promise.reject(
|
|
481
490
|
new Error("Ad already playing - cannot request new ads")
|
|
@@ -565,20 +574,85 @@ function createImaController(video, options) {
|
|
|
565
574
|
adsLoader.addEventListener(
|
|
566
575
|
google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,
|
|
567
576
|
(evt) => {
|
|
568
|
-
console.log(
|
|
569
|
-
|
|
570
|
-
);
|
|
577
|
+
console.log("[IMA] \u2705 ADS_MANAGER_LOADED - Ads fetched successfully!");
|
|
578
|
+
console.log("[IMA] Setting up ads manager with preloading enabled");
|
|
579
|
+
console.log("[IMA] ========================================");
|
|
580
|
+
console.log("[IMA] EXPECTED EVENT FLOW:");
|
|
581
|
+
console.log("[IMA] 1. requestAds() \u2192 fetch VAST");
|
|
582
|
+
console.log("[IMA] 2. ADS_MANAGER_LOADED \u2192 ads ready");
|
|
583
|
+
console.log("[IMA] 3. play() \u2192 start playback");
|
|
584
|
+
console.log("[IMA] 4. CONTENT_PAUSE_REQUESTED \u2192 show ad layer \u2728");
|
|
585
|
+
console.log("[IMA] 5. STARTED \u2192 ad is playing");
|
|
586
|
+
console.log("[IMA] 6. CONTENT_RESUME_REQUESTED \u2192 ad done");
|
|
587
|
+
console.log("[IMA] 7. ALL_ADS_COMPLETED \u2192 hide ad layer");
|
|
588
|
+
console.log("[IMA] ========================================");
|
|
571
589
|
try {
|
|
572
590
|
const adsRenderingSettings = new google.ima.AdsRenderingSettings();
|
|
573
591
|
adsRenderingSettings.enablePreloading = true;
|
|
574
592
|
adsManager = evt.getAdsManager(video, adsRenderingSettings);
|
|
575
593
|
const AdEvent = google.ima.AdEvent.Type;
|
|
576
594
|
const AdErrorEvent = google.ima.AdErrorEvent.Type;
|
|
595
|
+
console.log("[IMA] ========== IMA EVENT LOGGING ENABLED ==========");
|
|
596
|
+
console.log("[IMA] All IMA SDK events will be logged below");
|
|
597
|
+
const allAdEvents = [
|
|
598
|
+
"AD_BREAK_READY",
|
|
599
|
+
"AD_METADATA",
|
|
600
|
+
"ALL_ADS_COMPLETED",
|
|
601
|
+
"CLICK",
|
|
602
|
+
"COMPLETE",
|
|
603
|
+
"CONTENT_PAUSE_REQUESTED",
|
|
604
|
+
"CONTENT_RESUME_REQUESTED",
|
|
605
|
+
"DURATION_CHANGE",
|
|
606
|
+
"FIRST_QUARTILE",
|
|
607
|
+
"IMPRESSION",
|
|
608
|
+
"INTERACTION",
|
|
609
|
+
"LINEAR_CHANGED",
|
|
610
|
+
"LOADED",
|
|
611
|
+
"LOG",
|
|
612
|
+
"MIDPOINT",
|
|
613
|
+
"PAUSED",
|
|
614
|
+
"RESUMED",
|
|
615
|
+
"SKIPPABLE_STATE_CHANGED",
|
|
616
|
+
"SKIPPED",
|
|
617
|
+
"STARTED",
|
|
618
|
+
"THIRD_QUARTILE",
|
|
619
|
+
"USER_CLOSE",
|
|
620
|
+
"VOLUME_CHANGED",
|
|
621
|
+
"VOLUME_MUTED"
|
|
622
|
+
];
|
|
623
|
+
allAdEvents.forEach((eventType) => {
|
|
624
|
+
if (AdEvent[eventType]) {
|
|
625
|
+
adsManager.addEventListener(AdEvent[eventType], (e) => {
|
|
626
|
+
var _a, _b, _c, _d, _e, _f;
|
|
627
|
+
const ad = (_a = e.getAd) == null ? void 0 : _a.call(e);
|
|
628
|
+
const adData = ad ? {
|
|
629
|
+
adId: (_b = ad.getAdId) == null ? void 0 : _b.call(ad),
|
|
630
|
+
title: (_c = ad.getTitle) == null ? void 0 : _c.call(ad),
|
|
631
|
+
duration: (_d = ad.getDuration) == null ? void 0 : _d.call(ad),
|
|
632
|
+
isLinear: (_e = ad.isLinear) == null ? void 0 : _e.call(ad),
|
|
633
|
+
contentType: (_f = ad.getContentType) == null ? void 0 : _f.call(ad)
|
|
634
|
+
} : null;
|
|
635
|
+
console.log(`[IMA EVENT] ${eventType}`, {
|
|
636
|
+
eventType,
|
|
637
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
638
|
+
adData
|
|
639
|
+
});
|
|
640
|
+
});
|
|
641
|
+
}
|
|
642
|
+
});
|
|
643
|
+
console.log("[IMA] ========== EVENT LISTENERS ATTACHED ==========");
|
|
577
644
|
adsManager.addEventListener(
|
|
578
645
|
AdErrorEvent.AD_ERROR,
|
|
579
646
|
(errorEvent) => {
|
|
580
|
-
var _a;
|
|
581
|
-
|
|
647
|
+
var _a, _b, _c, _d, _e, _f;
|
|
648
|
+
const error = errorEvent.getError();
|
|
649
|
+
console.error("[IMA] \u274C AD_ERROR Event:", {
|
|
650
|
+
message: (_a = error.getMessage) == null ? void 0 : _a.call(error),
|
|
651
|
+
errorCode: (_b = error.getErrorCode) == null ? void 0 : _b.call(error),
|
|
652
|
+
type: (_c = error.getType) == null ? void 0 : _c.call(error),
|
|
653
|
+
vastErrorCode: (_d = error.getVastErrorCode) == null ? void 0 : _d.call(error),
|
|
654
|
+
innerError: (_e = error.getInnerError) == null ? void 0 : _e.call(error)
|
|
655
|
+
});
|
|
582
656
|
destroyAdsManager();
|
|
583
657
|
adPlaying = false;
|
|
584
658
|
setAdPlayingFlag(false);
|
|
@@ -620,7 +694,7 @@ function createImaController(video, options) {
|
|
|
620
694
|
console.log(
|
|
621
695
|
"[IMA] Resuming paused video after ad error"
|
|
622
696
|
);
|
|
623
|
-
(
|
|
697
|
+
(_f = video.play()) == null ? void 0 : _f.catch(() => {
|
|
624
698
|
});
|
|
625
699
|
}
|
|
626
700
|
}
|
|
@@ -630,7 +704,8 @@ function createImaController(video, options) {
|
|
|
630
704
|
adsManager.addEventListener(
|
|
631
705
|
AdEvent.CONTENT_PAUSE_REQUESTED,
|
|
632
706
|
() => {
|
|
633
|
-
console.log("[IMA]
|
|
707
|
+
console.log("[IMA] \u2705 CONTENT_PAUSE_REQUESTED - Ad is ready to play!");
|
|
708
|
+
console.log("[IMA] This is the event that triggers the ad layer to appear");
|
|
634
709
|
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
635
710
|
video.pause();
|
|
636
711
|
console.log("[IMA] Content video paused (VOD mode)");
|
|
@@ -639,13 +714,23 @@ function createImaController(video, options) {
|
|
|
639
714
|
"[IMA] Content video continues in background (Live mode)"
|
|
640
715
|
);
|
|
641
716
|
}
|
|
717
|
+
hideContentVideo();
|
|
718
|
+
if (adContainerEl) {
|
|
719
|
+
adContainerEl.style.pointerEvents = "auto";
|
|
720
|
+
adContainerEl.style.display = "flex";
|
|
721
|
+
adContainerEl.style.backgroundColor = "#000";
|
|
722
|
+
adContainerEl.offsetHeight;
|
|
723
|
+
adContainerEl.style.opacity = "1";
|
|
724
|
+
console.log("[IMA] \u2728 Ad container NOW VISIBLE (after content pause)");
|
|
725
|
+
}
|
|
642
726
|
adPlaying = true;
|
|
643
727
|
setAdPlayingFlag(true);
|
|
728
|
+
console.log("[IMA] Emitting 'content_pause' event to player");
|
|
644
729
|
emit("content_pause");
|
|
645
730
|
}
|
|
646
731
|
);
|
|
647
732
|
adsManager.addEventListener(AdEvent.STARTED, () => {
|
|
648
|
-
console.log("[IMA]
|
|
733
|
+
console.log("[IMA] \u25B6\uFE0F STARTED - Ad playback has begun");
|
|
649
734
|
setAdPlayingFlag(true);
|
|
650
735
|
hideContentVideo();
|
|
651
736
|
if (adVideoElement) {
|
|
@@ -661,20 +746,21 @@ function createImaController(video, options) {
|
|
|
661
746
|
adContainerEl.style.backgroundColor = "#000";
|
|
662
747
|
adContainerEl.offsetHeight;
|
|
663
748
|
adContainerEl.style.opacity = "1";
|
|
664
|
-
console.log("[IMA] Ad container now visible");
|
|
749
|
+
console.log("[IMA] Ad container now visible (STARTED event)");
|
|
665
750
|
}
|
|
666
751
|
});
|
|
667
752
|
adsManager.addEventListener(
|
|
668
753
|
AdEvent.CONTENT_RESUME_REQUESTED,
|
|
669
754
|
() => {
|
|
670
|
-
console.log("[IMA]
|
|
755
|
+
console.log("[IMA] \u23F8\uFE0F CONTENT_RESUME_REQUESTED - Single ad completed");
|
|
671
756
|
adPlaying = false;
|
|
672
757
|
setAdPlayingFlag(false);
|
|
758
|
+
console.log("[IMA] Emitting 'content_resume' event to player");
|
|
673
759
|
emit("content_resume");
|
|
674
760
|
}
|
|
675
761
|
);
|
|
676
762
|
adsManager.addEventListener(AdEvent.ALL_ADS_COMPLETED, () => {
|
|
677
|
-
console.log("[IMA] All ads
|
|
763
|
+
console.log("[IMA] \u{1F3C1} ALL_ADS_COMPLETED - All ads in break finished");
|
|
678
764
|
adPlaying = false;
|
|
679
765
|
setAdPlayingFlag(false);
|
|
680
766
|
if (adContainerEl) {
|
|
@@ -684,7 +770,7 @@ function createImaController(video, options) {
|
|
|
684
770
|
if (adContainerEl) {
|
|
685
771
|
adContainerEl.style.pointerEvents = "none";
|
|
686
772
|
adContainerEl.style.display = "none";
|
|
687
|
-
console.log("[IMA] Ad container hidden");
|
|
773
|
+
console.log("[IMA] \u{1F648} Ad container hidden (ALL_ADS_COMPLETED)");
|
|
688
774
|
}
|
|
689
775
|
}, 300);
|
|
690
776
|
}
|
|
@@ -695,6 +781,7 @@ function createImaController(video, options) {
|
|
|
695
781
|
console.warn("[IMA] Failed to resume content video:", e);
|
|
696
782
|
});
|
|
697
783
|
}
|
|
784
|
+
console.log("[IMA] Emitting 'all_ads_completed' event to player");
|
|
698
785
|
emit("all_ads_completed");
|
|
699
786
|
});
|
|
700
787
|
console.log("[IMA] Ads manager event listeners attached");
|
|
@@ -743,7 +830,17 @@ function createImaController(video, options) {
|
|
|
743
830
|
adsLoader.addEventListener(
|
|
744
831
|
google.ima.AdErrorEvent.Type.AD_ERROR,
|
|
745
832
|
(adErrorEvent) => {
|
|
746
|
-
|
|
833
|
+
var _a, _b, _c, _d;
|
|
834
|
+
const error = adErrorEvent.getError();
|
|
835
|
+
console.error("[IMA] \u274C ADS_LOADER ERROR - Ad request failed!", {
|
|
836
|
+
message: (_a = error.getMessage) == null ? void 0 : _a.call(error),
|
|
837
|
+
errorCode: (_b = error.getErrorCode) == null ? void 0 : _b.call(error),
|
|
838
|
+
type: (_c = error.getType) == null ? void 0 : _c.call(error),
|
|
839
|
+
vastErrorCode: (_d = error.getVastErrorCode) == null ? void 0 : _d.call(error)
|
|
840
|
+
});
|
|
841
|
+
console.error("[IMA] This means the ad server didn't return valid ads");
|
|
842
|
+
console.error("[IMA] Ad layer will NOT appear (no flicker)");
|
|
843
|
+
console.error("[IMA] Full error object:", adErrorEvent.getError());
|
|
747
844
|
adPlaying = false;
|
|
748
845
|
setAdPlayingFlag(false);
|
|
749
846
|
if (adContainerEl) {
|
|
@@ -775,8 +872,10 @@ function createImaController(video, options) {
|
|
|
775
872
|
false
|
|
776
873
|
);
|
|
777
874
|
}
|
|
778
|
-
console.log("[IMA] Making ads request");
|
|
875
|
+
console.log("[IMA] \u{1F680} Making ads request to IMA SDK");
|
|
876
|
+
console.log("[IMA] Waiting for IMA SDK response (LOADED or ERROR event)...");
|
|
779
877
|
makeAdsRequest(google, vastTagUrl);
|
|
878
|
+
console.log("[IMA] \u23F3 Returning promise that will resolve when ads are loaded");
|
|
780
879
|
return adsLoadedPromise;
|
|
781
880
|
} catch (error) {
|
|
782
881
|
console.error("[IMA] Failed to request ads:", error);
|
|
@@ -814,20 +913,23 @@ function createImaController(video, options) {
|
|
|
814
913
|
},
|
|
815
914
|
async play() {
|
|
816
915
|
var _a, _b;
|
|
916
|
+
console.log("[IMA] \u25B6\uFE0F === play() called ===");
|
|
917
|
+
console.log("[IMA] This initializes and starts the ad");
|
|
918
|
+
console.log("[IMA] Ad layer will appear when CONTENT_PAUSE_REQUESTED fires");
|
|
817
919
|
if (!((_a = window.google) == null ? void 0 : _a.ima) || !adDisplayContainer) {
|
|
818
920
|
console.warn(
|
|
819
|
-
"[IMA] Cannot play ad: IMA SDK or ad container not available"
|
|
921
|
+
"[IMA] \u274C Cannot play ad: IMA SDK or ad container not available"
|
|
820
922
|
);
|
|
821
923
|
return Promise.reject(new Error("IMA SDK not available"));
|
|
822
924
|
}
|
|
823
925
|
if (!adsManager) {
|
|
824
|
-
console.warn("[IMA] Cannot play ad: No ads manager available");
|
|
926
|
+
console.warn("[IMA] \u274C Cannot play ad: No ads manager available");
|
|
825
927
|
return Promise.reject(new Error("No ads manager"));
|
|
826
928
|
}
|
|
827
929
|
try {
|
|
828
930
|
const width = video.clientWidth || 640;
|
|
829
931
|
const height = video.clientHeight || 360;
|
|
830
|
-
console.log(`[IMA] Initializing ads manager (${width}x${height})`);
|
|
932
|
+
console.log(`[IMA] \u{1F3AC} Initializing ads manager (${width}x${height})`);
|
|
831
933
|
adsManager.init(width, height, window.google.ima.ViewMode.NORMAL);
|
|
832
934
|
adPlaying = true;
|
|
833
935
|
const adVolume = originalMutedState ? 0 : originalVolume;
|
|
@@ -835,7 +937,7 @@ function createImaController(video, options) {
|
|
|
835
937
|
adVideoElement.volume = adVolume;
|
|
836
938
|
adVideoElement.muted = originalMutedState;
|
|
837
939
|
console.log(
|
|
838
|
-
`[IMA] Set dedicated ad video volume to ${adVolume}, muted: ${originalMutedState}`
|
|
940
|
+
`[IMA] \u{1F50A} Set dedicated ad video volume to ${adVolume}, muted: ${originalMutedState}`
|
|
839
941
|
);
|
|
840
942
|
}
|
|
841
943
|
try {
|
|
@@ -844,11 +946,13 @@ function createImaController(video, options) {
|
|
|
844
946
|
} catch (error) {
|
|
845
947
|
console.warn("[IMA] Failed to set IMA manager volume:", error);
|
|
846
948
|
}
|
|
847
|
-
console.log("[IMA]
|
|
949
|
+
console.log("[IMA] \u{1F3AF} Calling adsManager.start()");
|
|
950
|
+
console.log("[IMA] If successful, IMA will fire CONTENT_PAUSE_REQUESTED");
|
|
848
951
|
adsManager.start();
|
|
952
|
+
console.log("[IMA] \u2705 play() completed successfully");
|
|
849
953
|
return Promise.resolve();
|
|
850
954
|
} catch (error) {
|
|
851
|
-
console.error("[IMA] Error starting ad playback:", error);
|
|
955
|
+
console.error("[IMA] \u274C Error starting ad playback:", error);
|
|
852
956
|
adPlaying = false;
|
|
853
957
|
setAdPlayingFlag(false);
|
|
854
958
|
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
@@ -2173,6 +2277,9 @@ var StormcloudVideoPlayer = class {
|
|
|
2173
2277
|
this.hasInitialBufferCompleted = false;
|
|
2174
2278
|
this.adPodAllUrls = [];
|
|
2175
2279
|
this.preloadingAdUrls = /* @__PURE__ */ new Set();
|
|
2280
|
+
this.vastToMediaUrlMap = /* @__PURE__ */ new Map();
|
|
2281
|
+
this.preloadedMediaUrls = /* @__PURE__ */ new Set();
|
|
2282
|
+
this.preloadingMediaUrls = /* @__PURE__ */ new Set();
|
|
2176
2283
|
initializePolyfills();
|
|
2177
2284
|
const browserOverrides = getBrowserConfigOverrides();
|
|
2178
2285
|
this.config = { ...config, ...browserOverrides };
|
|
@@ -2445,27 +2552,44 @@ var StormcloudVideoPlayer = class {
|
|
|
2445
2552
|
});
|
|
2446
2553
|
this.ima.on("ad_error", () => {
|
|
2447
2554
|
if (this.config.debugAdTiming) {
|
|
2448
|
-
console.log("[StormcloudVideoPlayer] IMA ad_error event received"
|
|
2555
|
+
console.log("[StormcloudVideoPlayer] IMA ad_error event received", {
|
|
2556
|
+
showAds: this.showAds,
|
|
2557
|
+
inAdBreak: this.inAdBreak,
|
|
2558
|
+
remainingAds: this.adPodQueue.length
|
|
2559
|
+
});
|
|
2449
2560
|
}
|
|
2450
|
-
if (this.
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2561
|
+
if (this.inAdBreak) {
|
|
2562
|
+
const remaining = this.getRemainingAdMs();
|
|
2563
|
+
if (remaining > 500 && this.adPodQueue.length > 0) {
|
|
2564
|
+
const nextPreloaded = this.findNextPreloadedAd();
|
|
2565
|
+
if (nextPreloaded) {
|
|
2455
2566
|
this.currentAdIndex++;
|
|
2456
|
-
this.
|
|
2567
|
+
if (this.config.debugAdTiming) {
|
|
2568
|
+
console.log(
|
|
2569
|
+
`[StormcloudVideoPlayer] Skipping to next preloaded ad after error`
|
|
2570
|
+
);
|
|
2571
|
+
}
|
|
2572
|
+
this.playSingleAd(nextPreloaded).catch(() => {
|
|
2573
|
+
this.handleAdFailure();
|
|
2457
2574
|
});
|
|
2458
2575
|
} else {
|
|
2576
|
+
if (this.config.debugAdTiming) {
|
|
2577
|
+
console.log(
|
|
2578
|
+
"[StormcloudVideoPlayer] No preloaded ads available, ending ad break"
|
|
2579
|
+
);
|
|
2580
|
+
}
|
|
2459
2581
|
this.handleAdFailure();
|
|
2460
2582
|
}
|
|
2461
2583
|
} else {
|
|
2462
|
-
if (this.config.debugAdTiming) {
|
|
2463
|
-
console.log(
|
|
2464
|
-
"[StormcloudVideoPlayer] Ad error before ad break established - cleaning up"
|
|
2465
|
-
);
|
|
2466
|
-
}
|
|
2467
2584
|
this.handleAdFailure();
|
|
2468
2585
|
}
|
|
2586
|
+
} else {
|
|
2587
|
+
if (this.config.debugAdTiming) {
|
|
2588
|
+
console.log(
|
|
2589
|
+
"[StormcloudVideoPlayer] Ad error before ad break established - cleaning up"
|
|
2590
|
+
);
|
|
2591
|
+
}
|
|
2592
|
+
this.handleAdFailure();
|
|
2469
2593
|
}
|
|
2470
2594
|
});
|
|
2471
2595
|
this.ima.on("content_pause", () => {
|
|
@@ -2496,22 +2620,30 @@ var StormcloudVideoPlayer = class {
|
|
|
2496
2620
|
}
|
|
2497
2621
|
const remaining = this.getRemainingAdMs();
|
|
2498
2622
|
if (remaining > 500 && this.adPodQueue.length > 0) {
|
|
2499
|
-
const
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
if (this.config.debugAdTiming) {
|
|
2503
|
-
console.log(
|
|
2504
|
-
`[StormcloudVideoPlayer] Playing next ad in pod (${this.currentAdIndex}/${this.totalAdsInBreak}) - IMMEDIATELY starting next ad`
|
|
2505
|
-
);
|
|
2506
|
-
}
|
|
2507
|
-
this.playSingleAd(next).catch(() => {
|
|
2623
|
+
const nextPreloaded = this.findNextPreloadedAd();
|
|
2624
|
+
if (nextPreloaded) {
|
|
2625
|
+
this.currentAdIndex++;
|
|
2508
2626
|
if (this.config.debugAdTiming) {
|
|
2509
|
-
console.
|
|
2510
|
-
|
|
2627
|
+
console.log(
|
|
2628
|
+
`[StormcloudVideoPlayer] Playing next preloaded ad in pod (${this.currentAdIndex}/${this.totalAdsInBreak}) - layer will stay visible if ad loads`
|
|
2629
|
+
);
|
|
2630
|
+
}
|
|
2631
|
+
this.playSingleAd(nextPreloaded).catch(() => {
|
|
2632
|
+
if (this.config.debugAdTiming) {
|
|
2633
|
+
console.error(
|
|
2634
|
+
"[StormcloudVideoPlayer] Failed to play next ad in pod"
|
|
2635
|
+
);
|
|
2636
|
+
}
|
|
2637
|
+
this.handleAdPodComplete();
|
|
2638
|
+
});
|
|
2639
|
+
} else {
|
|
2640
|
+
if (this.config.debugAdTiming) {
|
|
2641
|
+
console.log(
|
|
2642
|
+
"[StormcloudVideoPlayer] No preloaded ads available - completing ad break"
|
|
2511
2643
|
);
|
|
2512
2644
|
}
|
|
2513
2645
|
this.handleAdPodComplete();
|
|
2514
|
-
}
|
|
2646
|
+
}
|
|
2515
2647
|
} else {
|
|
2516
2648
|
if (this.config.debugAdTiming) {
|
|
2517
2649
|
console.log(
|
|
@@ -2756,6 +2888,9 @@ var StormcloudVideoPlayer = class {
|
|
|
2756
2888
|
const first = tags[0];
|
|
2757
2889
|
const rest = tags.slice(1);
|
|
2758
2890
|
this.adPodQueue = rest;
|
|
2891
|
+
if (!this.showAds) {
|
|
2892
|
+
this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);
|
|
2893
|
+
}
|
|
2759
2894
|
this.playSingleAd(first).catch(() => {
|
|
2760
2895
|
});
|
|
2761
2896
|
}
|
|
@@ -3112,19 +3247,37 @@ var StormcloudVideoPlayer = class {
|
|
|
3112
3247
|
if (vastTagUrls.length > 0) {
|
|
3113
3248
|
this.adPodAllUrls = [...vastTagUrls];
|
|
3114
3249
|
this.preloadingAdUrls.clear();
|
|
3250
|
+
this.vastToMediaUrlMap.clear();
|
|
3251
|
+
this.preloadedMediaUrls.clear();
|
|
3252
|
+
this.preloadingMediaUrls.clear();
|
|
3115
3253
|
this.logQueuedAdUrls(this.adPodAllUrls);
|
|
3254
|
+
if (this.config.debugAdTiming) {
|
|
3255
|
+
console.log(
|
|
3256
|
+
`[StormcloudVideoPlayer] Capturing original audio state before ad break:`,
|
|
3257
|
+
{
|
|
3258
|
+
videoMuted: this.video.muted,
|
|
3259
|
+
videoVolume: this.video.volume
|
|
3260
|
+
}
|
|
3261
|
+
);
|
|
3262
|
+
}
|
|
3263
|
+
this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);
|
|
3116
3264
|
this.inAdBreak = true;
|
|
3117
|
-
this.showAds = true;
|
|
3118
3265
|
this.currentAdIndex = 0;
|
|
3119
3266
|
this.totalAdsInBreak = vastTagUrls.length;
|
|
3120
3267
|
this.adPodQueue = [...vastTagUrls];
|
|
3121
|
-
this.enforceAdHoldState();
|
|
3122
|
-
this.preloadUpcomingAds();
|
|
3123
3268
|
if (this.config.debugAdTiming) {
|
|
3124
3269
|
console.log(
|
|
3125
|
-
`[StormcloudVideoPlayer] Starting ad pod with ${vastTagUrls.length} ads - will
|
|
3270
|
+
`[StormcloudVideoPlayer] Starting ad pod with ${vastTagUrls.length} ads - preloading all ads in parallel (ad layer will show after ad loads)`
|
|
3126
3271
|
);
|
|
3127
3272
|
}
|
|
3273
|
+
this.preloadAllAdsInBackground().catch((error) => {
|
|
3274
|
+
if (this.config.debugAdTiming) {
|
|
3275
|
+
console.warn(
|
|
3276
|
+
"[StormcloudVideoPlayer] Error in background preloading:",
|
|
3277
|
+
error
|
|
3278
|
+
);
|
|
3279
|
+
}
|
|
3280
|
+
});
|
|
3128
3281
|
try {
|
|
3129
3282
|
await this.playAdPod();
|
|
3130
3283
|
} catch (error) {
|
|
@@ -3150,14 +3303,28 @@ var StormcloudVideoPlayer = class {
|
|
|
3150
3303
|
}
|
|
3151
3304
|
return;
|
|
3152
3305
|
}
|
|
3153
|
-
|
|
3306
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
3307
|
+
const firstPreloaded = this.findNextPreloadedAd();
|
|
3308
|
+
if (!firstPreloaded) {
|
|
3309
|
+
if (this.config.debugAdTiming) {
|
|
3310
|
+
console.log(
|
|
3311
|
+
"[StormcloudVideoPlayer] No preloaded ads available after waiting, trying first ad anyway"
|
|
3312
|
+
);
|
|
3313
|
+
}
|
|
3314
|
+
const firstAd = this.adPodQueue.shift();
|
|
3315
|
+
if (firstAd) {
|
|
3316
|
+
this.currentAdIndex++;
|
|
3317
|
+
await this.playSingleAd(firstAd);
|
|
3318
|
+
}
|
|
3319
|
+
return;
|
|
3320
|
+
}
|
|
3154
3321
|
this.currentAdIndex++;
|
|
3155
3322
|
if (this.config.debugAdTiming) {
|
|
3156
3323
|
console.log(
|
|
3157
|
-
`[StormcloudVideoPlayer] Playing ad ${this.currentAdIndex}/${this.totalAdsInBreak}`
|
|
3324
|
+
`[StormcloudVideoPlayer] Playing first preloaded ad ${this.currentAdIndex}/${this.totalAdsInBreak}`
|
|
3158
3325
|
);
|
|
3159
3326
|
}
|
|
3160
|
-
await this.playSingleAd(
|
|
3327
|
+
await this.playSingleAd(firstPreloaded);
|
|
3161
3328
|
}
|
|
3162
3329
|
findCurrentOrNextBreak(nowMs) {
|
|
3163
3330
|
var _a;
|
|
@@ -3190,7 +3357,7 @@ var StormcloudVideoPlayer = class {
|
|
|
3190
3357
|
const first = tags[0];
|
|
3191
3358
|
const rest = tags.slice(1);
|
|
3192
3359
|
this.adPodQueue = rest;
|
|
3193
|
-
this.
|
|
3360
|
+
this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);
|
|
3194
3361
|
await this.playSingleAd(first);
|
|
3195
3362
|
this.inAdBreak = true;
|
|
3196
3363
|
this.expectedAdBreakDurationMs = remainingMs;
|
|
@@ -3310,38 +3477,20 @@ var StormcloudVideoPlayer = class {
|
|
|
3310
3477
|
`[StormcloudVideoPlayer] IMA SDK preloaded this ad already: ${vastTagUrl}`
|
|
3311
3478
|
);
|
|
3312
3479
|
}
|
|
3313
|
-
if (!this.showAds) {
|
|
3314
|
-
if (this.config.debugAdTiming) {
|
|
3315
|
-
console.log(
|
|
3316
|
-
`[StormcloudVideoPlayer] Capturing original state before ad request:`,
|
|
3317
|
-
{
|
|
3318
|
-
videoMuted: this.video.muted,
|
|
3319
|
-
videoVolume: this.video.volume,
|
|
3320
|
-
showAds: this.showAds
|
|
3321
|
-
}
|
|
3322
|
-
);
|
|
3323
|
-
}
|
|
3324
|
-
this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);
|
|
3325
|
-
} else if (this.config.debugAdTiming) {
|
|
3326
|
-
console.log(
|
|
3327
|
-
`[StormcloudVideoPlayer] Keeping existing original mute state (currently showing ads)`
|
|
3328
|
-
);
|
|
3329
|
-
}
|
|
3330
3480
|
this.startAdFailsafeTimer();
|
|
3331
3481
|
try {
|
|
3332
3482
|
await this.ima.requestAds(vastTagUrl);
|
|
3333
|
-
this.preloadUpcomingAds();
|
|
3334
3483
|
try {
|
|
3335
3484
|
if (this.config.debugAdTiming) {
|
|
3336
3485
|
console.log(
|
|
3337
|
-
"[StormcloudVideoPlayer] Ad request completed, attempting playback"
|
|
3486
|
+
"[StormcloudVideoPlayer] Ad request completed, attempting playback (ad layer will show when IMA triggers content pause)"
|
|
3338
3487
|
);
|
|
3339
3488
|
}
|
|
3340
|
-
this.enforceAdHoldState();
|
|
3341
3489
|
await this.ima.play();
|
|
3490
|
+
this.showAds = true;
|
|
3342
3491
|
if (this.config.debugAdTiming) {
|
|
3343
3492
|
console.log(
|
|
3344
|
-
"[StormcloudVideoPlayer] Ad playback started successfully"
|
|
3493
|
+
"[StormcloudVideoPlayer] Ad playback started successfully, showAds = true"
|
|
3345
3494
|
);
|
|
3346
3495
|
}
|
|
3347
3496
|
} catch (playError) {
|
|
@@ -3369,6 +3518,9 @@ var StormcloudVideoPlayer = class {
|
|
|
3369
3518
|
}
|
|
3370
3519
|
this.releaseAdHoldState();
|
|
3371
3520
|
this.preloadingAdUrls.clear();
|
|
3521
|
+
this.vastToMediaUrlMap.clear();
|
|
3522
|
+
this.preloadedMediaUrls.clear();
|
|
3523
|
+
this.preloadingMediaUrls.clear();
|
|
3372
3524
|
this.inAdBreak = false;
|
|
3373
3525
|
this.expectedAdBreakDurationMs = void 0;
|
|
3374
3526
|
this.currentAdBreakStartWallClockMs = void 0;
|
|
@@ -3478,44 +3630,204 @@ var StormcloudVideoPlayer = class {
|
|
|
3478
3630
|
this.ima.hidePlaceholder();
|
|
3479
3631
|
}
|
|
3480
3632
|
}
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3633
|
+
async fetchAndParseVastXml(vastTagUrl) {
|
|
3634
|
+
try {
|
|
3635
|
+
const response = await fetch(vastTagUrl, { mode: "cors" });
|
|
3636
|
+
if (!response.ok) {
|
|
3637
|
+
throw new Error(`Failed to fetch VAST: ${response.status}`);
|
|
3638
|
+
}
|
|
3639
|
+
const xmlText = await response.text();
|
|
3640
|
+
return this.extractMediaUrlsFromVast(xmlText);
|
|
3641
|
+
} catch (error) {
|
|
3642
|
+
if (this.config.debugAdTiming) {
|
|
3643
|
+
console.warn(
|
|
3644
|
+
`[StormcloudVideoPlayer] Failed to fetch/parse VAST XML: ${vastTagUrl}`,
|
|
3645
|
+
error
|
|
3646
|
+
);
|
|
3647
|
+
}
|
|
3648
|
+
return [];
|
|
3484
3649
|
}
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3650
|
+
}
|
|
3651
|
+
extractMediaUrlsFromVast(xmlText) {
|
|
3652
|
+
var _a;
|
|
3653
|
+
const mediaUrls = [];
|
|
3654
|
+
try {
|
|
3655
|
+
const parser = new DOMParser();
|
|
3656
|
+
const xmlDoc = parser.parseFromString(xmlText, "text/xml");
|
|
3657
|
+
const mediaFileElements = xmlDoc.querySelectorAll("MediaFile");
|
|
3658
|
+
for (const mediaFile of Array.from(mediaFileElements)) {
|
|
3659
|
+
const url = (_a = mediaFile.textContent) == null ? void 0 : _a.trim();
|
|
3660
|
+
if (url) {
|
|
3661
|
+
const lowerUrl = url.toLowerCase();
|
|
3662
|
+
if (lowerUrl.endsWith(".mp4") || lowerUrl.endsWith(".webm") || lowerUrl.endsWith(".mov") || lowerUrl.endsWith(".avi") || lowerUrl.includes(".mp4?") || lowerUrl.includes(".webm?") || lowerUrl.includes("/mp4/") || lowerUrl.includes("type=video")) {
|
|
3663
|
+
mediaUrls.push(url);
|
|
3664
|
+
}
|
|
3665
|
+
}
|
|
3491
3666
|
}
|
|
3492
|
-
if (this.
|
|
3493
|
-
|
|
3667
|
+
if (this.config.debugAdTiming && mediaUrls.length > 0) {
|
|
3668
|
+
console.log(
|
|
3669
|
+
`[StormcloudVideoPlayer] Extracted ${mediaUrls.length} media URLs from VAST:`,
|
|
3670
|
+
mediaUrls
|
|
3671
|
+
);
|
|
3494
3672
|
}
|
|
3673
|
+
} catch (error) {
|
|
3674
|
+
if (this.config.debugAdTiming) {
|
|
3675
|
+
console.warn(
|
|
3676
|
+
"[StormcloudVideoPlayer] Failed to parse VAST XML:",
|
|
3677
|
+
error
|
|
3678
|
+
);
|
|
3679
|
+
}
|
|
3680
|
+
}
|
|
3681
|
+
return mediaUrls;
|
|
3682
|
+
}
|
|
3683
|
+
async preloadMediaFile(mediaUrl) {
|
|
3684
|
+
if (this.preloadedMediaUrls.has(mediaUrl)) {
|
|
3685
|
+
return;
|
|
3686
|
+
}
|
|
3687
|
+
if (this.preloadingMediaUrls.has(mediaUrl)) {
|
|
3688
|
+
return;
|
|
3689
|
+
}
|
|
3690
|
+
this.preloadingMediaUrls.add(mediaUrl);
|
|
3691
|
+
try {
|
|
3495
3692
|
if (this.config.debugAdTiming) {
|
|
3496
3693
|
console.log(
|
|
3497
|
-
`[StormcloudVideoPlayer]
|
|
3694
|
+
`[StormcloudVideoPlayer] Preloading video file: ${mediaUrl}`
|
|
3498
3695
|
);
|
|
3499
3696
|
}
|
|
3500
|
-
|
|
3501
|
-
|
|
3697
|
+
const response = await fetch(mediaUrl, {
|
|
3698
|
+
mode: "cors",
|
|
3699
|
+
method: "GET",
|
|
3700
|
+
headers: {
|
|
3701
|
+
Range: "bytes=0-1048576"
|
|
3702
|
+
}
|
|
3703
|
+
});
|
|
3704
|
+
if (response.ok || response.status === 206) {
|
|
3705
|
+
this.preloadedMediaUrls.add(mediaUrl);
|
|
3502
3706
|
if (this.config.debugAdTiming) {
|
|
3503
3707
|
console.log(
|
|
3504
|
-
`[StormcloudVideoPlayer]
|
|
3708
|
+
`[StormcloudVideoPlayer] Successfully preloaded video file: ${mediaUrl}`
|
|
3505
3709
|
);
|
|
3506
3710
|
}
|
|
3507
|
-
}
|
|
3711
|
+
}
|
|
3712
|
+
} catch (error) {
|
|
3713
|
+
if (this.config.debugAdTiming) {
|
|
3714
|
+
console.warn(
|
|
3715
|
+
`[StormcloudVideoPlayer] Failed to preload video file: ${mediaUrl}`,
|
|
3716
|
+
error
|
|
3717
|
+
);
|
|
3718
|
+
}
|
|
3719
|
+
} finally {
|
|
3720
|
+
this.preloadingMediaUrls.delete(mediaUrl);
|
|
3721
|
+
}
|
|
3722
|
+
}
|
|
3723
|
+
async preloadAllAdsInBackground() {
|
|
3724
|
+
if (this.adPodAllUrls.length === 0) {
|
|
3725
|
+
return;
|
|
3726
|
+
}
|
|
3727
|
+
if (this.config.debugAdTiming) {
|
|
3728
|
+
console.log(
|
|
3729
|
+
`[StormcloudVideoPlayer] Starting parallel preload of ${this.adPodAllUrls.length} ads`
|
|
3730
|
+
);
|
|
3731
|
+
}
|
|
3732
|
+
const preloadPromises = this.adPodAllUrls.map(
|
|
3733
|
+
(vastTagUrl) => this.preloadSingleAd(vastTagUrl).catch((error) => {
|
|
3508
3734
|
if (this.config.debugAdTiming) {
|
|
3509
3735
|
console.warn(
|
|
3510
|
-
`[StormcloudVideoPlayer]
|
|
3736
|
+
`[StormcloudVideoPlayer] Preload failed for ${vastTagUrl}:`,
|
|
3511
3737
|
error
|
|
3512
3738
|
);
|
|
3513
3739
|
}
|
|
3514
|
-
})
|
|
3515
|
-
|
|
3516
|
-
|
|
3740
|
+
})
|
|
3741
|
+
);
|
|
3742
|
+
await Promise.all(preloadPromises);
|
|
3743
|
+
if (this.config.debugAdTiming) {
|
|
3744
|
+
console.log(
|
|
3745
|
+
`[StormcloudVideoPlayer] Background preloading completed for all ads`
|
|
3746
|
+
);
|
|
3517
3747
|
}
|
|
3518
3748
|
}
|
|
3749
|
+
async preloadSingleAd(vastTagUrl) {
|
|
3750
|
+
if (!vastTagUrl) return;
|
|
3751
|
+
try {
|
|
3752
|
+
if (this.ima.preloadAds && !this.ima.hasPreloadedAd(vastTagUrl)) {
|
|
3753
|
+
if (!this.preloadingAdUrls.has(vastTagUrl)) {
|
|
3754
|
+
if (this.config.debugAdTiming) {
|
|
3755
|
+
console.log(
|
|
3756
|
+
`[StormcloudVideoPlayer] Preloading VAST: ${vastTagUrl}`
|
|
3757
|
+
);
|
|
3758
|
+
}
|
|
3759
|
+
this.preloadingAdUrls.add(vastTagUrl);
|
|
3760
|
+
await this.ima.preloadAds(vastTagUrl).then(() => {
|
|
3761
|
+
if (this.config.debugAdTiming) {
|
|
3762
|
+
console.log(
|
|
3763
|
+
`[StormcloudVideoPlayer] IMA VAST preload complete: ${vastTagUrl}`
|
|
3764
|
+
);
|
|
3765
|
+
}
|
|
3766
|
+
}).catch((error) => {
|
|
3767
|
+
if (this.config.debugAdTiming) {
|
|
3768
|
+
console.warn(
|
|
3769
|
+
`[StormcloudVideoPlayer] IMA VAST preload failed: ${vastTagUrl}`,
|
|
3770
|
+
error
|
|
3771
|
+
);
|
|
3772
|
+
}
|
|
3773
|
+
}).finally(() => {
|
|
3774
|
+
this.preloadingAdUrls.delete(vastTagUrl);
|
|
3775
|
+
});
|
|
3776
|
+
}
|
|
3777
|
+
}
|
|
3778
|
+
let mediaUrls = this.vastToMediaUrlMap.get(vastTagUrl);
|
|
3779
|
+
if (!mediaUrls) {
|
|
3780
|
+
if (this.config.debugAdTiming) {
|
|
3781
|
+
console.log(
|
|
3782
|
+
`[StormcloudVideoPlayer] Fetching and parsing VAST to extract media URLs: ${vastTagUrl}`
|
|
3783
|
+
);
|
|
3784
|
+
}
|
|
3785
|
+
mediaUrls = await this.fetchAndParseVastXml(vastTagUrl);
|
|
3786
|
+
if (mediaUrls.length > 0) {
|
|
3787
|
+
this.vastToMediaUrlMap.set(vastTagUrl, mediaUrls);
|
|
3788
|
+
}
|
|
3789
|
+
}
|
|
3790
|
+
if (mediaUrls && mediaUrls.length > 0) {
|
|
3791
|
+
const primaryMediaUrl = mediaUrls[0];
|
|
3792
|
+
if (primaryMediaUrl && !this.preloadedMediaUrls.has(primaryMediaUrl)) {
|
|
3793
|
+
await this.preloadMediaFile(primaryMediaUrl);
|
|
3794
|
+
}
|
|
3795
|
+
}
|
|
3796
|
+
} catch (error) {
|
|
3797
|
+
if (this.config.debugAdTiming) {
|
|
3798
|
+
console.warn(
|
|
3799
|
+
`[StormcloudVideoPlayer] Failed to preload ad: ${vastTagUrl}`,
|
|
3800
|
+
error
|
|
3801
|
+
);
|
|
3802
|
+
}
|
|
3803
|
+
}
|
|
3804
|
+
}
|
|
3805
|
+
findNextPreloadedAd() {
|
|
3806
|
+
var _a, _b, _c;
|
|
3807
|
+
for (let i = 0; i < this.adPodQueue.length; i++) {
|
|
3808
|
+
const vastTagUrl = this.adPodQueue[i];
|
|
3809
|
+
if (!vastTagUrl) continue;
|
|
3810
|
+
const hasImaPreload = (_c = (_b = (_a = this.ima).hasPreloadedAd) == null ? void 0 : _b.call(_a, vastTagUrl)) != null ? _c : false;
|
|
3811
|
+
const mediaUrls = this.vastToMediaUrlMap.get(vastTagUrl);
|
|
3812
|
+
const hasMediaPreload = mediaUrls && mediaUrls.length > 0 ? this.preloadedMediaUrls.has(mediaUrls[0]) : false;
|
|
3813
|
+
if (hasImaPreload || hasMediaPreload) {
|
|
3814
|
+
if (this.config.debugAdTiming) {
|
|
3815
|
+
console.log(
|
|
3816
|
+
`[StormcloudVideoPlayer] Found preloaded ad at index ${i}: ${vastTagUrl}`,
|
|
3817
|
+
{ hasImaPreload, hasMediaPreload }
|
|
3818
|
+
);
|
|
3819
|
+
}
|
|
3820
|
+
this.adPodQueue.splice(0, i + 1);
|
|
3821
|
+
return vastTagUrl;
|
|
3822
|
+
}
|
|
3823
|
+
}
|
|
3824
|
+
if (this.config.debugAdTiming) {
|
|
3825
|
+
console.log(
|
|
3826
|
+
"[StormcloudVideoPlayer] No preloaded ads found in queue"
|
|
3827
|
+
);
|
|
3828
|
+
}
|
|
3829
|
+
return void 0;
|
|
3830
|
+
}
|
|
3519
3831
|
getRemainingAdMs() {
|
|
3520
3832
|
if (this.expectedAdBreakDurationMs == null || this.currentAdBreakStartWallClockMs == null)
|
|
3521
3833
|
return 0;
|
|
@@ -3684,6 +3996,9 @@ var StormcloudVideoPlayer = class {
|
|
|
3684
3996
|
(_b = this.ima) == null ? void 0 : _b.destroy();
|
|
3685
3997
|
this.releaseAdHoldState();
|
|
3686
3998
|
this.preloadingAdUrls.clear();
|
|
3999
|
+
this.vastToMediaUrlMap.clear();
|
|
4000
|
+
this.preloadedMediaUrls.clear();
|
|
4001
|
+
this.preloadingMediaUrls.clear();
|
|
3687
4002
|
this.adPodAllUrls = [];
|
|
3688
4003
|
}
|
|
3689
4004
|
};
|