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
|
@@ -45,7 +45,8 @@ function getWebKitVersion(ua) {
|
|
|
45
45
|
return match && match[1] ? parseInt(match[1], 10) : 0;
|
|
46
46
|
}
|
|
47
47
|
function getPlatform() {
|
|
48
|
-
|
|
48
|
+
var _a;
|
|
49
|
+
if ("userAgentData" in navigator && ((_a = navigator.userAgentData) == null ? void 0 : _a.platform)) {
|
|
49
50
|
return navigator.userAgentData.platform;
|
|
50
51
|
}
|
|
51
52
|
const ua = navigator.userAgent;
|
|
@@ -210,6 +211,7 @@ function createImaController(video, options) {
|
|
|
210
211
|
}
|
|
211
212
|
}
|
|
212
213
|
function ensureImaLoaded() {
|
|
214
|
+
var _a, _b, _c;
|
|
213
215
|
if (!supportsGoogleIMA()) {
|
|
214
216
|
console.warn(
|
|
215
217
|
"[IMA] Google IMA SDK is not supported on this browser. Please use HLS ad player instead."
|
|
@@ -220,7 +222,7 @@ function createImaController(video, options) {
|
|
|
220
222
|
}
|
|
221
223
|
try {
|
|
222
224
|
const frameEl = window.frameElement;
|
|
223
|
-
const sandboxAttr = frameEl
|
|
225
|
+
const sandboxAttr = ((_a = frameEl == null ? void 0 : frameEl.getAttribute) == null ? void 0 : _a.call(frameEl, "sandbox")) || "";
|
|
224
226
|
if (sandboxAttr) {
|
|
225
227
|
const tokens = new Set(
|
|
226
228
|
sandboxAttr.split(/\s+/).map((t) => t.trim()).filter((t) => t.length > 0)
|
|
@@ -234,13 +236,13 @@ function createImaController(video, options) {
|
|
|
234
236
|
}
|
|
235
237
|
} catch {
|
|
236
238
|
}
|
|
237
|
-
if (typeof window !== "undefined" && window.google
|
|
239
|
+
if (typeof window !== "undefined" && ((_b = window.google) == null ? void 0 : _b.ima))
|
|
238
240
|
return Promise.resolve();
|
|
239
241
|
const existing = document.querySelector(
|
|
240
242
|
'script[data-ima="true"]'
|
|
241
243
|
);
|
|
242
244
|
if (existing) {
|
|
243
|
-
if (window.google
|
|
245
|
+
if ((_c = window.google) == null ? void 0 : _c.ima) {
|
|
244
246
|
return Promise.resolve();
|
|
245
247
|
}
|
|
246
248
|
return new Promise((resolve, reject) => {
|
|
@@ -298,6 +300,7 @@ function createImaController(video, options) {
|
|
|
298
300
|
return {
|
|
299
301
|
initialize() {
|
|
300
302
|
ensureImaLoaded().then(() => {
|
|
303
|
+
var _a, _b;
|
|
301
304
|
const google = window.google;
|
|
302
305
|
if (!adDisplayContainer) {
|
|
303
306
|
const container = document.createElement("div");
|
|
@@ -311,14 +314,14 @@ function createImaController(video, options) {
|
|
|
311
314
|
container.style.justifyContent = "center";
|
|
312
315
|
container.style.pointerEvents = "none";
|
|
313
316
|
container.style.zIndex = "2";
|
|
314
|
-
video.parentElement
|
|
317
|
+
(_a = video.parentElement) == null ? void 0 : _a.appendChild(container);
|
|
315
318
|
adContainerEl = container;
|
|
316
319
|
adDisplayContainer = new google.ima.AdDisplayContainer(
|
|
317
320
|
container,
|
|
318
321
|
video
|
|
319
322
|
);
|
|
320
323
|
try {
|
|
321
|
-
adDisplayContainer.initialize
|
|
324
|
+
(_b = adDisplayContainer.initialize) == null ? void 0 : _b.call(adDisplayContainer);
|
|
322
325
|
} catch {
|
|
323
326
|
}
|
|
324
327
|
}
|
|
@@ -403,6 +406,7 @@ function createImaController(video, options) {
|
|
|
403
406
|
adsManager.addEventListener(
|
|
404
407
|
AdErrorEvent.AD_ERROR,
|
|
405
408
|
(errorEvent) => {
|
|
409
|
+
var _a;
|
|
406
410
|
console.error("[IMA] Ad error:", errorEvent.getError());
|
|
407
411
|
destroyAdsManager();
|
|
408
412
|
adPlaying = false;
|
|
@@ -433,10 +437,10 @@ function createImaController(video, options) {
|
|
|
433
437
|
"[IMA] Max retries reached, emitting ad_error"
|
|
434
438
|
);
|
|
435
439
|
emit("ad_error");
|
|
436
|
-
if (!options
|
|
440
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
437
441
|
if (video.paused) {
|
|
438
442
|
console.log("[IMA] Resuming paused video after ad error");
|
|
439
|
-
video.play()
|
|
443
|
+
(_a = video.play()) == null ? void 0 : _a.catch(() => {
|
|
440
444
|
});
|
|
441
445
|
}
|
|
442
446
|
}
|
|
@@ -447,7 +451,7 @@ function createImaController(video, options) {
|
|
|
447
451
|
AdEvent.CONTENT_PAUSE_REQUESTED,
|
|
448
452
|
() => {
|
|
449
453
|
console.log("[IMA] Content pause requested");
|
|
450
|
-
if (!options
|
|
454
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
451
455
|
video.pause();
|
|
452
456
|
console.log("[IMA] Video paused (VOD mode)");
|
|
453
457
|
} else {
|
|
@@ -473,6 +477,7 @@ function createImaController(video, options) {
|
|
|
473
477
|
adsManager.addEventListener(
|
|
474
478
|
AdEvent.CONTENT_RESUME_REQUESTED,
|
|
475
479
|
() => {
|
|
480
|
+
var _a;
|
|
476
481
|
console.log("[IMA] Content resume requested");
|
|
477
482
|
adPlaying = false;
|
|
478
483
|
video.muted = originalMutedState;
|
|
@@ -483,8 +488,8 @@ function createImaController(video, options) {
|
|
|
483
488
|
"[IMA] Ad container hidden - pointer events disabled"
|
|
484
489
|
);
|
|
485
490
|
}
|
|
486
|
-
if (!options
|
|
487
|
-
video.play()
|
|
491
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
492
|
+
(_a = video.play()) == null ? void 0 : _a.catch(() => {
|
|
488
493
|
});
|
|
489
494
|
console.log("[IMA] Video resumed (VOD mode)");
|
|
490
495
|
} else {
|
|
@@ -506,7 +511,7 @@ function createImaController(video, options) {
|
|
|
506
511
|
"[IMA] Ad container hidden after all ads completed"
|
|
507
512
|
);
|
|
508
513
|
}
|
|
509
|
-
if (!options
|
|
514
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
510
515
|
video.play().catch(() => {
|
|
511
516
|
});
|
|
512
517
|
console.log(
|
|
@@ -534,7 +539,7 @@ function createImaController(video, options) {
|
|
|
534
539
|
adContainerEl.style.display = "none";
|
|
535
540
|
console.log("[IMA] Ad container hidden after setup error");
|
|
536
541
|
}
|
|
537
|
-
if (!options
|
|
542
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
538
543
|
if (video.paused) {
|
|
539
544
|
console.log("[IMA] Resuming paused video after setup error");
|
|
540
545
|
video.play().catch(() => {
|
|
@@ -562,7 +567,7 @@ function createImaController(video, options) {
|
|
|
562
567
|
adContainerEl.style.display = "none";
|
|
563
568
|
console.log("[IMA] Ad container hidden after loader error");
|
|
564
569
|
}
|
|
565
|
-
if (!options
|
|
570
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
566
571
|
if (video.paused) {
|
|
567
572
|
console.log("[IMA] Resuming paused video after loader error");
|
|
568
573
|
video.play().catch(() => {
|
|
@@ -584,14 +589,15 @@ function createImaController(video, options) {
|
|
|
584
589
|
return adsLoadedPromise;
|
|
585
590
|
} catch (error) {
|
|
586
591
|
console.error("[IMA] Failed to request ads:", error);
|
|
587
|
-
currentReject
|
|
592
|
+
currentReject == null ? void 0 : currentReject(error);
|
|
588
593
|
adsLoadedReject = void 0;
|
|
589
594
|
adsLoadedResolve = void 0;
|
|
590
595
|
return Promise.reject(error);
|
|
591
596
|
}
|
|
592
597
|
},
|
|
593
598
|
async play() {
|
|
594
|
-
|
|
599
|
+
var _a, _b;
|
|
600
|
+
if (!((_a = window.google) == null ? void 0 : _a.ima) || !adDisplayContainer) {
|
|
595
601
|
console.warn(
|
|
596
602
|
"[IMA] Cannot play ad: IMA SDK or ad container not available"
|
|
597
603
|
);
|
|
@@ -613,14 +619,15 @@ function createImaController(video, options) {
|
|
|
613
619
|
} catch (error) {
|
|
614
620
|
console.error("[IMA] Error starting ad playback:", error);
|
|
615
621
|
adPlaying = false;
|
|
616
|
-
if (!options
|
|
617
|
-
video.play()
|
|
622
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
623
|
+
(_b = video.play()) == null ? void 0 : _b.catch(() => {
|
|
618
624
|
});
|
|
619
625
|
}
|
|
620
626
|
return Promise.reject(error);
|
|
621
627
|
}
|
|
622
628
|
},
|
|
623
629
|
async stop() {
|
|
630
|
+
var _a;
|
|
624
631
|
adPlaying = false;
|
|
625
632
|
video.muted = originalMutedState;
|
|
626
633
|
if (adContainerEl) {
|
|
@@ -629,11 +636,11 @@ function createImaController(video, options) {
|
|
|
629
636
|
console.log("[IMA] Ad container hidden after stop");
|
|
630
637
|
}
|
|
631
638
|
try {
|
|
632
|
-
adsManager
|
|
639
|
+
(_a = adsManager == null ? void 0 : adsManager.stop) == null ? void 0 : _a.call(adsManager);
|
|
633
640
|
} catch {
|
|
634
641
|
}
|
|
635
642
|
destroyAdsManager();
|
|
636
|
-
if (!options
|
|
643
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
637
644
|
video.play().catch(() => {
|
|
638
645
|
});
|
|
639
646
|
console.log("[IMA] Video resumed after stop (VOD mode)");
|
|
@@ -642,6 +649,7 @@ function createImaController(video, options) {
|
|
|
642
649
|
}
|
|
643
650
|
},
|
|
644
651
|
destroy() {
|
|
652
|
+
var _a;
|
|
645
653
|
destroyAdsManager();
|
|
646
654
|
adPlaying = false;
|
|
647
655
|
video.muted = originalMutedState;
|
|
@@ -650,10 +658,10 @@ function createImaController(video, options) {
|
|
|
650
658
|
adContainerEl.style.display = "none";
|
|
651
659
|
}
|
|
652
660
|
try {
|
|
653
|
-
adsLoader
|
|
661
|
+
(_a = adsLoader == null ? void 0 : adsLoader.destroy) == null ? void 0 : _a.call(adsLoader);
|
|
654
662
|
} catch {
|
|
655
663
|
}
|
|
656
|
-
if (adContainerEl
|
|
664
|
+
if (adContainerEl == null ? void 0 : adContainerEl.parentElement) {
|
|
657
665
|
adContainerEl.parentElement.removeChild(adContainerEl);
|
|
658
666
|
}
|
|
659
667
|
adContainerEl = void 0;
|
|
@@ -664,7 +672,8 @@ function createImaController(video, options) {
|
|
|
664
672
|
return adPlaying;
|
|
665
673
|
},
|
|
666
674
|
resize(width, height) {
|
|
667
|
-
|
|
675
|
+
var _a;
|
|
676
|
+
if (!adsManager || !((_a = window.google) == null ? void 0 : _a.ima)) {
|
|
668
677
|
console.warn(
|
|
669
678
|
"[IMA] Cannot resize: No ads manager or IMA SDK available"
|
|
670
679
|
);
|
|
@@ -682,7 +691,8 @@ function createImaController(video, options) {
|
|
|
682
691
|
listeners.get(event).add(listener);
|
|
683
692
|
},
|
|
684
693
|
off(event, listener) {
|
|
685
|
-
|
|
694
|
+
var _a;
|
|
695
|
+
(_a = listeners.get(event)) == null ? void 0 : _a.delete(listener);
|
|
686
696
|
},
|
|
687
697
|
updateOriginalMutedState(muted) {
|
|
688
698
|
originalMutedState = muted;
|
|
@@ -719,7 +729,8 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
719
729
|
let adPlaying = false;
|
|
720
730
|
let originalMutedState = false;
|
|
721
731
|
const listeners = /* @__PURE__ */ new Map();
|
|
722
|
-
const licenseKey = options
|
|
732
|
+
const licenseKey = options == null ? void 0 : options.licenseKey;
|
|
733
|
+
const mainHlsInstance = options == null ? void 0 : options.mainHlsInstance;
|
|
723
734
|
let adVideoElement;
|
|
724
735
|
let adHls;
|
|
725
736
|
let adContainerEl;
|
|
@@ -766,13 +777,80 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
766
777
|
}
|
|
767
778
|
});
|
|
768
779
|
}
|
|
780
|
+
function getMainStreamQuality() {
|
|
781
|
+
if (!mainHlsInstance || !mainHlsInstance.levels) {
|
|
782
|
+
return null;
|
|
783
|
+
}
|
|
784
|
+
const currentLevel = mainHlsInstance.currentLevel;
|
|
785
|
+
if (currentLevel === -1 || !mainHlsInstance.levels[currentLevel]) {
|
|
786
|
+
const autoLevel = mainHlsInstance.loadLevel;
|
|
787
|
+
if (autoLevel !== -1 && mainHlsInstance.levels[autoLevel]) {
|
|
788
|
+
const level2 = mainHlsInstance.levels[autoLevel];
|
|
789
|
+
return {
|
|
790
|
+
width: level2.width || 1920,
|
|
791
|
+
height: level2.height || 1080,
|
|
792
|
+
bitrate: level2.bitrate || 5e6
|
|
793
|
+
};
|
|
794
|
+
}
|
|
795
|
+
return null;
|
|
796
|
+
}
|
|
797
|
+
const level = mainHlsInstance.levels[currentLevel];
|
|
798
|
+
return {
|
|
799
|
+
width: level.width || 1920,
|
|
800
|
+
height: level.height || 1080,
|
|
801
|
+
bitrate: level.bitrate || 5e6
|
|
802
|
+
};
|
|
803
|
+
}
|
|
804
|
+
function selectBestMediaFile(mediaFiles) {
|
|
805
|
+
if (mediaFiles.length === 0) {
|
|
806
|
+
throw new Error("No media files available");
|
|
807
|
+
}
|
|
808
|
+
const firstFile = mediaFiles[0];
|
|
809
|
+
if (!firstFile) {
|
|
810
|
+
throw new Error("No media files available");
|
|
811
|
+
}
|
|
812
|
+
if (mediaFiles.length === 1) {
|
|
813
|
+
return firstFile;
|
|
814
|
+
}
|
|
815
|
+
const mainQuality = getMainStreamQuality();
|
|
816
|
+
if (!mainQuality) {
|
|
817
|
+
console.log("[HlsAdPlayer] No main stream quality info, using first media file");
|
|
818
|
+
return firstFile;
|
|
819
|
+
}
|
|
820
|
+
console.log("[HlsAdPlayer] Main stream quality:", mainQuality);
|
|
821
|
+
const scoredFiles = mediaFiles.map((file) => {
|
|
822
|
+
const widthDiff = Math.abs(file.width - mainQuality.width);
|
|
823
|
+
const heightDiff = Math.abs(file.height - mainQuality.height);
|
|
824
|
+
const resolutionDiff = widthDiff + heightDiff;
|
|
825
|
+
const fileBitrate = (file.bitrate || 5e3) * 1e3;
|
|
826
|
+
const bitrateDiff = Math.abs(fileBitrate - mainQuality.bitrate);
|
|
827
|
+
const score = resolutionDiff * 2 + bitrateDiff / 1e3;
|
|
828
|
+
return { file, score, resolutionDiff, bitrateDiff };
|
|
829
|
+
});
|
|
830
|
+
scoredFiles.sort((a, b) => a.score - b.score);
|
|
831
|
+
const bestMatch = scoredFiles[0];
|
|
832
|
+
if (!bestMatch) {
|
|
833
|
+
console.log("[HlsAdPlayer] No best match found, using first media file");
|
|
834
|
+
return firstFile;
|
|
835
|
+
}
|
|
836
|
+
console.log("[HlsAdPlayer] Selected media file:", {
|
|
837
|
+
url: bestMatch.file.url,
|
|
838
|
+
resolution: `${bestMatch.file.width}x${bestMatch.file.height}`,
|
|
839
|
+
bitrate: bestMatch.file.bitrate,
|
|
840
|
+
score: bestMatch.score,
|
|
841
|
+
resolutionDiff: bestMatch.resolutionDiff,
|
|
842
|
+
bitrateDiff: bestMatch.bitrateDiff
|
|
843
|
+
});
|
|
844
|
+
return bestMatch.file;
|
|
845
|
+
}
|
|
769
846
|
function parseVastXml(xmlString) {
|
|
847
|
+
var _a, _b, _c, _d;
|
|
770
848
|
try {
|
|
771
849
|
const parser = new DOMParser();
|
|
772
850
|
const xmlDoc = parser.parseFromString(xmlString, "text/xml");
|
|
773
851
|
const parserError = xmlDoc.querySelector("parsererror");
|
|
774
852
|
if (parserError) {
|
|
775
|
-
console.error("[HlsAdPlayer] XML parsing error:", parserError.textContent);
|
|
853
|
+
console.error("[HlsAdPlayer] XML parsing error (malformed VAST XML):", parserError.textContent);
|
|
776
854
|
return null;
|
|
777
855
|
}
|
|
778
856
|
const adElement = xmlDoc.querySelector("Ad");
|
|
@@ -781,28 +859,46 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
781
859
|
return null;
|
|
782
860
|
}
|
|
783
861
|
const adId = adElement.getAttribute("id") || "unknown";
|
|
784
|
-
const title = xmlDoc.querySelector("AdTitle")
|
|
785
|
-
const
|
|
862
|
+
const title = ((_a = xmlDoc.querySelector("AdTitle")) == null ? void 0 : _a.textContent) || "Ad";
|
|
863
|
+
const isNoAdAvailable = adId === "empty" || title.toLowerCase().includes("no ad available") || title.toLowerCase() === "no ad available";
|
|
864
|
+
const durationText = ((_b = xmlDoc.querySelector("Duration")) == null ? void 0 : _b.textContent) || "00:00:30";
|
|
786
865
|
const durationParts = durationText.split(":");
|
|
787
866
|
const duration = parseInt(durationParts[0] || "0", 10) * 3600 + parseInt(durationParts[1] || "0", 10) * 60 + parseInt(durationParts[2] || "0", 10);
|
|
788
867
|
const mediaFileElements = xmlDoc.querySelectorAll("MediaFile");
|
|
789
868
|
const mediaFiles = [];
|
|
790
|
-
mediaFileElements.
|
|
869
|
+
console.log(`[HlsAdPlayer] Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`);
|
|
870
|
+
mediaFileElements.forEach((mf, index) => {
|
|
871
|
+
var _a2;
|
|
791
872
|
const type = mf.getAttribute("type") || "";
|
|
873
|
+
const url = ((_a2 = mf.textContent) == null ? void 0 : _a2.trim()) || "";
|
|
874
|
+
const width = mf.getAttribute("width") || "";
|
|
875
|
+
const height = mf.getAttribute("height") || "";
|
|
876
|
+
console.log(`[HlsAdPlayer] MediaFile ${index}: type="${type}", url="${url}", width="${width}", height="${height}"`);
|
|
792
877
|
if (type === "application/x-mpegURL" || type.includes("m3u8")) {
|
|
878
|
+
if (!url) {
|
|
879
|
+
console.warn(`[HlsAdPlayer] MediaFile ${index} has HLS type but empty URL`);
|
|
880
|
+
return;
|
|
881
|
+
}
|
|
793
882
|
const bitrateAttr = mf.getAttribute("bitrate");
|
|
794
883
|
const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;
|
|
795
884
|
mediaFiles.push({
|
|
796
|
-
url
|
|
885
|
+
url,
|
|
797
886
|
type,
|
|
798
|
-
width: parseInt(
|
|
799
|
-
height: parseInt(
|
|
887
|
+
width: parseInt(width || "1920", 10),
|
|
888
|
+
height: parseInt(height || "1080", 10),
|
|
800
889
|
bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : void 0
|
|
801
890
|
});
|
|
891
|
+
console.log(`[HlsAdPlayer] Added HLS MediaFile: ${url}`);
|
|
892
|
+
} else {
|
|
893
|
+
console.log(`[HlsAdPlayer] MediaFile ${index} ignored (type="${type}" is not HLS)`);
|
|
802
894
|
}
|
|
803
895
|
});
|
|
804
896
|
if (mediaFiles.length === 0) {
|
|
805
|
-
|
|
897
|
+
if (isNoAdAvailable) {
|
|
898
|
+
console.warn("[HlsAdPlayer] No ads available (VAST response indicates no ads)");
|
|
899
|
+
} else {
|
|
900
|
+
console.warn("[HlsAdPlayer] No HLS media files found in VAST XML");
|
|
901
|
+
}
|
|
806
902
|
return null;
|
|
807
903
|
}
|
|
808
904
|
const trackingUrls = {
|
|
@@ -822,12 +918,14 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
822
918
|
error: []
|
|
823
919
|
};
|
|
824
920
|
xmlDoc.querySelectorAll("Impression").forEach((el) => {
|
|
825
|
-
|
|
921
|
+
var _a2;
|
|
922
|
+
const url = (_a2 = el.textContent) == null ? void 0 : _a2.trim();
|
|
826
923
|
if (url) trackingUrls.impression.push(url);
|
|
827
924
|
});
|
|
828
925
|
xmlDoc.querySelectorAll("Tracking").forEach((el) => {
|
|
926
|
+
var _a2;
|
|
829
927
|
const event = el.getAttribute("event");
|
|
830
|
-
const url = el.textContent
|
|
928
|
+
const url = (_a2 = el.textContent) == null ? void 0 : _a2.trim();
|
|
831
929
|
if (event && url) {
|
|
832
930
|
const eventKey = event;
|
|
833
931
|
if (trackingUrls[eventKey]) {
|
|
@@ -835,7 +933,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
835
933
|
}
|
|
836
934
|
}
|
|
837
935
|
});
|
|
838
|
-
const clickThrough = xmlDoc.querySelector("ClickThrough")
|
|
936
|
+
const clickThrough = (_d = (_c = xmlDoc.querySelector("ClickThrough")) == null ? void 0 : _c.textContent) == null ? void 0 : _d.trim();
|
|
839
937
|
return {
|
|
840
938
|
id: adId,
|
|
841
939
|
title,
|
|
@@ -927,7 +1025,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
927
1025
|
adContainerEl.style.display = "none";
|
|
928
1026
|
adContainerEl.style.pointerEvents = "none";
|
|
929
1027
|
}
|
|
930
|
-
if (!options
|
|
1028
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
931
1029
|
contentVideo.play().catch(() => {
|
|
932
1030
|
});
|
|
933
1031
|
console.log("[HlsAdPlayer] Content resumed (VOD mode)");
|
|
@@ -945,7 +1043,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
945
1043
|
adContainerEl.style.display = "none";
|
|
946
1044
|
adContainerEl.style.pointerEvents = "none";
|
|
947
1045
|
}
|
|
948
|
-
if (!options
|
|
1046
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
949
1047
|
if (contentVideo.paused) {
|
|
950
1048
|
contentVideo.play().catch(() => {
|
|
951
1049
|
});
|
|
@@ -955,6 +1053,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
955
1053
|
}
|
|
956
1054
|
return {
|
|
957
1055
|
initialize() {
|
|
1056
|
+
var _a;
|
|
958
1057
|
console.log("[HlsAdPlayer] Initializing");
|
|
959
1058
|
if (!adContainerEl) {
|
|
960
1059
|
const container = document.createElement("div");
|
|
@@ -969,7 +1068,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
969
1068
|
container.style.pointerEvents = "none";
|
|
970
1069
|
container.style.zIndex = "2";
|
|
971
1070
|
container.style.backgroundColor = "#000";
|
|
972
|
-
contentVideo.parentElement
|
|
1071
|
+
(_a = contentVideo.parentElement) == null ? void 0 : _a.appendChild(container);
|
|
973
1072
|
adContainerEl = container;
|
|
974
1073
|
}
|
|
975
1074
|
},
|
|
@@ -987,9 +1086,11 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
987
1086
|
}
|
|
988
1087
|
const vastXml = await response.text();
|
|
989
1088
|
console.log("[HlsAdPlayer] VAST XML received");
|
|
1089
|
+
console.log("[HlsAdPlayer] VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
|
|
990
1090
|
const ad = parseVastXml(vastXml);
|
|
991
1091
|
if (!ad) {
|
|
992
|
-
|
|
1092
|
+
console.warn("[HlsAdPlayer] No ads available from VAST response");
|
|
1093
|
+
return Promise.resolve();
|
|
993
1094
|
}
|
|
994
1095
|
currentAd = ad;
|
|
995
1096
|
console.log(`[HlsAdPlayer] Ad parsed: ${ad.title}, duration: ${ad.duration}s`);
|
|
@@ -1004,14 +1105,14 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1004
1105
|
},
|
|
1005
1106
|
async play() {
|
|
1006
1107
|
if (!currentAd) {
|
|
1007
|
-
console.warn("[HlsAdPlayer] Cannot play: No ad loaded");
|
|
1108
|
+
console.warn("[HlsAdPlayer] Cannot play: No ad loaded (no ads available)");
|
|
1008
1109
|
return Promise.reject(new Error("No ad loaded"));
|
|
1009
1110
|
}
|
|
1010
1111
|
console.log("[HlsAdPlayer] Starting ad playback");
|
|
1011
1112
|
try {
|
|
1012
1113
|
if (!adVideoElement) {
|
|
1013
1114
|
adVideoElement = createAdVideoElement();
|
|
1014
|
-
adContainerEl
|
|
1115
|
+
adContainerEl == null ? void 0 : adContainerEl.appendChild(adVideoElement);
|
|
1015
1116
|
setupAdEventListeners();
|
|
1016
1117
|
}
|
|
1017
1118
|
trackingFired = {
|
|
@@ -1022,7 +1123,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1022
1123
|
thirdQuartile: false,
|
|
1023
1124
|
complete: false
|
|
1024
1125
|
};
|
|
1025
|
-
if (!options
|
|
1126
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
1026
1127
|
contentVideo.pause();
|
|
1027
1128
|
console.log("[HlsAdPlayer] Content paused (VOD mode)");
|
|
1028
1129
|
} else {
|
|
@@ -1035,7 +1136,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1035
1136
|
adContainerEl.style.pointerEvents = "auto";
|
|
1036
1137
|
}
|
|
1037
1138
|
emit("content_pause");
|
|
1038
|
-
const mediaFile = currentAd.mediaFiles
|
|
1139
|
+
const mediaFile = selectBestMediaFile(currentAd.mediaFiles);
|
|
1039
1140
|
if (!mediaFile) {
|
|
1040
1141
|
throw new Error("No media file available for ad");
|
|
1041
1142
|
}
|
|
@@ -1095,7 +1196,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1095
1196
|
adVideoElement.pause();
|
|
1096
1197
|
adVideoElement.src = "";
|
|
1097
1198
|
}
|
|
1098
|
-
if (!options
|
|
1199
|
+
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
1099
1200
|
contentVideo.play().catch(() => {
|
|
1100
1201
|
});
|
|
1101
1202
|
}
|
|
@@ -1115,7 +1216,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1115
1216
|
adVideoElement.remove();
|
|
1116
1217
|
adVideoElement = void 0;
|
|
1117
1218
|
}
|
|
1118
|
-
if (adContainerEl
|
|
1219
|
+
if (adContainerEl == null ? void 0 : adContainerEl.parentElement) {
|
|
1119
1220
|
adContainerEl.parentElement.removeChild(adContainerEl);
|
|
1120
1221
|
}
|
|
1121
1222
|
adContainerEl = void 0;
|
|
@@ -1141,7 +1242,8 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1141
1242
|
listeners.get(event).add(listener);
|
|
1142
1243
|
},
|
|
1143
1244
|
off(event, listener) {
|
|
1144
|
-
|
|
1245
|
+
var _a;
|
|
1246
|
+
(_a = listeners.get(event)) == null ? void 0 : _a.delete(listener);
|
|
1145
1247
|
},
|
|
1146
1248
|
updateOriginalMutedState(muted) {
|
|
1147
1249
|
originalMutedState = muted;
|
|
@@ -1166,6 +1268,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1166
1268
|
// src/utils/tracking.ts
|
|
1167
1269
|
var cachedBrowserId = null;
|
|
1168
1270
|
function getClientInfo() {
|
|
1271
|
+
var _a, _b, _c, _d;
|
|
1169
1272
|
const ua = navigator.userAgent;
|
|
1170
1273
|
const platform = navigator.platform;
|
|
1171
1274
|
const vendor = navigator.vendor || "";
|
|
@@ -1173,12 +1276,12 @@ function getClientInfo() {
|
|
|
1173
1276
|
const memory = navigator.deviceMemory || null;
|
|
1174
1277
|
const hardwareConcurrency = navigator.hardwareConcurrency || 1;
|
|
1175
1278
|
const screenInfo = {
|
|
1176
|
-
width: screen
|
|
1177
|
-
height: screen
|
|
1178
|
-
availWidth: screen
|
|
1179
|
-
availHeight: screen
|
|
1180
|
-
orientation: screen
|
|
1181
|
-
pixelDepth: screen
|
|
1279
|
+
width: screen == null ? void 0 : screen.width,
|
|
1280
|
+
height: screen == null ? void 0 : screen.height,
|
|
1281
|
+
availWidth: screen == null ? void 0 : screen.availWidth,
|
|
1282
|
+
availHeight: screen == null ? void 0 : screen.availHeight,
|
|
1283
|
+
orientation: ((_a = screen == null ? void 0 : screen.orientation) == null ? void 0 : _a.type) || "",
|
|
1284
|
+
pixelDepth: screen == null ? void 0 : screen.pixelDepth
|
|
1182
1285
|
};
|
|
1183
1286
|
let deviceType = "desktop";
|
|
1184
1287
|
let brand = "Unknown";
|
|
@@ -1275,10 +1378,10 @@ function getClientInfo() {
|
|
|
1275
1378
|
if (vendor.includes("Samsung") || ua.includes("SM-")) brand = "Samsung";
|
|
1276
1379
|
}
|
|
1277
1380
|
isWebView = /wv|WebView|Linux; U;/.test(ua);
|
|
1278
|
-
if (window
|
|
1381
|
+
if ((window == null ? void 0 : window.outerHeight) === 0 && (window == null ? void 0 : window.outerWidth) === 0) {
|
|
1279
1382
|
isWebView = true;
|
|
1280
1383
|
}
|
|
1281
|
-
isWebApp = window.matchMedia("(display-mode: standalone)").matches || window.navigator.standalone === true || window.screen
|
|
1384
|
+
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;
|
|
1282
1385
|
return {
|
|
1283
1386
|
brand,
|
|
1284
1387
|
os,
|
|
@@ -1299,7 +1402,7 @@ function getClientInfo() {
|
|
|
1299
1402
|
deviceMemory: memory,
|
|
1300
1403
|
maxTouchPoints,
|
|
1301
1404
|
language: navigator.language,
|
|
1302
|
-
languages: navigator.languages
|
|
1405
|
+
languages: ((_d = navigator.languages) == null ? void 0 : _d.join(",")) || "",
|
|
1303
1406
|
cookieEnabled: navigator.cookieEnabled,
|
|
1304
1407
|
doNotTrack: navigator.doNotTrack || "",
|
|
1305
1408
|
referrer: document.referrer,
|
|
@@ -1657,7 +1760,8 @@ var StormcloudVideoPlayer = class {
|
|
|
1657
1760
|
}
|
|
1658
1761
|
return createHlsAdPlayer(this.video, {
|
|
1659
1762
|
continueLiveStreamDuringAds,
|
|
1660
|
-
...this.config.licenseKey ? { licenseKey: this.config.licenseKey } : {}
|
|
1763
|
+
...this.config.licenseKey ? { licenseKey: this.config.licenseKey } : {},
|
|
1764
|
+
...this.hls ? { mainHlsInstance: this.hls } : {}
|
|
1661
1765
|
});
|
|
1662
1766
|
} else {
|
|
1663
1767
|
if (this.config.debugAdTiming) {
|
|
@@ -1669,6 +1773,7 @@ var StormcloudVideoPlayer = class {
|
|
|
1669
1773
|
}
|
|
1670
1774
|
}
|
|
1671
1775
|
async load() {
|
|
1776
|
+
var _a, _b;
|
|
1672
1777
|
if (!this.attached) {
|
|
1673
1778
|
this.attach();
|
|
1674
1779
|
}
|
|
@@ -1685,7 +1790,7 @@ var StormcloudVideoPlayer = class {
|
|
|
1685
1790
|
this.initializeTracking();
|
|
1686
1791
|
if (this.shouldUseNativeHls()) {
|
|
1687
1792
|
this.video.src = this.config.src;
|
|
1688
|
-
this.isLiveStream = this.config.lowLatencyMode
|
|
1793
|
+
this.isLiveStream = (_a = this.config.lowLatencyMode) != null ? _a : false;
|
|
1689
1794
|
if (this.config.debugAdTiming) {
|
|
1690
1795
|
console.log(
|
|
1691
1796
|
"[StormcloudVideoPlayer] allowNativeHls: true - VOD mode detected:",
|
|
@@ -1700,8 +1805,8 @@ var StormcloudVideoPlayer = class {
|
|
|
1700
1805
|
this.ima = this.createAdPlayer(false);
|
|
1701
1806
|
this.ima.initialize();
|
|
1702
1807
|
if (this.config.autoplay) {
|
|
1703
|
-
await this.video.play()
|
|
1704
|
-
});
|
|
1808
|
+
await ((_b = this.video.play()) == null ? void 0 : _b.catch(() => {
|
|
1809
|
+
}));
|
|
1705
1810
|
}
|
|
1706
1811
|
return;
|
|
1707
1812
|
}
|
|
@@ -1714,12 +1819,17 @@ var StormcloudVideoPlayer = class {
|
|
|
1714
1819
|
...this.config.lowLatencyMode ? { liveSyncDuration: 2 } : {}
|
|
1715
1820
|
});
|
|
1716
1821
|
this.hls.on(import_hls2.default.Events.MEDIA_ATTACHED, () => {
|
|
1717
|
-
|
|
1822
|
+
var _a2;
|
|
1823
|
+
(_a2 = this.hls) == null ? void 0 : _a2.loadSource(this.config.src);
|
|
1718
1824
|
});
|
|
1719
1825
|
this.hls.on(import_hls2.default.Events.MANIFEST_PARSED, async (_, data) => {
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1826
|
+
var _a2, _b2, _c, _d;
|
|
1827
|
+
this.isLiveStream = (_c = (_b2 = (_a2 = this.hls) == null ? void 0 : _a2.levels) == null ? void 0 : _b2.some(
|
|
1828
|
+
(level) => {
|
|
1829
|
+
var _a3, _b3;
|
|
1830
|
+
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";
|
|
1831
|
+
}
|
|
1832
|
+
)) != null ? _c : false;
|
|
1723
1833
|
if (this.config.debugAdTiming) {
|
|
1724
1834
|
const adBehavior = this.shouldContinueLiveStreamDuringAds() ? "live (main video continues muted during ads)" : "vod (main video pauses during ads)";
|
|
1725
1835
|
console.log("[StormcloudVideoPlayer] Stream type detected:", {
|
|
@@ -1732,28 +1842,29 @@ var StormcloudVideoPlayer = class {
|
|
|
1732
1842
|
this.ima = this.createAdPlayer(this.shouldContinueLiveStreamDuringAds());
|
|
1733
1843
|
this.ima.initialize();
|
|
1734
1844
|
if (this.config.autoplay) {
|
|
1735
|
-
await this.video.play()
|
|
1736
|
-
});
|
|
1845
|
+
await ((_d = this.video.play()) == null ? void 0 : _d.catch(() => {
|
|
1846
|
+
}));
|
|
1737
1847
|
}
|
|
1738
1848
|
});
|
|
1739
1849
|
this.hls.on(import_hls2.default.Events.FRAG_PARSING_METADATA, (_evt, data) => {
|
|
1740
|
-
const id3Tags = (data
|
|
1850
|
+
const id3Tags = ((data == null ? void 0 : data.samples) || []).map((s) => ({
|
|
1741
1851
|
key: "ID3",
|
|
1742
|
-
value: s
|
|
1743
|
-
ptsSeconds: s
|
|
1852
|
+
value: s == null ? void 0 : s.data,
|
|
1853
|
+
ptsSeconds: s == null ? void 0 : s.pts
|
|
1744
1854
|
}));
|
|
1745
1855
|
id3Tags.forEach((tag) => this.onId3Tag(tag));
|
|
1746
1856
|
});
|
|
1747
1857
|
this.hls.on(import_hls2.default.Events.FRAG_CHANGED, (_evt, data) => {
|
|
1748
|
-
|
|
1749
|
-
const
|
|
1858
|
+
var _a2, _b2, _c;
|
|
1859
|
+
const frag = data == null ? void 0 : data.frag;
|
|
1860
|
+
const tagList = frag == null ? void 0 : frag.tagList;
|
|
1750
1861
|
if (!Array.isArray(tagList)) return;
|
|
1751
1862
|
for (const entry of tagList) {
|
|
1752
1863
|
let tag = "";
|
|
1753
1864
|
let value = "";
|
|
1754
1865
|
if (Array.isArray(entry)) {
|
|
1755
|
-
tag = String(entry[0]
|
|
1756
|
-
value = String(entry[1]
|
|
1866
|
+
tag = String((_a2 = entry[0]) != null ? _a2 : "");
|
|
1867
|
+
value = String((_b2 = entry[1]) != null ? _b2 : "");
|
|
1757
1868
|
} else if (typeof entry === "string") {
|
|
1758
1869
|
const idx = entry.indexOf(":");
|
|
1759
1870
|
if (idx >= 0) {
|
|
@@ -1777,8 +1888,8 @@ var StormcloudVideoPlayer = class {
|
|
|
1777
1888
|
const prog = this.parseCueOutCont(value);
|
|
1778
1889
|
const marker = {
|
|
1779
1890
|
type: "progress",
|
|
1780
|
-
...prog
|
|
1781
|
-
...prog
|
|
1891
|
+
...(prog == null ? void 0 : prog.duration) !== void 0 ? { durationSeconds: prog.duration } : {},
|
|
1892
|
+
...(prog == null ? void 0 : prog.elapsed) !== void 0 ? { ptsSeconds: prog.elapsed } : {},
|
|
1782
1893
|
raw: { tag, value }
|
|
1783
1894
|
};
|
|
1784
1895
|
this.onScte35Marker(marker);
|
|
@@ -1788,7 +1899,7 @@ var StormcloudVideoPlayer = class {
|
|
|
1788
1899
|
const attrs = this.parseAttributeList(value);
|
|
1789
1900
|
const hasScteOut = "SCTE35-OUT" in attrs || attrs["SCTE35-OUT"] !== void 0;
|
|
1790
1901
|
const hasScteIn = "SCTE35-IN" in attrs || attrs["SCTE35-IN"] !== void 0;
|
|
1791
|
-
const klass = String(attrs["CLASS"]
|
|
1902
|
+
const klass = String((_c = attrs["CLASS"]) != null ? _c : "");
|
|
1792
1903
|
const duration = this.toNumber(attrs["DURATION"]);
|
|
1793
1904
|
if (hasScteOut || /com\.apple\.hls\.cue/i.test(klass)) {
|
|
1794
1905
|
const marker = {
|
|
@@ -1805,13 +1916,14 @@ var StormcloudVideoPlayer = class {
|
|
|
1805
1916
|
}
|
|
1806
1917
|
});
|
|
1807
1918
|
this.hls.on(import_hls2.default.Events.ERROR, (_evt, data) => {
|
|
1808
|
-
|
|
1919
|
+
var _a2, _b2;
|
|
1920
|
+
if (data == null ? void 0 : data.fatal) {
|
|
1809
1921
|
switch (data.type) {
|
|
1810
1922
|
case import_hls2.default.ErrorTypes.NETWORK_ERROR:
|
|
1811
|
-
this.hls
|
|
1923
|
+
(_a2 = this.hls) == null ? void 0 : _a2.startLoad();
|
|
1812
1924
|
break;
|
|
1813
1925
|
case import_hls2.default.ErrorTypes.MEDIA_ERROR:
|
|
1814
|
-
this.hls
|
|
1926
|
+
(_b2 = this.hls) == null ? void 0 : _b2.recoverMediaError();
|
|
1815
1927
|
break;
|
|
1816
1928
|
default:
|
|
1817
1929
|
this.destroy();
|
|
@@ -1913,11 +2025,12 @@ var StormcloudVideoPlayer = class {
|
|
|
1913
2025
|
}
|
|
1914
2026
|
}
|
|
1915
2027
|
parseScte35FromId3(tag) {
|
|
2028
|
+
var _a, _b, _c, _d;
|
|
1916
2029
|
const text = this.decodeId3ValueToText(tag.value);
|
|
1917
2030
|
if (!text) return void 0;
|
|
1918
2031
|
const cueOutMatch = text.match(/EXT-X-CUE-OUT(?::([^\r\n]*))?/i) || text.match(/CUE-OUT(?::([^\r\n]*))?/i);
|
|
1919
2032
|
if (cueOutMatch) {
|
|
1920
|
-
const arg = (cueOutMatch[1]
|
|
2033
|
+
const arg = ((_a = cueOutMatch[1]) != null ? _a : "").trim();
|
|
1921
2034
|
const dur = this.parseCueOutDuration(arg);
|
|
1922
2035
|
const marker = {
|
|
1923
2036
|
type: "start",
|
|
@@ -1929,12 +2042,12 @@ var StormcloudVideoPlayer = class {
|
|
|
1929
2042
|
}
|
|
1930
2043
|
const cueOutContMatch = text.match(/EXT-X-CUE-OUT-CONT:([^\r\n]*)/i);
|
|
1931
2044
|
if (cueOutContMatch) {
|
|
1932
|
-
const arg = (cueOutContMatch[1]
|
|
2045
|
+
const arg = ((_b = cueOutContMatch[1]) != null ? _b : "").trim();
|
|
1933
2046
|
const cont = this.parseCueOutCont(arg);
|
|
1934
2047
|
const marker = {
|
|
1935
2048
|
type: "progress",
|
|
1936
2049
|
...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},
|
|
1937
|
-
...cont
|
|
2050
|
+
...(cont == null ? void 0 : cont.duration) !== void 0 ? { durationSeconds: cont.duration } : {},
|
|
1938
2051
|
raw: { id3: text }
|
|
1939
2052
|
};
|
|
1940
2053
|
return marker;
|
|
@@ -1950,10 +2063,10 @@ var StormcloudVideoPlayer = class {
|
|
|
1950
2063
|
}
|
|
1951
2064
|
const daterangeMatch = text.match(/EXT-X-DATERANGE:([^\r\n]*)/i);
|
|
1952
2065
|
if (daterangeMatch) {
|
|
1953
|
-
const attrs = this.parseAttributeList(daterangeMatch[1]
|
|
2066
|
+
const attrs = this.parseAttributeList((_c = daterangeMatch[1]) != null ? _c : "");
|
|
1954
2067
|
const hasScteOut = "SCTE35-OUT" in attrs || attrs["SCTE35-OUT"] !== void 0;
|
|
1955
2068
|
const hasScteIn = "SCTE35-IN" in attrs || attrs["SCTE35-IN"] !== void 0;
|
|
1956
|
-
const klass = String(attrs["CLASS"]
|
|
2069
|
+
const klass = String((_d = attrs["CLASS"]) != null ? _d : "");
|
|
1957
2070
|
const duration = this.toNumber(attrs["DURATION"]);
|
|
1958
2071
|
if (hasScteOut || /com\.apple\.hls\.cue/i.test(klass)) {
|
|
1959
2072
|
const marker = {
|
|
@@ -2010,6 +2123,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2010
2123
|
}
|
|
2011
2124
|
}
|
|
2012
2125
|
onScte35Marker(marker) {
|
|
2126
|
+
var _a, _b;
|
|
2013
2127
|
if (this.config.debugAdTiming) {
|
|
2014
2128
|
console.log("[StormcloudVideoPlayer] SCTE-35 marker detected:", {
|
|
2015
2129
|
type: marker.type,
|
|
@@ -2025,7 +2139,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2025
2139
|
this.expectedAdBreakDurationMs = durationMs;
|
|
2026
2140
|
this.currentAdBreakStartWallClockMs = Date.now();
|
|
2027
2141
|
const isManifestMarker = this.isManifestBasedMarker(marker);
|
|
2028
|
-
const forceImmediate = this.config.immediateManifestAds
|
|
2142
|
+
const forceImmediate = (_a = this.config.immediateManifestAds) != null ? _a : true;
|
|
2029
2143
|
if (this.config.debugAdTiming) {
|
|
2030
2144
|
console.log("[StormcloudVideoPlayer] Ad start decision:", {
|
|
2031
2145
|
isManifestMarker,
|
|
@@ -2042,7 +2156,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2042
2156
|
this.clearAdStartTimer();
|
|
2043
2157
|
this.handleAdStart(marker);
|
|
2044
2158
|
} else if (typeof marker.ptsSeconds === "number") {
|
|
2045
|
-
const tol = this.config.driftToleranceMs
|
|
2159
|
+
const tol = (_b = this.config.driftToleranceMs) != null ? _b : 1e3;
|
|
2046
2160
|
const nowMs = this.video.currentTime * 1e3;
|
|
2047
2161
|
const estCurrentPtsMs = nowMs - this.ptsDriftEmaMs;
|
|
2048
2162
|
const deltaMs = Math.floor(marker.ptsSeconds * 1e3 - estCurrentPtsMs);
|
|
@@ -2152,12 +2266,13 @@ var StormcloudVideoPlayer = class {
|
|
|
2152
2266
|
return void 0;
|
|
2153
2267
|
}
|
|
2154
2268
|
parseAttributeList(value) {
|
|
2269
|
+
var _a, _b, _c;
|
|
2155
2270
|
const attrs = {};
|
|
2156
2271
|
const regex = /([A-Z0-9-]+)=(("[^"]*")|([^",]*))(?:,|$)/gi;
|
|
2157
2272
|
let match;
|
|
2158
2273
|
while ((match = regex.exec(value)) !== null) {
|
|
2159
|
-
const key = match[1]
|
|
2160
|
-
let rawVal = match[3]
|
|
2274
|
+
const key = (_a = match[1]) != null ? _a : "";
|
|
2275
|
+
let rawVal = (_c = (_b = match[3]) != null ? _b : match[4]) != null ? _c : "";
|
|
2161
2276
|
if (rawVal.startsWith('"') && rawVal.endsWith('"')) {
|
|
2162
2277
|
rawVal = rawVal.slice(1, -1);
|
|
2163
2278
|
}
|
|
@@ -2321,6 +2436,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2321
2436
|
}
|
|
2322
2437
|
}
|
|
2323
2438
|
async fetchAdConfiguration() {
|
|
2439
|
+
var _a, _b, _c;
|
|
2324
2440
|
const vastMode = this.config.vastMode || "default";
|
|
2325
2441
|
if (this.config.debugAdTiming) {
|
|
2326
2442
|
console.log(
|
|
@@ -2341,7 +2457,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2341
2457
|
this.apiVastTagUrl = vastEndpoint;
|
|
2342
2458
|
if (this.config.debugAdTiming) {
|
|
2343
2459
|
console.log(
|
|
2344
|
-
"[StormcloudVideoPlayer] Using AdStorm VAST endpoint:",
|
|
2460
|
+
"[StormcloudVideoPlayer] Using AdStorm VAST endpoint (adstorm mode):",
|
|
2345
2461
|
vastEndpoint
|
|
2346
2462
|
);
|
|
2347
2463
|
}
|
|
@@ -2378,7 +2494,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2378
2494
|
return;
|
|
2379
2495
|
}
|
|
2380
2496
|
const data = await response.json();
|
|
2381
|
-
const imaPayload = data.response
|
|
2497
|
+
const imaPayload = (_c = (_b = (_a = data.response) == null ? void 0 : _a.ima) == null ? void 0 : _b["publisherdesk.ima"]) == null ? void 0 : _c.payload;
|
|
2382
2498
|
if (imaPayload) {
|
|
2383
2499
|
this.apiVastTagUrl = decodeURIComponent(imaPayload);
|
|
2384
2500
|
if (this.config.debugAdTiming) {
|
|
@@ -2415,11 +2531,12 @@ var StormcloudVideoPlayer = class {
|
|
|
2415
2531
|
return "other";
|
|
2416
2532
|
}
|
|
2417
2533
|
shouldShowNativeControls() {
|
|
2534
|
+
var _a, _b;
|
|
2418
2535
|
const streamType = this.getStreamType();
|
|
2419
2536
|
if (streamType === "other") {
|
|
2420
|
-
return !(this.config.showCustomControls
|
|
2537
|
+
return !((_a = this.config.showCustomControls) != null ? _a : false);
|
|
2421
2538
|
}
|
|
2422
|
-
return !!(this.config.allowNativeHls && !(this.config.showCustomControls
|
|
2539
|
+
return !!(this.config.allowNativeHls && !((_b = this.config.showCustomControls) != null ? _b : false));
|
|
2423
2540
|
}
|
|
2424
2541
|
shouldContinueLiveStreamDuringAds() {
|
|
2425
2542
|
if (this.config.allowNativeHls) {
|
|
@@ -2431,6 +2548,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2431
2548
|
return true;
|
|
2432
2549
|
}
|
|
2433
2550
|
async handleAdStart(_marker) {
|
|
2551
|
+
var _a;
|
|
2434
2552
|
const scheduled = this.findCurrentOrNextBreak(
|
|
2435
2553
|
this.video.currentTime * 1e3
|
|
2436
2554
|
);
|
|
@@ -2481,17 +2599,18 @@ var StormcloudVideoPlayer = class {
|
|
|
2481
2599
|
this.handleAdFailure();
|
|
2482
2600
|
}
|
|
2483
2601
|
}
|
|
2484
|
-
if (this.expectedAdBreakDurationMs == null && scheduled
|
|
2602
|
+
if (this.expectedAdBreakDurationMs == null && (scheduled == null ? void 0 : scheduled.durationMs) != null) {
|
|
2485
2603
|
this.expectedAdBreakDurationMs = scheduled.durationMs;
|
|
2486
|
-
this.currentAdBreakStartWallClockMs = this.currentAdBreakStartWallClockMs
|
|
2604
|
+
this.currentAdBreakStartWallClockMs = (_a = this.currentAdBreakStartWallClockMs) != null ? _a : Date.now();
|
|
2487
2605
|
this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);
|
|
2488
2606
|
}
|
|
2489
2607
|
}
|
|
2490
2608
|
findCurrentOrNextBreak(nowMs) {
|
|
2609
|
+
var _a;
|
|
2491
2610
|
const schedule = [];
|
|
2492
2611
|
let candidate;
|
|
2493
2612
|
for (const b of schedule) {
|
|
2494
|
-
const tol = this.config.driftToleranceMs
|
|
2613
|
+
const tol = (_a = this.config.driftToleranceMs) != null ? _a : 1e3;
|
|
2495
2614
|
if (b.startTimeMs <= nowMs + tol && (candidate == null || b.startTimeMs > (candidate.startTimeMs || 0))) {
|
|
2496
2615
|
candidate = b;
|
|
2497
2616
|
}
|
|
@@ -2507,7 +2626,8 @@ var StormcloudVideoPlayer = class {
|
|
|
2507
2626
|
}
|
|
2508
2627
|
}
|
|
2509
2628
|
async handleMidAdJoin(adBreak, nowMs) {
|
|
2510
|
-
|
|
2629
|
+
var _a;
|
|
2630
|
+
const durationMs = (_a = adBreak.durationMs) != null ? _a : 0;
|
|
2511
2631
|
const endMs = adBreak.startTimeMs + durationMs;
|
|
2512
2632
|
if (durationMs > 0 && nowMs > adBreak.startTimeMs && nowMs < endMs) {
|
|
2513
2633
|
const remainingMs = endMs - nowMs;
|
|
@@ -2593,12 +2713,20 @@ var StormcloudVideoPlayer = class {
|
|
|
2593
2713
|
this.startAdFailsafeTimer();
|
|
2594
2714
|
try {
|
|
2595
2715
|
await this.ima.requestAds(vastTagUrl);
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2716
|
+
try {
|
|
2717
|
+
if (this.config.debugAdTiming) {
|
|
2718
|
+
console.log("[StormcloudVideoPlayer] Ad request completed, attempting playback");
|
|
2719
|
+
}
|
|
2720
|
+
await this.ima.play();
|
|
2721
|
+
if (this.config.debugAdTiming) {
|
|
2722
|
+
console.log("[StormcloudVideoPlayer] Ad playback started successfully");
|
|
2723
|
+
}
|
|
2724
|
+
} catch (playError) {
|
|
2725
|
+
if (this.config.debugAdTiming) {
|
|
2726
|
+
console.log("[StormcloudVideoPlayer] No ads available, skipping playback");
|
|
2727
|
+
}
|
|
2728
|
+
this.handleAdFailure();
|
|
2729
|
+
return;
|
|
2602
2730
|
}
|
|
2603
2731
|
} catch (error) {
|
|
2604
2732
|
if (this.config.debugAdTiming) {
|
|
@@ -2608,6 +2736,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2608
2736
|
}
|
|
2609
2737
|
}
|
|
2610
2738
|
handleAdFailure() {
|
|
2739
|
+
var _a;
|
|
2611
2740
|
if (this.config.debugAdTiming) {
|
|
2612
2741
|
console.log(
|
|
2613
2742
|
"[StormcloudVideoPlayer] Handling ad failure - resuming content",
|
|
@@ -2640,7 +2769,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2640
2769
|
if (this.config.debugAdTiming) {
|
|
2641
2770
|
console.log("[StormcloudVideoPlayer] Resuming paused video");
|
|
2642
2771
|
}
|
|
2643
|
-
this.video.play()
|
|
2772
|
+
(_a = this.video.play()) == null ? void 0 : _a.catch((error) => {
|
|
2644
2773
|
if (this.config.debugAdTiming) {
|
|
2645
2774
|
console.error(
|
|
2646
2775
|
"[StormcloudVideoPlayer] Failed to resume video after ad failure:",
|
|
@@ -2655,8 +2784,9 @@ var StormcloudVideoPlayer = class {
|
|
|
2655
2784
|
}
|
|
2656
2785
|
}
|
|
2657
2786
|
startAdFailsafeTimer() {
|
|
2787
|
+
var _a;
|
|
2658
2788
|
this.clearAdFailsafeTimer();
|
|
2659
|
-
const failsafeMs = this.config.adFailsafeTimeoutMs
|
|
2789
|
+
const failsafeMs = (_a = this.config.adFailsafeTimeoutMs) != null ? _a : 1e4;
|
|
2660
2790
|
if (this.config.debugAdTiming) {
|
|
2661
2791
|
console.log(
|
|
2662
2792
|
`[StormcloudVideoPlayer] Starting failsafe timer (${failsafeMs}ms)`
|
|
@@ -2792,6 +2922,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2792
2922
|
}
|
|
2793
2923
|
}
|
|
2794
2924
|
destroy() {
|
|
2925
|
+
var _a, _b;
|
|
2795
2926
|
this.clearAdStartTimer();
|
|
2796
2927
|
this.clearAdStopTimer();
|
|
2797
2928
|
this.clearAdFailsafeTimer();
|
|
@@ -2799,8 +2930,8 @@ var StormcloudVideoPlayer = class {
|
|
|
2799
2930
|
clearInterval(this.heartbeatInterval);
|
|
2800
2931
|
this.heartbeatInterval = void 0;
|
|
2801
2932
|
}
|
|
2802
|
-
this.hls
|
|
2803
|
-
this.ima
|
|
2933
|
+
(_a = this.hls) == null ? void 0 : _a.destroy();
|
|
2934
|
+
(_b = this.ima) == null ? void 0 : _b.destroy();
|
|
2804
2935
|
}
|
|
2805
2936
|
};
|
|
2806
2937
|
// Annotate the CommonJS export names for ESM import in node:
|