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
|
@@ -48,7 +48,8 @@ function getWebKitVersion(ua) {
|
|
|
48
48
|
return match && match[1] ? parseInt(match[1], 10) : 0;
|
|
49
49
|
}
|
|
50
50
|
function getPlatform() {
|
|
51
|
-
|
|
51
|
+
var _a;
|
|
52
|
+
if ("userAgentData" in navigator && ((_a = navigator.userAgentData) == null ? void 0 : _a.platform)) {
|
|
52
53
|
return navigator.userAgentData.platform;
|
|
53
54
|
}
|
|
54
55
|
const ua = navigator.userAgent;
|
|
@@ -213,6 +214,7 @@ function createImaController(video, options) {
|
|
|
213
214
|
}
|
|
214
215
|
}
|
|
215
216
|
function ensureImaLoaded() {
|
|
217
|
+
var _a, _b, _c;
|
|
216
218
|
if (!supportsGoogleIMA()) {
|
|
217
219
|
console.warn(
|
|
218
220
|
"[IMA] Google IMA SDK is not supported on this browser. Please use HLS ad player instead."
|
|
@@ -223,7 +225,7 @@ function createImaController(video, options) {
|
|
|
223
225
|
}
|
|
224
226
|
try {
|
|
225
227
|
const frameEl = window.frameElement;
|
|
226
|
-
const sandboxAttr = frameEl
|
|
228
|
+
const sandboxAttr = ((_a = frameEl == null ? void 0 : frameEl.getAttribute) == null ? void 0 : _a.call(frameEl, "sandbox")) || "";
|
|
227
229
|
if (sandboxAttr) {
|
|
228
230
|
const tokens = new Set(
|
|
229
231
|
sandboxAttr.split(/\s+/).map((t) => t.trim()).filter((t) => t.length > 0)
|
|
@@ -237,13 +239,13 @@ function createImaController(video, options) {
|
|
|
237
239
|
}
|
|
238
240
|
} catch {
|
|
239
241
|
}
|
|
240
|
-
if (typeof window !== "undefined" && window.google
|
|
242
|
+
if (typeof window !== "undefined" && ((_b = window.google) == null ? void 0 : _b.ima))
|
|
241
243
|
return Promise.resolve();
|
|
242
244
|
const existing = document.querySelector(
|
|
243
245
|
'script[data-ima="true"]'
|
|
244
246
|
);
|
|
245
247
|
if (existing) {
|
|
246
|
-
if (window.google
|
|
248
|
+
if ((_c = window.google) == null ? void 0 : _c.ima) {
|
|
247
249
|
return Promise.resolve();
|
|
248
250
|
}
|
|
249
251
|
return new Promise((resolve, reject) => {
|
|
@@ -301,6 +303,7 @@ function createImaController(video, options) {
|
|
|
301
303
|
return {
|
|
302
304
|
initialize() {
|
|
303
305
|
ensureImaLoaded().then(() => {
|
|
306
|
+
var _a, _b;
|
|
304
307
|
const google = window.google;
|
|
305
308
|
if (!adDisplayContainer) {
|
|
306
309
|
const container = document.createElement("div");
|
|
@@ -314,14 +317,14 @@ function createImaController(video, options) {
|
|
|
314
317
|
container.style.justifyContent = "center";
|
|
315
318
|
container.style.pointerEvents = "none";
|
|
316
319
|
container.style.zIndex = "2";
|
|
317
|
-
video.parentElement
|
|
320
|
+
(_a = video.parentElement) == null ? void 0 : _a.appendChild(container);
|
|
318
321
|
adContainerEl = container;
|
|
319
322
|
adDisplayContainer = new google.ima.AdDisplayContainer(
|
|
320
323
|
container,
|
|
321
324
|
video
|
|
322
325
|
);
|
|
323
326
|
try {
|
|
324
|
-
adDisplayContainer.initialize
|
|
327
|
+
(_b = adDisplayContainer.initialize) == null ? void 0 : _b.call(adDisplayContainer);
|
|
325
328
|
} catch {
|
|
326
329
|
}
|
|
327
330
|
}
|
|
@@ -406,6 +409,7 @@ function createImaController(video, options) {
|
|
|
406
409
|
adsManager.addEventListener(
|
|
407
410
|
AdErrorEvent.AD_ERROR,
|
|
408
411
|
(errorEvent) => {
|
|
412
|
+
var _a;
|
|
409
413
|
console.error("[IMA] Ad error:", errorEvent.getError());
|
|
410
414
|
destroyAdsManager();
|
|
411
415
|
adPlaying = false;
|
|
@@ -436,10 +440,10 @@ function createImaController(video, options) {
|
|
|
436
440
|
"[IMA] Max retries reached, emitting ad_error"
|
|
437
441
|
);
|
|
438
442
|
emit("ad_error");
|
|
439
|
-
if (!options
|
|
443
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
440
444
|
if (video.paused) {
|
|
441
445
|
console.log("[IMA] Resuming paused video after ad error");
|
|
442
|
-
video.play()
|
|
446
|
+
(_a = video.play()) == null ? void 0 : _a.catch(() => {
|
|
443
447
|
});
|
|
444
448
|
}
|
|
445
449
|
}
|
|
@@ -450,7 +454,7 @@ function createImaController(video, options) {
|
|
|
450
454
|
AdEvent.CONTENT_PAUSE_REQUESTED,
|
|
451
455
|
() => {
|
|
452
456
|
console.log("[IMA] Content pause requested");
|
|
453
|
-
if (!options
|
|
457
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
454
458
|
video.pause();
|
|
455
459
|
console.log("[IMA] Video paused (VOD mode)");
|
|
456
460
|
} else {
|
|
@@ -476,6 +480,7 @@ function createImaController(video, options) {
|
|
|
476
480
|
adsManager.addEventListener(
|
|
477
481
|
AdEvent.CONTENT_RESUME_REQUESTED,
|
|
478
482
|
() => {
|
|
483
|
+
var _a;
|
|
479
484
|
console.log("[IMA] Content resume requested");
|
|
480
485
|
adPlaying = false;
|
|
481
486
|
video.muted = originalMutedState;
|
|
@@ -486,8 +491,8 @@ function createImaController(video, options) {
|
|
|
486
491
|
"[IMA] Ad container hidden - pointer events disabled"
|
|
487
492
|
);
|
|
488
493
|
}
|
|
489
|
-
if (!options
|
|
490
|
-
video.play()
|
|
494
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
495
|
+
(_a = video.play()) == null ? void 0 : _a.catch(() => {
|
|
491
496
|
});
|
|
492
497
|
console.log("[IMA] Video resumed (VOD mode)");
|
|
493
498
|
} else {
|
|
@@ -509,7 +514,7 @@ function createImaController(video, options) {
|
|
|
509
514
|
"[IMA] Ad container hidden after all ads completed"
|
|
510
515
|
);
|
|
511
516
|
}
|
|
512
|
-
if (!options
|
|
517
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
513
518
|
video.play().catch(() => {
|
|
514
519
|
});
|
|
515
520
|
console.log(
|
|
@@ -537,7 +542,7 @@ function createImaController(video, options) {
|
|
|
537
542
|
adContainerEl.style.display = "none";
|
|
538
543
|
console.log("[IMA] Ad container hidden after setup error");
|
|
539
544
|
}
|
|
540
|
-
if (!options
|
|
545
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
541
546
|
if (video.paused) {
|
|
542
547
|
console.log("[IMA] Resuming paused video after setup error");
|
|
543
548
|
video.play().catch(() => {
|
|
@@ -565,7 +570,7 @@ function createImaController(video, options) {
|
|
|
565
570
|
adContainerEl.style.display = "none";
|
|
566
571
|
console.log("[IMA] Ad container hidden after loader error");
|
|
567
572
|
}
|
|
568
|
-
if (!options
|
|
573
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
569
574
|
if (video.paused) {
|
|
570
575
|
console.log("[IMA] Resuming paused video after loader error");
|
|
571
576
|
video.play().catch(() => {
|
|
@@ -587,14 +592,15 @@ function createImaController(video, options) {
|
|
|
587
592
|
return adsLoadedPromise;
|
|
588
593
|
} catch (error) {
|
|
589
594
|
console.error("[IMA] Failed to request ads:", error);
|
|
590
|
-
currentReject
|
|
595
|
+
currentReject == null ? void 0 : currentReject(error);
|
|
591
596
|
adsLoadedReject = void 0;
|
|
592
597
|
adsLoadedResolve = void 0;
|
|
593
598
|
return Promise.reject(error);
|
|
594
599
|
}
|
|
595
600
|
},
|
|
596
601
|
async play() {
|
|
597
|
-
|
|
602
|
+
var _a, _b;
|
|
603
|
+
if (!((_a = window.google) == null ? void 0 : _a.ima) || !adDisplayContainer) {
|
|
598
604
|
console.warn(
|
|
599
605
|
"[IMA] Cannot play ad: IMA SDK or ad container not available"
|
|
600
606
|
);
|
|
@@ -616,14 +622,15 @@ function createImaController(video, options) {
|
|
|
616
622
|
} catch (error) {
|
|
617
623
|
console.error("[IMA] Error starting ad playback:", error);
|
|
618
624
|
adPlaying = false;
|
|
619
|
-
if (!options
|
|
620
|
-
video.play()
|
|
625
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
626
|
+
(_b = video.play()) == null ? void 0 : _b.catch(() => {
|
|
621
627
|
});
|
|
622
628
|
}
|
|
623
629
|
return Promise.reject(error);
|
|
624
630
|
}
|
|
625
631
|
},
|
|
626
632
|
async stop() {
|
|
633
|
+
var _a;
|
|
627
634
|
adPlaying = false;
|
|
628
635
|
video.muted = originalMutedState;
|
|
629
636
|
if (adContainerEl) {
|
|
@@ -632,11 +639,11 @@ function createImaController(video, options) {
|
|
|
632
639
|
console.log("[IMA] Ad container hidden after stop");
|
|
633
640
|
}
|
|
634
641
|
try {
|
|
635
|
-
adsManager
|
|
642
|
+
(_a = adsManager == null ? void 0 : adsManager.stop) == null ? void 0 : _a.call(adsManager);
|
|
636
643
|
} catch {
|
|
637
644
|
}
|
|
638
645
|
destroyAdsManager();
|
|
639
|
-
if (!options
|
|
646
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
640
647
|
video.play().catch(() => {
|
|
641
648
|
});
|
|
642
649
|
console.log("[IMA] Video resumed after stop (VOD mode)");
|
|
@@ -645,6 +652,7 @@ function createImaController(video, options) {
|
|
|
645
652
|
}
|
|
646
653
|
},
|
|
647
654
|
destroy() {
|
|
655
|
+
var _a;
|
|
648
656
|
destroyAdsManager();
|
|
649
657
|
adPlaying = false;
|
|
650
658
|
video.muted = originalMutedState;
|
|
@@ -653,10 +661,10 @@ function createImaController(video, options) {
|
|
|
653
661
|
adContainerEl.style.display = "none";
|
|
654
662
|
}
|
|
655
663
|
try {
|
|
656
|
-
adsLoader
|
|
664
|
+
(_a = adsLoader == null ? void 0 : adsLoader.destroy) == null ? void 0 : _a.call(adsLoader);
|
|
657
665
|
} catch {
|
|
658
666
|
}
|
|
659
|
-
if (adContainerEl
|
|
667
|
+
if (adContainerEl == null ? void 0 : adContainerEl.parentElement) {
|
|
660
668
|
adContainerEl.parentElement.removeChild(adContainerEl);
|
|
661
669
|
}
|
|
662
670
|
adContainerEl = void 0;
|
|
@@ -667,7 +675,8 @@ function createImaController(video, options) {
|
|
|
667
675
|
return adPlaying;
|
|
668
676
|
},
|
|
669
677
|
resize(width, height) {
|
|
670
|
-
|
|
678
|
+
var _a;
|
|
679
|
+
if (!adsManager || !((_a = window.google) == null ? void 0 : _a.ima)) {
|
|
671
680
|
console.warn(
|
|
672
681
|
"[IMA] Cannot resize: No ads manager or IMA SDK available"
|
|
673
682
|
);
|
|
@@ -685,7 +694,8 @@ function createImaController(video, options) {
|
|
|
685
694
|
listeners.get(event).add(listener);
|
|
686
695
|
},
|
|
687
696
|
off(event, listener) {
|
|
688
|
-
|
|
697
|
+
var _a;
|
|
698
|
+
(_a = listeners.get(event)) == null ? void 0 : _a.delete(listener);
|
|
689
699
|
},
|
|
690
700
|
updateOriginalMutedState(muted) {
|
|
691
701
|
originalMutedState = muted;
|
|
@@ -722,7 +732,8 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
722
732
|
let adPlaying = false;
|
|
723
733
|
let originalMutedState = false;
|
|
724
734
|
const listeners = /* @__PURE__ */ new Map();
|
|
725
|
-
const licenseKey = options
|
|
735
|
+
const licenseKey = options == null ? void 0 : options.licenseKey;
|
|
736
|
+
const mainHlsInstance = options == null ? void 0 : options.mainHlsInstance;
|
|
726
737
|
let adVideoElement;
|
|
727
738
|
let adHls;
|
|
728
739
|
let adContainerEl;
|
|
@@ -769,7 +780,74 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
769
780
|
}
|
|
770
781
|
});
|
|
771
782
|
}
|
|
783
|
+
function getMainStreamQuality() {
|
|
784
|
+
if (!mainHlsInstance || !mainHlsInstance.levels) {
|
|
785
|
+
return null;
|
|
786
|
+
}
|
|
787
|
+
const currentLevel = mainHlsInstance.currentLevel;
|
|
788
|
+
if (currentLevel === -1 || !mainHlsInstance.levels[currentLevel]) {
|
|
789
|
+
const autoLevel = mainHlsInstance.loadLevel;
|
|
790
|
+
if (autoLevel !== -1 && mainHlsInstance.levels[autoLevel]) {
|
|
791
|
+
const level2 = mainHlsInstance.levels[autoLevel];
|
|
792
|
+
return {
|
|
793
|
+
width: level2.width || 1920,
|
|
794
|
+
height: level2.height || 1080,
|
|
795
|
+
bitrate: level2.bitrate || 5e6
|
|
796
|
+
};
|
|
797
|
+
}
|
|
798
|
+
return null;
|
|
799
|
+
}
|
|
800
|
+
const level = mainHlsInstance.levels[currentLevel];
|
|
801
|
+
return {
|
|
802
|
+
width: level.width || 1920,
|
|
803
|
+
height: level.height || 1080,
|
|
804
|
+
bitrate: level.bitrate || 5e6
|
|
805
|
+
};
|
|
806
|
+
}
|
|
807
|
+
function selectBestMediaFile(mediaFiles) {
|
|
808
|
+
if (mediaFiles.length === 0) {
|
|
809
|
+
throw new Error("No media files available");
|
|
810
|
+
}
|
|
811
|
+
const firstFile = mediaFiles[0];
|
|
812
|
+
if (!firstFile) {
|
|
813
|
+
throw new Error("No media files available");
|
|
814
|
+
}
|
|
815
|
+
if (mediaFiles.length === 1) {
|
|
816
|
+
return firstFile;
|
|
817
|
+
}
|
|
818
|
+
const mainQuality = getMainStreamQuality();
|
|
819
|
+
if (!mainQuality) {
|
|
820
|
+
console.log("[HlsAdPlayer] No main stream quality info, using first media file");
|
|
821
|
+
return firstFile;
|
|
822
|
+
}
|
|
823
|
+
console.log("[HlsAdPlayer] Main stream quality:", mainQuality);
|
|
824
|
+
const scoredFiles = mediaFiles.map((file) => {
|
|
825
|
+
const widthDiff = Math.abs(file.width - mainQuality.width);
|
|
826
|
+
const heightDiff = Math.abs(file.height - mainQuality.height);
|
|
827
|
+
const resolutionDiff = widthDiff + heightDiff;
|
|
828
|
+
const fileBitrate = (file.bitrate || 5e3) * 1e3;
|
|
829
|
+
const bitrateDiff = Math.abs(fileBitrate - mainQuality.bitrate);
|
|
830
|
+
const score = resolutionDiff * 2 + bitrateDiff / 1e3;
|
|
831
|
+
return { file, score, resolutionDiff, bitrateDiff };
|
|
832
|
+
});
|
|
833
|
+
scoredFiles.sort((a, b) => a.score - b.score);
|
|
834
|
+
const bestMatch = scoredFiles[0];
|
|
835
|
+
if (!bestMatch) {
|
|
836
|
+
console.log("[HlsAdPlayer] No best match found, using first media file");
|
|
837
|
+
return firstFile;
|
|
838
|
+
}
|
|
839
|
+
console.log("[HlsAdPlayer] Selected media file:", {
|
|
840
|
+
url: bestMatch.file.url,
|
|
841
|
+
resolution: `${bestMatch.file.width}x${bestMatch.file.height}`,
|
|
842
|
+
bitrate: bestMatch.file.bitrate,
|
|
843
|
+
score: bestMatch.score,
|
|
844
|
+
resolutionDiff: bestMatch.resolutionDiff,
|
|
845
|
+
bitrateDiff: bestMatch.bitrateDiff
|
|
846
|
+
});
|
|
847
|
+
return bestMatch.file;
|
|
848
|
+
}
|
|
772
849
|
function parseVastXml(xmlString) {
|
|
850
|
+
var _a, _b, _c, _d;
|
|
773
851
|
try {
|
|
774
852
|
const parser = new DOMParser();
|
|
775
853
|
const xmlDoc = parser.parseFromString(xmlString, "text/xml");
|
|
@@ -784,19 +862,20 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
784
862
|
return null;
|
|
785
863
|
}
|
|
786
864
|
const adId = adElement.getAttribute("id") || "unknown";
|
|
787
|
-
const title = xmlDoc.querySelector("AdTitle")
|
|
788
|
-
const durationText = xmlDoc.querySelector("Duration")
|
|
865
|
+
const title = ((_a = xmlDoc.querySelector("AdTitle")) == null ? void 0 : _a.textContent) || "Ad";
|
|
866
|
+
const durationText = ((_b = xmlDoc.querySelector("Duration")) == null ? void 0 : _b.textContent) || "00:00:30";
|
|
789
867
|
const durationParts = durationText.split(":");
|
|
790
868
|
const duration = parseInt(durationParts[0] || "0", 10) * 3600 + parseInt(durationParts[1] || "0", 10) * 60 + parseInt(durationParts[2] || "0", 10);
|
|
791
869
|
const mediaFileElements = xmlDoc.querySelectorAll("MediaFile");
|
|
792
870
|
const mediaFiles = [];
|
|
793
871
|
mediaFileElements.forEach((mf) => {
|
|
872
|
+
var _a2;
|
|
794
873
|
const type = mf.getAttribute("type") || "";
|
|
795
874
|
if (type === "application/x-mpegURL" || type.includes("m3u8")) {
|
|
796
875
|
const bitrateAttr = mf.getAttribute("bitrate");
|
|
797
876
|
const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;
|
|
798
877
|
mediaFiles.push({
|
|
799
|
-
url: mf.textContent
|
|
878
|
+
url: ((_a2 = mf.textContent) == null ? void 0 : _a2.trim()) || "",
|
|
800
879
|
type,
|
|
801
880
|
width: parseInt(mf.getAttribute("width") || "1920", 10),
|
|
802
881
|
height: parseInt(mf.getAttribute("height") || "1080", 10),
|
|
@@ -825,12 +904,14 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
825
904
|
error: []
|
|
826
905
|
};
|
|
827
906
|
xmlDoc.querySelectorAll("Impression").forEach((el) => {
|
|
828
|
-
|
|
907
|
+
var _a2;
|
|
908
|
+
const url = (_a2 = el.textContent) == null ? void 0 : _a2.trim();
|
|
829
909
|
if (url) trackingUrls.impression.push(url);
|
|
830
910
|
});
|
|
831
911
|
xmlDoc.querySelectorAll("Tracking").forEach((el) => {
|
|
912
|
+
var _a2;
|
|
832
913
|
const event = el.getAttribute("event");
|
|
833
|
-
const url = el.textContent
|
|
914
|
+
const url = (_a2 = el.textContent) == null ? void 0 : _a2.trim();
|
|
834
915
|
if (event && url) {
|
|
835
916
|
const eventKey = event;
|
|
836
917
|
if (trackingUrls[eventKey]) {
|
|
@@ -838,7 +919,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
838
919
|
}
|
|
839
920
|
}
|
|
840
921
|
});
|
|
841
|
-
const clickThrough = xmlDoc.querySelector("ClickThrough")
|
|
922
|
+
const clickThrough = (_d = (_c = xmlDoc.querySelector("ClickThrough")) == null ? void 0 : _c.textContent) == null ? void 0 : _d.trim();
|
|
842
923
|
return {
|
|
843
924
|
id: adId,
|
|
844
925
|
title,
|
|
@@ -930,7 +1011,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
930
1011
|
adContainerEl.style.display = "none";
|
|
931
1012
|
adContainerEl.style.pointerEvents = "none";
|
|
932
1013
|
}
|
|
933
|
-
if (!options
|
|
1014
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
934
1015
|
contentVideo.play().catch(() => {
|
|
935
1016
|
});
|
|
936
1017
|
console.log("[HlsAdPlayer] Content resumed (VOD mode)");
|
|
@@ -948,7 +1029,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
948
1029
|
adContainerEl.style.display = "none";
|
|
949
1030
|
adContainerEl.style.pointerEvents = "none";
|
|
950
1031
|
}
|
|
951
|
-
if (!options
|
|
1032
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
952
1033
|
if (contentVideo.paused) {
|
|
953
1034
|
contentVideo.play().catch(() => {
|
|
954
1035
|
});
|
|
@@ -958,6 +1039,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
958
1039
|
}
|
|
959
1040
|
return {
|
|
960
1041
|
initialize() {
|
|
1042
|
+
var _a;
|
|
961
1043
|
console.log("[HlsAdPlayer] Initializing");
|
|
962
1044
|
if (!adContainerEl) {
|
|
963
1045
|
const container = document.createElement("div");
|
|
@@ -972,7 +1054,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
972
1054
|
container.style.pointerEvents = "none";
|
|
973
1055
|
container.style.zIndex = "2";
|
|
974
1056
|
container.style.backgroundColor = "#000";
|
|
975
|
-
contentVideo.parentElement
|
|
1057
|
+
(_a = contentVideo.parentElement) == null ? void 0 : _a.appendChild(container);
|
|
976
1058
|
adContainerEl = container;
|
|
977
1059
|
}
|
|
978
1060
|
},
|
|
@@ -1014,7 +1096,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1014
1096
|
try {
|
|
1015
1097
|
if (!adVideoElement) {
|
|
1016
1098
|
adVideoElement = createAdVideoElement();
|
|
1017
|
-
adContainerEl
|
|
1099
|
+
adContainerEl == null ? void 0 : adContainerEl.appendChild(adVideoElement);
|
|
1018
1100
|
setupAdEventListeners();
|
|
1019
1101
|
}
|
|
1020
1102
|
trackingFired = {
|
|
@@ -1025,7 +1107,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1025
1107
|
thirdQuartile: false,
|
|
1026
1108
|
complete: false
|
|
1027
1109
|
};
|
|
1028
|
-
if (!options
|
|
1110
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
1029
1111
|
contentVideo.pause();
|
|
1030
1112
|
console.log("[HlsAdPlayer] Content paused (VOD mode)");
|
|
1031
1113
|
} else {
|
|
@@ -1038,7 +1120,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1038
1120
|
adContainerEl.style.pointerEvents = "auto";
|
|
1039
1121
|
}
|
|
1040
1122
|
emit("content_pause");
|
|
1041
|
-
const mediaFile = currentAd.mediaFiles
|
|
1123
|
+
const mediaFile = selectBestMediaFile(currentAd.mediaFiles);
|
|
1042
1124
|
if (!mediaFile) {
|
|
1043
1125
|
throw new Error("No media file available for ad");
|
|
1044
1126
|
}
|
|
@@ -1098,7 +1180,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1098
1180
|
adVideoElement.pause();
|
|
1099
1181
|
adVideoElement.src = "";
|
|
1100
1182
|
}
|
|
1101
|
-
if (!options
|
|
1183
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
1102
1184
|
contentVideo.play().catch(() => {
|
|
1103
1185
|
});
|
|
1104
1186
|
}
|
|
@@ -1118,7 +1200,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1118
1200
|
adVideoElement.remove();
|
|
1119
1201
|
adVideoElement = void 0;
|
|
1120
1202
|
}
|
|
1121
|
-
if (adContainerEl
|
|
1203
|
+
if (adContainerEl == null ? void 0 : adContainerEl.parentElement) {
|
|
1122
1204
|
adContainerEl.parentElement.removeChild(adContainerEl);
|
|
1123
1205
|
}
|
|
1124
1206
|
adContainerEl = void 0;
|
|
@@ -1144,7 +1226,8 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1144
1226
|
listeners.get(event).add(listener);
|
|
1145
1227
|
},
|
|
1146
1228
|
off(event, listener) {
|
|
1147
|
-
|
|
1229
|
+
var _a;
|
|
1230
|
+
(_a = listeners.get(event)) == null ? void 0 : _a.delete(listener);
|
|
1148
1231
|
},
|
|
1149
1232
|
updateOriginalMutedState(muted) {
|
|
1150
1233
|
originalMutedState = muted;
|
|
@@ -1169,6 +1252,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1169
1252
|
// src/utils/tracking.ts
|
|
1170
1253
|
var cachedBrowserId = null;
|
|
1171
1254
|
function getClientInfo() {
|
|
1255
|
+
var _a, _b, _c, _d;
|
|
1172
1256
|
const ua = navigator.userAgent;
|
|
1173
1257
|
const platform = navigator.platform;
|
|
1174
1258
|
const vendor = navigator.vendor || "";
|
|
@@ -1176,12 +1260,12 @@ function getClientInfo() {
|
|
|
1176
1260
|
const memory = navigator.deviceMemory || null;
|
|
1177
1261
|
const hardwareConcurrency = navigator.hardwareConcurrency || 1;
|
|
1178
1262
|
const screenInfo = {
|
|
1179
|
-
width: screen
|
|
1180
|
-
height: screen
|
|
1181
|
-
availWidth: screen
|
|
1182
|
-
availHeight: screen
|
|
1183
|
-
orientation: screen
|
|
1184
|
-
pixelDepth: screen
|
|
1263
|
+
width: screen == null ? void 0 : screen.width,
|
|
1264
|
+
height: screen == null ? void 0 : screen.height,
|
|
1265
|
+
availWidth: screen == null ? void 0 : screen.availWidth,
|
|
1266
|
+
availHeight: screen == null ? void 0 : screen.availHeight,
|
|
1267
|
+
orientation: ((_a = screen == null ? void 0 : screen.orientation) == null ? void 0 : _a.type) || "",
|
|
1268
|
+
pixelDepth: screen == null ? void 0 : screen.pixelDepth
|
|
1185
1269
|
};
|
|
1186
1270
|
let deviceType = "desktop";
|
|
1187
1271
|
let brand = "Unknown";
|
|
@@ -1278,10 +1362,10 @@ function getClientInfo() {
|
|
|
1278
1362
|
if (vendor.includes("Samsung") || ua.includes("SM-")) brand = "Samsung";
|
|
1279
1363
|
}
|
|
1280
1364
|
isWebView = /wv|WebView|Linux; U;/.test(ua);
|
|
1281
|
-
if (window
|
|
1365
|
+
if ((window == null ? void 0 : window.outerHeight) === 0 && (window == null ? void 0 : window.outerWidth) === 0) {
|
|
1282
1366
|
isWebView = true;
|
|
1283
1367
|
}
|
|
1284
|
-
isWebApp = window.matchMedia("(display-mode: standalone)").matches || window.navigator.standalone === true || window.screen
|
|
1368
|
+
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;
|
|
1285
1369
|
return {
|
|
1286
1370
|
brand,
|
|
1287
1371
|
os,
|
|
@@ -1302,7 +1386,7 @@ function getClientInfo() {
|
|
|
1302
1386
|
deviceMemory: memory,
|
|
1303
1387
|
maxTouchPoints,
|
|
1304
1388
|
language: navigator.language,
|
|
1305
|
-
languages: navigator.languages
|
|
1389
|
+
languages: ((_d = navigator.languages) == null ? void 0 : _d.join(",")) || "",
|
|
1306
1390
|
cookieEnabled: navigator.cookieEnabled,
|
|
1307
1391
|
doNotTrack: navigator.doNotTrack || "",
|
|
1308
1392
|
referrer: document.referrer,
|
|
@@ -1660,7 +1744,8 @@ var StormcloudVideoPlayer = class {
|
|
|
1660
1744
|
}
|
|
1661
1745
|
return createHlsAdPlayer(this.video, {
|
|
1662
1746
|
continueLiveStreamDuringAds,
|
|
1663
|
-
...this.config.licenseKey ? { licenseKey: this.config.licenseKey } : {}
|
|
1747
|
+
...this.config.licenseKey ? { licenseKey: this.config.licenseKey } : {},
|
|
1748
|
+
...this.hls ? { mainHlsInstance: this.hls } : {}
|
|
1664
1749
|
});
|
|
1665
1750
|
} else {
|
|
1666
1751
|
if (this.config.debugAdTiming) {
|
|
@@ -1672,6 +1757,7 @@ var StormcloudVideoPlayer = class {
|
|
|
1672
1757
|
}
|
|
1673
1758
|
}
|
|
1674
1759
|
async load() {
|
|
1760
|
+
var _a, _b;
|
|
1675
1761
|
if (!this.attached) {
|
|
1676
1762
|
this.attach();
|
|
1677
1763
|
}
|
|
@@ -1688,7 +1774,7 @@ var StormcloudVideoPlayer = class {
|
|
|
1688
1774
|
this.initializeTracking();
|
|
1689
1775
|
if (this.shouldUseNativeHls()) {
|
|
1690
1776
|
this.video.src = this.config.src;
|
|
1691
|
-
this.isLiveStream = this.config.lowLatencyMode
|
|
1777
|
+
this.isLiveStream = (_a = this.config.lowLatencyMode) != null ? _a : false;
|
|
1692
1778
|
if (this.config.debugAdTiming) {
|
|
1693
1779
|
console.log(
|
|
1694
1780
|
"[StormcloudVideoPlayer] allowNativeHls: true - VOD mode detected:",
|
|
@@ -1703,8 +1789,8 @@ var StormcloudVideoPlayer = class {
|
|
|
1703
1789
|
this.ima = this.createAdPlayer(false);
|
|
1704
1790
|
this.ima.initialize();
|
|
1705
1791
|
if (this.config.autoplay) {
|
|
1706
|
-
await this.video.play()
|
|
1707
|
-
});
|
|
1792
|
+
await ((_b = this.video.play()) == null ? void 0 : _b.catch(() => {
|
|
1793
|
+
}));
|
|
1708
1794
|
}
|
|
1709
1795
|
return;
|
|
1710
1796
|
}
|
|
@@ -1717,12 +1803,17 @@ var StormcloudVideoPlayer = class {
|
|
|
1717
1803
|
...this.config.lowLatencyMode ? { liveSyncDuration: 2 } : {}
|
|
1718
1804
|
});
|
|
1719
1805
|
this.hls.on(import_hls2.default.Events.MEDIA_ATTACHED, () => {
|
|
1720
|
-
|
|
1806
|
+
var _a2;
|
|
1807
|
+
(_a2 = this.hls) == null ? void 0 : _a2.loadSource(this.config.src);
|
|
1721
1808
|
});
|
|
1722
1809
|
this.hls.on(import_hls2.default.Events.MANIFEST_PARSED, async (_, data) => {
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1810
|
+
var _a2, _b2, _c, _d;
|
|
1811
|
+
this.isLiveStream = (_c = (_b2 = (_a2 = this.hls) == null ? void 0 : _a2.levels) == null ? void 0 : _b2.some(
|
|
1812
|
+
(level) => {
|
|
1813
|
+
var _a3, _b3;
|
|
1814
|
+
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";
|
|
1815
|
+
}
|
|
1816
|
+
)) != null ? _c : false;
|
|
1726
1817
|
if (this.config.debugAdTiming) {
|
|
1727
1818
|
const adBehavior = this.shouldContinueLiveStreamDuringAds() ? "live (main video continues muted during ads)" : "vod (main video pauses during ads)";
|
|
1728
1819
|
console.log("[StormcloudVideoPlayer] Stream type detected:", {
|
|
@@ -1735,28 +1826,29 @@ var StormcloudVideoPlayer = class {
|
|
|
1735
1826
|
this.ima = this.createAdPlayer(this.shouldContinueLiveStreamDuringAds());
|
|
1736
1827
|
this.ima.initialize();
|
|
1737
1828
|
if (this.config.autoplay) {
|
|
1738
|
-
await this.video.play()
|
|
1739
|
-
});
|
|
1829
|
+
await ((_d = this.video.play()) == null ? void 0 : _d.catch(() => {
|
|
1830
|
+
}));
|
|
1740
1831
|
}
|
|
1741
1832
|
});
|
|
1742
1833
|
this.hls.on(import_hls2.default.Events.FRAG_PARSING_METADATA, (_evt, data) => {
|
|
1743
|
-
const id3Tags = (data
|
|
1834
|
+
const id3Tags = ((data == null ? void 0 : data.samples) || []).map((s) => ({
|
|
1744
1835
|
key: "ID3",
|
|
1745
|
-
value: s
|
|
1746
|
-
ptsSeconds: s
|
|
1836
|
+
value: s == null ? void 0 : s.data,
|
|
1837
|
+
ptsSeconds: s == null ? void 0 : s.pts
|
|
1747
1838
|
}));
|
|
1748
1839
|
id3Tags.forEach((tag) => this.onId3Tag(tag));
|
|
1749
1840
|
});
|
|
1750
1841
|
this.hls.on(import_hls2.default.Events.FRAG_CHANGED, (_evt, data) => {
|
|
1751
|
-
|
|
1752
|
-
const
|
|
1842
|
+
var _a2, _b2, _c;
|
|
1843
|
+
const frag = data == null ? void 0 : data.frag;
|
|
1844
|
+
const tagList = frag == null ? void 0 : frag.tagList;
|
|
1753
1845
|
if (!Array.isArray(tagList)) return;
|
|
1754
1846
|
for (const entry of tagList) {
|
|
1755
1847
|
let tag = "";
|
|
1756
1848
|
let value = "";
|
|
1757
1849
|
if (Array.isArray(entry)) {
|
|
1758
|
-
tag = String(entry[0]
|
|
1759
|
-
value = String(entry[1]
|
|
1850
|
+
tag = String((_a2 = entry[0]) != null ? _a2 : "");
|
|
1851
|
+
value = String((_b2 = entry[1]) != null ? _b2 : "");
|
|
1760
1852
|
} else if (typeof entry === "string") {
|
|
1761
1853
|
const idx = entry.indexOf(":");
|
|
1762
1854
|
if (idx >= 0) {
|
|
@@ -1780,8 +1872,8 @@ var StormcloudVideoPlayer = class {
|
|
|
1780
1872
|
const prog = this.parseCueOutCont(value);
|
|
1781
1873
|
const marker = {
|
|
1782
1874
|
type: "progress",
|
|
1783
|
-
...prog
|
|
1784
|
-
...prog
|
|
1875
|
+
...(prog == null ? void 0 : prog.duration) !== void 0 ? { durationSeconds: prog.duration } : {},
|
|
1876
|
+
...(prog == null ? void 0 : prog.elapsed) !== void 0 ? { ptsSeconds: prog.elapsed } : {},
|
|
1785
1877
|
raw: { tag, value }
|
|
1786
1878
|
};
|
|
1787
1879
|
this.onScte35Marker(marker);
|
|
@@ -1791,7 +1883,7 @@ var StormcloudVideoPlayer = class {
|
|
|
1791
1883
|
const attrs = this.parseAttributeList(value);
|
|
1792
1884
|
const hasScteOut = "SCTE35-OUT" in attrs || attrs["SCTE35-OUT"] !== void 0;
|
|
1793
1885
|
const hasScteIn = "SCTE35-IN" in attrs || attrs["SCTE35-IN"] !== void 0;
|
|
1794
|
-
const klass = String(attrs["CLASS"]
|
|
1886
|
+
const klass = String((_c = attrs["CLASS"]) != null ? _c : "");
|
|
1795
1887
|
const duration = this.toNumber(attrs["DURATION"]);
|
|
1796
1888
|
if (hasScteOut || /com\.apple\.hls\.cue/i.test(klass)) {
|
|
1797
1889
|
const marker = {
|
|
@@ -1808,13 +1900,14 @@ var StormcloudVideoPlayer = class {
|
|
|
1808
1900
|
}
|
|
1809
1901
|
});
|
|
1810
1902
|
this.hls.on(import_hls2.default.Events.ERROR, (_evt, data) => {
|
|
1811
|
-
|
|
1903
|
+
var _a2, _b2;
|
|
1904
|
+
if (data == null ? void 0 : data.fatal) {
|
|
1812
1905
|
switch (data.type) {
|
|
1813
1906
|
case import_hls2.default.ErrorTypes.NETWORK_ERROR:
|
|
1814
|
-
this.hls
|
|
1907
|
+
(_a2 = this.hls) == null ? void 0 : _a2.startLoad();
|
|
1815
1908
|
break;
|
|
1816
1909
|
case import_hls2.default.ErrorTypes.MEDIA_ERROR:
|
|
1817
|
-
this.hls
|
|
1910
|
+
(_b2 = this.hls) == null ? void 0 : _b2.recoverMediaError();
|
|
1818
1911
|
break;
|
|
1819
1912
|
default:
|
|
1820
1913
|
this.destroy();
|
|
@@ -1916,11 +2009,12 @@ var StormcloudVideoPlayer = class {
|
|
|
1916
2009
|
}
|
|
1917
2010
|
}
|
|
1918
2011
|
parseScte35FromId3(tag) {
|
|
2012
|
+
var _a, _b, _c, _d;
|
|
1919
2013
|
const text = this.decodeId3ValueToText(tag.value);
|
|
1920
2014
|
if (!text) return void 0;
|
|
1921
2015
|
const cueOutMatch = text.match(/EXT-X-CUE-OUT(?::([^\r\n]*))?/i) || text.match(/CUE-OUT(?::([^\r\n]*))?/i);
|
|
1922
2016
|
if (cueOutMatch) {
|
|
1923
|
-
const arg = (cueOutMatch[1]
|
|
2017
|
+
const arg = ((_a = cueOutMatch[1]) != null ? _a : "").trim();
|
|
1924
2018
|
const dur = this.parseCueOutDuration(arg);
|
|
1925
2019
|
const marker = {
|
|
1926
2020
|
type: "start",
|
|
@@ -1932,12 +2026,12 @@ var StormcloudVideoPlayer = class {
|
|
|
1932
2026
|
}
|
|
1933
2027
|
const cueOutContMatch = text.match(/EXT-X-CUE-OUT-CONT:([^\r\n]*)/i);
|
|
1934
2028
|
if (cueOutContMatch) {
|
|
1935
|
-
const arg = (cueOutContMatch[1]
|
|
2029
|
+
const arg = ((_b = cueOutContMatch[1]) != null ? _b : "").trim();
|
|
1936
2030
|
const cont = this.parseCueOutCont(arg);
|
|
1937
2031
|
const marker = {
|
|
1938
2032
|
type: "progress",
|
|
1939
2033
|
...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},
|
|
1940
|
-
...cont
|
|
2034
|
+
...(cont == null ? void 0 : cont.duration) !== void 0 ? { durationSeconds: cont.duration } : {},
|
|
1941
2035
|
raw: { id3: text }
|
|
1942
2036
|
};
|
|
1943
2037
|
return marker;
|
|
@@ -1953,10 +2047,10 @@ var StormcloudVideoPlayer = class {
|
|
|
1953
2047
|
}
|
|
1954
2048
|
const daterangeMatch = text.match(/EXT-X-DATERANGE:([^\r\n]*)/i);
|
|
1955
2049
|
if (daterangeMatch) {
|
|
1956
|
-
const attrs = this.parseAttributeList(daterangeMatch[1]
|
|
2050
|
+
const attrs = this.parseAttributeList((_c = daterangeMatch[1]) != null ? _c : "");
|
|
1957
2051
|
const hasScteOut = "SCTE35-OUT" in attrs || attrs["SCTE35-OUT"] !== void 0;
|
|
1958
2052
|
const hasScteIn = "SCTE35-IN" in attrs || attrs["SCTE35-IN"] !== void 0;
|
|
1959
|
-
const klass = String(attrs["CLASS"]
|
|
2053
|
+
const klass = String((_d = attrs["CLASS"]) != null ? _d : "");
|
|
1960
2054
|
const duration = this.toNumber(attrs["DURATION"]);
|
|
1961
2055
|
if (hasScteOut || /com\.apple\.hls\.cue/i.test(klass)) {
|
|
1962
2056
|
const marker = {
|
|
@@ -2013,6 +2107,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2013
2107
|
}
|
|
2014
2108
|
}
|
|
2015
2109
|
onScte35Marker(marker) {
|
|
2110
|
+
var _a, _b;
|
|
2016
2111
|
if (this.config.debugAdTiming) {
|
|
2017
2112
|
console.log("[StormcloudVideoPlayer] SCTE-35 marker detected:", {
|
|
2018
2113
|
type: marker.type,
|
|
@@ -2028,7 +2123,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2028
2123
|
this.expectedAdBreakDurationMs = durationMs;
|
|
2029
2124
|
this.currentAdBreakStartWallClockMs = Date.now();
|
|
2030
2125
|
const isManifestMarker = this.isManifestBasedMarker(marker);
|
|
2031
|
-
const forceImmediate = this.config.immediateManifestAds
|
|
2126
|
+
const forceImmediate = (_a = this.config.immediateManifestAds) != null ? _a : true;
|
|
2032
2127
|
if (this.config.debugAdTiming) {
|
|
2033
2128
|
console.log("[StormcloudVideoPlayer] Ad start decision:", {
|
|
2034
2129
|
isManifestMarker,
|
|
@@ -2045,7 +2140,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2045
2140
|
this.clearAdStartTimer();
|
|
2046
2141
|
this.handleAdStart(marker);
|
|
2047
2142
|
} else if (typeof marker.ptsSeconds === "number") {
|
|
2048
|
-
const tol = this.config.driftToleranceMs
|
|
2143
|
+
const tol = (_b = this.config.driftToleranceMs) != null ? _b : 1e3;
|
|
2049
2144
|
const nowMs = this.video.currentTime * 1e3;
|
|
2050
2145
|
const estCurrentPtsMs = nowMs - this.ptsDriftEmaMs;
|
|
2051
2146
|
const deltaMs = Math.floor(marker.ptsSeconds * 1e3 - estCurrentPtsMs);
|
|
@@ -2155,12 +2250,13 @@ var StormcloudVideoPlayer = class {
|
|
|
2155
2250
|
return void 0;
|
|
2156
2251
|
}
|
|
2157
2252
|
parseAttributeList(value) {
|
|
2253
|
+
var _a, _b, _c;
|
|
2158
2254
|
const attrs = {};
|
|
2159
2255
|
const regex = /([A-Z0-9-]+)=(("[^"]*")|([^",]*))(?:,|$)/gi;
|
|
2160
2256
|
let match;
|
|
2161
2257
|
while ((match = regex.exec(value)) !== null) {
|
|
2162
|
-
const key = match[1]
|
|
2163
|
-
let rawVal = match[3]
|
|
2258
|
+
const key = (_a = match[1]) != null ? _a : "";
|
|
2259
|
+
let rawVal = (_c = (_b = match[3]) != null ? _b : match[4]) != null ? _c : "";
|
|
2164
2260
|
if (rawVal.startsWith('"') && rawVal.endsWith('"')) {
|
|
2165
2261
|
rawVal = rawVal.slice(1, -1);
|
|
2166
2262
|
}
|
|
@@ -2324,6 +2420,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2324
2420
|
}
|
|
2325
2421
|
}
|
|
2326
2422
|
async fetchAdConfiguration() {
|
|
2423
|
+
var _a, _b, _c;
|
|
2327
2424
|
const vastMode = this.config.vastMode || "default";
|
|
2328
2425
|
if (this.config.debugAdTiming) {
|
|
2329
2426
|
console.log(
|
|
@@ -2381,7 +2478,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2381
2478
|
return;
|
|
2382
2479
|
}
|
|
2383
2480
|
const data = await response.json();
|
|
2384
|
-
const imaPayload = data.response
|
|
2481
|
+
const imaPayload = (_c = (_b = (_a = data.response) == null ? void 0 : _a.ima) == null ? void 0 : _b["publisherdesk.ima"]) == null ? void 0 : _c.payload;
|
|
2385
2482
|
if (imaPayload) {
|
|
2386
2483
|
this.apiVastTagUrl = decodeURIComponent(imaPayload);
|
|
2387
2484
|
if (this.config.debugAdTiming) {
|
|
@@ -2418,11 +2515,12 @@ var StormcloudVideoPlayer = class {
|
|
|
2418
2515
|
return "other";
|
|
2419
2516
|
}
|
|
2420
2517
|
shouldShowNativeControls() {
|
|
2518
|
+
var _a, _b;
|
|
2421
2519
|
const streamType = this.getStreamType();
|
|
2422
2520
|
if (streamType === "other") {
|
|
2423
|
-
return !(this.config.showCustomControls
|
|
2521
|
+
return !((_a = this.config.showCustomControls) != null ? _a : false);
|
|
2424
2522
|
}
|
|
2425
|
-
return !!(this.config.allowNativeHls && !(this.config.showCustomControls
|
|
2523
|
+
return !!(this.config.allowNativeHls && !((_b = this.config.showCustomControls) != null ? _b : false));
|
|
2426
2524
|
}
|
|
2427
2525
|
shouldContinueLiveStreamDuringAds() {
|
|
2428
2526
|
if (this.config.allowNativeHls) {
|
|
@@ -2434,6 +2532,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2434
2532
|
return true;
|
|
2435
2533
|
}
|
|
2436
2534
|
async handleAdStart(_marker) {
|
|
2535
|
+
var _a;
|
|
2437
2536
|
const scheduled = this.findCurrentOrNextBreak(
|
|
2438
2537
|
this.video.currentTime * 1e3
|
|
2439
2538
|
);
|
|
@@ -2484,17 +2583,18 @@ var StormcloudVideoPlayer = class {
|
|
|
2484
2583
|
this.handleAdFailure();
|
|
2485
2584
|
}
|
|
2486
2585
|
}
|
|
2487
|
-
if (this.expectedAdBreakDurationMs == null && scheduled
|
|
2586
|
+
if (this.expectedAdBreakDurationMs == null && (scheduled == null ? void 0 : scheduled.durationMs) != null) {
|
|
2488
2587
|
this.expectedAdBreakDurationMs = scheduled.durationMs;
|
|
2489
|
-
this.currentAdBreakStartWallClockMs = this.currentAdBreakStartWallClockMs
|
|
2588
|
+
this.currentAdBreakStartWallClockMs = (_a = this.currentAdBreakStartWallClockMs) != null ? _a : Date.now();
|
|
2490
2589
|
this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);
|
|
2491
2590
|
}
|
|
2492
2591
|
}
|
|
2493
2592
|
findCurrentOrNextBreak(nowMs) {
|
|
2593
|
+
var _a;
|
|
2494
2594
|
const schedule = [];
|
|
2495
2595
|
let candidate;
|
|
2496
2596
|
for (const b of schedule) {
|
|
2497
|
-
const tol = this.config.driftToleranceMs
|
|
2597
|
+
const tol = (_a = this.config.driftToleranceMs) != null ? _a : 1e3;
|
|
2498
2598
|
if (b.startTimeMs <= nowMs + tol && (candidate == null || b.startTimeMs > (candidate.startTimeMs || 0))) {
|
|
2499
2599
|
candidate = b;
|
|
2500
2600
|
}
|
|
@@ -2510,7 +2610,8 @@ var StormcloudVideoPlayer = class {
|
|
|
2510
2610
|
}
|
|
2511
2611
|
}
|
|
2512
2612
|
async handleMidAdJoin(adBreak, nowMs) {
|
|
2513
|
-
|
|
2613
|
+
var _a;
|
|
2614
|
+
const durationMs = (_a = adBreak.durationMs) != null ? _a : 0;
|
|
2514
2615
|
const endMs = adBreak.startTimeMs + durationMs;
|
|
2515
2616
|
if (durationMs > 0 && nowMs > adBreak.startTimeMs && nowMs < endMs) {
|
|
2516
2617
|
const remainingMs = endMs - nowMs;
|
|
@@ -2611,6 +2712,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2611
2712
|
}
|
|
2612
2713
|
}
|
|
2613
2714
|
handleAdFailure() {
|
|
2715
|
+
var _a;
|
|
2614
2716
|
if (this.config.debugAdTiming) {
|
|
2615
2717
|
console.log(
|
|
2616
2718
|
"[StormcloudVideoPlayer] Handling ad failure - resuming content",
|
|
@@ -2643,7 +2745,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2643
2745
|
if (this.config.debugAdTiming) {
|
|
2644
2746
|
console.log("[StormcloudVideoPlayer] Resuming paused video");
|
|
2645
2747
|
}
|
|
2646
|
-
this.video.play()
|
|
2748
|
+
(_a = this.video.play()) == null ? void 0 : _a.catch((error) => {
|
|
2647
2749
|
if (this.config.debugAdTiming) {
|
|
2648
2750
|
console.error(
|
|
2649
2751
|
"[StormcloudVideoPlayer] Failed to resume video after ad failure:",
|
|
@@ -2658,8 +2760,9 @@ var StormcloudVideoPlayer = class {
|
|
|
2658
2760
|
}
|
|
2659
2761
|
}
|
|
2660
2762
|
startAdFailsafeTimer() {
|
|
2763
|
+
var _a;
|
|
2661
2764
|
this.clearAdFailsafeTimer();
|
|
2662
|
-
const failsafeMs = this.config.adFailsafeTimeoutMs
|
|
2765
|
+
const failsafeMs = (_a = this.config.adFailsafeTimeoutMs) != null ? _a : 1e4;
|
|
2663
2766
|
if (this.config.debugAdTiming) {
|
|
2664
2767
|
console.log(
|
|
2665
2768
|
`[StormcloudVideoPlayer] Starting failsafe timer (${failsafeMs}ms)`
|
|
@@ -2795,6 +2898,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2795
2898
|
}
|
|
2796
2899
|
}
|
|
2797
2900
|
destroy() {
|
|
2901
|
+
var _a, _b;
|
|
2798
2902
|
this.clearAdStartTimer();
|
|
2799
2903
|
this.clearAdStopTimer();
|
|
2800
2904
|
this.clearAdFailsafeTimer();
|
|
@@ -2802,8 +2906,8 @@ var StormcloudVideoPlayer = class {
|
|
|
2802
2906
|
clearInterval(this.heartbeatInterval);
|
|
2803
2907
|
this.heartbeatInterval = void 0;
|
|
2804
2908
|
}
|
|
2805
|
-
this.hls
|
|
2806
|
-
this.ima
|
|
2909
|
+
(_a = this.hls) == null ? void 0 : _a.destroy();
|
|
2910
|
+
(_b = this.ima) == null ? void 0 : _b.destroy();
|
|
2807
2911
|
}
|
|
2808
2912
|
};
|
|
2809
2913
|
|
|
@@ -2910,7 +3014,7 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(
|
|
|
2910
3014
|
}
|
|
2911
3015
|
setShowSpeedMenu(false);
|
|
2912
3016
|
};
|
|
2913
|
-
const isHlsStream = src
|
|
3017
|
+
const isHlsStream = (src == null ? void 0 : src.toLowerCase().includes(".m3u8")) || (src == null ? void 0 : src.toLowerCase().includes("/hls/"));
|
|
2914
3018
|
const shouldShowEnhancedControls = showCustomControls && (isHlsStream ? allowNativeHls : true);
|
|
2915
3019
|
const criticalPropsKey = (0, import_react.useMemo)(() => {
|
|
2916
3020
|
return CRITICAL_PROPS.map((prop) => `${prop}:${props[prop]}`).join("|");
|
|
@@ -2960,13 +3064,13 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(
|
|
|
2960
3064
|
player.load().then(() => {
|
|
2961
3065
|
const showNative = player.shouldShowNativeControls();
|
|
2962
3066
|
setShouldShowNativeControls(showNative);
|
|
2963
|
-
onReady
|
|
3067
|
+
onReady == null ? void 0 : onReady(player);
|
|
2964
3068
|
}).catch((error) => {
|
|
2965
3069
|
console.error(
|
|
2966
3070
|
"StormcloudVideoPlayer: Failed to load player:",
|
|
2967
3071
|
error
|
|
2968
3072
|
);
|
|
2969
|
-
onReady
|
|
3073
|
+
onReady == null ? void 0 : onReady(player);
|
|
2970
3074
|
});
|
|
2971
3075
|
return () => {
|
|
2972
3076
|
try {
|
|
@@ -3022,6 +3126,7 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(
|
|
|
3022
3126
|
(0, import_react.useEffect)(() => {
|
|
3023
3127
|
if (!playerRef.current || !videoRef.current) return;
|
|
3024
3128
|
const updateStates = () => {
|
|
3129
|
+
var _a;
|
|
3025
3130
|
if (playerRef.current && videoRef.current) {
|
|
3026
3131
|
setIsMuted(playerRef.current.isMuted());
|
|
3027
3132
|
setIsPlaying(!videoRef.current.paused);
|
|
@@ -3039,13 +3144,14 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(
|
|
|
3039
3144
|
);
|
|
3040
3145
|
}
|
|
3041
3146
|
setIsFullscreen(
|
|
3042
|
-
document.fullscreenElement === videoRef.current
|
|
3147
|
+
document.fullscreenElement === ((_a = videoRef.current) == null ? void 0 : _a.parentElement)
|
|
3043
3148
|
);
|
|
3044
3149
|
};
|
|
3045
3150
|
const interval = setInterval(updateStates, 200);
|
|
3046
3151
|
const handleFullscreenChange = () => {
|
|
3152
|
+
var _a;
|
|
3047
3153
|
setIsFullscreen(
|
|
3048
|
-
document.fullscreenElement === videoRef.current
|
|
3154
|
+
document.fullscreenElement === ((_a = videoRef.current) == null ? void 0 : _a.parentElement)
|
|
3049
3155
|
);
|
|
3050
3156
|
};
|
|
3051
3157
|
document.addEventListener("fullscreenchange", handleFullscreenChange);
|