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.js
CHANGED
|
@@ -14,7 +14,8 @@ function getWebKitVersion(ua) {
|
|
|
14
14
|
return match && match[1] ? parseInt(match[1], 10) : 0;
|
|
15
15
|
}
|
|
16
16
|
function getPlatform() {
|
|
17
|
-
|
|
17
|
+
var _a;
|
|
18
|
+
if ("userAgentData" in navigator && ((_a = navigator.userAgentData) == null ? void 0 : _a.platform)) {
|
|
18
19
|
return navigator.userAgentData.platform;
|
|
19
20
|
}
|
|
20
21
|
const ua = navigator.userAgent;
|
|
@@ -208,6 +209,7 @@ function createImaController(video, options) {
|
|
|
208
209
|
}
|
|
209
210
|
}
|
|
210
211
|
function ensureImaLoaded() {
|
|
212
|
+
var _a, _b, _c;
|
|
211
213
|
if (!supportsGoogleIMA()) {
|
|
212
214
|
console.warn(
|
|
213
215
|
"[IMA] Google IMA SDK is not supported on this browser. Please use HLS ad player instead."
|
|
@@ -218,7 +220,7 @@ function createImaController(video, options) {
|
|
|
218
220
|
}
|
|
219
221
|
try {
|
|
220
222
|
const frameEl = window.frameElement;
|
|
221
|
-
const sandboxAttr = frameEl
|
|
223
|
+
const sandboxAttr = ((_a = frameEl == null ? void 0 : frameEl.getAttribute) == null ? void 0 : _a.call(frameEl, "sandbox")) || "";
|
|
222
224
|
if (sandboxAttr) {
|
|
223
225
|
const tokens = new Set(
|
|
224
226
|
sandboxAttr.split(/\s+/).map((t) => t.trim()).filter((t) => t.length > 0)
|
|
@@ -232,13 +234,13 @@ function createImaController(video, options) {
|
|
|
232
234
|
}
|
|
233
235
|
} catch {
|
|
234
236
|
}
|
|
235
|
-
if (typeof window !== "undefined" && window.google
|
|
237
|
+
if (typeof window !== "undefined" && ((_b = window.google) == null ? void 0 : _b.ima))
|
|
236
238
|
return Promise.resolve();
|
|
237
239
|
const existing = document.querySelector(
|
|
238
240
|
'script[data-ima="true"]'
|
|
239
241
|
);
|
|
240
242
|
if (existing) {
|
|
241
|
-
if (window.google
|
|
243
|
+
if ((_c = window.google) == null ? void 0 : _c.ima) {
|
|
242
244
|
return Promise.resolve();
|
|
243
245
|
}
|
|
244
246
|
return new Promise((resolve, reject) => {
|
|
@@ -296,6 +298,7 @@ function createImaController(video, options) {
|
|
|
296
298
|
return {
|
|
297
299
|
initialize() {
|
|
298
300
|
ensureImaLoaded().then(() => {
|
|
301
|
+
var _a, _b;
|
|
299
302
|
const google = window.google;
|
|
300
303
|
if (!adDisplayContainer) {
|
|
301
304
|
const container = document.createElement("div");
|
|
@@ -309,14 +312,14 @@ function createImaController(video, options) {
|
|
|
309
312
|
container.style.justifyContent = "center";
|
|
310
313
|
container.style.pointerEvents = "none";
|
|
311
314
|
container.style.zIndex = "2";
|
|
312
|
-
video.parentElement
|
|
315
|
+
(_a = video.parentElement) == null ? void 0 : _a.appendChild(container);
|
|
313
316
|
adContainerEl = container;
|
|
314
317
|
adDisplayContainer = new google.ima.AdDisplayContainer(
|
|
315
318
|
container,
|
|
316
319
|
video
|
|
317
320
|
);
|
|
318
321
|
try {
|
|
319
|
-
adDisplayContainer.initialize
|
|
322
|
+
(_b = adDisplayContainer.initialize) == null ? void 0 : _b.call(adDisplayContainer);
|
|
320
323
|
} catch {
|
|
321
324
|
}
|
|
322
325
|
}
|
|
@@ -401,6 +404,7 @@ function createImaController(video, options) {
|
|
|
401
404
|
adsManager.addEventListener(
|
|
402
405
|
AdErrorEvent.AD_ERROR,
|
|
403
406
|
(errorEvent) => {
|
|
407
|
+
var _a;
|
|
404
408
|
console.error("[IMA] Ad error:", errorEvent.getError());
|
|
405
409
|
destroyAdsManager();
|
|
406
410
|
adPlaying = false;
|
|
@@ -431,10 +435,10 @@ function createImaController(video, options) {
|
|
|
431
435
|
"[IMA] Max retries reached, emitting ad_error"
|
|
432
436
|
);
|
|
433
437
|
emit("ad_error");
|
|
434
|
-
if (!options
|
|
438
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
435
439
|
if (video.paused) {
|
|
436
440
|
console.log("[IMA] Resuming paused video after ad error");
|
|
437
|
-
video.play()
|
|
441
|
+
(_a = video.play()) == null ? void 0 : _a.catch(() => {
|
|
438
442
|
});
|
|
439
443
|
}
|
|
440
444
|
}
|
|
@@ -445,7 +449,7 @@ function createImaController(video, options) {
|
|
|
445
449
|
AdEvent.CONTENT_PAUSE_REQUESTED,
|
|
446
450
|
() => {
|
|
447
451
|
console.log("[IMA] Content pause requested");
|
|
448
|
-
if (!options
|
|
452
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
449
453
|
video.pause();
|
|
450
454
|
console.log("[IMA] Video paused (VOD mode)");
|
|
451
455
|
} else {
|
|
@@ -471,6 +475,7 @@ function createImaController(video, options) {
|
|
|
471
475
|
adsManager.addEventListener(
|
|
472
476
|
AdEvent.CONTENT_RESUME_REQUESTED,
|
|
473
477
|
() => {
|
|
478
|
+
var _a;
|
|
474
479
|
console.log("[IMA] Content resume requested");
|
|
475
480
|
adPlaying = false;
|
|
476
481
|
video.muted = originalMutedState;
|
|
@@ -481,8 +486,8 @@ function createImaController(video, options) {
|
|
|
481
486
|
"[IMA] Ad container hidden - pointer events disabled"
|
|
482
487
|
);
|
|
483
488
|
}
|
|
484
|
-
if (!options
|
|
485
|
-
video.play()
|
|
489
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
490
|
+
(_a = video.play()) == null ? void 0 : _a.catch(() => {
|
|
486
491
|
});
|
|
487
492
|
console.log("[IMA] Video resumed (VOD mode)");
|
|
488
493
|
} else {
|
|
@@ -504,7 +509,7 @@ function createImaController(video, options) {
|
|
|
504
509
|
"[IMA] Ad container hidden after all ads completed"
|
|
505
510
|
);
|
|
506
511
|
}
|
|
507
|
-
if (!options
|
|
512
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
508
513
|
video.play().catch(() => {
|
|
509
514
|
});
|
|
510
515
|
console.log(
|
|
@@ -532,7 +537,7 @@ function createImaController(video, options) {
|
|
|
532
537
|
adContainerEl.style.display = "none";
|
|
533
538
|
console.log("[IMA] Ad container hidden after setup error");
|
|
534
539
|
}
|
|
535
|
-
if (!options
|
|
540
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
536
541
|
if (video.paused) {
|
|
537
542
|
console.log("[IMA] Resuming paused video after setup error");
|
|
538
543
|
video.play().catch(() => {
|
|
@@ -560,7 +565,7 @@ function createImaController(video, options) {
|
|
|
560
565
|
adContainerEl.style.display = "none";
|
|
561
566
|
console.log("[IMA] Ad container hidden after loader error");
|
|
562
567
|
}
|
|
563
|
-
if (!options
|
|
568
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
564
569
|
if (video.paused) {
|
|
565
570
|
console.log("[IMA] Resuming paused video after loader error");
|
|
566
571
|
video.play().catch(() => {
|
|
@@ -582,14 +587,15 @@ function createImaController(video, options) {
|
|
|
582
587
|
return adsLoadedPromise;
|
|
583
588
|
} catch (error) {
|
|
584
589
|
console.error("[IMA] Failed to request ads:", error);
|
|
585
|
-
currentReject
|
|
590
|
+
currentReject == null ? void 0 : currentReject(error);
|
|
586
591
|
adsLoadedReject = void 0;
|
|
587
592
|
adsLoadedResolve = void 0;
|
|
588
593
|
return Promise.reject(error);
|
|
589
594
|
}
|
|
590
595
|
},
|
|
591
596
|
async play() {
|
|
592
|
-
|
|
597
|
+
var _a, _b;
|
|
598
|
+
if (!((_a = window.google) == null ? void 0 : _a.ima) || !adDisplayContainer) {
|
|
593
599
|
console.warn(
|
|
594
600
|
"[IMA] Cannot play ad: IMA SDK or ad container not available"
|
|
595
601
|
);
|
|
@@ -611,14 +617,15 @@ function createImaController(video, options) {
|
|
|
611
617
|
} catch (error) {
|
|
612
618
|
console.error("[IMA] Error starting ad playback:", error);
|
|
613
619
|
adPlaying = false;
|
|
614
|
-
if (!options
|
|
615
|
-
video.play()
|
|
620
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
621
|
+
(_b = video.play()) == null ? void 0 : _b.catch(() => {
|
|
616
622
|
});
|
|
617
623
|
}
|
|
618
624
|
return Promise.reject(error);
|
|
619
625
|
}
|
|
620
626
|
},
|
|
621
627
|
async stop() {
|
|
628
|
+
var _a;
|
|
622
629
|
adPlaying = false;
|
|
623
630
|
video.muted = originalMutedState;
|
|
624
631
|
if (adContainerEl) {
|
|
@@ -627,11 +634,11 @@ function createImaController(video, options) {
|
|
|
627
634
|
console.log("[IMA] Ad container hidden after stop");
|
|
628
635
|
}
|
|
629
636
|
try {
|
|
630
|
-
adsManager
|
|
637
|
+
(_a = adsManager == null ? void 0 : adsManager.stop) == null ? void 0 : _a.call(adsManager);
|
|
631
638
|
} catch {
|
|
632
639
|
}
|
|
633
640
|
destroyAdsManager();
|
|
634
|
-
if (!options
|
|
641
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
635
642
|
video.play().catch(() => {
|
|
636
643
|
});
|
|
637
644
|
console.log("[IMA] Video resumed after stop (VOD mode)");
|
|
@@ -640,6 +647,7 @@ function createImaController(video, options) {
|
|
|
640
647
|
}
|
|
641
648
|
},
|
|
642
649
|
destroy() {
|
|
650
|
+
var _a;
|
|
643
651
|
destroyAdsManager();
|
|
644
652
|
adPlaying = false;
|
|
645
653
|
video.muted = originalMutedState;
|
|
@@ -648,10 +656,10 @@ function createImaController(video, options) {
|
|
|
648
656
|
adContainerEl.style.display = "none";
|
|
649
657
|
}
|
|
650
658
|
try {
|
|
651
|
-
adsLoader
|
|
659
|
+
(_a = adsLoader == null ? void 0 : adsLoader.destroy) == null ? void 0 : _a.call(adsLoader);
|
|
652
660
|
} catch {
|
|
653
661
|
}
|
|
654
|
-
if (adContainerEl
|
|
662
|
+
if (adContainerEl == null ? void 0 : adContainerEl.parentElement) {
|
|
655
663
|
adContainerEl.parentElement.removeChild(adContainerEl);
|
|
656
664
|
}
|
|
657
665
|
adContainerEl = void 0;
|
|
@@ -662,7 +670,8 @@ function createImaController(video, options) {
|
|
|
662
670
|
return adPlaying;
|
|
663
671
|
},
|
|
664
672
|
resize(width, height) {
|
|
665
|
-
|
|
673
|
+
var _a;
|
|
674
|
+
if (!adsManager || !((_a = window.google) == null ? void 0 : _a.ima)) {
|
|
666
675
|
console.warn(
|
|
667
676
|
"[IMA] Cannot resize: No ads manager or IMA SDK available"
|
|
668
677
|
);
|
|
@@ -680,7 +689,8 @@ function createImaController(video, options) {
|
|
|
680
689
|
listeners.get(event).add(listener);
|
|
681
690
|
},
|
|
682
691
|
off(event, listener) {
|
|
683
|
-
|
|
692
|
+
var _a;
|
|
693
|
+
(_a = listeners.get(event)) == null ? void 0 : _a.delete(listener);
|
|
684
694
|
},
|
|
685
695
|
updateOriginalMutedState(muted) {
|
|
686
696
|
originalMutedState = muted;
|
|
@@ -717,7 +727,8 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
717
727
|
let adPlaying = false;
|
|
718
728
|
let originalMutedState = false;
|
|
719
729
|
const listeners = /* @__PURE__ */ new Map();
|
|
720
|
-
const licenseKey = options
|
|
730
|
+
const licenseKey = options == null ? void 0 : options.licenseKey;
|
|
731
|
+
const mainHlsInstance = options == null ? void 0 : options.mainHlsInstance;
|
|
721
732
|
let adVideoElement;
|
|
722
733
|
let adHls;
|
|
723
734
|
let adContainerEl;
|
|
@@ -764,7 +775,74 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
764
775
|
}
|
|
765
776
|
});
|
|
766
777
|
}
|
|
778
|
+
function getMainStreamQuality() {
|
|
779
|
+
if (!mainHlsInstance || !mainHlsInstance.levels) {
|
|
780
|
+
return null;
|
|
781
|
+
}
|
|
782
|
+
const currentLevel = mainHlsInstance.currentLevel;
|
|
783
|
+
if (currentLevel === -1 || !mainHlsInstance.levels[currentLevel]) {
|
|
784
|
+
const autoLevel = mainHlsInstance.loadLevel;
|
|
785
|
+
if (autoLevel !== -1 && mainHlsInstance.levels[autoLevel]) {
|
|
786
|
+
const level2 = mainHlsInstance.levels[autoLevel];
|
|
787
|
+
return {
|
|
788
|
+
width: level2.width || 1920,
|
|
789
|
+
height: level2.height || 1080,
|
|
790
|
+
bitrate: level2.bitrate || 5e6
|
|
791
|
+
};
|
|
792
|
+
}
|
|
793
|
+
return null;
|
|
794
|
+
}
|
|
795
|
+
const level = mainHlsInstance.levels[currentLevel];
|
|
796
|
+
return {
|
|
797
|
+
width: level.width || 1920,
|
|
798
|
+
height: level.height || 1080,
|
|
799
|
+
bitrate: level.bitrate || 5e6
|
|
800
|
+
};
|
|
801
|
+
}
|
|
802
|
+
function selectBestMediaFile(mediaFiles) {
|
|
803
|
+
if (mediaFiles.length === 0) {
|
|
804
|
+
throw new Error("No media files available");
|
|
805
|
+
}
|
|
806
|
+
const firstFile = mediaFiles[0];
|
|
807
|
+
if (!firstFile) {
|
|
808
|
+
throw new Error("No media files available");
|
|
809
|
+
}
|
|
810
|
+
if (mediaFiles.length === 1) {
|
|
811
|
+
return firstFile;
|
|
812
|
+
}
|
|
813
|
+
const mainQuality = getMainStreamQuality();
|
|
814
|
+
if (!mainQuality) {
|
|
815
|
+
console.log("[HlsAdPlayer] No main stream quality info, using first media file");
|
|
816
|
+
return firstFile;
|
|
817
|
+
}
|
|
818
|
+
console.log("[HlsAdPlayer] Main stream quality:", mainQuality);
|
|
819
|
+
const scoredFiles = mediaFiles.map((file) => {
|
|
820
|
+
const widthDiff = Math.abs(file.width - mainQuality.width);
|
|
821
|
+
const heightDiff = Math.abs(file.height - mainQuality.height);
|
|
822
|
+
const resolutionDiff = widthDiff + heightDiff;
|
|
823
|
+
const fileBitrate = (file.bitrate || 5e3) * 1e3;
|
|
824
|
+
const bitrateDiff = Math.abs(fileBitrate - mainQuality.bitrate);
|
|
825
|
+
const score = resolutionDiff * 2 + bitrateDiff / 1e3;
|
|
826
|
+
return { file, score, resolutionDiff, bitrateDiff };
|
|
827
|
+
});
|
|
828
|
+
scoredFiles.sort((a, b) => a.score - b.score);
|
|
829
|
+
const bestMatch = scoredFiles[0];
|
|
830
|
+
if (!bestMatch) {
|
|
831
|
+
console.log("[HlsAdPlayer] No best match found, using first media file");
|
|
832
|
+
return firstFile;
|
|
833
|
+
}
|
|
834
|
+
console.log("[HlsAdPlayer] Selected media file:", {
|
|
835
|
+
url: bestMatch.file.url,
|
|
836
|
+
resolution: `${bestMatch.file.width}x${bestMatch.file.height}`,
|
|
837
|
+
bitrate: bestMatch.file.bitrate,
|
|
838
|
+
score: bestMatch.score,
|
|
839
|
+
resolutionDiff: bestMatch.resolutionDiff,
|
|
840
|
+
bitrateDiff: bestMatch.bitrateDiff
|
|
841
|
+
});
|
|
842
|
+
return bestMatch.file;
|
|
843
|
+
}
|
|
767
844
|
function parseVastXml(xmlString) {
|
|
845
|
+
var _a, _b, _c, _d;
|
|
768
846
|
try {
|
|
769
847
|
const parser = new DOMParser();
|
|
770
848
|
const xmlDoc = parser.parseFromString(xmlString, "text/xml");
|
|
@@ -779,19 +857,20 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
779
857
|
return null;
|
|
780
858
|
}
|
|
781
859
|
const adId = adElement.getAttribute("id") || "unknown";
|
|
782
|
-
const title = xmlDoc.querySelector("AdTitle")
|
|
783
|
-
const durationText = xmlDoc.querySelector("Duration")
|
|
860
|
+
const title = ((_a = xmlDoc.querySelector("AdTitle")) == null ? void 0 : _a.textContent) || "Ad";
|
|
861
|
+
const durationText = ((_b = xmlDoc.querySelector("Duration")) == null ? void 0 : _b.textContent) || "00:00:30";
|
|
784
862
|
const durationParts = durationText.split(":");
|
|
785
863
|
const duration = parseInt(durationParts[0] || "0", 10) * 3600 + parseInt(durationParts[1] || "0", 10) * 60 + parseInt(durationParts[2] || "0", 10);
|
|
786
864
|
const mediaFileElements = xmlDoc.querySelectorAll("MediaFile");
|
|
787
865
|
const mediaFiles = [];
|
|
788
866
|
mediaFileElements.forEach((mf) => {
|
|
867
|
+
var _a2;
|
|
789
868
|
const type = mf.getAttribute("type") || "";
|
|
790
869
|
if (type === "application/x-mpegURL" || type.includes("m3u8")) {
|
|
791
870
|
const bitrateAttr = mf.getAttribute("bitrate");
|
|
792
871
|
const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;
|
|
793
872
|
mediaFiles.push({
|
|
794
|
-
url: mf.textContent
|
|
873
|
+
url: ((_a2 = mf.textContent) == null ? void 0 : _a2.trim()) || "",
|
|
795
874
|
type,
|
|
796
875
|
width: parseInt(mf.getAttribute("width") || "1920", 10),
|
|
797
876
|
height: parseInt(mf.getAttribute("height") || "1080", 10),
|
|
@@ -820,12 +899,14 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
820
899
|
error: []
|
|
821
900
|
};
|
|
822
901
|
xmlDoc.querySelectorAll("Impression").forEach((el) => {
|
|
823
|
-
|
|
902
|
+
var _a2;
|
|
903
|
+
const url = (_a2 = el.textContent) == null ? void 0 : _a2.trim();
|
|
824
904
|
if (url) trackingUrls.impression.push(url);
|
|
825
905
|
});
|
|
826
906
|
xmlDoc.querySelectorAll("Tracking").forEach((el) => {
|
|
907
|
+
var _a2;
|
|
827
908
|
const event = el.getAttribute("event");
|
|
828
|
-
const url = el.textContent
|
|
909
|
+
const url = (_a2 = el.textContent) == null ? void 0 : _a2.trim();
|
|
829
910
|
if (event && url) {
|
|
830
911
|
const eventKey = event;
|
|
831
912
|
if (trackingUrls[eventKey]) {
|
|
@@ -833,7 +914,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
833
914
|
}
|
|
834
915
|
}
|
|
835
916
|
});
|
|
836
|
-
const clickThrough = xmlDoc.querySelector("ClickThrough")
|
|
917
|
+
const clickThrough = (_d = (_c = xmlDoc.querySelector("ClickThrough")) == null ? void 0 : _c.textContent) == null ? void 0 : _d.trim();
|
|
837
918
|
return {
|
|
838
919
|
id: adId,
|
|
839
920
|
title,
|
|
@@ -925,7 +1006,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
925
1006
|
adContainerEl.style.display = "none";
|
|
926
1007
|
adContainerEl.style.pointerEvents = "none";
|
|
927
1008
|
}
|
|
928
|
-
if (!options
|
|
1009
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
929
1010
|
contentVideo.play().catch(() => {
|
|
930
1011
|
});
|
|
931
1012
|
console.log("[HlsAdPlayer] Content resumed (VOD mode)");
|
|
@@ -943,7 +1024,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
943
1024
|
adContainerEl.style.display = "none";
|
|
944
1025
|
adContainerEl.style.pointerEvents = "none";
|
|
945
1026
|
}
|
|
946
|
-
if (!options
|
|
1027
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
947
1028
|
if (contentVideo.paused) {
|
|
948
1029
|
contentVideo.play().catch(() => {
|
|
949
1030
|
});
|
|
@@ -953,6 +1034,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
953
1034
|
}
|
|
954
1035
|
return {
|
|
955
1036
|
initialize() {
|
|
1037
|
+
var _a;
|
|
956
1038
|
console.log("[HlsAdPlayer] Initializing");
|
|
957
1039
|
if (!adContainerEl) {
|
|
958
1040
|
const container = document.createElement("div");
|
|
@@ -967,7 +1049,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
967
1049
|
container.style.pointerEvents = "none";
|
|
968
1050
|
container.style.zIndex = "2";
|
|
969
1051
|
container.style.backgroundColor = "#000";
|
|
970
|
-
contentVideo.parentElement
|
|
1052
|
+
(_a = contentVideo.parentElement) == null ? void 0 : _a.appendChild(container);
|
|
971
1053
|
adContainerEl = container;
|
|
972
1054
|
}
|
|
973
1055
|
},
|
|
@@ -1009,7 +1091,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1009
1091
|
try {
|
|
1010
1092
|
if (!adVideoElement) {
|
|
1011
1093
|
adVideoElement = createAdVideoElement();
|
|
1012
|
-
adContainerEl
|
|
1094
|
+
adContainerEl == null ? void 0 : adContainerEl.appendChild(adVideoElement);
|
|
1013
1095
|
setupAdEventListeners();
|
|
1014
1096
|
}
|
|
1015
1097
|
trackingFired = {
|
|
@@ -1020,7 +1102,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1020
1102
|
thirdQuartile: false,
|
|
1021
1103
|
complete: false
|
|
1022
1104
|
};
|
|
1023
|
-
if (!options
|
|
1105
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
1024
1106
|
contentVideo.pause();
|
|
1025
1107
|
console.log("[HlsAdPlayer] Content paused (VOD mode)");
|
|
1026
1108
|
} else {
|
|
@@ -1033,7 +1115,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1033
1115
|
adContainerEl.style.pointerEvents = "auto";
|
|
1034
1116
|
}
|
|
1035
1117
|
emit("content_pause");
|
|
1036
|
-
const mediaFile = currentAd.mediaFiles
|
|
1118
|
+
const mediaFile = selectBestMediaFile(currentAd.mediaFiles);
|
|
1037
1119
|
if (!mediaFile) {
|
|
1038
1120
|
throw new Error("No media file available for ad");
|
|
1039
1121
|
}
|
|
@@ -1093,7 +1175,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1093
1175
|
adVideoElement.pause();
|
|
1094
1176
|
adVideoElement.src = "";
|
|
1095
1177
|
}
|
|
1096
|
-
if (!options
|
|
1178
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
1097
1179
|
contentVideo.play().catch(() => {
|
|
1098
1180
|
});
|
|
1099
1181
|
}
|
|
@@ -1113,7 +1195,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1113
1195
|
adVideoElement.remove();
|
|
1114
1196
|
adVideoElement = void 0;
|
|
1115
1197
|
}
|
|
1116
|
-
if (adContainerEl
|
|
1198
|
+
if (adContainerEl == null ? void 0 : adContainerEl.parentElement) {
|
|
1117
1199
|
adContainerEl.parentElement.removeChild(adContainerEl);
|
|
1118
1200
|
}
|
|
1119
1201
|
adContainerEl = void 0;
|
|
@@ -1139,7 +1221,8 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1139
1221
|
listeners.get(event).add(listener);
|
|
1140
1222
|
},
|
|
1141
1223
|
off(event, listener) {
|
|
1142
|
-
|
|
1224
|
+
var _a;
|
|
1225
|
+
(_a = listeners.get(event)) == null ? void 0 : _a.delete(listener);
|
|
1143
1226
|
},
|
|
1144
1227
|
updateOriginalMutedState(muted) {
|
|
1145
1228
|
originalMutedState = muted;
|
|
@@ -1164,6 +1247,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1164
1247
|
// src/utils/tracking.ts
|
|
1165
1248
|
var cachedBrowserId = null;
|
|
1166
1249
|
function getClientInfo() {
|
|
1250
|
+
var _a, _b, _c, _d;
|
|
1167
1251
|
const ua = navigator.userAgent;
|
|
1168
1252
|
const platform = navigator.platform;
|
|
1169
1253
|
const vendor = navigator.vendor || "";
|
|
@@ -1171,12 +1255,12 @@ function getClientInfo() {
|
|
|
1171
1255
|
const memory = navigator.deviceMemory || null;
|
|
1172
1256
|
const hardwareConcurrency = navigator.hardwareConcurrency || 1;
|
|
1173
1257
|
const screenInfo = {
|
|
1174
|
-
width: screen
|
|
1175
|
-
height: screen
|
|
1176
|
-
availWidth: screen
|
|
1177
|
-
availHeight: screen
|
|
1178
|
-
orientation: screen
|
|
1179
|
-
pixelDepth: screen
|
|
1258
|
+
width: screen == null ? void 0 : screen.width,
|
|
1259
|
+
height: screen == null ? void 0 : screen.height,
|
|
1260
|
+
availWidth: screen == null ? void 0 : screen.availWidth,
|
|
1261
|
+
availHeight: screen == null ? void 0 : screen.availHeight,
|
|
1262
|
+
orientation: ((_a = screen == null ? void 0 : screen.orientation) == null ? void 0 : _a.type) || "",
|
|
1263
|
+
pixelDepth: screen == null ? void 0 : screen.pixelDepth
|
|
1180
1264
|
};
|
|
1181
1265
|
let deviceType = "desktop";
|
|
1182
1266
|
let brand = "Unknown";
|
|
@@ -1273,10 +1357,10 @@ function getClientInfo() {
|
|
|
1273
1357
|
if (vendor.includes("Samsung") || ua.includes("SM-")) brand = "Samsung";
|
|
1274
1358
|
}
|
|
1275
1359
|
isWebView = /wv|WebView|Linux; U;/.test(ua);
|
|
1276
|
-
if (window
|
|
1360
|
+
if ((window == null ? void 0 : window.outerHeight) === 0 && (window == null ? void 0 : window.outerWidth) === 0) {
|
|
1277
1361
|
isWebView = true;
|
|
1278
1362
|
}
|
|
1279
|
-
isWebApp = window.matchMedia("(display-mode: standalone)").matches || window.navigator.standalone === true || window.screen
|
|
1363
|
+
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;
|
|
1280
1364
|
return {
|
|
1281
1365
|
brand,
|
|
1282
1366
|
os,
|
|
@@ -1297,7 +1381,7 @@ function getClientInfo() {
|
|
|
1297
1381
|
deviceMemory: memory,
|
|
1298
1382
|
maxTouchPoints,
|
|
1299
1383
|
language: navigator.language,
|
|
1300
|
-
languages: navigator.languages
|
|
1384
|
+
languages: ((_d = navigator.languages) == null ? void 0 : _d.join(",")) || "",
|
|
1301
1385
|
cookieEnabled: navigator.cookieEnabled,
|
|
1302
1386
|
doNotTrack: navigator.doNotTrack || "",
|
|
1303
1387
|
referrer: document.referrer,
|
|
@@ -1655,7 +1739,8 @@ var StormcloudVideoPlayer = class {
|
|
|
1655
1739
|
}
|
|
1656
1740
|
return createHlsAdPlayer(this.video, {
|
|
1657
1741
|
continueLiveStreamDuringAds,
|
|
1658
|
-
...this.config.licenseKey ? { licenseKey: this.config.licenseKey } : {}
|
|
1742
|
+
...this.config.licenseKey ? { licenseKey: this.config.licenseKey } : {},
|
|
1743
|
+
...this.hls ? { mainHlsInstance: this.hls } : {}
|
|
1659
1744
|
});
|
|
1660
1745
|
} else {
|
|
1661
1746
|
if (this.config.debugAdTiming) {
|
|
@@ -1667,6 +1752,7 @@ var StormcloudVideoPlayer = class {
|
|
|
1667
1752
|
}
|
|
1668
1753
|
}
|
|
1669
1754
|
async load() {
|
|
1755
|
+
var _a, _b;
|
|
1670
1756
|
if (!this.attached) {
|
|
1671
1757
|
this.attach();
|
|
1672
1758
|
}
|
|
@@ -1683,7 +1769,7 @@ var StormcloudVideoPlayer = class {
|
|
|
1683
1769
|
this.initializeTracking();
|
|
1684
1770
|
if (this.shouldUseNativeHls()) {
|
|
1685
1771
|
this.video.src = this.config.src;
|
|
1686
|
-
this.isLiveStream = this.config.lowLatencyMode
|
|
1772
|
+
this.isLiveStream = (_a = this.config.lowLatencyMode) != null ? _a : false;
|
|
1687
1773
|
if (this.config.debugAdTiming) {
|
|
1688
1774
|
console.log(
|
|
1689
1775
|
"[StormcloudVideoPlayer] allowNativeHls: true - VOD mode detected:",
|
|
@@ -1698,8 +1784,8 @@ var StormcloudVideoPlayer = class {
|
|
|
1698
1784
|
this.ima = this.createAdPlayer(false);
|
|
1699
1785
|
this.ima.initialize();
|
|
1700
1786
|
if (this.config.autoplay) {
|
|
1701
|
-
await this.video.play()
|
|
1702
|
-
});
|
|
1787
|
+
await ((_b = this.video.play()) == null ? void 0 : _b.catch(() => {
|
|
1788
|
+
}));
|
|
1703
1789
|
}
|
|
1704
1790
|
return;
|
|
1705
1791
|
}
|
|
@@ -1712,12 +1798,17 @@ var StormcloudVideoPlayer = class {
|
|
|
1712
1798
|
...this.config.lowLatencyMode ? { liveSyncDuration: 2 } : {}
|
|
1713
1799
|
});
|
|
1714
1800
|
this.hls.on(Hls2.Events.MEDIA_ATTACHED, () => {
|
|
1715
|
-
|
|
1801
|
+
var _a2;
|
|
1802
|
+
(_a2 = this.hls) == null ? void 0 : _a2.loadSource(this.config.src);
|
|
1716
1803
|
});
|
|
1717
1804
|
this.hls.on(Hls2.Events.MANIFEST_PARSED, async (_, data) => {
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1805
|
+
var _a2, _b2, _c, _d;
|
|
1806
|
+
this.isLiveStream = (_c = (_b2 = (_a2 = this.hls) == null ? void 0 : _a2.levels) == null ? void 0 : _b2.some(
|
|
1807
|
+
(level) => {
|
|
1808
|
+
var _a3, _b3;
|
|
1809
|
+
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";
|
|
1810
|
+
}
|
|
1811
|
+
)) != null ? _c : false;
|
|
1721
1812
|
if (this.config.debugAdTiming) {
|
|
1722
1813
|
const adBehavior = this.shouldContinueLiveStreamDuringAds() ? "live (main video continues muted during ads)" : "vod (main video pauses during ads)";
|
|
1723
1814
|
console.log("[StormcloudVideoPlayer] Stream type detected:", {
|
|
@@ -1730,28 +1821,29 @@ var StormcloudVideoPlayer = class {
|
|
|
1730
1821
|
this.ima = this.createAdPlayer(this.shouldContinueLiveStreamDuringAds());
|
|
1731
1822
|
this.ima.initialize();
|
|
1732
1823
|
if (this.config.autoplay) {
|
|
1733
|
-
await this.video.play()
|
|
1734
|
-
});
|
|
1824
|
+
await ((_d = this.video.play()) == null ? void 0 : _d.catch(() => {
|
|
1825
|
+
}));
|
|
1735
1826
|
}
|
|
1736
1827
|
});
|
|
1737
1828
|
this.hls.on(Hls2.Events.FRAG_PARSING_METADATA, (_evt, data) => {
|
|
1738
|
-
const id3Tags = (data
|
|
1829
|
+
const id3Tags = ((data == null ? void 0 : data.samples) || []).map((s) => ({
|
|
1739
1830
|
key: "ID3",
|
|
1740
|
-
value: s
|
|
1741
|
-
ptsSeconds: s
|
|
1831
|
+
value: s == null ? void 0 : s.data,
|
|
1832
|
+
ptsSeconds: s == null ? void 0 : s.pts
|
|
1742
1833
|
}));
|
|
1743
1834
|
id3Tags.forEach((tag) => this.onId3Tag(tag));
|
|
1744
1835
|
});
|
|
1745
1836
|
this.hls.on(Hls2.Events.FRAG_CHANGED, (_evt, data) => {
|
|
1746
|
-
|
|
1747
|
-
const
|
|
1837
|
+
var _a2, _b2, _c;
|
|
1838
|
+
const frag = data == null ? void 0 : data.frag;
|
|
1839
|
+
const tagList = frag == null ? void 0 : frag.tagList;
|
|
1748
1840
|
if (!Array.isArray(tagList)) return;
|
|
1749
1841
|
for (const entry of tagList) {
|
|
1750
1842
|
let tag = "";
|
|
1751
1843
|
let value = "";
|
|
1752
1844
|
if (Array.isArray(entry)) {
|
|
1753
|
-
tag = String(entry[0]
|
|
1754
|
-
value = String(entry[1]
|
|
1845
|
+
tag = String((_a2 = entry[0]) != null ? _a2 : "");
|
|
1846
|
+
value = String((_b2 = entry[1]) != null ? _b2 : "");
|
|
1755
1847
|
} else if (typeof entry === "string") {
|
|
1756
1848
|
const idx = entry.indexOf(":");
|
|
1757
1849
|
if (idx >= 0) {
|
|
@@ -1775,8 +1867,8 @@ var StormcloudVideoPlayer = class {
|
|
|
1775
1867
|
const prog = this.parseCueOutCont(value);
|
|
1776
1868
|
const marker = {
|
|
1777
1869
|
type: "progress",
|
|
1778
|
-
...prog
|
|
1779
|
-
...prog
|
|
1870
|
+
...(prog == null ? void 0 : prog.duration) !== void 0 ? { durationSeconds: prog.duration } : {},
|
|
1871
|
+
...(prog == null ? void 0 : prog.elapsed) !== void 0 ? { ptsSeconds: prog.elapsed } : {},
|
|
1780
1872
|
raw: { tag, value }
|
|
1781
1873
|
};
|
|
1782
1874
|
this.onScte35Marker(marker);
|
|
@@ -1786,7 +1878,7 @@ var StormcloudVideoPlayer = class {
|
|
|
1786
1878
|
const attrs = this.parseAttributeList(value);
|
|
1787
1879
|
const hasScteOut = "SCTE35-OUT" in attrs || attrs["SCTE35-OUT"] !== void 0;
|
|
1788
1880
|
const hasScteIn = "SCTE35-IN" in attrs || attrs["SCTE35-IN"] !== void 0;
|
|
1789
|
-
const klass = String(attrs["CLASS"]
|
|
1881
|
+
const klass = String((_c = attrs["CLASS"]) != null ? _c : "");
|
|
1790
1882
|
const duration = this.toNumber(attrs["DURATION"]);
|
|
1791
1883
|
if (hasScteOut || /com\.apple\.hls\.cue/i.test(klass)) {
|
|
1792
1884
|
const marker = {
|
|
@@ -1803,13 +1895,14 @@ var StormcloudVideoPlayer = class {
|
|
|
1803
1895
|
}
|
|
1804
1896
|
});
|
|
1805
1897
|
this.hls.on(Hls2.Events.ERROR, (_evt, data) => {
|
|
1806
|
-
|
|
1898
|
+
var _a2, _b2;
|
|
1899
|
+
if (data == null ? void 0 : data.fatal) {
|
|
1807
1900
|
switch (data.type) {
|
|
1808
1901
|
case Hls2.ErrorTypes.NETWORK_ERROR:
|
|
1809
|
-
this.hls
|
|
1902
|
+
(_a2 = this.hls) == null ? void 0 : _a2.startLoad();
|
|
1810
1903
|
break;
|
|
1811
1904
|
case Hls2.ErrorTypes.MEDIA_ERROR:
|
|
1812
|
-
this.hls
|
|
1905
|
+
(_b2 = this.hls) == null ? void 0 : _b2.recoverMediaError();
|
|
1813
1906
|
break;
|
|
1814
1907
|
default:
|
|
1815
1908
|
this.destroy();
|
|
@@ -1911,11 +2004,12 @@ var StormcloudVideoPlayer = class {
|
|
|
1911
2004
|
}
|
|
1912
2005
|
}
|
|
1913
2006
|
parseScte35FromId3(tag) {
|
|
2007
|
+
var _a, _b, _c, _d;
|
|
1914
2008
|
const text = this.decodeId3ValueToText(tag.value);
|
|
1915
2009
|
if (!text) return void 0;
|
|
1916
2010
|
const cueOutMatch = text.match(/EXT-X-CUE-OUT(?::([^\r\n]*))?/i) || text.match(/CUE-OUT(?::([^\r\n]*))?/i);
|
|
1917
2011
|
if (cueOutMatch) {
|
|
1918
|
-
const arg = (cueOutMatch[1]
|
|
2012
|
+
const arg = ((_a = cueOutMatch[1]) != null ? _a : "").trim();
|
|
1919
2013
|
const dur = this.parseCueOutDuration(arg);
|
|
1920
2014
|
const marker = {
|
|
1921
2015
|
type: "start",
|
|
@@ -1927,12 +2021,12 @@ var StormcloudVideoPlayer = class {
|
|
|
1927
2021
|
}
|
|
1928
2022
|
const cueOutContMatch = text.match(/EXT-X-CUE-OUT-CONT:([^\r\n]*)/i);
|
|
1929
2023
|
if (cueOutContMatch) {
|
|
1930
|
-
const arg = (cueOutContMatch[1]
|
|
2024
|
+
const arg = ((_b = cueOutContMatch[1]) != null ? _b : "").trim();
|
|
1931
2025
|
const cont = this.parseCueOutCont(arg);
|
|
1932
2026
|
const marker = {
|
|
1933
2027
|
type: "progress",
|
|
1934
2028
|
...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},
|
|
1935
|
-
...cont
|
|
2029
|
+
...(cont == null ? void 0 : cont.duration) !== void 0 ? { durationSeconds: cont.duration } : {},
|
|
1936
2030
|
raw: { id3: text }
|
|
1937
2031
|
};
|
|
1938
2032
|
return marker;
|
|
@@ -1948,10 +2042,10 @@ var StormcloudVideoPlayer = class {
|
|
|
1948
2042
|
}
|
|
1949
2043
|
const daterangeMatch = text.match(/EXT-X-DATERANGE:([^\r\n]*)/i);
|
|
1950
2044
|
if (daterangeMatch) {
|
|
1951
|
-
const attrs = this.parseAttributeList(daterangeMatch[1]
|
|
2045
|
+
const attrs = this.parseAttributeList((_c = daterangeMatch[1]) != null ? _c : "");
|
|
1952
2046
|
const hasScteOut = "SCTE35-OUT" in attrs || attrs["SCTE35-OUT"] !== void 0;
|
|
1953
2047
|
const hasScteIn = "SCTE35-IN" in attrs || attrs["SCTE35-IN"] !== void 0;
|
|
1954
|
-
const klass = String(attrs["CLASS"]
|
|
2048
|
+
const klass = String((_d = attrs["CLASS"]) != null ? _d : "");
|
|
1955
2049
|
const duration = this.toNumber(attrs["DURATION"]);
|
|
1956
2050
|
if (hasScteOut || /com\.apple\.hls\.cue/i.test(klass)) {
|
|
1957
2051
|
const marker = {
|
|
@@ -2008,6 +2102,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2008
2102
|
}
|
|
2009
2103
|
}
|
|
2010
2104
|
onScte35Marker(marker) {
|
|
2105
|
+
var _a, _b;
|
|
2011
2106
|
if (this.config.debugAdTiming) {
|
|
2012
2107
|
console.log("[StormcloudVideoPlayer] SCTE-35 marker detected:", {
|
|
2013
2108
|
type: marker.type,
|
|
@@ -2023,7 +2118,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2023
2118
|
this.expectedAdBreakDurationMs = durationMs;
|
|
2024
2119
|
this.currentAdBreakStartWallClockMs = Date.now();
|
|
2025
2120
|
const isManifestMarker = this.isManifestBasedMarker(marker);
|
|
2026
|
-
const forceImmediate = this.config.immediateManifestAds
|
|
2121
|
+
const forceImmediate = (_a = this.config.immediateManifestAds) != null ? _a : true;
|
|
2027
2122
|
if (this.config.debugAdTiming) {
|
|
2028
2123
|
console.log("[StormcloudVideoPlayer] Ad start decision:", {
|
|
2029
2124
|
isManifestMarker,
|
|
@@ -2040,7 +2135,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2040
2135
|
this.clearAdStartTimer();
|
|
2041
2136
|
this.handleAdStart(marker);
|
|
2042
2137
|
} else if (typeof marker.ptsSeconds === "number") {
|
|
2043
|
-
const tol = this.config.driftToleranceMs
|
|
2138
|
+
const tol = (_b = this.config.driftToleranceMs) != null ? _b : 1e3;
|
|
2044
2139
|
const nowMs = this.video.currentTime * 1e3;
|
|
2045
2140
|
const estCurrentPtsMs = nowMs - this.ptsDriftEmaMs;
|
|
2046
2141
|
const deltaMs = Math.floor(marker.ptsSeconds * 1e3 - estCurrentPtsMs);
|
|
@@ -2150,12 +2245,13 @@ var StormcloudVideoPlayer = class {
|
|
|
2150
2245
|
return void 0;
|
|
2151
2246
|
}
|
|
2152
2247
|
parseAttributeList(value) {
|
|
2248
|
+
var _a, _b, _c;
|
|
2153
2249
|
const attrs = {};
|
|
2154
2250
|
const regex = /([A-Z0-9-]+)=(("[^"]*")|([^",]*))(?:,|$)/gi;
|
|
2155
2251
|
let match;
|
|
2156
2252
|
while ((match = regex.exec(value)) !== null) {
|
|
2157
|
-
const key = match[1]
|
|
2158
|
-
let rawVal = match[3]
|
|
2253
|
+
const key = (_a = match[1]) != null ? _a : "";
|
|
2254
|
+
let rawVal = (_c = (_b = match[3]) != null ? _b : match[4]) != null ? _c : "";
|
|
2159
2255
|
if (rawVal.startsWith('"') && rawVal.endsWith('"')) {
|
|
2160
2256
|
rawVal = rawVal.slice(1, -1);
|
|
2161
2257
|
}
|
|
@@ -2319,6 +2415,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2319
2415
|
}
|
|
2320
2416
|
}
|
|
2321
2417
|
async fetchAdConfiguration() {
|
|
2418
|
+
var _a, _b, _c;
|
|
2322
2419
|
const vastMode = this.config.vastMode || "default";
|
|
2323
2420
|
if (this.config.debugAdTiming) {
|
|
2324
2421
|
console.log(
|
|
@@ -2376,7 +2473,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2376
2473
|
return;
|
|
2377
2474
|
}
|
|
2378
2475
|
const data = await response.json();
|
|
2379
|
-
const imaPayload = data.response
|
|
2476
|
+
const imaPayload = (_c = (_b = (_a = data.response) == null ? void 0 : _a.ima) == null ? void 0 : _b["publisherdesk.ima"]) == null ? void 0 : _c.payload;
|
|
2380
2477
|
if (imaPayload) {
|
|
2381
2478
|
this.apiVastTagUrl = decodeURIComponent(imaPayload);
|
|
2382
2479
|
if (this.config.debugAdTiming) {
|
|
@@ -2413,11 +2510,12 @@ var StormcloudVideoPlayer = class {
|
|
|
2413
2510
|
return "other";
|
|
2414
2511
|
}
|
|
2415
2512
|
shouldShowNativeControls() {
|
|
2513
|
+
var _a, _b;
|
|
2416
2514
|
const streamType = this.getStreamType();
|
|
2417
2515
|
if (streamType === "other") {
|
|
2418
|
-
return !(this.config.showCustomControls
|
|
2516
|
+
return !((_a = this.config.showCustomControls) != null ? _a : false);
|
|
2419
2517
|
}
|
|
2420
|
-
return !!(this.config.allowNativeHls && !(this.config.showCustomControls
|
|
2518
|
+
return !!(this.config.allowNativeHls && !((_b = this.config.showCustomControls) != null ? _b : false));
|
|
2421
2519
|
}
|
|
2422
2520
|
shouldContinueLiveStreamDuringAds() {
|
|
2423
2521
|
if (this.config.allowNativeHls) {
|
|
@@ -2429,6 +2527,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2429
2527
|
return true;
|
|
2430
2528
|
}
|
|
2431
2529
|
async handleAdStart(_marker) {
|
|
2530
|
+
var _a;
|
|
2432
2531
|
const scheduled = this.findCurrentOrNextBreak(
|
|
2433
2532
|
this.video.currentTime * 1e3
|
|
2434
2533
|
);
|
|
@@ -2479,17 +2578,18 @@ var StormcloudVideoPlayer = class {
|
|
|
2479
2578
|
this.handleAdFailure();
|
|
2480
2579
|
}
|
|
2481
2580
|
}
|
|
2482
|
-
if (this.expectedAdBreakDurationMs == null && scheduled
|
|
2581
|
+
if (this.expectedAdBreakDurationMs == null && (scheduled == null ? void 0 : scheduled.durationMs) != null) {
|
|
2483
2582
|
this.expectedAdBreakDurationMs = scheduled.durationMs;
|
|
2484
|
-
this.currentAdBreakStartWallClockMs = this.currentAdBreakStartWallClockMs
|
|
2583
|
+
this.currentAdBreakStartWallClockMs = (_a = this.currentAdBreakStartWallClockMs) != null ? _a : Date.now();
|
|
2485
2584
|
this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);
|
|
2486
2585
|
}
|
|
2487
2586
|
}
|
|
2488
2587
|
findCurrentOrNextBreak(nowMs) {
|
|
2588
|
+
var _a;
|
|
2489
2589
|
const schedule = [];
|
|
2490
2590
|
let candidate;
|
|
2491
2591
|
for (const b of schedule) {
|
|
2492
|
-
const tol = this.config.driftToleranceMs
|
|
2592
|
+
const tol = (_a = this.config.driftToleranceMs) != null ? _a : 1e3;
|
|
2493
2593
|
if (b.startTimeMs <= nowMs + tol && (candidate == null || b.startTimeMs > (candidate.startTimeMs || 0))) {
|
|
2494
2594
|
candidate = b;
|
|
2495
2595
|
}
|
|
@@ -2505,7 +2605,8 @@ var StormcloudVideoPlayer = class {
|
|
|
2505
2605
|
}
|
|
2506
2606
|
}
|
|
2507
2607
|
async handleMidAdJoin(adBreak, nowMs) {
|
|
2508
|
-
|
|
2608
|
+
var _a;
|
|
2609
|
+
const durationMs = (_a = adBreak.durationMs) != null ? _a : 0;
|
|
2509
2610
|
const endMs = adBreak.startTimeMs + durationMs;
|
|
2510
2611
|
if (durationMs > 0 && nowMs > adBreak.startTimeMs && nowMs < endMs) {
|
|
2511
2612
|
const remainingMs = endMs - nowMs;
|
|
@@ -2606,6 +2707,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2606
2707
|
}
|
|
2607
2708
|
}
|
|
2608
2709
|
handleAdFailure() {
|
|
2710
|
+
var _a;
|
|
2609
2711
|
if (this.config.debugAdTiming) {
|
|
2610
2712
|
console.log(
|
|
2611
2713
|
"[StormcloudVideoPlayer] Handling ad failure - resuming content",
|
|
@@ -2638,7 +2740,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2638
2740
|
if (this.config.debugAdTiming) {
|
|
2639
2741
|
console.log("[StormcloudVideoPlayer] Resuming paused video");
|
|
2640
2742
|
}
|
|
2641
|
-
this.video.play()
|
|
2743
|
+
(_a = this.video.play()) == null ? void 0 : _a.catch((error) => {
|
|
2642
2744
|
if (this.config.debugAdTiming) {
|
|
2643
2745
|
console.error(
|
|
2644
2746
|
"[StormcloudVideoPlayer] Failed to resume video after ad failure:",
|
|
@@ -2653,8 +2755,9 @@ var StormcloudVideoPlayer = class {
|
|
|
2653
2755
|
}
|
|
2654
2756
|
}
|
|
2655
2757
|
startAdFailsafeTimer() {
|
|
2758
|
+
var _a;
|
|
2656
2759
|
this.clearAdFailsafeTimer();
|
|
2657
|
-
const failsafeMs = this.config.adFailsafeTimeoutMs
|
|
2760
|
+
const failsafeMs = (_a = this.config.adFailsafeTimeoutMs) != null ? _a : 1e4;
|
|
2658
2761
|
if (this.config.debugAdTiming) {
|
|
2659
2762
|
console.log(
|
|
2660
2763
|
`[StormcloudVideoPlayer] Starting failsafe timer (${failsafeMs}ms)`
|
|
@@ -2790,6 +2893,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2790
2893
|
}
|
|
2791
2894
|
}
|
|
2792
2895
|
destroy() {
|
|
2896
|
+
var _a, _b;
|
|
2793
2897
|
this.clearAdStartTimer();
|
|
2794
2898
|
this.clearAdStopTimer();
|
|
2795
2899
|
this.clearAdFailsafeTimer();
|
|
@@ -2797,8 +2901,8 @@ var StormcloudVideoPlayer = class {
|
|
|
2797
2901
|
clearInterval(this.heartbeatInterval);
|
|
2798
2902
|
this.heartbeatInterval = void 0;
|
|
2799
2903
|
}
|
|
2800
|
-
this.hls
|
|
2801
|
-
this.ima
|
|
2904
|
+
(_a = this.hls) == null ? void 0 : _a.destroy();
|
|
2905
|
+
(_b = this.ima) == null ? void 0 : _b.destroy();
|
|
2802
2906
|
}
|
|
2803
2907
|
};
|
|
2804
2908
|
|
|
@@ -2914,7 +3018,7 @@ var StormcloudVideoPlayerComponent = React.memo(
|
|
|
2914
3018
|
}
|
|
2915
3019
|
setShowSpeedMenu(false);
|
|
2916
3020
|
};
|
|
2917
|
-
const isHlsStream = src
|
|
3021
|
+
const isHlsStream = (src == null ? void 0 : src.toLowerCase().includes(".m3u8")) || (src == null ? void 0 : src.toLowerCase().includes("/hls/"));
|
|
2918
3022
|
const shouldShowEnhancedControls = showCustomControls && (isHlsStream ? allowNativeHls : true);
|
|
2919
3023
|
const criticalPropsKey = useMemo(() => {
|
|
2920
3024
|
return CRITICAL_PROPS.map((prop) => `${prop}:${props[prop]}`).join("|");
|
|
@@ -2964,13 +3068,13 @@ var StormcloudVideoPlayerComponent = React.memo(
|
|
|
2964
3068
|
player.load().then(() => {
|
|
2965
3069
|
const showNative = player.shouldShowNativeControls();
|
|
2966
3070
|
setShouldShowNativeControls(showNative);
|
|
2967
|
-
onReady
|
|
3071
|
+
onReady == null ? void 0 : onReady(player);
|
|
2968
3072
|
}).catch((error) => {
|
|
2969
3073
|
console.error(
|
|
2970
3074
|
"StormcloudVideoPlayer: Failed to load player:",
|
|
2971
3075
|
error
|
|
2972
3076
|
);
|
|
2973
|
-
onReady
|
|
3077
|
+
onReady == null ? void 0 : onReady(player);
|
|
2974
3078
|
});
|
|
2975
3079
|
return () => {
|
|
2976
3080
|
try {
|
|
@@ -3026,6 +3130,7 @@ var StormcloudVideoPlayerComponent = React.memo(
|
|
|
3026
3130
|
useEffect(() => {
|
|
3027
3131
|
if (!playerRef.current || !videoRef.current) return;
|
|
3028
3132
|
const updateStates = () => {
|
|
3133
|
+
var _a;
|
|
3029
3134
|
if (playerRef.current && videoRef.current) {
|
|
3030
3135
|
setIsMuted(playerRef.current.isMuted());
|
|
3031
3136
|
setIsPlaying(!videoRef.current.paused);
|
|
@@ -3043,13 +3148,14 @@ var StormcloudVideoPlayerComponent = React.memo(
|
|
|
3043
3148
|
);
|
|
3044
3149
|
}
|
|
3045
3150
|
setIsFullscreen(
|
|
3046
|
-
document.fullscreenElement === videoRef.current
|
|
3151
|
+
document.fullscreenElement === ((_a = videoRef.current) == null ? void 0 : _a.parentElement)
|
|
3047
3152
|
);
|
|
3048
3153
|
};
|
|
3049
3154
|
const interval = setInterval(updateStates, 200);
|
|
3050
3155
|
const handleFullscreenChange = () => {
|
|
3156
|
+
var _a;
|
|
3051
3157
|
setIsFullscreen(
|
|
3052
|
-
document.fullscreenElement === videoRef.current
|
|
3158
|
+
document.fullscreenElement === ((_a = videoRef.current) == null ? void 0 : _a.parentElement)
|
|
3053
3159
|
);
|
|
3054
3160
|
};
|
|
3055
3161
|
document.addEventListener("fullscreenchange", handleFullscreenChange);
|
|
@@ -4492,6 +4598,7 @@ var HlsPlayer = class extends Component {
|
|
|
4492
4598
|
this.player = null;
|
|
4493
4599
|
this.mounted = false;
|
|
4494
4600
|
this.load = async () => {
|
|
4601
|
+
var _a, _b, _c, _d, _e, _f;
|
|
4495
4602
|
if (!this.props.videoElement || !this.props.src) return;
|
|
4496
4603
|
try {
|
|
4497
4604
|
if (this.player) {
|
|
@@ -4528,27 +4635,29 @@ var HlsPlayer = class extends Component {
|
|
|
4528
4635
|
if (this.props.adFailsafeTimeoutMs !== void 0)
|
|
4529
4636
|
config.adFailsafeTimeoutMs = this.props.adFailsafeTimeoutMs;
|
|
4530
4637
|
this.player = new StormcloudVideoPlayer(config);
|
|
4531
|
-
this.props.onMount
|
|
4638
|
+
(_b = (_a = this.props).onMount) == null ? void 0 : _b.call(_a, this);
|
|
4532
4639
|
await this.player.load();
|
|
4533
4640
|
if (this.mounted) {
|
|
4534
|
-
this.props.onReady
|
|
4641
|
+
(_d = (_c = this.props).onReady) == null ? void 0 : _d.call(_c);
|
|
4535
4642
|
}
|
|
4536
4643
|
} catch (error) {
|
|
4537
4644
|
if (this.mounted) {
|
|
4538
|
-
this.props.onError
|
|
4645
|
+
(_f = (_e = this.props).onError) == null ? void 0 : _f.call(_e, error);
|
|
4539
4646
|
}
|
|
4540
4647
|
}
|
|
4541
4648
|
};
|
|
4542
4649
|
this.play = () => {
|
|
4650
|
+
var _a, _b;
|
|
4543
4651
|
if (this.props.videoElement) {
|
|
4544
4652
|
this.props.videoElement.play();
|
|
4545
|
-
this.props.onPlay
|
|
4653
|
+
(_b = (_a = this.props).onPlay) == null ? void 0 : _b.call(_a);
|
|
4546
4654
|
}
|
|
4547
4655
|
};
|
|
4548
4656
|
this.pause = () => {
|
|
4657
|
+
var _a, _b;
|
|
4549
4658
|
if (this.props.videoElement) {
|
|
4550
4659
|
this.props.videoElement.pause();
|
|
4551
|
-
this.props.onPause
|
|
4660
|
+
(_b = (_a = this.props).onPause) == null ? void 0 : _b.call(_a);
|
|
4552
4661
|
}
|
|
4553
4662
|
};
|
|
4554
4663
|
this.stop = () => {
|
|
@@ -4643,37 +4752,44 @@ var FilePlayer = class extends Component2 {
|
|
|
4643
4752
|
this.mounted = false;
|
|
4644
4753
|
this.ready = false;
|
|
4645
4754
|
this.load = () => {
|
|
4755
|
+
var _a, _b;
|
|
4646
4756
|
if (!this.props.videoElement || !this.props.src) return;
|
|
4647
4757
|
const video = this.props.videoElement;
|
|
4648
4758
|
const handleLoadedMetadata = () => {
|
|
4759
|
+
var _a2, _b2;
|
|
4649
4760
|
if (this.mounted && !this.ready) {
|
|
4650
4761
|
this.ready = true;
|
|
4651
|
-
this.props.onReady
|
|
4762
|
+
(_b2 = (_a2 = this.props).onReady) == null ? void 0 : _b2.call(_a2);
|
|
4652
4763
|
}
|
|
4653
4764
|
};
|
|
4654
4765
|
const handlePlay = () => {
|
|
4766
|
+
var _a2, _b2;
|
|
4655
4767
|
if (this.mounted) {
|
|
4656
|
-
this.props.onPlay
|
|
4768
|
+
(_b2 = (_a2 = this.props).onPlay) == null ? void 0 : _b2.call(_a2);
|
|
4657
4769
|
}
|
|
4658
4770
|
};
|
|
4659
4771
|
const handlePause = () => {
|
|
4772
|
+
var _a2, _b2;
|
|
4660
4773
|
if (this.mounted) {
|
|
4661
|
-
this.props.onPause
|
|
4774
|
+
(_b2 = (_a2 = this.props).onPause) == null ? void 0 : _b2.call(_a2);
|
|
4662
4775
|
}
|
|
4663
4776
|
};
|
|
4664
4777
|
const handleEnded = () => {
|
|
4778
|
+
var _a2, _b2;
|
|
4665
4779
|
if (this.mounted) {
|
|
4666
|
-
this.props.onEnded
|
|
4780
|
+
(_b2 = (_a2 = this.props).onEnded) == null ? void 0 : _b2.call(_a2);
|
|
4667
4781
|
}
|
|
4668
4782
|
};
|
|
4669
4783
|
const handleError = (error) => {
|
|
4784
|
+
var _a2, _b2;
|
|
4670
4785
|
if (this.mounted) {
|
|
4671
|
-
this.props.onError
|
|
4786
|
+
(_b2 = (_a2 = this.props).onError) == null ? void 0 : _b2.call(_a2, error);
|
|
4672
4787
|
}
|
|
4673
4788
|
};
|
|
4674
4789
|
const handleLoadedData = () => {
|
|
4790
|
+
var _a2, _b2;
|
|
4675
4791
|
if (this.mounted) {
|
|
4676
|
-
this.props.onLoaded
|
|
4792
|
+
(_b2 = (_a2 = this.props).onLoaded) == null ? void 0 : _b2.call(_a2);
|
|
4677
4793
|
}
|
|
4678
4794
|
};
|
|
4679
4795
|
video.addEventListener("loadedmetadata", handleLoadedMetadata);
|
|
@@ -4692,7 +4808,7 @@ var FilePlayer = class extends Component2 {
|
|
|
4692
4808
|
if (this.props.preload !== void 0)
|
|
4693
4809
|
video.preload = this.props.preload;
|
|
4694
4810
|
if (this.props.poster !== void 0) video.poster = this.props.poster;
|
|
4695
|
-
this.props.onMount
|
|
4811
|
+
(_b = (_a = this.props).onMount) == null ? void 0 : _b.call(_a, this);
|
|
4696
4812
|
return () => {
|
|
4697
4813
|
video.removeEventListener("loadedmetadata", handleLoadedMetadata);
|
|
4698
4814
|
video.removeEventListener("play", handlePlay);
|
|
@@ -4861,6 +4977,7 @@ var Player = class extends Component3 {
|
|
|
4861
4977
|
return this.player.getInternalPlayer(key);
|
|
4862
4978
|
};
|
|
4863
4979
|
this.progress = () => {
|
|
4980
|
+
var _a, _b;
|
|
4864
4981
|
if (this.props.src && this.player && this.isReady) {
|
|
4865
4982
|
const playedSeconds = this.getCurrentTime() || 0;
|
|
4866
4983
|
const loadedSeconds = this.getSecondsLoaded();
|
|
@@ -4877,7 +4994,7 @@ var Player = class extends Component3 {
|
|
|
4877
4994
|
progress.loaded = loadedSeconds / duration;
|
|
4878
4995
|
}
|
|
4879
4996
|
if (progress.playedSeconds !== this.prevPlayed || progress.loadedSeconds !== this.prevLoaded) {
|
|
4880
|
-
this.props.onProgress
|
|
4997
|
+
(_b = (_a = this.props).onProgress) == null ? void 0 : _b.call(_a, progress);
|
|
4881
4998
|
}
|
|
4882
4999
|
this.prevPlayed = progress.playedSeconds;
|
|
4883
5000
|
this.prevLoaded = progress.loadedSeconds;
|
|
@@ -4913,10 +5030,10 @@ var Player = class extends Component3 {
|
|
|
4913
5030
|
if (this.player.setPlaybackRate && playbackRate !== 1) {
|
|
4914
5031
|
this.player.setPlaybackRate(playbackRate);
|
|
4915
5032
|
}
|
|
4916
|
-
onStart
|
|
5033
|
+
onStart == null ? void 0 : onStart();
|
|
4917
5034
|
this.startOnPlay = false;
|
|
4918
5035
|
}
|
|
4919
|
-
onPlay
|
|
5036
|
+
onPlay == null ? void 0 : onPlay();
|
|
4920
5037
|
if (this.seekOnPlay) {
|
|
4921
5038
|
this.seekTo(this.seekOnPlay);
|
|
4922
5039
|
this.seekOnPlay = null;
|
|
@@ -4924,9 +5041,10 @@ var Player = class extends Component3 {
|
|
|
4924
5041
|
this.handleDurationCheck();
|
|
4925
5042
|
};
|
|
4926
5043
|
this.handlePause = (e) => {
|
|
5044
|
+
var _a, _b;
|
|
4927
5045
|
this.isPlaying = false;
|
|
4928
5046
|
if (!this.isLoading) {
|
|
4929
|
-
this.props.onPause
|
|
5047
|
+
(_b = (_a = this.props).onPause) == null ? void 0 : _b.call(_a, e);
|
|
4930
5048
|
}
|
|
4931
5049
|
};
|
|
4932
5050
|
this.handleEnded = () => {
|
|
@@ -4936,19 +5054,21 @@ var Player = class extends Component3 {
|
|
|
4936
5054
|
}
|
|
4937
5055
|
if (!loop) {
|
|
4938
5056
|
this.isPlaying = false;
|
|
4939
|
-
onEnded
|
|
5057
|
+
onEnded == null ? void 0 : onEnded();
|
|
4940
5058
|
}
|
|
4941
5059
|
};
|
|
4942
5060
|
this.handleError = (...args) => {
|
|
5061
|
+
var _a, _b;
|
|
4943
5062
|
this.isLoading = false;
|
|
4944
|
-
this.props.onError
|
|
5063
|
+
(_b = (_a = this.props).onError) == null ? void 0 : _b.call(_a, args[0], args[1], args[2], args[3]);
|
|
4945
5064
|
};
|
|
4946
5065
|
this.handleDurationCheck = () => {
|
|
5066
|
+
var _a, _b;
|
|
4947
5067
|
clearTimeout(this.durationCheckTimeout);
|
|
4948
5068
|
const duration = this.getDuration();
|
|
4949
5069
|
if (duration) {
|
|
4950
5070
|
if (!this.onDurationCalled) {
|
|
4951
|
-
this.props.onDuration
|
|
5071
|
+
(_b = (_a = this.props).onDuration) == null ? void 0 : _b.call(_a, duration);
|
|
4952
5072
|
this.onDurationCalled = true;
|
|
4953
5073
|
}
|
|
4954
5074
|
} else {
|
|
@@ -5147,7 +5267,8 @@ var createStormcloudPlayer = (playerList, fallback) => {
|
|
|
5147
5267
|
return omit(this.props, SUPPORTED_PROPS);
|
|
5148
5268
|
};
|
|
5149
5269
|
this.handleReady = () => {
|
|
5150
|
-
|
|
5270
|
+
var _a2, _b;
|
|
5271
|
+
(_b = (_a2 = this.props).onReady) == null ? void 0 : _b.call(_a2, this);
|
|
5151
5272
|
};
|
|
5152
5273
|
this.seekTo = (fraction, type, keepPlaying) => {
|
|
5153
5274
|
if (!this.player) return null;
|