stormcloud-video-player 0.2.13 → 0.2.14
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 +238 -117
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +2 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +238 -117
- package/lib/index.js.map +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +196 -92
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/players/FilePlayer.cjs +14 -7
- package/lib/players/FilePlayer.cjs.map +1 -1
- package/lib/players/HlsPlayer.cjs +204 -97
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/index.cjs +218 -104
- package/lib/players/index.cjs.map +1 -1
- package/lib/sdk/hlsAdPlayer.cjs +89 -16
- package/lib/sdk/hlsAdPlayer.cjs.map +1 -1
- package/lib/sdk/hlsAdPlayer.d.cts +2 -0
- package/lib/sdk/ima.cjs +34 -24
- package/lib/sdk/ima.cjs.map +1 -1
- package/lib/ui/StormcloudVideoPlayer.cjs +203 -97
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/utils/browserCompat.cjs +2 -1
- package/lib/utils/browserCompat.cjs.map +1 -1
- package/lib/utils/tracking.cjs +10 -9
- package/lib/utils/tracking.cjs.map +1 -1
- package/package.json +1 -1
package/lib/index.cjs
CHANGED
|
@@ -83,7 +83,8 @@ function getWebKitVersion(ua) {
|
|
|
83
83
|
return match && match[1] ? parseInt(match[1], 10) : 0;
|
|
84
84
|
}
|
|
85
85
|
function getPlatform() {
|
|
86
|
-
|
|
86
|
+
var _a;
|
|
87
|
+
if ("userAgentData" in navigator && ((_a = navigator.userAgentData) == null ? void 0 : _a.platform)) {
|
|
87
88
|
return navigator.userAgentData.platform;
|
|
88
89
|
}
|
|
89
90
|
const ua = navigator.userAgent;
|
|
@@ -277,6 +278,7 @@ function createImaController(video, options) {
|
|
|
277
278
|
}
|
|
278
279
|
}
|
|
279
280
|
function ensureImaLoaded() {
|
|
281
|
+
var _a, _b, _c;
|
|
280
282
|
if (!supportsGoogleIMA()) {
|
|
281
283
|
console.warn(
|
|
282
284
|
"[IMA] Google IMA SDK is not supported on this browser. Please use HLS ad player instead."
|
|
@@ -287,7 +289,7 @@ function createImaController(video, options) {
|
|
|
287
289
|
}
|
|
288
290
|
try {
|
|
289
291
|
const frameEl = window.frameElement;
|
|
290
|
-
const sandboxAttr = frameEl
|
|
292
|
+
const sandboxAttr = ((_a = frameEl == null ? void 0 : frameEl.getAttribute) == null ? void 0 : _a.call(frameEl, "sandbox")) || "";
|
|
291
293
|
if (sandboxAttr) {
|
|
292
294
|
const tokens = new Set(
|
|
293
295
|
sandboxAttr.split(/\s+/).map((t) => t.trim()).filter((t) => t.length > 0)
|
|
@@ -301,13 +303,13 @@ function createImaController(video, options) {
|
|
|
301
303
|
}
|
|
302
304
|
} catch {
|
|
303
305
|
}
|
|
304
|
-
if (typeof window !== "undefined" && window.google
|
|
306
|
+
if (typeof window !== "undefined" && ((_b = window.google) == null ? void 0 : _b.ima))
|
|
305
307
|
return Promise.resolve();
|
|
306
308
|
const existing = document.querySelector(
|
|
307
309
|
'script[data-ima="true"]'
|
|
308
310
|
);
|
|
309
311
|
if (existing) {
|
|
310
|
-
if (window.google
|
|
312
|
+
if ((_c = window.google) == null ? void 0 : _c.ima) {
|
|
311
313
|
return Promise.resolve();
|
|
312
314
|
}
|
|
313
315
|
return new Promise((resolve, reject) => {
|
|
@@ -365,6 +367,7 @@ function createImaController(video, options) {
|
|
|
365
367
|
return {
|
|
366
368
|
initialize() {
|
|
367
369
|
ensureImaLoaded().then(() => {
|
|
370
|
+
var _a, _b;
|
|
368
371
|
const google = window.google;
|
|
369
372
|
if (!adDisplayContainer) {
|
|
370
373
|
const container = document.createElement("div");
|
|
@@ -378,14 +381,14 @@ function createImaController(video, options) {
|
|
|
378
381
|
container.style.justifyContent = "center";
|
|
379
382
|
container.style.pointerEvents = "none";
|
|
380
383
|
container.style.zIndex = "2";
|
|
381
|
-
video.parentElement
|
|
384
|
+
(_a = video.parentElement) == null ? void 0 : _a.appendChild(container);
|
|
382
385
|
adContainerEl = container;
|
|
383
386
|
adDisplayContainer = new google.ima.AdDisplayContainer(
|
|
384
387
|
container,
|
|
385
388
|
video
|
|
386
389
|
);
|
|
387
390
|
try {
|
|
388
|
-
adDisplayContainer.initialize
|
|
391
|
+
(_b = adDisplayContainer.initialize) == null ? void 0 : _b.call(adDisplayContainer);
|
|
389
392
|
} catch {
|
|
390
393
|
}
|
|
391
394
|
}
|
|
@@ -470,6 +473,7 @@ function createImaController(video, options) {
|
|
|
470
473
|
adsManager.addEventListener(
|
|
471
474
|
AdErrorEvent.AD_ERROR,
|
|
472
475
|
(errorEvent) => {
|
|
476
|
+
var _a;
|
|
473
477
|
console.error("[IMA] Ad error:", errorEvent.getError());
|
|
474
478
|
destroyAdsManager();
|
|
475
479
|
adPlaying = false;
|
|
@@ -500,10 +504,10 @@ function createImaController(video, options) {
|
|
|
500
504
|
"[IMA] Max retries reached, emitting ad_error"
|
|
501
505
|
);
|
|
502
506
|
emit("ad_error");
|
|
503
|
-
if (!options
|
|
507
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
504
508
|
if (video.paused) {
|
|
505
509
|
console.log("[IMA] Resuming paused video after ad error");
|
|
506
|
-
video.play()
|
|
510
|
+
(_a = video.play()) == null ? void 0 : _a.catch(() => {
|
|
507
511
|
});
|
|
508
512
|
}
|
|
509
513
|
}
|
|
@@ -514,7 +518,7 @@ function createImaController(video, options) {
|
|
|
514
518
|
AdEvent.CONTENT_PAUSE_REQUESTED,
|
|
515
519
|
() => {
|
|
516
520
|
console.log("[IMA] Content pause requested");
|
|
517
|
-
if (!options
|
|
521
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
518
522
|
video.pause();
|
|
519
523
|
console.log("[IMA] Video paused (VOD mode)");
|
|
520
524
|
} else {
|
|
@@ -540,6 +544,7 @@ function createImaController(video, options) {
|
|
|
540
544
|
adsManager.addEventListener(
|
|
541
545
|
AdEvent.CONTENT_RESUME_REQUESTED,
|
|
542
546
|
() => {
|
|
547
|
+
var _a;
|
|
543
548
|
console.log("[IMA] Content resume requested");
|
|
544
549
|
adPlaying = false;
|
|
545
550
|
video.muted = originalMutedState;
|
|
@@ -550,8 +555,8 @@ function createImaController(video, options) {
|
|
|
550
555
|
"[IMA] Ad container hidden - pointer events disabled"
|
|
551
556
|
);
|
|
552
557
|
}
|
|
553
|
-
if (!options
|
|
554
|
-
video.play()
|
|
558
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
559
|
+
(_a = video.play()) == null ? void 0 : _a.catch(() => {
|
|
555
560
|
});
|
|
556
561
|
console.log("[IMA] Video resumed (VOD mode)");
|
|
557
562
|
} else {
|
|
@@ -573,7 +578,7 @@ function createImaController(video, options) {
|
|
|
573
578
|
"[IMA] Ad container hidden after all ads completed"
|
|
574
579
|
);
|
|
575
580
|
}
|
|
576
|
-
if (!options
|
|
581
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
577
582
|
video.play().catch(() => {
|
|
578
583
|
});
|
|
579
584
|
console.log(
|
|
@@ -601,7 +606,7 @@ function createImaController(video, options) {
|
|
|
601
606
|
adContainerEl.style.display = "none";
|
|
602
607
|
console.log("[IMA] Ad container hidden after setup error");
|
|
603
608
|
}
|
|
604
|
-
if (!options
|
|
609
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
605
610
|
if (video.paused) {
|
|
606
611
|
console.log("[IMA] Resuming paused video after setup error");
|
|
607
612
|
video.play().catch(() => {
|
|
@@ -629,7 +634,7 @@ function createImaController(video, options) {
|
|
|
629
634
|
adContainerEl.style.display = "none";
|
|
630
635
|
console.log("[IMA] Ad container hidden after loader error");
|
|
631
636
|
}
|
|
632
|
-
if (!options
|
|
637
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
633
638
|
if (video.paused) {
|
|
634
639
|
console.log("[IMA] Resuming paused video after loader error");
|
|
635
640
|
video.play().catch(() => {
|
|
@@ -651,14 +656,15 @@ function createImaController(video, options) {
|
|
|
651
656
|
return adsLoadedPromise;
|
|
652
657
|
} catch (error) {
|
|
653
658
|
console.error("[IMA] Failed to request ads:", error);
|
|
654
|
-
currentReject
|
|
659
|
+
currentReject == null ? void 0 : currentReject(error);
|
|
655
660
|
adsLoadedReject = void 0;
|
|
656
661
|
adsLoadedResolve = void 0;
|
|
657
662
|
return Promise.reject(error);
|
|
658
663
|
}
|
|
659
664
|
},
|
|
660
665
|
async play() {
|
|
661
|
-
|
|
666
|
+
var _a, _b;
|
|
667
|
+
if (!((_a = window.google) == null ? void 0 : _a.ima) || !adDisplayContainer) {
|
|
662
668
|
console.warn(
|
|
663
669
|
"[IMA] Cannot play ad: IMA SDK or ad container not available"
|
|
664
670
|
);
|
|
@@ -680,14 +686,15 @@ function createImaController(video, options) {
|
|
|
680
686
|
} catch (error) {
|
|
681
687
|
console.error("[IMA] Error starting ad playback:", error);
|
|
682
688
|
adPlaying = false;
|
|
683
|
-
if (!options
|
|
684
|
-
video.play()
|
|
689
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
690
|
+
(_b = video.play()) == null ? void 0 : _b.catch(() => {
|
|
685
691
|
});
|
|
686
692
|
}
|
|
687
693
|
return Promise.reject(error);
|
|
688
694
|
}
|
|
689
695
|
},
|
|
690
696
|
async stop() {
|
|
697
|
+
var _a;
|
|
691
698
|
adPlaying = false;
|
|
692
699
|
video.muted = originalMutedState;
|
|
693
700
|
if (adContainerEl) {
|
|
@@ -696,11 +703,11 @@ function createImaController(video, options) {
|
|
|
696
703
|
console.log("[IMA] Ad container hidden after stop");
|
|
697
704
|
}
|
|
698
705
|
try {
|
|
699
|
-
adsManager
|
|
706
|
+
(_a = adsManager == null ? void 0 : adsManager.stop) == null ? void 0 : _a.call(adsManager);
|
|
700
707
|
} catch {
|
|
701
708
|
}
|
|
702
709
|
destroyAdsManager();
|
|
703
|
-
if (!options
|
|
710
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
704
711
|
video.play().catch(() => {
|
|
705
712
|
});
|
|
706
713
|
console.log("[IMA] Video resumed after stop (VOD mode)");
|
|
@@ -709,6 +716,7 @@ function createImaController(video, options) {
|
|
|
709
716
|
}
|
|
710
717
|
},
|
|
711
718
|
destroy() {
|
|
719
|
+
var _a;
|
|
712
720
|
destroyAdsManager();
|
|
713
721
|
adPlaying = false;
|
|
714
722
|
video.muted = originalMutedState;
|
|
@@ -717,10 +725,10 @@ function createImaController(video, options) {
|
|
|
717
725
|
adContainerEl.style.display = "none";
|
|
718
726
|
}
|
|
719
727
|
try {
|
|
720
|
-
adsLoader
|
|
728
|
+
(_a = adsLoader == null ? void 0 : adsLoader.destroy) == null ? void 0 : _a.call(adsLoader);
|
|
721
729
|
} catch {
|
|
722
730
|
}
|
|
723
|
-
if (adContainerEl
|
|
731
|
+
if (adContainerEl == null ? void 0 : adContainerEl.parentElement) {
|
|
724
732
|
adContainerEl.parentElement.removeChild(adContainerEl);
|
|
725
733
|
}
|
|
726
734
|
adContainerEl = void 0;
|
|
@@ -731,7 +739,8 @@ function createImaController(video, options) {
|
|
|
731
739
|
return adPlaying;
|
|
732
740
|
},
|
|
733
741
|
resize(width, height) {
|
|
734
|
-
|
|
742
|
+
var _a;
|
|
743
|
+
if (!adsManager || !((_a = window.google) == null ? void 0 : _a.ima)) {
|
|
735
744
|
console.warn(
|
|
736
745
|
"[IMA] Cannot resize: No ads manager or IMA SDK available"
|
|
737
746
|
);
|
|
@@ -749,7 +758,8 @@ function createImaController(video, options) {
|
|
|
749
758
|
listeners.get(event).add(listener);
|
|
750
759
|
},
|
|
751
760
|
off(event, listener) {
|
|
752
|
-
|
|
761
|
+
var _a;
|
|
762
|
+
(_a = listeners.get(event)) == null ? void 0 : _a.delete(listener);
|
|
753
763
|
},
|
|
754
764
|
updateOriginalMutedState(muted) {
|
|
755
765
|
originalMutedState = muted;
|
|
@@ -786,7 +796,8 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
786
796
|
let adPlaying = false;
|
|
787
797
|
let originalMutedState = false;
|
|
788
798
|
const listeners = /* @__PURE__ */ new Map();
|
|
789
|
-
const licenseKey = options
|
|
799
|
+
const licenseKey = options == null ? void 0 : options.licenseKey;
|
|
800
|
+
const mainHlsInstance = options == null ? void 0 : options.mainHlsInstance;
|
|
790
801
|
let adVideoElement;
|
|
791
802
|
let adHls;
|
|
792
803
|
let adContainerEl;
|
|
@@ -833,7 +844,74 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
833
844
|
}
|
|
834
845
|
});
|
|
835
846
|
}
|
|
847
|
+
function getMainStreamQuality() {
|
|
848
|
+
if (!mainHlsInstance || !mainHlsInstance.levels) {
|
|
849
|
+
return null;
|
|
850
|
+
}
|
|
851
|
+
const currentLevel = mainHlsInstance.currentLevel;
|
|
852
|
+
if (currentLevel === -1 || !mainHlsInstance.levels[currentLevel]) {
|
|
853
|
+
const autoLevel = mainHlsInstance.loadLevel;
|
|
854
|
+
if (autoLevel !== -1 && mainHlsInstance.levels[autoLevel]) {
|
|
855
|
+
const level2 = mainHlsInstance.levels[autoLevel];
|
|
856
|
+
return {
|
|
857
|
+
width: level2.width || 1920,
|
|
858
|
+
height: level2.height || 1080,
|
|
859
|
+
bitrate: level2.bitrate || 5e6
|
|
860
|
+
};
|
|
861
|
+
}
|
|
862
|
+
return null;
|
|
863
|
+
}
|
|
864
|
+
const level = mainHlsInstance.levels[currentLevel];
|
|
865
|
+
return {
|
|
866
|
+
width: level.width || 1920,
|
|
867
|
+
height: level.height || 1080,
|
|
868
|
+
bitrate: level.bitrate || 5e6
|
|
869
|
+
};
|
|
870
|
+
}
|
|
871
|
+
function selectBestMediaFile(mediaFiles) {
|
|
872
|
+
if (mediaFiles.length === 0) {
|
|
873
|
+
throw new Error("No media files available");
|
|
874
|
+
}
|
|
875
|
+
const firstFile = mediaFiles[0];
|
|
876
|
+
if (!firstFile) {
|
|
877
|
+
throw new Error("No media files available");
|
|
878
|
+
}
|
|
879
|
+
if (mediaFiles.length === 1) {
|
|
880
|
+
return firstFile;
|
|
881
|
+
}
|
|
882
|
+
const mainQuality = getMainStreamQuality();
|
|
883
|
+
if (!mainQuality) {
|
|
884
|
+
console.log("[HlsAdPlayer] No main stream quality info, using first media file");
|
|
885
|
+
return firstFile;
|
|
886
|
+
}
|
|
887
|
+
console.log("[HlsAdPlayer] Main stream quality:", mainQuality);
|
|
888
|
+
const scoredFiles = mediaFiles.map((file) => {
|
|
889
|
+
const widthDiff = Math.abs(file.width - mainQuality.width);
|
|
890
|
+
const heightDiff = Math.abs(file.height - mainQuality.height);
|
|
891
|
+
const resolutionDiff = widthDiff + heightDiff;
|
|
892
|
+
const fileBitrate = (file.bitrate || 5e3) * 1e3;
|
|
893
|
+
const bitrateDiff = Math.abs(fileBitrate - mainQuality.bitrate);
|
|
894
|
+
const score = resolutionDiff * 2 + bitrateDiff / 1e3;
|
|
895
|
+
return { file, score, resolutionDiff, bitrateDiff };
|
|
896
|
+
});
|
|
897
|
+
scoredFiles.sort((a, b) => a.score - b.score);
|
|
898
|
+
const bestMatch = scoredFiles[0];
|
|
899
|
+
if (!bestMatch) {
|
|
900
|
+
console.log("[HlsAdPlayer] No best match found, using first media file");
|
|
901
|
+
return firstFile;
|
|
902
|
+
}
|
|
903
|
+
console.log("[HlsAdPlayer] Selected media file:", {
|
|
904
|
+
url: bestMatch.file.url,
|
|
905
|
+
resolution: `${bestMatch.file.width}x${bestMatch.file.height}`,
|
|
906
|
+
bitrate: bestMatch.file.bitrate,
|
|
907
|
+
score: bestMatch.score,
|
|
908
|
+
resolutionDiff: bestMatch.resolutionDiff,
|
|
909
|
+
bitrateDiff: bestMatch.bitrateDiff
|
|
910
|
+
});
|
|
911
|
+
return bestMatch.file;
|
|
912
|
+
}
|
|
836
913
|
function parseVastXml(xmlString) {
|
|
914
|
+
var _a, _b, _c, _d;
|
|
837
915
|
try {
|
|
838
916
|
const parser = new DOMParser();
|
|
839
917
|
const xmlDoc = parser.parseFromString(xmlString, "text/xml");
|
|
@@ -848,19 +926,20 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
848
926
|
return null;
|
|
849
927
|
}
|
|
850
928
|
const adId = adElement.getAttribute("id") || "unknown";
|
|
851
|
-
const title = xmlDoc.querySelector("AdTitle")
|
|
852
|
-
const durationText = xmlDoc.querySelector("Duration")
|
|
929
|
+
const title = ((_a = xmlDoc.querySelector("AdTitle")) == null ? void 0 : _a.textContent) || "Ad";
|
|
930
|
+
const durationText = ((_b = xmlDoc.querySelector("Duration")) == null ? void 0 : _b.textContent) || "00:00:30";
|
|
853
931
|
const durationParts = durationText.split(":");
|
|
854
932
|
const duration = parseInt(durationParts[0] || "0", 10) * 3600 + parseInt(durationParts[1] || "0", 10) * 60 + parseInt(durationParts[2] || "0", 10);
|
|
855
933
|
const mediaFileElements = xmlDoc.querySelectorAll("MediaFile");
|
|
856
934
|
const mediaFiles = [];
|
|
857
935
|
mediaFileElements.forEach((mf) => {
|
|
936
|
+
var _a2;
|
|
858
937
|
const type = mf.getAttribute("type") || "";
|
|
859
938
|
if (type === "application/x-mpegURL" || type.includes("m3u8")) {
|
|
860
939
|
const bitrateAttr = mf.getAttribute("bitrate");
|
|
861
940
|
const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;
|
|
862
941
|
mediaFiles.push({
|
|
863
|
-
url: mf.textContent
|
|
942
|
+
url: ((_a2 = mf.textContent) == null ? void 0 : _a2.trim()) || "",
|
|
864
943
|
type,
|
|
865
944
|
width: parseInt(mf.getAttribute("width") || "1920", 10),
|
|
866
945
|
height: parseInt(mf.getAttribute("height") || "1080", 10),
|
|
@@ -889,12 +968,14 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
889
968
|
error: []
|
|
890
969
|
};
|
|
891
970
|
xmlDoc.querySelectorAll("Impression").forEach((el) => {
|
|
892
|
-
|
|
971
|
+
var _a2;
|
|
972
|
+
const url = (_a2 = el.textContent) == null ? void 0 : _a2.trim();
|
|
893
973
|
if (url) trackingUrls.impression.push(url);
|
|
894
974
|
});
|
|
895
975
|
xmlDoc.querySelectorAll("Tracking").forEach((el) => {
|
|
976
|
+
var _a2;
|
|
896
977
|
const event = el.getAttribute("event");
|
|
897
|
-
const url = el.textContent
|
|
978
|
+
const url = (_a2 = el.textContent) == null ? void 0 : _a2.trim();
|
|
898
979
|
if (event && url) {
|
|
899
980
|
const eventKey = event;
|
|
900
981
|
if (trackingUrls[eventKey]) {
|
|
@@ -902,7 +983,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
902
983
|
}
|
|
903
984
|
}
|
|
904
985
|
});
|
|
905
|
-
const clickThrough = xmlDoc.querySelector("ClickThrough")
|
|
986
|
+
const clickThrough = (_d = (_c = xmlDoc.querySelector("ClickThrough")) == null ? void 0 : _c.textContent) == null ? void 0 : _d.trim();
|
|
906
987
|
return {
|
|
907
988
|
id: adId,
|
|
908
989
|
title,
|
|
@@ -994,7 +1075,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
994
1075
|
adContainerEl.style.display = "none";
|
|
995
1076
|
adContainerEl.style.pointerEvents = "none";
|
|
996
1077
|
}
|
|
997
|
-
if (!options
|
|
1078
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
998
1079
|
contentVideo.play().catch(() => {
|
|
999
1080
|
});
|
|
1000
1081
|
console.log("[HlsAdPlayer] Content resumed (VOD mode)");
|
|
@@ -1012,7 +1093,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1012
1093
|
adContainerEl.style.display = "none";
|
|
1013
1094
|
adContainerEl.style.pointerEvents = "none";
|
|
1014
1095
|
}
|
|
1015
|
-
if (!options
|
|
1096
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
1016
1097
|
if (contentVideo.paused) {
|
|
1017
1098
|
contentVideo.play().catch(() => {
|
|
1018
1099
|
});
|
|
@@ -1022,6 +1103,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1022
1103
|
}
|
|
1023
1104
|
return {
|
|
1024
1105
|
initialize() {
|
|
1106
|
+
var _a;
|
|
1025
1107
|
console.log("[HlsAdPlayer] Initializing");
|
|
1026
1108
|
if (!adContainerEl) {
|
|
1027
1109
|
const container = document.createElement("div");
|
|
@@ -1036,7 +1118,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1036
1118
|
container.style.pointerEvents = "none";
|
|
1037
1119
|
container.style.zIndex = "2";
|
|
1038
1120
|
container.style.backgroundColor = "#000";
|
|
1039
|
-
contentVideo.parentElement
|
|
1121
|
+
(_a = contentVideo.parentElement) == null ? void 0 : _a.appendChild(container);
|
|
1040
1122
|
adContainerEl = container;
|
|
1041
1123
|
}
|
|
1042
1124
|
},
|
|
@@ -1078,7 +1160,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1078
1160
|
try {
|
|
1079
1161
|
if (!adVideoElement) {
|
|
1080
1162
|
adVideoElement = createAdVideoElement();
|
|
1081
|
-
adContainerEl
|
|
1163
|
+
adContainerEl == null ? void 0 : adContainerEl.appendChild(adVideoElement);
|
|
1082
1164
|
setupAdEventListeners();
|
|
1083
1165
|
}
|
|
1084
1166
|
trackingFired = {
|
|
@@ -1089,7 +1171,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1089
1171
|
thirdQuartile: false,
|
|
1090
1172
|
complete: false
|
|
1091
1173
|
};
|
|
1092
|
-
if (!options
|
|
1174
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
1093
1175
|
contentVideo.pause();
|
|
1094
1176
|
console.log("[HlsAdPlayer] Content paused (VOD mode)");
|
|
1095
1177
|
} else {
|
|
@@ -1102,7 +1184,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1102
1184
|
adContainerEl.style.pointerEvents = "auto";
|
|
1103
1185
|
}
|
|
1104
1186
|
emit("content_pause");
|
|
1105
|
-
const mediaFile = currentAd.mediaFiles
|
|
1187
|
+
const mediaFile = selectBestMediaFile(currentAd.mediaFiles);
|
|
1106
1188
|
if (!mediaFile) {
|
|
1107
1189
|
throw new Error("No media file available for ad");
|
|
1108
1190
|
}
|
|
@@ -1162,7 +1244,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1162
1244
|
adVideoElement.pause();
|
|
1163
1245
|
adVideoElement.src = "";
|
|
1164
1246
|
}
|
|
1165
|
-
if (!options
|
|
1247
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
1166
1248
|
contentVideo.play().catch(() => {
|
|
1167
1249
|
});
|
|
1168
1250
|
}
|
|
@@ -1182,7 +1264,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1182
1264
|
adVideoElement.remove();
|
|
1183
1265
|
adVideoElement = void 0;
|
|
1184
1266
|
}
|
|
1185
|
-
if (adContainerEl
|
|
1267
|
+
if (adContainerEl == null ? void 0 : adContainerEl.parentElement) {
|
|
1186
1268
|
adContainerEl.parentElement.removeChild(adContainerEl);
|
|
1187
1269
|
}
|
|
1188
1270
|
adContainerEl = void 0;
|
|
@@ -1208,7 +1290,8 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1208
1290
|
listeners.get(event).add(listener);
|
|
1209
1291
|
},
|
|
1210
1292
|
off(event, listener) {
|
|
1211
|
-
|
|
1293
|
+
var _a;
|
|
1294
|
+
(_a = listeners.get(event)) == null ? void 0 : _a.delete(listener);
|
|
1212
1295
|
},
|
|
1213
1296
|
updateOriginalMutedState(muted) {
|
|
1214
1297
|
originalMutedState = muted;
|
|
@@ -1233,6 +1316,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1233
1316
|
// src/utils/tracking.ts
|
|
1234
1317
|
var cachedBrowserId = null;
|
|
1235
1318
|
function getClientInfo() {
|
|
1319
|
+
var _a, _b, _c, _d;
|
|
1236
1320
|
const ua = navigator.userAgent;
|
|
1237
1321
|
const platform = navigator.platform;
|
|
1238
1322
|
const vendor = navigator.vendor || "";
|
|
@@ -1240,12 +1324,12 @@ function getClientInfo() {
|
|
|
1240
1324
|
const memory = navigator.deviceMemory || null;
|
|
1241
1325
|
const hardwareConcurrency = navigator.hardwareConcurrency || 1;
|
|
1242
1326
|
const screenInfo = {
|
|
1243
|
-
width: screen
|
|
1244
|
-
height: screen
|
|
1245
|
-
availWidth: screen
|
|
1246
|
-
availHeight: screen
|
|
1247
|
-
orientation: screen
|
|
1248
|
-
pixelDepth: screen
|
|
1327
|
+
width: screen == null ? void 0 : screen.width,
|
|
1328
|
+
height: screen == null ? void 0 : screen.height,
|
|
1329
|
+
availWidth: screen == null ? void 0 : screen.availWidth,
|
|
1330
|
+
availHeight: screen == null ? void 0 : screen.availHeight,
|
|
1331
|
+
orientation: ((_a = screen == null ? void 0 : screen.orientation) == null ? void 0 : _a.type) || "",
|
|
1332
|
+
pixelDepth: screen == null ? void 0 : screen.pixelDepth
|
|
1249
1333
|
};
|
|
1250
1334
|
let deviceType = "desktop";
|
|
1251
1335
|
let brand = "Unknown";
|
|
@@ -1342,10 +1426,10 @@ function getClientInfo() {
|
|
|
1342
1426
|
if (vendor.includes("Samsung") || ua.includes("SM-")) brand = "Samsung";
|
|
1343
1427
|
}
|
|
1344
1428
|
isWebView = /wv|WebView|Linux; U;/.test(ua);
|
|
1345
|
-
if (window
|
|
1429
|
+
if ((window == null ? void 0 : window.outerHeight) === 0 && (window == null ? void 0 : window.outerWidth) === 0) {
|
|
1346
1430
|
isWebView = true;
|
|
1347
1431
|
}
|
|
1348
|
-
isWebApp = window.matchMedia("(display-mode: standalone)").matches || window.navigator.standalone === true || window.screen
|
|
1432
|
+
isWebApp = window.matchMedia("(display-mode: standalone)").matches || window.navigator.standalone === true || ((_c = (_b = window.screen) == null ? void 0 : _b.orientation) == null ? void 0 : _c.angle) !== void 0;
|
|
1349
1433
|
return {
|
|
1350
1434
|
brand,
|
|
1351
1435
|
os,
|
|
@@ -1366,7 +1450,7 @@ function getClientInfo() {
|
|
|
1366
1450
|
deviceMemory: memory,
|
|
1367
1451
|
maxTouchPoints,
|
|
1368
1452
|
language: navigator.language,
|
|
1369
|
-
languages: navigator.languages
|
|
1453
|
+
languages: ((_d = navigator.languages) == null ? void 0 : _d.join(",")) || "",
|
|
1370
1454
|
cookieEnabled: navigator.cookieEnabled,
|
|
1371
1455
|
doNotTrack: navigator.doNotTrack || "",
|
|
1372
1456
|
referrer: document.referrer,
|
|
@@ -1724,7 +1808,8 @@ var StormcloudVideoPlayer = class {
|
|
|
1724
1808
|
}
|
|
1725
1809
|
return createHlsAdPlayer(this.video, {
|
|
1726
1810
|
continueLiveStreamDuringAds,
|
|
1727
|
-
...this.config.licenseKey ? { licenseKey: this.config.licenseKey } : {}
|
|
1811
|
+
...this.config.licenseKey ? { licenseKey: this.config.licenseKey } : {},
|
|
1812
|
+
...this.hls ? { mainHlsInstance: this.hls } : {}
|
|
1728
1813
|
});
|
|
1729
1814
|
} else {
|
|
1730
1815
|
if (this.config.debugAdTiming) {
|
|
@@ -1736,6 +1821,7 @@ var StormcloudVideoPlayer = class {
|
|
|
1736
1821
|
}
|
|
1737
1822
|
}
|
|
1738
1823
|
async load() {
|
|
1824
|
+
var _a, _b;
|
|
1739
1825
|
if (!this.attached) {
|
|
1740
1826
|
this.attach();
|
|
1741
1827
|
}
|
|
@@ -1752,7 +1838,7 @@ var StormcloudVideoPlayer = class {
|
|
|
1752
1838
|
this.initializeTracking();
|
|
1753
1839
|
if (this.shouldUseNativeHls()) {
|
|
1754
1840
|
this.video.src = this.config.src;
|
|
1755
|
-
this.isLiveStream = this.config.lowLatencyMode
|
|
1841
|
+
this.isLiveStream = (_a = this.config.lowLatencyMode) != null ? _a : false;
|
|
1756
1842
|
if (this.config.debugAdTiming) {
|
|
1757
1843
|
console.log(
|
|
1758
1844
|
"[StormcloudVideoPlayer] allowNativeHls: true - VOD mode detected:",
|
|
@@ -1767,8 +1853,8 @@ var StormcloudVideoPlayer = class {
|
|
|
1767
1853
|
this.ima = this.createAdPlayer(false);
|
|
1768
1854
|
this.ima.initialize();
|
|
1769
1855
|
if (this.config.autoplay) {
|
|
1770
|
-
await this.video.play()
|
|
1771
|
-
});
|
|
1856
|
+
await ((_b = this.video.play()) == null ? void 0 : _b.catch(() => {
|
|
1857
|
+
}));
|
|
1772
1858
|
}
|
|
1773
1859
|
return;
|
|
1774
1860
|
}
|
|
@@ -1781,12 +1867,17 @@ var StormcloudVideoPlayer = class {
|
|
|
1781
1867
|
...this.config.lowLatencyMode ? { liveSyncDuration: 2 } : {}
|
|
1782
1868
|
});
|
|
1783
1869
|
this.hls.on(import_hls2.default.Events.MEDIA_ATTACHED, () => {
|
|
1784
|
-
|
|
1870
|
+
var _a2;
|
|
1871
|
+
(_a2 = this.hls) == null ? void 0 : _a2.loadSource(this.config.src);
|
|
1785
1872
|
});
|
|
1786
1873
|
this.hls.on(import_hls2.default.Events.MANIFEST_PARSED, async (_, data) => {
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1874
|
+
var _a2, _b2, _c, _d;
|
|
1875
|
+
this.isLiveStream = (_c = (_b2 = (_a2 = this.hls) == null ? void 0 : _a2.levels) == null ? void 0 : _b2.some(
|
|
1876
|
+
(level) => {
|
|
1877
|
+
var _a3, _b3;
|
|
1878
|
+
return ((_a3 = level == null ? void 0 : level.details) == null ? void 0 : _a3.live) === true || ((_b3 = level == null ? void 0 : level.details) == null ? void 0 : _b3.type) === "LIVE";
|
|
1879
|
+
}
|
|
1880
|
+
)) != null ? _c : false;
|
|
1790
1881
|
if (this.config.debugAdTiming) {
|
|
1791
1882
|
const adBehavior = this.shouldContinueLiveStreamDuringAds() ? "live (main video continues muted during ads)" : "vod (main video pauses during ads)";
|
|
1792
1883
|
console.log("[StormcloudVideoPlayer] Stream type detected:", {
|
|
@@ -1799,28 +1890,29 @@ var StormcloudVideoPlayer = class {
|
|
|
1799
1890
|
this.ima = this.createAdPlayer(this.shouldContinueLiveStreamDuringAds());
|
|
1800
1891
|
this.ima.initialize();
|
|
1801
1892
|
if (this.config.autoplay) {
|
|
1802
|
-
await this.video.play()
|
|
1803
|
-
});
|
|
1893
|
+
await ((_d = this.video.play()) == null ? void 0 : _d.catch(() => {
|
|
1894
|
+
}));
|
|
1804
1895
|
}
|
|
1805
1896
|
});
|
|
1806
1897
|
this.hls.on(import_hls2.default.Events.FRAG_PARSING_METADATA, (_evt, data) => {
|
|
1807
|
-
const id3Tags = (data
|
|
1898
|
+
const id3Tags = ((data == null ? void 0 : data.samples) || []).map((s) => ({
|
|
1808
1899
|
key: "ID3",
|
|
1809
|
-
value: s
|
|
1810
|
-
ptsSeconds: s
|
|
1900
|
+
value: s == null ? void 0 : s.data,
|
|
1901
|
+
ptsSeconds: s == null ? void 0 : s.pts
|
|
1811
1902
|
}));
|
|
1812
1903
|
id3Tags.forEach((tag) => this.onId3Tag(tag));
|
|
1813
1904
|
});
|
|
1814
1905
|
this.hls.on(import_hls2.default.Events.FRAG_CHANGED, (_evt, data) => {
|
|
1815
|
-
|
|
1816
|
-
const
|
|
1906
|
+
var _a2, _b2, _c;
|
|
1907
|
+
const frag = data == null ? void 0 : data.frag;
|
|
1908
|
+
const tagList = frag == null ? void 0 : frag.tagList;
|
|
1817
1909
|
if (!Array.isArray(tagList)) return;
|
|
1818
1910
|
for (const entry of tagList) {
|
|
1819
1911
|
let tag = "";
|
|
1820
1912
|
let value = "";
|
|
1821
1913
|
if (Array.isArray(entry)) {
|
|
1822
|
-
tag = String(entry[0]
|
|
1823
|
-
value = String(entry[1]
|
|
1914
|
+
tag = String((_a2 = entry[0]) != null ? _a2 : "");
|
|
1915
|
+
value = String((_b2 = entry[1]) != null ? _b2 : "");
|
|
1824
1916
|
} else if (typeof entry === "string") {
|
|
1825
1917
|
const idx = entry.indexOf(":");
|
|
1826
1918
|
if (idx >= 0) {
|
|
@@ -1844,8 +1936,8 @@ var StormcloudVideoPlayer = class {
|
|
|
1844
1936
|
const prog = this.parseCueOutCont(value);
|
|
1845
1937
|
const marker = {
|
|
1846
1938
|
type: "progress",
|
|
1847
|
-
...prog
|
|
1848
|
-
...prog
|
|
1939
|
+
...(prog == null ? void 0 : prog.duration) !== void 0 ? { durationSeconds: prog.duration } : {},
|
|
1940
|
+
...(prog == null ? void 0 : prog.elapsed) !== void 0 ? { ptsSeconds: prog.elapsed } : {},
|
|
1849
1941
|
raw: { tag, value }
|
|
1850
1942
|
};
|
|
1851
1943
|
this.onScte35Marker(marker);
|
|
@@ -1855,7 +1947,7 @@ var StormcloudVideoPlayer = class {
|
|
|
1855
1947
|
const attrs = this.parseAttributeList(value);
|
|
1856
1948
|
const hasScteOut = "SCTE35-OUT" in attrs || attrs["SCTE35-OUT"] !== void 0;
|
|
1857
1949
|
const hasScteIn = "SCTE35-IN" in attrs || attrs["SCTE35-IN"] !== void 0;
|
|
1858
|
-
const klass = String(attrs["CLASS"]
|
|
1950
|
+
const klass = String((_c = attrs["CLASS"]) != null ? _c : "");
|
|
1859
1951
|
const duration = this.toNumber(attrs["DURATION"]);
|
|
1860
1952
|
if (hasScteOut || /com\.apple\.hls\.cue/i.test(klass)) {
|
|
1861
1953
|
const marker = {
|
|
@@ -1872,13 +1964,14 @@ var StormcloudVideoPlayer = class {
|
|
|
1872
1964
|
}
|
|
1873
1965
|
});
|
|
1874
1966
|
this.hls.on(import_hls2.default.Events.ERROR, (_evt, data) => {
|
|
1875
|
-
|
|
1967
|
+
var _a2, _b2;
|
|
1968
|
+
if (data == null ? void 0 : data.fatal) {
|
|
1876
1969
|
switch (data.type) {
|
|
1877
1970
|
case import_hls2.default.ErrorTypes.NETWORK_ERROR:
|
|
1878
|
-
this.hls
|
|
1971
|
+
(_a2 = this.hls) == null ? void 0 : _a2.startLoad();
|
|
1879
1972
|
break;
|
|
1880
1973
|
case import_hls2.default.ErrorTypes.MEDIA_ERROR:
|
|
1881
|
-
this.hls
|
|
1974
|
+
(_b2 = this.hls) == null ? void 0 : _b2.recoverMediaError();
|
|
1882
1975
|
break;
|
|
1883
1976
|
default:
|
|
1884
1977
|
this.destroy();
|
|
@@ -1980,11 +2073,12 @@ var StormcloudVideoPlayer = class {
|
|
|
1980
2073
|
}
|
|
1981
2074
|
}
|
|
1982
2075
|
parseScte35FromId3(tag) {
|
|
2076
|
+
var _a, _b, _c, _d;
|
|
1983
2077
|
const text = this.decodeId3ValueToText(tag.value);
|
|
1984
2078
|
if (!text) return void 0;
|
|
1985
2079
|
const cueOutMatch = text.match(/EXT-X-CUE-OUT(?::([^\r\n]*))?/i) || text.match(/CUE-OUT(?::([^\r\n]*))?/i);
|
|
1986
2080
|
if (cueOutMatch) {
|
|
1987
|
-
const arg = (cueOutMatch[1]
|
|
2081
|
+
const arg = ((_a = cueOutMatch[1]) != null ? _a : "").trim();
|
|
1988
2082
|
const dur = this.parseCueOutDuration(arg);
|
|
1989
2083
|
const marker = {
|
|
1990
2084
|
type: "start",
|
|
@@ -1996,12 +2090,12 @@ var StormcloudVideoPlayer = class {
|
|
|
1996
2090
|
}
|
|
1997
2091
|
const cueOutContMatch = text.match(/EXT-X-CUE-OUT-CONT:([^\r\n]*)/i);
|
|
1998
2092
|
if (cueOutContMatch) {
|
|
1999
|
-
const arg = (cueOutContMatch[1]
|
|
2093
|
+
const arg = ((_b = cueOutContMatch[1]) != null ? _b : "").trim();
|
|
2000
2094
|
const cont = this.parseCueOutCont(arg);
|
|
2001
2095
|
const marker = {
|
|
2002
2096
|
type: "progress",
|
|
2003
2097
|
...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},
|
|
2004
|
-
...cont
|
|
2098
|
+
...(cont == null ? void 0 : cont.duration) !== void 0 ? { durationSeconds: cont.duration } : {},
|
|
2005
2099
|
raw: { id3: text }
|
|
2006
2100
|
};
|
|
2007
2101
|
return marker;
|
|
@@ -2017,10 +2111,10 @@ var StormcloudVideoPlayer = class {
|
|
|
2017
2111
|
}
|
|
2018
2112
|
const daterangeMatch = text.match(/EXT-X-DATERANGE:([^\r\n]*)/i);
|
|
2019
2113
|
if (daterangeMatch) {
|
|
2020
|
-
const attrs = this.parseAttributeList(daterangeMatch[1]
|
|
2114
|
+
const attrs = this.parseAttributeList((_c = daterangeMatch[1]) != null ? _c : "");
|
|
2021
2115
|
const hasScteOut = "SCTE35-OUT" in attrs || attrs["SCTE35-OUT"] !== void 0;
|
|
2022
2116
|
const hasScteIn = "SCTE35-IN" in attrs || attrs["SCTE35-IN"] !== void 0;
|
|
2023
|
-
const klass = String(attrs["CLASS"]
|
|
2117
|
+
const klass = String((_d = attrs["CLASS"]) != null ? _d : "");
|
|
2024
2118
|
const duration = this.toNumber(attrs["DURATION"]);
|
|
2025
2119
|
if (hasScteOut || /com\.apple\.hls\.cue/i.test(klass)) {
|
|
2026
2120
|
const marker = {
|
|
@@ -2077,6 +2171,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2077
2171
|
}
|
|
2078
2172
|
}
|
|
2079
2173
|
onScte35Marker(marker) {
|
|
2174
|
+
var _a, _b;
|
|
2080
2175
|
if (this.config.debugAdTiming) {
|
|
2081
2176
|
console.log("[StormcloudVideoPlayer] SCTE-35 marker detected:", {
|
|
2082
2177
|
type: marker.type,
|
|
@@ -2092,7 +2187,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2092
2187
|
this.expectedAdBreakDurationMs = durationMs;
|
|
2093
2188
|
this.currentAdBreakStartWallClockMs = Date.now();
|
|
2094
2189
|
const isManifestMarker = this.isManifestBasedMarker(marker);
|
|
2095
|
-
const forceImmediate = this.config.immediateManifestAds
|
|
2190
|
+
const forceImmediate = (_a = this.config.immediateManifestAds) != null ? _a : true;
|
|
2096
2191
|
if (this.config.debugAdTiming) {
|
|
2097
2192
|
console.log("[StormcloudVideoPlayer] Ad start decision:", {
|
|
2098
2193
|
isManifestMarker,
|
|
@@ -2109,7 +2204,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2109
2204
|
this.clearAdStartTimer();
|
|
2110
2205
|
this.handleAdStart(marker);
|
|
2111
2206
|
} else if (typeof marker.ptsSeconds === "number") {
|
|
2112
|
-
const tol = this.config.driftToleranceMs
|
|
2207
|
+
const tol = (_b = this.config.driftToleranceMs) != null ? _b : 1e3;
|
|
2113
2208
|
const nowMs = this.video.currentTime * 1e3;
|
|
2114
2209
|
const estCurrentPtsMs = nowMs - this.ptsDriftEmaMs;
|
|
2115
2210
|
const deltaMs = Math.floor(marker.ptsSeconds * 1e3 - estCurrentPtsMs);
|
|
@@ -2219,12 +2314,13 @@ var StormcloudVideoPlayer = class {
|
|
|
2219
2314
|
return void 0;
|
|
2220
2315
|
}
|
|
2221
2316
|
parseAttributeList(value) {
|
|
2317
|
+
var _a, _b, _c;
|
|
2222
2318
|
const attrs = {};
|
|
2223
2319
|
const regex = /([A-Z0-9-]+)=(("[^"]*")|([^",]*))(?:,|$)/gi;
|
|
2224
2320
|
let match;
|
|
2225
2321
|
while ((match = regex.exec(value)) !== null) {
|
|
2226
|
-
const key = match[1]
|
|
2227
|
-
let rawVal = match[3]
|
|
2322
|
+
const key = (_a = match[1]) != null ? _a : "";
|
|
2323
|
+
let rawVal = (_c = (_b = match[3]) != null ? _b : match[4]) != null ? _c : "";
|
|
2228
2324
|
if (rawVal.startsWith('"') && rawVal.endsWith('"')) {
|
|
2229
2325
|
rawVal = rawVal.slice(1, -1);
|
|
2230
2326
|
}
|
|
@@ -2388,6 +2484,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2388
2484
|
}
|
|
2389
2485
|
}
|
|
2390
2486
|
async fetchAdConfiguration() {
|
|
2487
|
+
var _a, _b, _c;
|
|
2391
2488
|
const vastMode = this.config.vastMode || "default";
|
|
2392
2489
|
if (this.config.debugAdTiming) {
|
|
2393
2490
|
console.log(
|
|
@@ -2445,7 +2542,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2445
2542
|
return;
|
|
2446
2543
|
}
|
|
2447
2544
|
const data = await response.json();
|
|
2448
|
-
const imaPayload = data.response
|
|
2545
|
+
const imaPayload = (_c = (_b = (_a = data.response) == null ? void 0 : _a.ima) == null ? void 0 : _b["publisherdesk.ima"]) == null ? void 0 : _c.payload;
|
|
2449
2546
|
if (imaPayload) {
|
|
2450
2547
|
this.apiVastTagUrl = decodeURIComponent(imaPayload);
|
|
2451
2548
|
if (this.config.debugAdTiming) {
|
|
@@ -2482,11 +2579,12 @@ var StormcloudVideoPlayer = class {
|
|
|
2482
2579
|
return "other";
|
|
2483
2580
|
}
|
|
2484
2581
|
shouldShowNativeControls() {
|
|
2582
|
+
var _a, _b;
|
|
2485
2583
|
const streamType = this.getStreamType();
|
|
2486
2584
|
if (streamType === "other") {
|
|
2487
|
-
return !(this.config.showCustomControls
|
|
2585
|
+
return !((_a = this.config.showCustomControls) != null ? _a : false);
|
|
2488
2586
|
}
|
|
2489
|
-
return !!(this.config.allowNativeHls && !(this.config.showCustomControls
|
|
2587
|
+
return !!(this.config.allowNativeHls && !((_b = this.config.showCustomControls) != null ? _b : false));
|
|
2490
2588
|
}
|
|
2491
2589
|
shouldContinueLiveStreamDuringAds() {
|
|
2492
2590
|
if (this.config.allowNativeHls) {
|
|
@@ -2498,6 +2596,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2498
2596
|
return true;
|
|
2499
2597
|
}
|
|
2500
2598
|
async handleAdStart(_marker) {
|
|
2599
|
+
var _a;
|
|
2501
2600
|
const scheduled = this.findCurrentOrNextBreak(
|
|
2502
2601
|
this.video.currentTime * 1e3
|
|
2503
2602
|
);
|
|
@@ -2548,17 +2647,18 @@ var StormcloudVideoPlayer = class {
|
|
|
2548
2647
|
this.handleAdFailure();
|
|
2549
2648
|
}
|
|
2550
2649
|
}
|
|
2551
|
-
if (this.expectedAdBreakDurationMs == null && scheduled
|
|
2650
|
+
if (this.expectedAdBreakDurationMs == null && (scheduled == null ? void 0 : scheduled.durationMs) != null) {
|
|
2552
2651
|
this.expectedAdBreakDurationMs = scheduled.durationMs;
|
|
2553
|
-
this.currentAdBreakStartWallClockMs = this.currentAdBreakStartWallClockMs
|
|
2652
|
+
this.currentAdBreakStartWallClockMs = (_a = this.currentAdBreakStartWallClockMs) != null ? _a : Date.now();
|
|
2554
2653
|
this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);
|
|
2555
2654
|
}
|
|
2556
2655
|
}
|
|
2557
2656
|
findCurrentOrNextBreak(nowMs) {
|
|
2657
|
+
var _a;
|
|
2558
2658
|
const schedule = [];
|
|
2559
2659
|
let candidate;
|
|
2560
2660
|
for (const b of schedule) {
|
|
2561
|
-
const tol = this.config.driftToleranceMs
|
|
2661
|
+
const tol = (_a = this.config.driftToleranceMs) != null ? _a : 1e3;
|
|
2562
2662
|
if (b.startTimeMs <= nowMs + tol && (candidate == null || b.startTimeMs > (candidate.startTimeMs || 0))) {
|
|
2563
2663
|
candidate = b;
|
|
2564
2664
|
}
|
|
@@ -2574,7 +2674,8 @@ var StormcloudVideoPlayer = class {
|
|
|
2574
2674
|
}
|
|
2575
2675
|
}
|
|
2576
2676
|
async handleMidAdJoin(adBreak, nowMs) {
|
|
2577
|
-
|
|
2677
|
+
var _a;
|
|
2678
|
+
const durationMs = (_a = adBreak.durationMs) != null ? _a : 0;
|
|
2578
2679
|
const endMs = adBreak.startTimeMs + durationMs;
|
|
2579
2680
|
if (durationMs > 0 && nowMs > adBreak.startTimeMs && nowMs < endMs) {
|
|
2580
2681
|
const remainingMs = endMs - nowMs;
|
|
@@ -2675,6 +2776,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2675
2776
|
}
|
|
2676
2777
|
}
|
|
2677
2778
|
handleAdFailure() {
|
|
2779
|
+
var _a;
|
|
2678
2780
|
if (this.config.debugAdTiming) {
|
|
2679
2781
|
console.log(
|
|
2680
2782
|
"[StormcloudVideoPlayer] Handling ad failure - resuming content",
|
|
@@ -2707,7 +2809,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2707
2809
|
if (this.config.debugAdTiming) {
|
|
2708
2810
|
console.log("[StormcloudVideoPlayer] Resuming paused video");
|
|
2709
2811
|
}
|
|
2710
|
-
this.video.play()
|
|
2812
|
+
(_a = this.video.play()) == null ? void 0 : _a.catch((error) => {
|
|
2711
2813
|
if (this.config.debugAdTiming) {
|
|
2712
2814
|
console.error(
|
|
2713
2815
|
"[StormcloudVideoPlayer] Failed to resume video after ad failure:",
|
|
@@ -2722,8 +2824,9 @@ var StormcloudVideoPlayer = class {
|
|
|
2722
2824
|
}
|
|
2723
2825
|
}
|
|
2724
2826
|
startAdFailsafeTimer() {
|
|
2827
|
+
var _a;
|
|
2725
2828
|
this.clearAdFailsafeTimer();
|
|
2726
|
-
const failsafeMs = this.config.adFailsafeTimeoutMs
|
|
2829
|
+
const failsafeMs = (_a = this.config.adFailsafeTimeoutMs) != null ? _a : 1e4;
|
|
2727
2830
|
if (this.config.debugAdTiming) {
|
|
2728
2831
|
console.log(
|
|
2729
2832
|
`[StormcloudVideoPlayer] Starting failsafe timer (${failsafeMs}ms)`
|
|
@@ -2859,6 +2962,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2859
2962
|
}
|
|
2860
2963
|
}
|
|
2861
2964
|
destroy() {
|
|
2965
|
+
var _a, _b;
|
|
2862
2966
|
this.clearAdStartTimer();
|
|
2863
2967
|
this.clearAdStopTimer();
|
|
2864
2968
|
this.clearAdFailsafeTimer();
|
|
@@ -2866,8 +2970,8 @@ var StormcloudVideoPlayer = class {
|
|
|
2866
2970
|
clearInterval(this.heartbeatInterval);
|
|
2867
2971
|
this.heartbeatInterval = void 0;
|
|
2868
2972
|
}
|
|
2869
|
-
this.hls
|
|
2870
|
-
this.ima
|
|
2973
|
+
(_a = this.hls) == null ? void 0 : _a.destroy();
|
|
2974
|
+
(_b = this.ima) == null ? void 0 : _b.destroy();
|
|
2871
2975
|
}
|
|
2872
2976
|
};
|
|
2873
2977
|
|
|
@@ -2974,7 +3078,7 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(
|
|
|
2974
3078
|
}
|
|
2975
3079
|
setShowSpeedMenu(false);
|
|
2976
3080
|
};
|
|
2977
|
-
const isHlsStream = src
|
|
3081
|
+
const isHlsStream = (src == null ? void 0 : src.toLowerCase().includes(".m3u8")) || (src == null ? void 0 : src.toLowerCase().includes("/hls/"));
|
|
2978
3082
|
const shouldShowEnhancedControls = showCustomControls && (isHlsStream ? allowNativeHls : true);
|
|
2979
3083
|
const criticalPropsKey = (0, import_react.useMemo)(() => {
|
|
2980
3084
|
return CRITICAL_PROPS.map((prop) => `${prop}:${props[prop]}`).join("|");
|
|
@@ -3024,13 +3128,13 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(
|
|
|
3024
3128
|
player.load().then(() => {
|
|
3025
3129
|
const showNative = player.shouldShowNativeControls();
|
|
3026
3130
|
setShouldShowNativeControls(showNative);
|
|
3027
|
-
onReady
|
|
3131
|
+
onReady == null ? void 0 : onReady(player);
|
|
3028
3132
|
}).catch((error) => {
|
|
3029
3133
|
console.error(
|
|
3030
3134
|
"StormcloudVideoPlayer: Failed to load player:",
|
|
3031
3135
|
error
|
|
3032
3136
|
);
|
|
3033
|
-
onReady
|
|
3137
|
+
onReady == null ? void 0 : onReady(player);
|
|
3034
3138
|
});
|
|
3035
3139
|
return () => {
|
|
3036
3140
|
try {
|
|
@@ -3086,6 +3190,7 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(
|
|
|
3086
3190
|
(0, import_react.useEffect)(() => {
|
|
3087
3191
|
if (!playerRef.current || !videoRef.current) return;
|
|
3088
3192
|
const updateStates = () => {
|
|
3193
|
+
var _a;
|
|
3089
3194
|
if (playerRef.current && videoRef.current) {
|
|
3090
3195
|
setIsMuted(playerRef.current.isMuted());
|
|
3091
3196
|
setIsPlaying(!videoRef.current.paused);
|
|
@@ -3103,13 +3208,14 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(
|
|
|
3103
3208
|
);
|
|
3104
3209
|
}
|
|
3105
3210
|
setIsFullscreen(
|
|
3106
|
-
document.fullscreenElement === videoRef.current
|
|
3211
|
+
document.fullscreenElement === ((_a = videoRef.current) == null ? void 0 : _a.parentElement)
|
|
3107
3212
|
);
|
|
3108
3213
|
};
|
|
3109
3214
|
const interval = setInterval(updateStates, 200);
|
|
3110
3215
|
const handleFullscreenChange = () => {
|
|
3216
|
+
var _a;
|
|
3111
3217
|
setIsFullscreen(
|
|
3112
|
-
document.fullscreenElement === videoRef.current
|
|
3218
|
+
document.fullscreenElement === ((_a = videoRef.current) == null ? void 0 : _a.parentElement)
|
|
3113
3219
|
);
|
|
3114
3220
|
};
|
|
3115
3221
|
document.addEventListener("fullscreenchange", handleFullscreenChange);
|
|
@@ -4552,6 +4658,7 @@ var HlsPlayer = class extends import_react3.Component {
|
|
|
4552
4658
|
this.player = null;
|
|
4553
4659
|
this.mounted = false;
|
|
4554
4660
|
this.load = async () => {
|
|
4661
|
+
var _a, _b, _c, _d, _e, _f;
|
|
4555
4662
|
if (!this.props.videoElement || !this.props.src) return;
|
|
4556
4663
|
try {
|
|
4557
4664
|
if (this.player) {
|
|
@@ -4588,27 +4695,29 @@ var HlsPlayer = class extends import_react3.Component {
|
|
|
4588
4695
|
if (this.props.adFailsafeTimeoutMs !== void 0)
|
|
4589
4696
|
config.adFailsafeTimeoutMs = this.props.adFailsafeTimeoutMs;
|
|
4590
4697
|
this.player = new StormcloudVideoPlayer(config);
|
|
4591
|
-
this.props.onMount
|
|
4698
|
+
(_b = (_a = this.props).onMount) == null ? void 0 : _b.call(_a, this);
|
|
4592
4699
|
await this.player.load();
|
|
4593
4700
|
if (this.mounted) {
|
|
4594
|
-
this.props.onReady
|
|
4701
|
+
(_d = (_c = this.props).onReady) == null ? void 0 : _d.call(_c);
|
|
4595
4702
|
}
|
|
4596
4703
|
} catch (error) {
|
|
4597
4704
|
if (this.mounted) {
|
|
4598
|
-
this.props.onError
|
|
4705
|
+
(_f = (_e = this.props).onError) == null ? void 0 : _f.call(_e, error);
|
|
4599
4706
|
}
|
|
4600
4707
|
}
|
|
4601
4708
|
};
|
|
4602
4709
|
this.play = () => {
|
|
4710
|
+
var _a, _b;
|
|
4603
4711
|
if (this.props.videoElement) {
|
|
4604
4712
|
this.props.videoElement.play();
|
|
4605
|
-
this.props.onPlay
|
|
4713
|
+
(_b = (_a = this.props).onPlay) == null ? void 0 : _b.call(_a);
|
|
4606
4714
|
}
|
|
4607
4715
|
};
|
|
4608
4716
|
this.pause = () => {
|
|
4717
|
+
var _a, _b;
|
|
4609
4718
|
if (this.props.videoElement) {
|
|
4610
4719
|
this.props.videoElement.pause();
|
|
4611
|
-
this.props.onPause
|
|
4720
|
+
(_b = (_a = this.props).onPause) == null ? void 0 : _b.call(_a);
|
|
4612
4721
|
}
|
|
4613
4722
|
};
|
|
4614
4723
|
this.stop = () => {
|
|
@@ -4703,37 +4812,44 @@ var FilePlayer = class extends import_react4.Component {
|
|
|
4703
4812
|
this.mounted = false;
|
|
4704
4813
|
this.ready = false;
|
|
4705
4814
|
this.load = () => {
|
|
4815
|
+
var _a, _b;
|
|
4706
4816
|
if (!this.props.videoElement || !this.props.src) return;
|
|
4707
4817
|
const video = this.props.videoElement;
|
|
4708
4818
|
const handleLoadedMetadata = () => {
|
|
4819
|
+
var _a2, _b2;
|
|
4709
4820
|
if (this.mounted && !this.ready) {
|
|
4710
4821
|
this.ready = true;
|
|
4711
|
-
this.props.onReady
|
|
4822
|
+
(_b2 = (_a2 = this.props).onReady) == null ? void 0 : _b2.call(_a2);
|
|
4712
4823
|
}
|
|
4713
4824
|
};
|
|
4714
4825
|
const handlePlay = () => {
|
|
4826
|
+
var _a2, _b2;
|
|
4715
4827
|
if (this.mounted) {
|
|
4716
|
-
this.props.onPlay
|
|
4828
|
+
(_b2 = (_a2 = this.props).onPlay) == null ? void 0 : _b2.call(_a2);
|
|
4717
4829
|
}
|
|
4718
4830
|
};
|
|
4719
4831
|
const handlePause = () => {
|
|
4832
|
+
var _a2, _b2;
|
|
4720
4833
|
if (this.mounted) {
|
|
4721
|
-
this.props.onPause
|
|
4834
|
+
(_b2 = (_a2 = this.props).onPause) == null ? void 0 : _b2.call(_a2);
|
|
4722
4835
|
}
|
|
4723
4836
|
};
|
|
4724
4837
|
const handleEnded = () => {
|
|
4838
|
+
var _a2, _b2;
|
|
4725
4839
|
if (this.mounted) {
|
|
4726
|
-
this.props.onEnded
|
|
4840
|
+
(_b2 = (_a2 = this.props).onEnded) == null ? void 0 : _b2.call(_a2);
|
|
4727
4841
|
}
|
|
4728
4842
|
};
|
|
4729
4843
|
const handleError = (error) => {
|
|
4844
|
+
var _a2, _b2;
|
|
4730
4845
|
if (this.mounted) {
|
|
4731
|
-
this.props.onError
|
|
4846
|
+
(_b2 = (_a2 = this.props).onError) == null ? void 0 : _b2.call(_a2, error);
|
|
4732
4847
|
}
|
|
4733
4848
|
};
|
|
4734
4849
|
const handleLoadedData = () => {
|
|
4850
|
+
var _a2, _b2;
|
|
4735
4851
|
if (this.mounted) {
|
|
4736
|
-
this.props.onLoaded
|
|
4852
|
+
(_b2 = (_a2 = this.props).onLoaded) == null ? void 0 : _b2.call(_a2);
|
|
4737
4853
|
}
|
|
4738
4854
|
};
|
|
4739
4855
|
video.addEventListener("loadedmetadata", handleLoadedMetadata);
|
|
@@ -4752,7 +4868,7 @@ var FilePlayer = class extends import_react4.Component {
|
|
|
4752
4868
|
if (this.props.preload !== void 0)
|
|
4753
4869
|
video.preload = this.props.preload;
|
|
4754
4870
|
if (this.props.poster !== void 0) video.poster = this.props.poster;
|
|
4755
|
-
this.props.onMount
|
|
4871
|
+
(_b = (_a = this.props).onMount) == null ? void 0 : _b.call(_a, this);
|
|
4756
4872
|
return () => {
|
|
4757
4873
|
video.removeEventListener("loadedmetadata", handleLoadedMetadata);
|
|
4758
4874
|
video.removeEventListener("play", handlePlay);
|
|
@@ -4921,6 +5037,7 @@ var Player = class extends import_react5.Component {
|
|
|
4921
5037
|
return this.player.getInternalPlayer(key);
|
|
4922
5038
|
};
|
|
4923
5039
|
this.progress = () => {
|
|
5040
|
+
var _a, _b;
|
|
4924
5041
|
if (this.props.src && this.player && this.isReady) {
|
|
4925
5042
|
const playedSeconds = this.getCurrentTime() || 0;
|
|
4926
5043
|
const loadedSeconds = this.getSecondsLoaded();
|
|
@@ -4937,7 +5054,7 @@ var Player = class extends import_react5.Component {
|
|
|
4937
5054
|
progress.loaded = loadedSeconds / duration;
|
|
4938
5055
|
}
|
|
4939
5056
|
if (progress.playedSeconds !== this.prevPlayed || progress.loadedSeconds !== this.prevLoaded) {
|
|
4940
|
-
this.props.onProgress
|
|
5057
|
+
(_b = (_a = this.props).onProgress) == null ? void 0 : _b.call(_a, progress);
|
|
4941
5058
|
}
|
|
4942
5059
|
this.prevPlayed = progress.playedSeconds;
|
|
4943
5060
|
this.prevLoaded = progress.loadedSeconds;
|
|
@@ -4973,10 +5090,10 @@ var Player = class extends import_react5.Component {
|
|
|
4973
5090
|
if (this.player.setPlaybackRate && playbackRate !== 1) {
|
|
4974
5091
|
this.player.setPlaybackRate(playbackRate);
|
|
4975
5092
|
}
|
|
4976
|
-
onStart
|
|
5093
|
+
onStart == null ? void 0 : onStart();
|
|
4977
5094
|
this.startOnPlay = false;
|
|
4978
5095
|
}
|
|
4979
|
-
onPlay
|
|
5096
|
+
onPlay == null ? void 0 : onPlay();
|
|
4980
5097
|
if (this.seekOnPlay) {
|
|
4981
5098
|
this.seekTo(this.seekOnPlay);
|
|
4982
5099
|
this.seekOnPlay = null;
|
|
@@ -4984,9 +5101,10 @@ var Player = class extends import_react5.Component {
|
|
|
4984
5101
|
this.handleDurationCheck();
|
|
4985
5102
|
};
|
|
4986
5103
|
this.handlePause = (e) => {
|
|
5104
|
+
var _a, _b;
|
|
4987
5105
|
this.isPlaying = false;
|
|
4988
5106
|
if (!this.isLoading) {
|
|
4989
|
-
this.props.onPause
|
|
5107
|
+
(_b = (_a = this.props).onPause) == null ? void 0 : _b.call(_a, e);
|
|
4990
5108
|
}
|
|
4991
5109
|
};
|
|
4992
5110
|
this.handleEnded = () => {
|
|
@@ -4996,19 +5114,21 @@ var Player = class extends import_react5.Component {
|
|
|
4996
5114
|
}
|
|
4997
5115
|
if (!loop) {
|
|
4998
5116
|
this.isPlaying = false;
|
|
4999
|
-
onEnded
|
|
5117
|
+
onEnded == null ? void 0 : onEnded();
|
|
5000
5118
|
}
|
|
5001
5119
|
};
|
|
5002
5120
|
this.handleError = (...args) => {
|
|
5121
|
+
var _a, _b;
|
|
5003
5122
|
this.isLoading = false;
|
|
5004
|
-
this.props.onError
|
|
5123
|
+
(_b = (_a = this.props).onError) == null ? void 0 : _b.call(_a, args[0], args[1], args[2], args[3]);
|
|
5005
5124
|
};
|
|
5006
5125
|
this.handleDurationCheck = () => {
|
|
5126
|
+
var _a, _b;
|
|
5007
5127
|
clearTimeout(this.durationCheckTimeout);
|
|
5008
5128
|
const duration = this.getDuration();
|
|
5009
5129
|
if (duration) {
|
|
5010
5130
|
if (!this.onDurationCalled) {
|
|
5011
|
-
this.props.onDuration
|
|
5131
|
+
(_b = (_a = this.props).onDuration) == null ? void 0 : _b.call(_a, duration);
|
|
5012
5132
|
this.onDurationCalled = true;
|
|
5013
5133
|
}
|
|
5014
5134
|
} else {
|
|
@@ -5207,7 +5327,8 @@ var createStormcloudPlayer = (playerList, fallback) => {
|
|
|
5207
5327
|
return omit(this.props, SUPPORTED_PROPS);
|
|
5208
5328
|
};
|
|
5209
5329
|
this.handleReady = () => {
|
|
5210
|
-
|
|
5330
|
+
var _a2, _b;
|
|
5331
|
+
(_b = (_a2 = this.props).onReady) == null ? void 0 : _b.call(_a2, this);
|
|
5211
5332
|
};
|
|
5212
5333
|
this.seekTo = (fraction, type, keepPlaying) => {
|
|
5213
5334
|
if (!this.player) return null;
|