stormcloud-video-player 0.2.13 → 0.2.15
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/README.md +92 -11
- package/dist/stormcloud-vp.min.js +2 -2
- package/lib/index.cjs +288 -133
- 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 +288 -133
- package/lib/index.js.map +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +237 -106
- 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 +245 -111
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/index.cjs +259 -118
- package/lib/players/index.cjs.map +1 -1
- package/lib/sdk/hlsAdPlayer.cjs +115 -23
- 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 +253 -113
- 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,13 +780,80 @@ 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");
|
|
776
854
|
const parserError = xmlDoc.querySelector("parsererror");
|
|
777
855
|
if (parserError) {
|
|
778
|
-
console.error("[HlsAdPlayer] XML parsing error:", parserError.textContent);
|
|
856
|
+
console.error("[HlsAdPlayer] XML parsing error (malformed VAST XML):", parserError.textContent);
|
|
779
857
|
return null;
|
|
780
858
|
}
|
|
781
859
|
const adElement = xmlDoc.querySelector("Ad");
|
|
@@ -784,28 +862,46 @@ 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
|
|
865
|
+
const title = ((_a = xmlDoc.querySelector("AdTitle")) == null ? void 0 : _a.textContent) || "Ad";
|
|
866
|
+
const isNoAdAvailable = adId === "empty" || title.toLowerCase().includes("no ad available") || title.toLowerCase() === "no ad available";
|
|
867
|
+
const durationText = ((_b = xmlDoc.querySelector("Duration")) == null ? void 0 : _b.textContent) || "00:00:30";
|
|
789
868
|
const durationParts = durationText.split(":");
|
|
790
869
|
const duration = parseInt(durationParts[0] || "0", 10) * 3600 + parseInt(durationParts[1] || "0", 10) * 60 + parseInt(durationParts[2] || "0", 10);
|
|
791
870
|
const mediaFileElements = xmlDoc.querySelectorAll("MediaFile");
|
|
792
871
|
const mediaFiles = [];
|
|
793
|
-
mediaFileElements.
|
|
872
|
+
console.log(`[HlsAdPlayer] Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`);
|
|
873
|
+
mediaFileElements.forEach((mf, index) => {
|
|
874
|
+
var _a2;
|
|
794
875
|
const type = mf.getAttribute("type") || "";
|
|
876
|
+
const url = ((_a2 = mf.textContent) == null ? void 0 : _a2.trim()) || "";
|
|
877
|
+
const width = mf.getAttribute("width") || "";
|
|
878
|
+
const height = mf.getAttribute("height") || "";
|
|
879
|
+
console.log(`[HlsAdPlayer] MediaFile ${index}: type="${type}", url="${url}", width="${width}", height="${height}"`);
|
|
795
880
|
if (type === "application/x-mpegURL" || type.includes("m3u8")) {
|
|
881
|
+
if (!url) {
|
|
882
|
+
console.warn(`[HlsAdPlayer] MediaFile ${index} has HLS type but empty URL`);
|
|
883
|
+
return;
|
|
884
|
+
}
|
|
796
885
|
const bitrateAttr = mf.getAttribute("bitrate");
|
|
797
886
|
const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;
|
|
798
887
|
mediaFiles.push({
|
|
799
|
-
url
|
|
888
|
+
url,
|
|
800
889
|
type,
|
|
801
|
-
width: parseInt(
|
|
802
|
-
height: parseInt(
|
|
890
|
+
width: parseInt(width || "1920", 10),
|
|
891
|
+
height: parseInt(height || "1080", 10),
|
|
803
892
|
bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : void 0
|
|
804
893
|
});
|
|
894
|
+
console.log(`[HlsAdPlayer] Added HLS MediaFile: ${url}`);
|
|
895
|
+
} else {
|
|
896
|
+
console.log(`[HlsAdPlayer] MediaFile ${index} ignored (type="${type}" is not HLS)`);
|
|
805
897
|
}
|
|
806
898
|
});
|
|
807
899
|
if (mediaFiles.length === 0) {
|
|
808
|
-
|
|
900
|
+
if (isNoAdAvailable) {
|
|
901
|
+
console.warn("[HlsAdPlayer] No ads available (VAST response indicates no ads)");
|
|
902
|
+
} else {
|
|
903
|
+
console.warn("[HlsAdPlayer] No HLS media files found in VAST XML");
|
|
904
|
+
}
|
|
809
905
|
return null;
|
|
810
906
|
}
|
|
811
907
|
const trackingUrls = {
|
|
@@ -825,12 +921,14 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
825
921
|
error: []
|
|
826
922
|
};
|
|
827
923
|
xmlDoc.querySelectorAll("Impression").forEach((el) => {
|
|
828
|
-
|
|
924
|
+
var _a2;
|
|
925
|
+
const url = (_a2 = el.textContent) == null ? void 0 : _a2.trim();
|
|
829
926
|
if (url) trackingUrls.impression.push(url);
|
|
830
927
|
});
|
|
831
928
|
xmlDoc.querySelectorAll("Tracking").forEach((el) => {
|
|
929
|
+
var _a2;
|
|
832
930
|
const event = el.getAttribute("event");
|
|
833
|
-
const url = el.textContent
|
|
931
|
+
const url = (_a2 = el.textContent) == null ? void 0 : _a2.trim();
|
|
834
932
|
if (event && url) {
|
|
835
933
|
const eventKey = event;
|
|
836
934
|
if (trackingUrls[eventKey]) {
|
|
@@ -838,7 +936,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
838
936
|
}
|
|
839
937
|
}
|
|
840
938
|
});
|
|
841
|
-
const clickThrough = xmlDoc.querySelector("ClickThrough")
|
|
939
|
+
const clickThrough = (_d = (_c = xmlDoc.querySelector("ClickThrough")) == null ? void 0 : _c.textContent) == null ? void 0 : _d.trim();
|
|
842
940
|
return {
|
|
843
941
|
id: adId,
|
|
844
942
|
title,
|
|
@@ -930,7 +1028,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
930
1028
|
adContainerEl.style.display = "none";
|
|
931
1029
|
adContainerEl.style.pointerEvents = "none";
|
|
932
1030
|
}
|
|
933
|
-
if (!options
|
|
1031
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
934
1032
|
contentVideo.play().catch(() => {
|
|
935
1033
|
});
|
|
936
1034
|
console.log("[HlsAdPlayer] Content resumed (VOD mode)");
|
|
@@ -948,7 +1046,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
948
1046
|
adContainerEl.style.display = "none";
|
|
949
1047
|
adContainerEl.style.pointerEvents = "none";
|
|
950
1048
|
}
|
|
951
|
-
if (!options
|
|
1049
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
952
1050
|
if (contentVideo.paused) {
|
|
953
1051
|
contentVideo.play().catch(() => {
|
|
954
1052
|
});
|
|
@@ -958,6 +1056,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
958
1056
|
}
|
|
959
1057
|
return {
|
|
960
1058
|
initialize() {
|
|
1059
|
+
var _a;
|
|
961
1060
|
console.log("[HlsAdPlayer] Initializing");
|
|
962
1061
|
if (!adContainerEl) {
|
|
963
1062
|
const container = document.createElement("div");
|
|
@@ -972,7 +1071,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
972
1071
|
container.style.pointerEvents = "none";
|
|
973
1072
|
container.style.zIndex = "2";
|
|
974
1073
|
container.style.backgroundColor = "#000";
|
|
975
|
-
contentVideo.parentElement
|
|
1074
|
+
(_a = contentVideo.parentElement) == null ? void 0 : _a.appendChild(container);
|
|
976
1075
|
adContainerEl = container;
|
|
977
1076
|
}
|
|
978
1077
|
},
|
|
@@ -990,9 +1089,11 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
990
1089
|
}
|
|
991
1090
|
const vastXml = await response.text();
|
|
992
1091
|
console.log("[HlsAdPlayer] VAST XML received");
|
|
1092
|
+
console.log("[HlsAdPlayer] VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
|
|
993
1093
|
const ad = parseVastXml(vastXml);
|
|
994
1094
|
if (!ad) {
|
|
995
|
-
|
|
1095
|
+
console.warn("[HlsAdPlayer] No ads available from VAST response");
|
|
1096
|
+
return Promise.resolve();
|
|
996
1097
|
}
|
|
997
1098
|
currentAd = ad;
|
|
998
1099
|
console.log(`[HlsAdPlayer] Ad parsed: ${ad.title}, duration: ${ad.duration}s`);
|
|
@@ -1007,14 +1108,14 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1007
1108
|
},
|
|
1008
1109
|
async play() {
|
|
1009
1110
|
if (!currentAd) {
|
|
1010
|
-
console.warn("[HlsAdPlayer] Cannot play: No ad loaded");
|
|
1111
|
+
console.warn("[HlsAdPlayer] Cannot play: No ad loaded (no ads available)");
|
|
1011
1112
|
return Promise.reject(new Error("No ad loaded"));
|
|
1012
1113
|
}
|
|
1013
1114
|
console.log("[HlsAdPlayer] Starting ad playback");
|
|
1014
1115
|
try {
|
|
1015
1116
|
if (!adVideoElement) {
|
|
1016
1117
|
adVideoElement = createAdVideoElement();
|
|
1017
|
-
adContainerEl
|
|
1118
|
+
adContainerEl == null ? void 0 : adContainerEl.appendChild(adVideoElement);
|
|
1018
1119
|
setupAdEventListeners();
|
|
1019
1120
|
}
|
|
1020
1121
|
trackingFired = {
|
|
@@ -1025,7 +1126,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1025
1126
|
thirdQuartile: false,
|
|
1026
1127
|
complete: false
|
|
1027
1128
|
};
|
|
1028
|
-
if (!options
|
|
1129
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
1029
1130
|
contentVideo.pause();
|
|
1030
1131
|
console.log("[HlsAdPlayer] Content paused (VOD mode)");
|
|
1031
1132
|
} else {
|
|
@@ -1038,7 +1139,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1038
1139
|
adContainerEl.style.pointerEvents = "auto";
|
|
1039
1140
|
}
|
|
1040
1141
|
emit("content_pause");
|
|
1041
|
-
const mediaFile = currentAd.mediaFiles
|
|
1142
|
+
const mediaFile = selectBestMediaFile(currentAd.mediaFiles);
|
|
1042
1143
|
if (!mediaFile) {
|
|
1043
1144
|
throw new Error("No media file available for ad");
|
|
1044
1145
|
}
|
|
@@ -1098,7 +1199,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1098
1199
|
adVideoElement.pause();
|
|
1099
1200
|
adVideoElement.src = "";
|
|
1100
1201
|
}
|
|
1101
|
-
if (!options
|
|
1202
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
1102
1203
|
contentVideo.play().catch(() => {
|
|
1103
1204
|
});
|
|
1104
1205
|
}
|
|
@@ -1118,7 +1219,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1118
1219
|
adVideoElement.remove();
|
|
1119
1220
|
adVideoElement = void 0;
|
|
1120
1221
|
}
|
|
1121
|
-
if (adContainerEl
|
|
1222
|
+
if (adContainerEl == null ? void 0 : adContainerEl.parentElement) {
|
|
1122
1223
|
adContainerEl.parentElement.removeChild(adContainerEl);
|
|
1123
1224
|
}
|
|
1124
1225
|
adContainerEl = void 0;
|
|
@@ -1144,7 +1245,8 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1144
1245
|
listeners.get(event).add(listener);
|
|
1145
1246
|
},
|
|
1146
1247
|
off(event, listener) {
|
|
1147
|
-
|
|
1248
|
+
var _a;
|
|
1249
|
+
(_a = listeners.get(event)) == null ? void 0 : _a.delete(listener);
|
|
1148
1250
|
},
|
|
1149
1251
|
updateOriginalMutedState(muted) {
|
|
1150
1252
|
originalMutedState = muted;
|
|
@@ -1169,6 +1271,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1169
1271
|
// src/utils/tracking.ts
|
|
1170
1272
|
var cachedBrowserId = null;
|
|
1171
1273
|
function getClientInfo() {
|
|
1274
|
+
var _a, _b, _c, _d;
|
|
1172
1275
|
const ua = navigator.userAgent;
|
|
1173
1276
|
const platform = navigator.platform;
|
|
1174
1277
|
const vendor = navigator.vendor || "";
|
|
@@ -1176,12 +1279,12 @@ function getClientInfo() {
|
|
|
1176
1279
|
const memory = navigator.deviceMemory || null;
|
|
1177
1280
|
const hardwareConcurrency = navigator.hardwareConcurrency || 1;
|
|
1178
1281
|
const screenInfo = {
|
|
1179
|
-
width: screen
|
|
1180
|
-
height: screen
|
|
1181
|
-
availWidth: screen
|
|
1182
|
-
availHeight: screen
|
|
1183
|
-
orientation: screen
|
|
1184
|
-
pixelDepth: screen
|
|
1282
|
+
width: screen == null ? void 0 : screen.width,
|
|
1283
|
+
height: screen == null ? void 0 : screen.height,
|
|
1284
|
+
availWidth: screen == null ? void 0 : screen.availWidth,
|
|
1285
|
+
availHeight: screen == null ? void 0 : screen.availHeight,
|
|
1286
|
+
orientation: ((_a = screen == null ? void 0 : screen.orientation) == null ? void 0 : _a.type) || "",
|
|
1287
|
+
pixelDepth: screen == null ? void 0 : screen.pixelDepth
|
|
1185
1288
|
};
|
|
1186
1289
|
let deviceType = "desktop";
|
|
1187
1290
|
let brand = "Unknown";
|
|
@@ -1278,10 +1381,10 @@ function getClientInfo() {
|
|
|
1278
1381
|
if (vendor.includes("Samsung") || ua.includes("SM-")) brand = "Samsung";
|
|
1279
1382
|
}
|
|
1280
1383
|
isWebView = /wv|WebView|Linux; U;/.test(ua);
|
|
1281
|
-
if (window
|
|
1384
|
+
if ((window == null ? void 0 : window.outerHeight) === 0 && (window == null ? void 0 : window.outerWidth) === 0) {
|
|
1282
1385
|
isWebView = true;
|
|
1283
1386
|
}
|
|
1284
|
-
isWebApp = window.matchMedia("(display-mode: standalone)").matches || window.navigator.standalone === true || window.screen
|
|
1387
|
+
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
1388
|
return {
|
|
1286
1389
|
brand,
|
|
1287
1390
|
os,
|
|
@@ -1302,7 +1405,7 @@ function getClientInfo() {
|
|
|
1302
1405
|
deviceMemory: memory,
|
|
1303
1406
|
maxTouchPoints,
|
|
1304
1407
|
language: navigator.language,
|
|
1305
|
-
languages: navigator.languages
|
|
1408
|
+
languages: ((_d = navigator.languages) == null ? void 0 : _d.join(",")) || "",
|
|
1306
1409
|
cookieEnabled: navigator.cookieEnabled,
|
|
1307
1410
|
doNotTrack: navigator.doNotTrack || "",
|
|
1308
1411
|
referrer: document.referrer,
|
|
@@ -1660,7 +1763,8 @@ var StormcloudVideoPlayer = class {
|
|
|
1660
1763
|
}
|
|
1661
1764
|
return createHlsAdPlayer(this.video, {
|
|
1662
1765
|
continueLiveStreamDuringAds,
|
|
1663
|
-
...this.config.licenseKey ? { licenseKey: this.config.licenseKey } : {}
|
|
1766
|
+
...this.config.licenseKey ? { licenseKey: this.config.licenseKey } : {},
|
|
1767
|
+
...this.hls ? { mainHlsInstance: this.hls } : {}
|
|
1664
1768
|
});
|
|
1665
1769
|
} else {
|
|
1666
1770
|
if (this.config.debugAdTiming) {
|
|
@@ -1672,6 +1776,7 @@ var StormcloudVideoPlayer = class {
|
|
|
1672
1776
|
}
|
|
1673
1777
|
}
|
|
1674
1778
|
async load() {
|
|
1779
|
+
var _a, _b;
|
|
1675
1780
|
if (!this.attached) {
|
|
1676
1781
|
this.attach();
|
|
1677
1782
|
}
|
|
@@ -1688,7 +1793,7 @@ var StormcloudVideoPlayer = class {
|
|
|
1688
1793
|
this.initializeTracking();
|
|
1689
1794
|
if (this.shouldUseNativeHls()) {
|
|
1690
1795
|
this.video.src = this.config.src;
|
|
1691
|
-
this.isLiveStream = this.config.lowLatencyMode
|
|
1796
|
+
this.isLiveStream = (_a = this.config.lowLatencyMode) != null ? _a : false;
|
|
1692
1797
|
if (this.config.debugAdTiming) {
|
|
1693
1798
|
console.log(
|
|
1694
1799
|
"[StormcloudVideoPlayer] allowNativeHls: true - VOD mode detected:",
|
|
@@ -1703,8 +1808,8 @@ var StormcloudVideoPlayer = class {
|
|
|
1703
1808
|
this.ima = this.createAdPlayer(false);
|
|
1704
1809
|
this.ima.initialize();
|
|
1705
1810
|
if (this.config.autoplay) {
|
|
1706
|
-
await this.video.play()
|
|
1707
|
-
});
|
|
1811
|
+
await ((_b = this.video.play()) == null ? void 0 : _b.catch(() => {
|
|
1812
|
+
}));
|
|
1708
1813
|
}
|
|
1709
1814
|
return;
|
|
1710
1815
|
}
|
|
@@ -1717,12 +1822,17 @@ var StormcloudVideoPlayer = class {
|
|
|
1717
1822
|
...this.config.lowLatencyMode ? { liveSyncDuration: 2 } : {}
|
|
1718
1823
|
});
|
|
1719
1824
|
this.hls.on(import_hls2.default.Events.MEDIA_ATTACHED, () => {
|
|
1720
|
-
|
|
1825
|
+
var _a2;
|
|
1826
|
+
(_a2 = this.hls) == null ? void 0 : _a2.loadSource(this.config.src);
|
|
1721
1827
|
});
|
|
1722
1828
|
this.hls.on(import_hls2.default.Events.MANIFEST_PARSED, async (_, data) => {
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1829
|
+
var _a2, _b2, _c, _d;
|
|
1830
|
+
this.isLiveStream = (_c = (_b2 = (_a2 = this.hls) == null ? void 0 : _a2.levels) == null ? void 0 : _b2.some(
|
|
1831
|
+
(level) => {
|
|
1832
|
+
var _a3, _b3;
|
|
1833
|
+
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";
|
|
1834
|
+
}
|
|
1835
|
+
)) != null ? _c : false;
|
|
1726
1836
|
if (this.config.debugAdTiming) {
|
|
1727
1837
|
const adBehavior = this.shouldContinueLiveStreamDuringAds() ? "live (main video continues muted during ads)" : "vod (main video pauses during ads)";
|
|
1728
1838
|
console.log("[StormcloudVideoPlayer] Stream type detected:", {
|
|
@@ -1735,28 +1845,29 @@ var StormcloudVideoPlayer = class {
|
|
|
1735
1845
|
this.ima = this.createAdPlayer(this.shouldContinueLiveStreamDuringAds());
|
|
1736
1846
|
this.ima.initialize();
|
|
1737
1847
|
if (this.config.autoplay) {
|
|
1738
|
-
await this.video.play()
|
|
1739
|
-
});
|
|
1848
|
+
await ((_d = this.video.play()) == null ? void 0 : _d.catch(() => {
|
|
1849
|
+
}));
|
|
1740
1850
|
}
|
|
1741
1851
|
});
|
|
1742
1852
|
this.hls.on(import_hls2.default.Events.FRAG_PARSING_METADATA, (_evt, data) => {
|
|
1743
|
-
const id3Tags = (data
|
|
1853
|
+
const id3Tags = ((data == null ? void 0 : data.samples) || []).map((s) => ({
|
|
1744
1854
|
key: "ID3",
|
|
1745
|
-
value: s
|
|
1746
|
-
ptsSeconds: s
|
|
1855
|
+
value: s == null ? void 0 : s.data,
|
|
1856
|
+
ptsSeconds: s == null ? void 0 : s.pts
|
|
1747
1857
|
}));
|
|
1748
1858
|
id3Tags.forEach((tag) => this.onId3Tag(tag));
|
|
1749
1859
|
});
|
|
1750
1860
|
this.hls.on(import_hls2.default.Events.FRAG_CHANGED, (_evt, data) => {
|
|
1751
|
-
|
|
1752
|
-
const
|
|
1861
|
+
var _a2, _b2, _c;
|
|
1862
|
+
const frag = data == null ? void 0 : data.frag;
|
|
1863
|
+
const tagList = frag == null ? void 0 : frag.tagList;
|
|
1753
1864
|
if (!Array.isArray(tagList)) return;
|
|
1754
1865
|
for (const entry of tagList) {
|
|
1755
1866
|
let tag = "";
|
|
1756
1867
|
let value = "";
|
|
1757
1868
|
if (Array.isArray(entry)) {
|
|
1758
|
-
tag = String(entry[0]
|
|
1759
|
-
value = String(entry[1]
|
|
1869
|
+
tag = String((_a2 = entry[0]) != null ? _a2 : "");
|
|
1870
|
+
value = String((_b2 = entry[1]) != null ? _b2 : "");
|
|
1760
1871
|
} else if (typeof entry === "string") {
|
|
1761
1872
|
const idx = entry.indexOf(":");
|
|
1762
1873
|
if (idx >= 0) {
|
|
@@ -1780,8 +1891,8 @@ var StormcloudVideoPlayer = class {
|
|
|
1780
1891
|
const prog = this.parseCueOutCont(value);
|
|
1781
1892
|
const marker = {
|
|
1782
1893
|
type: "progress",
|
|
1783
|
-
...prog
|
|
1784
|
-
...prog
|
|
1894
|
+
...(prog == null ? void 0 : prog.duration) !== void 0 ? { durationSeconds: prog.duration } : {},
|
|
1895
|
+
...(prog == null ? void 0 : prog.elapsed) !== void 0 ? { ptsSeconds: prog.elapsed } : {},
|
|
1785
1896
|
raw: { tag, value }
|
|
1786
1897
|
};
|
|
1787
1898
|
this.onScte35Marker(marker);
|
|
@@ -1791,7 +1902,7 @@ var StormcloudVideoPlayer = class {
|
|
|
1791
1902
|
const attrs = this.parseAttributeList(value);
|
|
1792
1903
|
const hasScteOut = "SCTE35-OUT" in attrs || attrs["SCTE35-OUT"] !== void 0;
|
|
1793
1904
|
const hasScteIn = "SCTE35-IN" in attrs || attrs["SCTE35-IN"] !== void 0;
|
|
1794
|
-
const klass = String(attrs["CLASS"]
|
|
1905
|
+
const klass = String((_c = attrs["CLASS"]) != null ? _c : "");
|
|
1795
1906
|
const duration = this.toNumber(attrs["DURATION"]);
|
|
1796
1907
|
if (hasScteOut || /com\.apple\.hls\.cue/i.test(klass)) {
|
|
1797
1908
|
const marker = {
|
|
@@ -1808,13 +1919,14 @@ var StormcloudVideoPlayer = class {
|
|
|
1808
1919
|
}
|
|
1809
1920
|
});
|
|
1810
1921
|
this.hls.on(import_hls2.default.Events.ERROR, (_evt, data) => {
|
|
1811
|
-
|
|
1922
|
+
var _a2, _b2;
|
|
1923
|
+
if (data == null ? void 0 : data.fatal) {
|
|
1812
1924
|
switch (data.type) {
|
|
1813
1925
|
case import_hls2.default.ErrorTypes.NETWORK_ERROR:
|
|
1814
|
-
this.hls
|
|
1926
|
+
(_a2 = this.hls) == null ? void 0 : _a2.startLoad();
|
|
1815
1927
|
break;
|
|
1816
1928
|
case import_hls2.default.ErrorTypes.MEDIA_ERROR:
|
|
1817
|
-
this.hls
|
|
1929
|
+
(_b2 = this.hls) == null ? void 0 : _b2.recoverMediaError();
|
|
1818
1930
|
break;
|
|
1819
1931
|
default:
|
|
1820
1932
|
this.destroy();
|
|
@@ -1916,11 +2028,12 @@ var StormcloudVideoPlayer = class {
|
|
|
1916
2028
|
}
|
|
1917
2029
|
}
|
|
1918
2030
|
parseScte35FromId3(tag) {
|
|
2031
|
+
var _a, _b, _c, _d;
|
|
1919
2032
|
const text = this.decodeId3ValueToText(tag.value);
|
|
1920
2033
|
if (!text) return void 0;
|
|
1921
2034
|
const cueOutMatch = text.match(/EXT-X-CUE-OUT(?::([^\r\n]*))?/i) || text.match(/CUE-OUT(?::([^\r\n]*))?/i);
|
|
1922
2035
|
if (cueOutMatch) {
|
|
1923
|
-
const arg = (cueOutMatch[1]
|
|
2036
|
+
const arg = ((_a = cueOutMatch[1]) != null ? _a : "").trim();
|
|
1924
2037
|
const dur = this.parseCueOutDuration(arg);
|
|
1925
2038
|
const marker = {
|
|
1926
2039
|
type: "start",
|
|
@@ -1932,12 +2045,12 @@ var StormcloudVideoPlayer = class {
|
|
|
1932
2045
|
}
|
|
1933
2046
|
const cueOutContMatch = text.match(/EXT-X-CUE-OUT-CONT:([^\r\n]*)/i);
|
|
1934
2047
|
if (cueOutContMatch) {
|
|
1935
|
-
const arg = (cueOutContMatch[1]
|
|
2048
|
+
const arg = ((_b = cueOutContMatch[1]) != null ? _b : "").trim();
|
|
1936
2049
|
const cont = this.parseCueOutCont(arg);
|
|
1937
2050
|
const marker = {
|
|
1938
2051
|
type: "progress",
|
|
1939
2052
|
...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},
|
|
1940
|
-
...cont
|
|
2053
|
+
...(cont == null ? void 0 : cont.duration) !== void 0 ? { durationSeconds: cont.duration } : {},
|
|
1941
2054
|
raw: { id3: text }
|
|
1942
2055
|
};
|
|
1943
2056
|
return marker;
|
|
@@ -1953,10 +2066,10 @@ var StormcloudVideoPlayer = class {
|
|
|
1953
2066
|
}
|
|
1954
2067
|
const daterangeMatch = text.match(/EXT-X-DATERANGE:([^\r\n]*)/i);
|
|
1955
2068
|
if (daterangeMatch) {
|
|
1956
|
-
const attrs = this.parseAttributeList(daterangeMatch[1]
|
|
2069
|
+
const attrs = this.parseAttributeList((_c = daterangeMatch[1]) != null ? _c : "");
|
|
1957
2070
|
const hasScteOut = "SCTE35-OUT" in attrs || attrs["SCTE35-OUT"] !== void 0;
|
|
1958
2071
|
const hasScteIn = "SCTE35-IN" in attrs || attrs["SCTE35-IN"] !== void 0;
|
|
1959
|
-
const klass = String(attrs["CLASS"]
|
|
2072
|
+
const klass = String((_d = attrs["CLASS"]) != null ? _d : "");
|
|
1960
2073
|
const duration = this.toNumber(attrs["DURATION"]);
|
|
1961
2074
|
if (hasScteOut || /com\.apple\.hls\.cue/i.test(klass)) {
|
|
1962
2075
|
const marker = {
|
|
@@ -2013,6 +2126,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2013
2126
|
}
|
|
2014
2127
|
}
|
|
2015
2128
|
onScte35Marker(marker) {
|
|
2129
|
+
var _a, _b;
|
|
2016
2130
|
if (this.config.debugAdTiming) {
|
|
2017
2131
|
console.log("[StormcloudVideoPlayer] SCTE-35 marker detected:", {
|
|
2018
2132
|
type: marker.type,
|
|
@@ -2028,7 +2142,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2028
2142
|
this.expectedAdBreakDurationMs = durationMs;
|
|
2029
2143
|
this.currentAdBreakStartWallClockMs = Date.now();
|
|
2030
2144
|
const isManifestMarker = this.isManifestBasedMarker(marker);
|
|
2031
|
-
const forceImmediate = this.config.immediateManifestAds
|
|
2145
|
+
const forceImmediate = (_a = this.config.immediateManifestAds) != null ? _a : true;
|
|
2032
2146
|
if (this.config.debugAdTiming) {
|
|
2033
2147
|
console.log("[StormcloudVideoPlayer] Ad start decision:", {
|
|
2034
2148
|
isManifestMarker,
|
|
@@ -2045,7 +2159,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2045
2159
|
this.clearAdStartTimer();
|
|
2046
2160
|
this.handleAdStart(marker);
|
|
2047
2161
|
} else if (typeof marker.ptsSeconds === "number") {
|
|
2048
|
-
const tol = this.config.driftToleranceMs
|
|
2162
|
+
const tol = (_b = this.config.driftToleranceMs) != null ? _b : 1e3;
|
|
2049
2163
|
const nowMs = this.video.currentTime * 1e3;
|
|
2050
2164
|
const estCurrentPtsMs = nowMs - this.ptsDriftEmaMs;
|
|
2051
2165
|
const deltaMs = Math.floor(marker.ptsSeconds * 1e3 - estCurrentPtsMs);
|
|
@@ -2155,12 +2269,13 @@ var StormcloudVideoPlayer = class {
|
|
|
2155
2269
|
return void 0;
|
|
2156
2270
|
}
|
|
2157
2271
|
parseAttributeList(value) {
|
|
2272
|
+
var _a, _b, _c;
|
|
2158
2273
|
const attrs = {};
|
|
2159
2274
|
const regex = /([A-Z0-9-]+)=(("[^"]*")|([^",]*))(?:,|$)/gi;
|
|
2160
2275
|
let match;
|
|
2161
2276
|
while ((match = regex.exec(value)) !== null) {
|
|
2162
|
-
const key = match[1]
|
|
2163
|
-
let rawVal = match[3]
|
|
2277
|
+
const key = (_a = match[1]) != null ? _a : "";
|
|
2278
|
+
let rawVal = (_c = (_b = match[3]) != null ? _b : match[4]) != null ? _c : "";
|
|
2164
2279
|
if (rawVal.startsWith('"') && rawVal.endsWith('"')) {
|
|
2165
2280
|
rawVal = rawVal.slice(1, -1);
|
|
2166
2281
|
}
|
|
@@ -2324,6 +2439,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2324
2439
|
}
|
|
2325
2440
|
}
|
|
2326
2441
|
async fetchAdConfiguration() {
|
|
2442
|
+
var _a, _b, _c;
|
|
2327
2443
|
const vastMode = this.config.vastMode || "default";
|
|
2328
2444
|
if (this.config.debugAdTiming) {
|
|
2329
2445
|
console.log(
|
|
@@ -2344,7 +2460,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2344
2460
|
this.apiVastTagUrl = vastEndpoint;
|
|
2345
2461
|
if (this.config.debugAdTiming) {
|
|
2346
2462
|
console.log(
|
|
2347
|
-
"[StormcloudVideoPlayer] Using AdStorm VAST endpoint:",
|
|
2463
|
+
"[StormcloudVideoPlayer] Using AdStorm VAST endpoint (adstorm mode):",
|
|
2348
2464
|
vastEndpoint
|
|
2349
2465
|
);
|
|
2350
2466
|
}
|
|
@@ -2381,7 +2497,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2381
2497
|
return;
|
|
2382
2498
|
}
|
|
2383
2499
|
const data = await response.json();
|
|
2384
|
-
const imaPayload = data.response
|
|
2500
|
+
const imaPayload = (_c = (_b = (_a = data.response) == null ? void 0 : _a.ima) == null ? void 0 : _b["publisherdesk.ima"]) == null ? void 0 : _c.payload;
|
|
2385
2501
|
if (imaPayload) {
|
|
2386
2502
|
this.apiVastTagUrl = decodeURIComponent(imaPayload);
|
|
2387
2503
|
if (this.config.debugAdTiming) {
|
|
@@ -2418,11 +2534,12 @@ var StormcloudVideoPlayer = class {
|
|
|
2418
2534
|
return "other";
|
|
2419
2535
|
}
|
|
2420
2536
|
shouldShowNativeControls() {
|
|
2537
|
+
var _a, _b;
|
|
2421
2538
|
const streamType = this.getStreamType();
|
|
2422
2539
|
if (streamType === "other") {
|
|
2423
|
-
return !(this.config.showCustomControls
|
|
2540
|
+
return !((_a = this.config.showCustomControls) != null ? _a : false);
|
|
2424
2541
|
}
|
|
2425
|
-
return !!(this.config.allowNativeHls && !(this.config.showCustomControls
|
|
2542
|
+
return !!(this.config.allowNativeHls && !((_b = this.config.showCustomControls) != null ? _b : false));
|
|
2426
2543
|
}
|
|
2427
2544
|
shouldContinueLiveStreamDuringAds() {
|
|
2428
2545
|
if (this.config.allowNativeHls) {
|
|
@@ -2434,6 +2551,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2434
2551
|
return true;
|
|
2435
2552
|
}
|
|
2436
2553
|
async handleAdStart(_marker) {
|
|
2554
|
+
var _a;
|
|
2437
2555
|
const scheduled = this.findCurrentOrNextBreak(
|
|
2438
2556
|
this.video.currentTime * 1e3
|
|
2439
2557
|
);
|
|
@@ -2484,17 +2602,18 @@ var StormcloudVideoPlayer = class {
|
|
|
2484
2602
|
this.handleAdFailure();
|
|
2485
2603
|
}
|
|
2486
2604
|
}
|
|
2487
|
-
if (this.expectedAdBreakDurationMs == null && scheduled
|
|
2605
|
+
if (this.expectedAdBreakDurationMs == null && (scheduled == null ? void 0 : scheduled.durationMs) != null) {
|
|
2488
2606
|
this.expectedAdBreakDurationMs = scheduled.durationMs;
|
|
2489
|
-
this.currentAdBreakStartWallClockMs = this.currentAdBreakStartWallClockMs
|
|
2607
|
+
this.currentAdBreakStartWallClockMs = (_a = this.currentAdBreakStartWallClockMs) != null ? _a : Date.now();
|
|
2490
2608
|
this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);
|
|
2491
2609
|
}
|
|
2492
2610
|
}
|
|
2493
2611
|
findCurrentOrNextBreak(nowMs) {
|
|
2612
|
+
var _a;
|
|
2494
2613
|
const schedule = [];
|
|
2495
2614
|
let candidate;
|
|
2496
2615
|
for (const b of schedule) {
|
|
2497
|
-
const tol = this.config.driftToleranceMs
|
|
2616
|
+
const tol = (_a = this.config.driftToleranceMs) != null ? _a : 1e3;
|
|
2498
2617
|
if (b.startTimeMs <= nowMs + tol && (candidate == null || b.startTimeMs > (candidate.startTimeMs || 0))) {
|
|
2499
2618
|
candidate = b;
|
|
2500
2619
|
}
|
|
@@ -2510,7 +2629,8 @@ var StormcloudVideoPlayer = class {
|
|
|
2510
2629
|
}
|
|
2511
2630
|
}
|
|
2512
2631
|
async handleMidAdJoin(adBreak, nowMs) {
|
|
2513
|
-
|
|
2632
|
+
var _a;
|
|
2633
|
+
const durationMs = (_a = adBreak.durationMs) != null ? _a : 0;
|
|
2514
2634
|
const endMs = adBreak.startTimeMs + durationMs;
|
|
2515
2635
|
if (durationMs > 0 && nowMs > adBreak.startTimeMs && nowMs < endMs) {
|
|
2516
2636
|
const remainingMs = endMs - nowMs;
|
|
@@ -2596,12 +2716,20 @@ var StormcloudVideoPlayer = class {
|
|
|
2596
2716
|
this.startAdFailsafeTimer();
|
|
2597
2717
|
try {
|
|
2598
2718
|
await this.ima.requestAds(vastTagUrl);
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2719
|
+
try {
|
|
2720
|
+
if (this.config.debugAdTiming) {
|
|
2721
|
+
console.log("[StormcloudVideoPlayer] Ad request completed, attempting playback");
|
|
2722
|
+
}
|
|
2723
|
+
await this.ima.play();
|
|
2724
|
+
if (this.config.debugAdTiming) {
|
|
2725
|
+
console.log("[StormcloudVideoPlayer] Ad playback started successfully");
|
|
2726
|
+
}
|
|
2727
|
+
} catch (playError) {
|
|
2728
|
+
if (this.config.debugAdTiming) {
|
|
2729
|
+
console.log("[StormcloudVideoPlayer] No ads available, skipping playback");
|
|
2730
|
+
}
|
|
2731
|
+
this.handleAdFailure();
|
|
2732
|
+
return;
|
|
2605
2733
|
}
|
|
2606
2734
|
} catch (error) {
|
|
2607
2735
|
if (this.config.debugAdTiming) {
|
|
@@ -2611,6 +2739,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2611
2739
|
}
|
|
2612
2740
|
}
|
|
2613
2741
|
handleAdFailure() {
|
|
2742
|
+
var _a;
|
|
2614
2743
|
if (this.config.debugAdTiming) {
|
|
2615
2744
|
console.log(
|
|
2616
2745
|
"[StormcloudVideoPlayer] Handling ad failure - resuming content",
|
|
@@ -2643,7 +2772,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2643
2772
|
if (this.config.debugAdTiming) {
|
|
2644
2773
|
console.log("[StormcloudVideoPlayer] Resuming paused video");
|
|
2645
2774
|
}
|
|
2646
|
-
this.video.play()
|
|
2775
|
+
(_a = this.video.play()) == null ? void 0 : _a.catch((error) => {
|
|
2647
2776
|
if (this.config.debugAdTiming) {
|
|
2648
2777
|
console.error(
|
|
2649
2778
|
"[StormcloudVideoPlayer] Failed to resume video after ad failure:",
|
|
@@ -2658,8 +2787,9 @@ var StormcloudVideoPlayer = class {
|
|
|
2658
2787
|
}
|
|
2659
2788
|
}
|
|
2660
2789
|
startAdFailsafeTimer() {
|
|
2790
|
+
var _a;
|
|
2661
2791
|
this.clearAdFailsafeTimer();
|
|
2662
|
-
const failsafeMs = this.config.adFailsafeTimeoutMs
|
|
2792
|
+
const failsafeMs = (_a = this.config.adFailsafeTimeoutMs) != null ? _a : 1e4;
|
|
2663
2793
|
if (this.config.debugAdTiming) {
|
|
2664
2794
|
console.log(
|
|
2665
2795
|
`[StormcloudVideoPlayer] Starting failsafe timer (${failsafeMs}ms)`
|
|
@@ -2795,6 +2925,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2795
2925
|
}
|
|
2796
2926
|
}
|
|
2797
2927
|
destroy() {
|
|
2928
|
+
var _a, _b;
|
|
2798
2929
|
this.clearAdStartTimer();
|
|
2799
2930
|
this.clearAdStopTimer();
|
|
2800
2931
|
this.clearAdFailsafeTimer();
|
|
@@ -2802,8 +2933,8 @@ var StormcloudVideoPlayer = class {
|
|
|
2802
2933
|
clearInterval(this.heartbeatInterval);
|
|
2803
2934
|
this.heartbeatInterval = void 0;
|
|
2804
2935
|
}
|
|
2805
|
-
this.hls
|
|
2806
|
-
this.ima
|
|
2936
|
+
(_a = this.hls) == null ? void 0 : _a.destroy();
|
|
2937
|
+
(_b = this.ima) == null ? void 0 : _b.destroy();
|
|
2807
2938
|
}
|
|
2808
2939
|
};
|
|
2809
2940
|
|
|
@@ -2843,6 +2974,7 @@ var HlsPlayer = class extends import_react.Component {
|
|
|
2843
2974
|
this.player = null;
|
|
2844
2975
|
this.mounted = false;
|
|
2845
2976
|
this.load = async () => {
|
|
2977
|
+
var _a, _b, _c, _d, _e, _f;
|
|
2846
2978
|
if (!this.props.videoElement || !this.props.src) return;
|
|
2847
2979
|
try {
|
|
2848
2980
|
if (this.player) {
|
|
@@ -2879,27 +3011,29 @@ var HlsPlayer = class extends import_react.Component {
|
|
|
2879
3011
|
if (this.props.adFailsafeTimeoutMs !== void 0)
|
|
2880
3012
|
config.adFailsafeTimeoutMs = this.props.adFailsafeTimeoutMs;
|
|
2881
3013
|
this.player = new StormcloudVideoPlayer(config);
|
|
2882
|
-
this.props.onMount
|
|
3014
|
+
(_b = (_a = this.props).onMount) == null ? void 0 : _b.call(_a, this);
|
|
2883
3015
|
await this.player.load();
|
|
2884
3016
|
if (this.mounted) {
|
|
2885
|
-
this.props.onReady
|
|
3017
|
+
(_d = (_c = this.props).onReady) == null ? void 0 : _d.call(_c);
|
|
2886
3018
|
}
|
|
2887
3019
|
} catch (error) {
|
|
2888
3020
|
if (this.mounted) {
|
|
2889
|
-
this.props.onError
|
|
3021
|
+
(_f = (_e = this.props).onError) == null ? void 0 : _f.call(_e, error);
|
|
2890
3022
|
}
|
|
2891
3023
|
}
|
|
2892
3024
|
};
|
|
2893
3025
|
this.play = () => {
|
|
3026
|
+
var _a, _b;
|
|
2894
3027
|
if (this.props.videoElement) {
|
|
2895
3028
|
this.props.videoElement.play();
|
|
2896
|
-
this.props.onPlay
|
|
3029
|
+
(_b = (_a = this.props).onPlay) == null ? void 0 : _b.call(_a);
|
|
2897
3030
|
}
|
|
2898
3031
|
};
|
|
2899
3032
|
this.pause = () => {
|
|
3033
|
+
var _a, _b;
|
|
2900
3034
|
if (this.props.videoElement) {
|
|
2901
3035
|
this.props.videoElement.pause();
|
|
2902
|
-
this.props.onPause
|
|
3036
|
+
(_b = (_a = this.props).onPause) == null ? void 0 : _b.call(_a);
|
|
2903
3037
|
}
|
|
2904
3038
|
};
|
|
2905
3039
|
this.stop = () => {
|