stormcloud-video-player 0.2.13 → 0.2.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
- if ("userAgentData" in navigator && navigator.userAgentData?.platform) {
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?.getAttribute?.("sandbox") || "";
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?.ima)
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?.ima) {
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?.appendChild(container);
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?.continueLiveStreamDuringAds) {
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()?.catch(() => {
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?.continueLiveStreamDuringAds) {
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?.continueLiveStreamDuringAds) {
490
- video.play()?.catch(() => {
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?.continueLiveStreamDuringAds) {
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?.continueLiveStreamDuringAds) {
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?.continueLiveStreamDuringAds) {
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?.(error);
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
- if (!window.google?.ima || !adDisplayContainer) {
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?.continueLiveStreamDuringAds) {
620
- video.play()?.catch(() => {
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?.stop?.();
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?.continueLiveStreamDuringAds) {
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?.destroy?.();
664
+ (_a = adsLoader == null ? void 0 : adsLoader.destroy) == null ? void 0 : _a.call(adsLoader);
657
665
  } catch {
658
666
  }
659
- if (adContainerEl?.parentElement) {
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
- if (!adsManager || !window.google?.ima) {
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
- listeners.get(event)?.delete(listener);
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?.licenseKey;
735
+ const licenseKey = options == null ? void 0 : options.licenseKey;
736
+ const mainHlsInstance = options == null ? void 0 : options.mainHlsInstance;
726
737
  let adVideoElement;
727
738
  let adHls;
728
739
  let adContainerEl;
@@ -769,7 +780,74 @@ function createHlsAdPlayer(contentVideo, options) {
769
780
  }
770
781
  });
771
782
  }
783
+ function getMainStreamQuality() {
784
+ if (!mainHlsInstance || !mainHlsInstance.levels) {
785
+ return null;
786
+ }
787
+ const currentLevel = mainHlsInstance.currentLevel;
788
+ if (currentLevel === -1 || !mainHlsInstance.levels[currentLevel]) {
789
+ const autoLevel = mainHlsInstance.loadLevel;
790
+ if (autoLevel !== -1 && mainHlsInstance.levels[autoLevel]) {
791
+ const level2 = mainHlsInstance.levels[autoLevel];
792
+ return {
793
+ width: level2.width || 1920,
794
+ height: level2.height || 1080,
795
+ bitrate: level2.bitrate || 5e6
796
+ };
797
+ }
798
+ return null;
799
+ }
800
+ const level = mainHlsInstance.levels[currentLevel];
801
+ return {
802
+ width: level.width || 1920,
803
+ height: level.height || 1080,
804
+ bitrate: level.bitrate || 5e6
805
+ };
806
+ }
807
+ function selectBestMediaFile(mediaFiles) {
808
+ if (mediaFiles.length === 0) {
809
+ throw new Error("No media files available");
810
+ }
811
+ const firstFile = mediaFiles[0];
812
+ if (!firstFile) {
813
+ throw new Error("No media files available");
814
+ }
815
+ if (mediaFiles.length === 1) {
816
+ return firstFile;
817
+ }
818
+ const mainQuality = getMainStreamQuality();
819
+ if (!mainQuality) {
820
+ console.log("[HlsAdPlayer] No main stream quality info, using first media file");
821
+ return firstFile;
822
+ }
823
+ console.log("[HlsAdPlayer] Main stream quality:", mainQuality);
824
+ const scoredFiles = mediaFiles.map((file) => {
825
+ const widthDiff = Math.abs(file.width - mainQuality.width);
826
+ const heightDiff = Math.abs(file.height - mainQuality.height);
827
+ const resolutionDiff = widthDiff + heightDiff;
828
+ const fileBitrate = (file.bitrate || 5e3) * 1e3;
829
+ const bitrateDiff = Math.abs(fileBitrate - mainQuality.bitrate);
830
+ const score = resolutionDiff * 2 + bitrateDiff / 1e3;
831
+ return { file, score, resolutionDiff, bitrateDiff };
832
+ });
833
+ scoredFiles.sort((a, b) => a.score - b.score);
834
+ const bestMatch = scoredFiles[0];
835
+ if (!bestMatch) {
836
+ console.log("[HlsAdPlayer] No best match found, using first media file");
837
+ return firstFile;
838
+ }
839
+ console.log("[HlsAdPlayer] Selected media file:", {
840
+ url: bestMatch.file.url,
841
+ resolution: `${bestMatch.file.width}x${bestMatch.file.height}`,
842
+ bitrate: bestMatch.file.bitrate,
843
+ score: bestMatch.score,
844
+ resolutionDiff: bestMatch.resolutionDiff,
845
+ bitrateDiff: bestMatch.bitrateDiff
846
+ });
847
+ return bestMatch.file;
848
+ }
772
849
  function parseVastXml(xmlString) {
850
+ var _a, _b, _c, _d;
773
851
  try {
774
852
  const parser = new DOMParser();
775
853
  const xmlDoc = parser.parseFromString(xmlString, "text/xml");
@@ -784,19 +862,20 @@ function createHlsAdPlayer(contentVideo, options) {
784
862
  return null;
785
863
  }
786
864
  const adId = adElement.getAttribute("id") || "unknown";
787
- const title = xmlDoc.querySelector("AdTitle")?.textContent || "Ad";
788
- const durationText = xmlDoc.querySelector("Duration")?.textContent || "00:00:30";
865
+ const title = ((_a = xmlDoc.querySelector("AdTitle")) == null ? void 0 : _a.textContent) || "Ad";
866
+ const durationText = ((_b = xmlDoc.querySelector("Duration")) == null ? void 0 : _b.textContent) || "00:00:30";
789
867
  const durationParts = durationText.split(":");
790
868
  const duration = parseInt(durationParts[0] || "0", 10) * 3600 + parseInt(durationParts[1] || "0", 10) * 60 + parseInt(durationParts[2] || "0", 10);
791
869
  const mediaFileElements = xmlDoc.querySelectorAll("MediaFile");
792
870
  const mediaFiles = [];
793
871
  mediaFileElements.forEach((mf) => {
872
+ var _a2;
794
873
  const type = mf.getAttribute("type") || "";
795
874
  if (type === "application/x-mpegURL" || type.includes("m3u8")) {
796
875
  const bitrateAttr = mf.getAttribute("bitrate");
797
876
  const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;
798
877
  mediaFiles.push({
799
- url: mf.textContent?.trim() || "",
878
+ url: ((_a2 = mf.textContent) == null ? void 0 : _a2.trim()) || "",
800
879
  type,
801
880
  width: parseInt(mf.getAttribute("width") || "1920", 10),
802
881
  height: parseInt(mf.getAttribute("height") || "1080", 10),
@@ -825,12 +904,14 @@ function createHlsAdPlayer(contentVideo, options) {
825
904
  error: []
826
905
  };
827
906
  xmlDoc.querySelectorAll("Impression").forEach((el) => {
828
- const url = el.textContent?.trim();
907
+ var _a2;
908
+ const url = (_a2 = el.textContent) == null ? void 0 : _a2.trim();
829
909
  if (url) trackingUrls.impression.push(url);
830
910
  });
831
911
  xmlDoc.querySelectorAll("Tracking").forEach((el) => {
912
+ var _a2;
832
913
  const event = el.getAttribute("event");
833
- const url = el.textContent?.trim();
914
+ const url = (_a2 = el.textContent) == null ? void 0 : _a2.trim();
834
915
  if (event && url) {
835
916
  const eventKey = event;
836
917
  if (trackingUrls[eventKey]) {
@@ -838,7 +919,7 @@ function createHlsAdPlayer(contentVideo, options) {
838
919
  }
839
920
  }
840
921
  });
841
- const clickThrough = xmlDoc.querySelector("ClickThrough")?.textContent?.trim();
922
+ const clickThrough = (_d = (_c = xmlDoc.querySelector("ClickThrough")) == null ? void 0 : _c.textContent) == null ? void 0 : _d.trim();
842
923
  return {
843
924
  id: adId,
844
925
  title,
@@ -930,7 +1011,7 @@ function createHlsAdPlayer(contentVideo, options) {
930
1011
  adContainerEl.style.display = "none";
931
1012
  adContainerEl.style.pointerEvents = "none";
932
1013
  }
933
- if (!options?.continueLiveStreamDuringAds) {
1014
+ if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
934
1015
  contentVideo.play().catch(() => {
935
1016
  });
936
1017
  console.log("[HlsAdPlayer] Content resumed (VOD mode)");
@@ -948,7 +1029,7 @@ function createHlsAdPlayer(contentVideo, options) {
948
1029
  adContainerEl.style.display = "none";
949
1030
  adContainerEl.style.pointerEvents = "none";
950
1031
  }
951
- if (!options?.continueLiveStreamDuringAds) {
1032
+ if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
952
1033
  if (contentVideo.paused) {
953
1034
  contentVideo.play().catch(() => {
954
1035
  });
@@ -958,6 +1039,7 @@ function createHlsAdPlayer(contentVideo, options) {
958
1039
  }
959
1040
  return {
960
1041
  initialize() {
1042
+ var _a;
961
1043
  console.log("[HlsAdPlayer] Initializing");
962
1044
  if (!adContainerEl) {
963
1045
  const container = document.createElement("div");
@@ -972,7 +1054,7 @@ function createHlsAdPlayer(contentVideo, options) {
972
1054
  container.style.pointerEvents = "none";
973
1055
  container.style.zIndex = "2";
974
1056
  container.style.backgroundColor = "#000";
975
- contentVideo.parentElement?.appendChild(container);
1057
+ (_a = contentVideo.parentElement) == null ? void 0 : _a.appendChild(container);
976
1058
  adContainerEl = container;
977
1059
  }
978
1060
  },
@@ -1014,7 +1096,7 @@ function createHlsAdPlayer(contentVideo, options) {
1014
1096
  try {
1015
1097
  if (!adVideoElement) {
1016
1098
  adVideoElement = createAdVideoElement();
1017
- adContainerEl?.appendChild(adVideoElement);
1099
+ adContainerEl == null ? void 0 : adContainerEl.appendChild(adVideoElement);
1018
1100
  setupAdEventListeners();
1019
1101
  }
1020
1102
  trackingFired = {
@@ -1025,7 +1107,7 @@ function createHlsAdPlayer(contentVideo, options) {
1025
1107
  thirdQuartile: false,
1026
1108
  complete: false
1027
1109
  };
1028
- if (!options?.continueLiveStreamDuringAds) {
1110
+ if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
1029
1111
  contentVideo.pause();
1030
1112
  console.log("[HlsAdPlayer] Content paused (VOD mode)");
1031
1113
  } else {
@@ -1038,7 +1120,7 @@ function createHlsAdPlayer(contentVideo, options) {
1038
1120
  adContainerEl.style.pointerEvents = "auto";
1039
1121
  }
1040
1122
  emit("content_pause");
1041
- const mediaFile = currentAd.mediaFiles[0];
1123
+ const mediaFile = selectBestMediaFile(currentAd.mediaFiles);
1042
1124
  if (!mediaFile) {
1043
1125
  throw new Error("No media file available for ad");
1044
1126
  }
@@ -1098,7 +1180,7 @@ function createHlsAdPlayer(contentVideo, options) {
1098
1180
  adVideoElement.pause();
1099
1181
  adVideoElement.src = "";
1100
1182
  }
1101
- if (!options?.continueLiveStreamDuringAds) {
1183
+ if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
1102
1184
  contentVideo.play().catch(() => {
1103
1185
  });
1104
1186
  }
@@ -1118,7 +1200,7 @@ function createHlsAdPlayer(contentVideo, options) {
1118
1200
  adVideoElement.remove();
1119
1201
  adVideoElement = void 0;
1120
1202
  }
1121
- if (adContainerEl?.parentElement) {
1203
+ if (adContainerEl == null ? void 0 : adContainerEl.parentElement) {
1122
1204
  adContainerEl.parentElement.removeChild(adContainerEl);
1123
1205
  }
1124
1206
  adContainerEl = void 0;
@@ -1144,7 +1226,8 @@ function createHlsAdPlayer(contentVideo, options) {
1144
1226
  listeners.get(event).add(listener);
1145
1227
  },
1146
1228
  off(event, listener) {
1147
- listeners.get(event)?.delete(listener);
1229
+ var _a;
1230
+ (_a = listeners.get(event)) == null ? void 0 : _a.delete(listener);
1148
1231
  },
1149
1232
  updateOriginalMutedState(muted) {
1150
1233
  originalMutedState = muted;
@@ -1169,6 +1252,7 @@ function createHlsAdPlayer(contentVideo, options) {
1169
1252
  // src/utils/tracking.ts
1170
1253
  var cachedBrowserId = null;
1171
1254
  function getClientInfo() {
1255
+ var _a, _b, _c, _d;
1172
1256
  const ua = navigator.userAgent;
1173
1257
  const platform = navigator.platform;
1174
1258
  const vendor = navigator.vendor || "";
@@ -1176,12 +1260,12 @@ function getClientInfo() {
1176
1260
  const memory = navigator.deviceMemory || null;
1177
1261
  const hardwareConcurrency = navigator.hardwareConcurrency || 1;
1178
1262
  const screenInfo = {
1179
- width: screen?.width,
1180
- height: screen?.height,
1181
- availWidth: screen?.availWidth,
1182
- availHeight: screen?.availHeight,
1183
- orientation: screen?.orientation?.type || "",
1184
- pixelDepth: screen?.pixelDepth
1263
+ width: screen == null ? void 0 : screen.width,
1264
+ height: screen == null ? void 0 : screen.height,
1265
+ availWidth: screen == null ? void 0 : screen.availWidth,
1266
+ availHeight: screen == null ? void 0 : screen.availHeight,
1267
+ orientation: ((_a = screen == null ? void 0 : screen.orientation) == null ? void 0 : _a.type) || "",
1268
+ pixelDepth: screen == null ? void 0 : screen.pixelDepth
1185
1269
  };
1186
1270
  let deviceType = "desktop";
1187
1271
  let brand = "Unknown";
@@ -1278,10 +1362,10 @@ function getClientInfo() {
1278
1362
  if (vendor.includes("Samsung") || ua.includes("SM-")) brand = "Samsung";
1279
1363
  }
1280
1364
  isWebView = /wv|WebView|Linux; U;/.test(ua);
1281
- if (window?.outerHeight === 0 && window?.outerWidth === 0) {
1365
+ if ((window == null ? void 0 : window.outerHeight) === 0 && (window == null ? void 0 : window.outerWidth) === 0) {
1282
1366
  isWebView = true;
1283
1367
  }
1284
- isWebApp = window.matchMedia("(display-mode: standalone)").matches || window.navigator.standalone === true || window.screen?.orientation?.angle !== void 0;
1368
+ isWebApp = window.matchMedia("(display-mode: standalone)").matches || window.navigator.standalone === true || ((_c = (_b = window.screen) == null ? void 0 : _b.orientation) == null ? void 0 : _c.angle) !== void 0;
1285
1369
  return {
1286
1370
  brand,
1287
1371
  os,
@@ -1302,7 +1386,7 @@ function getClientInfo() {
1302
1386
  deviceMemory: memory,
1303
1387
  maxTouchPoints,
1304
1388
  language: navigator.language,
1305
- languages: navigator.languages?.join(",") || "",
1389
+ languages: ((_d = navigator.languages) == null ? void 0 : _d.join(",")) || "",
1306
1390
  cookieEnabled: navigator.cookieEnabled,
1307
1391
  doNotTrack: navigator.doNotTrack || "",
1308
1392
  referrer: document.referrer,
@@ -1660,7 +1744,8 @@ var StormcloudVideoPlayer = class {
1660
1744
  }
1661
1745
  return createHlsAdPlayer(this.video, {
1662
1746
  continueLiveStreamDuringAds,
1663
- ...this.config.licenseKey ? { licenseKey: this.config.licenseKey } : {}
1747
+ ...this.config.licenseKey ? { licenseKey: this.config.licenseKey } : {},
1748
+ ...this.hls ? { mainHlsInstance: this.hls } : {}
1664
1749
  });
1665
1750
  } else {
1666
1751
  if (this.config.debugAdTiming) {
@@ -1672,6 +1757,7 @@ var StormcloudVideoPlayer = class {
1672
1757
  }
1673
1758
  }
1674
1759
  async load() {
1760
+ var _a, _b;
1675
1761
  if (!this.attached) {
1676
1762
  this.attach();
1677
1763
  }
@@ -1688,7 +1774,7 @@ var StormcloudVideoPlayer = class {
1688
1774
  this.initializeTracking();
1689
1775
  if (this.shouldUseNativeHls()) {
1690
1776
  this.video.src = this.config.src;
1691
- this.isLiveStream = this.config.lowLatencyMode ?? false;
1777
+ this.isLiveStream = (_a = this.config.lowLatencyMode) != null ? _a : false;
1692
1778
  if (this.config.debugAdTiming) {
1693
1779
  console.log(
1694
1780
  "[StormcloudVideoPlayer] allowNativeHls: true - VOD mode detected:",
@@ -1703,8 +1789,8 @@ var StormcloudVideoPlayer = class {
1703
1789
  this.ima = this.createAdPlayer(false);
1704
1790
  this.ima.initialize();
1705
1791
  if (this.config.autoplay) {
1706
- await this.video.play()?.catch(() => {
1707
- });
1792
+ await ((_b = this.video.play()) == null ? void 0 : _b.catch(() => {
1793
+ }));
1708
1794
  }
1709
1795
  return;
1710
1796
  }
@@ -1717,12 +1803,17 @@ var StormcloudVideoPlayer = class {
1717
1803
  ...this.config.lowLatencyMode ? { liveSyncDuration: 2 } : {}
1718
1804
  });
1719
1805
  this.hls.on(import_hls2.default.Events.MEDIA_ATTACHED, () => {
1720
- this.hls?.loadSource(this.config.src);
1806
+ var _a2;
1807
+ (_a2 = this.hls) == null ? void 0 : _a2.loadSource(this.config.src);
1721
1808
  });
1722
1809
  this.hls.on(import_hls2.default.Events.MANIFEST_PARSED, async (_, data) => {
1723
- this.isLiveStream = this.hls?.levels?.some(
1724
- (level) => level?.details?.live === true || level?.details?.type === "LIVE"
1725
- ) ?? false;
1810
+ var _a2, _b2, _c, _d;
1811
+ this.isLiveStream = (_c = (_b2 = (_a2 = this.hls) == null ? void 0 : _a2.levels) == null ? void 0 : _b2.some(
1812
+ (level) => {
1813
+ var _a3, _b3;
1814
+ return ((_a3 = level == null ? void 0 : level.details) == null ? void 0 : _a3.live) === true || ((_b3 = level == null ? void 0 : level.details) == null ? void 0 : _b3.type) === "LIVE";
1815
+ }
1816
+ )) != null ? _c : false;
1726
1817
  if (this.config.debugAdTiming) {
1727
1818
  const adBehavior = this.shouldContinueLiveStreamDuringAds() ? "live (main video continues muted during ads)" : "vod (main video pauses during ads)";
1728
1819
  console.log("[StormcloudVideoPlayer] Stream type detected:", {
@@ -1735,28 +1826,29 @@ var StormcloudVideoPlayer = class {
1735
1826
  this.ima = this.createAdPlayer(this.shouldContinueLiveStreamDuringAds());
1736
1827
  this.ima.initialize();
1737
1828
  if (this.config.autoplay) {
1738
- await this.video.play()?.catch(() => {
1739
- });
1829
+ await ((_d = this.video.play()) == null ? void 0 : _d.catch(() => {
1830
+ }));
1740
1831
  }
1741
1832
  });
1742
1833
  this.hls.on(import_hls2.default.Events.FRAG_PARSING_METADATA, (_evt, data) => {
1743
- const id3Tags = (data?.samples || []).map((s) => ({
1834
+ const id3Tags = ((data == null ? void 0 : data.samples) || []).map((s) => ({
1744
1835
  key: "ID3",
1745
- value: s?.data,
1746
- ptsSeconds: s?.pts
1836
+ value: s == null ? void 0 : s.data,
1837
+ ptsSeconds: s == null ? void 0 : s.pts
1747
1838
  }));
1748
1839
  id3Tags.forEach((tag) => this.onId3Tag(tag));
1749
1840
  });
1750
1841
  this.hls.on(import_hls2.default.Events.FRAG_CHANGED, (_evt, data) => {
1751
- const frag = data?.frag;
1752
- const tagList = frag?.tagList;
1842
+ var _a2, _b2, _c;
1843
+ const frag = data == null ? void 0 : data.frag;
1844
+ const tagList = frag == null ? void 0 : frag.tagList;
1753
1845
  if (!Array.isArray(tagList)) return;
1754
1846
  for (const entry of tagList) {
1755
1847
  let tag = "";
1756
1848
  let value = "";
1757
1849
  if (Array.isArray(entry)) {
1758
- tag = String(entry[0] ?? "");
1759
- value = String(entry[1] ?? "");
1850
+ tag = String((_a2 = entry[0]) != null ? _a2 : "");
1851
+ value = String((_b2 = entry[1]) != null ? _b2 : "");
1760
1852
  } else if (typeof entry === "string") {
1761
1853
  const idx = entry.indexOf(":");
1762
1854
  if (idx >= 0) {
@@ -1780,8 +1872,8 @@ var StormcloudVideoPlayer = class {
1780
1872
  const prog = this.parseCueOutCont(value);
1781
1873
  const marker = {
1782
1874
  type: "progress",
1783
- ...prog?.duration !== void 0 ? { durationSeconds: prog.duration } : {},
1784
- ...prog?.elapsed !== void 0 ? { ptsSeconds: prog.elapsed } : {},
1875
+ ...(prog == null ? void 0 : prog.duration) !== void 0 ? { durationSeconds: prog.duration } : {},
1876
+ ...(prog == null ? void 0 : prog.elapsed) !== void 0 ? { ptsSeconds: prog.elapsed } : {},
1785
1877
  raw: { tag, value }
1786
1878
  };
1787
1879
  this.onScte35Marker(marker);
@@ -1791,7 +1883,7 @@ var StormcloudVideoPlayer = class {
1791
1883
  const attrs = this.parseAttributeList(value);
1792
1884
  const hasScteOut = "SCTE35-OUT" in attrs || attrs["SCTE35-OUT"] !== void 0;
1793
1885
  const hasScteIn = "SCTE35-IN" in attrs || attrs["SCTE35-IN"] !== void 0;
1794
- const klass = String(attrs["CLASS"] ?? "");
1886
+ const klass = String((_c = attrs["CLASS"]) != null ? _c : "");
1795
1887
  const duration = this.toNumber(attrs["DURATION"]);
1796
1888
  if (hasScteOut || /com\.apple\.hls\.cue/i.test(klass)) {
1797
1889
  const marker = {
@@ -1808,13 +1900,14 @@ var StormcloudVideoPlayer = class {
1808
1900
  }
1809
1901
  });
1810
1902
  this.hls.on(import_hls2.default.Events.ERROR, (_evt, data) => {
1811
- if (data?.fatal) {
1903
+ var _a2, _b2;
1904
+ if (data == null ? void 0 : data.fatal) {
1812
1905
  switch (data.type) {
1813
1906
  case import_hls2.default.ErrorTypes.NETWORK_ERROR:
1814
- this.hls?.startLoad();
1907
+ (_a2 = this.hls) == null ? void 0 : _a2.startLoad();
1815
1908
  break;
1816
1909
  case import_hls2.default.ErrorTypes.MEDIA_ERROR:
1817
- this.hls?.recoverMediaError();
1910
+ (_b2 = this.hls) == null ? void 0 : _b2.recoverMediaError();
1818
1911
  break;
1819
1912
  default:
1820
1913
  this.destroy();
@@ -1916,11 +2009,12 @@ var StormcloudVideoPlayer = class {
1916
2009
  }
1917
2010
  }
1918
2011
  parseScte35FromId3(tag) {
2012
+ var _a, _b, _c, _d;
1919
2013
  const text = this.decodeId3ValueToText(tag.value);
1920
2014
  if (!text) return void 0;
1921
2015
  const cueOutMatch = text.match(/EXT-X-CUE-OUT(?::([^\r\n]*))?/i) || text.match(/CUE-OUT(?::([^\r\n]*))?/i);
1922
2016
  if (cueOutMatch) {
1923
- const arg = (cueOutMatch[1] ?? "").trim();
2017
+ const arg = ((_a = cueOutMatch[1]) != null ? _a : "").trim();
1924
2018
  const dur = this.parseCueOutDuration(arg);
1925
2019
  const marker = {
1926
2020
  type: "start",
@@ -1932,12 +2026,12 @@ var StormcloudVideoPlayer = class {
1932
2026
  }
1933
2027
  const cueOutContMatch = text.match(/EXT-X-CUE-OUT-CONT:([^\r\n]*)/i);
1934
2028
  if (cueOutContMatch) {
1935
- const arg = (cueOutContMatch[1] ?? "").trim();
2029
+ const arg = ((_b = cueOutContMatch[1]) != null ? _b : "").trim();
1936
2030
  const cont = this.parseCueOutCont(arg);
1937
2031
  const marker = {
1938
2032
  type: "progress",
1939
2033
  ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},
1940
- ...cont?.duration !== void 0 ? { durationSeconds: cont.duration } : {},
2034
+ ...(cont == null ? void 0 : cont.duration) !== void 0 ? { durationSeconds: cont.duration } : {},
1941
2035
  raw: { id3: text }
1942
2036
  };
1943
2037
  return marker;
@@ -1953,10 +2047,10 @@ var StormcloudVideoPlayer = class {
1953
2047
  }
1954
2048
  const daterangeMatch = text.match(/EXT-X-DATERANGE:([^\r\n]*)/i);
1955
2049
  if (daterangeMatch) {
1956
- const attrs = this.parseAttributeList(daterangeMatch[1] ?? "");
2050
+ const attrs = this.parseAttributeList((_c = daterangeMatch[1]) != null ? _c : "");
1957
2051
  const hasScteOut = "SCTE35-OUT" in attrs || attrs["SCTE35-OUT"] !== void 0;
1958
2052
  const hasScteIn = "SCTE35-IN" in attrs || attrs["SCTE35-IN"] !== void 0;
1959
- const klass = String(attrs["CLASS"] ?? "");
2053
+ const klass = String((_d = attrs["CLASS"]) != null ? _d : "");
1960
2054
  const duration = this.toNumber(attrs["DURATION"]);
1961
2055
  if (hasScteOut || /com\.apple\.hls\.cue/i.test(klass)) {
1962
2056
  const marker = {
@@ -2013,6 +2107,7 @@ var StormcloudVideoPlayer = class {
2013
2107
  }
2014
2108
  }
2015
2109
  onScte35Marker(marker) {
2110
+ var _a, _b;
2016
2111
  if (this.config.debugAdTiming) {
2017
2112
  console.log("[StormcloudVideoPlayer] SCTE-35 marker detected:", {
2018
2113
  type: marker.type,
@@ -2028,7 +2123,7 @@ var StormcloudVideoPlayer = class {
2028
2123
  this.expectedAdBreakDurationMs = durationMs;
2029
2124
  this.currentAdBreakStartWallClockMs = Date.now();
2030
2125
  const isManifestMarker = this.isManifestBasedMarker(marker);
2031
- const forceImmediate = this.config.immediateManifestAds ?? true;
2126
+ const forceImmediate = (_a = this.config.immediateManifestAds) != null ? _a : true;
2032
2127
  if (this.config.debugAdTiming) {
2033
2128
  console.log("[StormcloudVideoPlayer] Ad start decision:", {
2034
2129
  isManifestMarker,
@@ -2045,7 +2140,7 @@ var StormcloudVideoPlayer = class {
2045
2140
  this.clearAdStartTimer();
2046
2141
  this.handleAdStart(marker);
2047
2142
  } else if (typeof marker.ptsSeconds === "number") {
2048
- const tol = this.config.driftToleranceMs ?? 1e3;
2143
+ const tol = (_b = this.config.driftToleranceMs) != null ? _b : 1e3;
2049
2144
  const nowMs = this.video.currentTime * 1e3;
2050
2145
  const estCurrentPtsMs = nowMs - this.ptsDriftEmaMs;
2051
2146
  const deltaMs = Math.floor(marker.ptsSeconds * 1e3 - estCurrentPtsMs);
@@ -2155,12 +2250,13 @@ var StormcloudVideoPlayer = class {
2155
2250
  return void 0;
2156
2251
  }
2157
2252
  parseAttributeList(value) {
2253
+ var _a, _b, _c;
2158
2254
  const attrs = {};
2159
2255
  const regex = /([A-Z0-9-]+)=(("[^"]*")|([^",]*))(?:,|$)/gi;
2160
2256
  let match;
2161
2257
  while ((match = regex.exec(value)) !== null) {
2162
- const key = match[1] ?? "";
2163
- let rawVal = match[3] ?? match[4] ?? "";
2258
+ const key = (_a = match[1]) != null ? _a : "";
2259
+ let rawVal = (_c = (_b = match[3]) != null ? _b : match[4]) != null ? _c : "";
2164
2260
  if (rawVal.startsWith('"') && rawVal.endsWith('"')) {
2165
2261
  rawVal = rawVal.slice(1, -1);
2166
2262
  }
@@ -2324,6 +2420,7 @@ var StormcloudVideoPlayer = class {
2324
2420
  }
2325
2421
  }
2326
2422
  async fetchAdConfiguration() {
2423
+ var _a, _b, _c;
2327
2424
  const vastMode = this.config.vastMode || "default";
2328
2425
  if (this.config.debugAdTiming) {
2329
2426
  console.log(
@@ -2381,7 +2478,7 @@ var StormcloudVideoPlayer = class {
2381
2478
  return;
2382
2479
  }
2383
2480
  const data = await response.json();
2384
- const imaPayload = data.response?.ima?.["publisherdesk.ima"]?.payload;
2481
+ const imaPayload = (_c = (_b = (_a = data.response) == null ? void 0 : _a.ima) == null ? void 0 : _b["publisherdesk.ima"]) == null ? void 0 : _c.payload;
2385
2482
  if (imaPayload) {
2386
2483
  this.apiVastTagUrl = decodeURIComponent(imaPayload);
2387
2484
  if (this.config.debugAdTiming) {
@@ -2418,11 +2515,12 @@ var StormcloudVideoPlayer = class {
2418
2515
  return "other";
2419
2516
  }
2420
2517
  shouldShowNativeControls() {
2518
+ var _a, _b;
2421
2519
  const streamType = this.getStreamType();
2422
2520
  if (streamType === "other") {
2423
- return !(this.config.showCustomControls ?? false);
2521
+ return !((_a = this.config.showCustomControls) != null ? _a : false);
2424
2522
  }
2425
- return !!(this.config.allowNativeHls && !(this.config.showCustomControls ?? false));
2523
+ return !!(this.config.allowNativeHls && !((_b = this.config.showCustomControls) != null ? _b : false));
2426
2524
  }
2427
2525
  shouldContinueLiveStreamDuringAds() {
2428
2526
  if (this.config.allowNativeHls) {
@@ -2434,6 +2532,7 @@ var StormcloudVideoPlayer = class {
2434
2532
  return true;
2435
2533
  }
2436
2534
  async handleAdStart(_marker) {
2535
+ var _a;
2437
2536
  const scheduled = this.findCurrentOrNextBreak(
2438
2537
  this.video.currentTime * 1e3
2439
2538
  );
@@ -2484,17 +2583,18 @@ var StormcloudVideoPlayer = class {
2484
2583
  this.handleAdFailure();
2485
2584
  }
2486
2585
  }
2487
- if (this.expectedAdBreakDurationMs == null && scheduled?.durationMs != null) {
2586
+ if (this.expectedAdBreakDurationMs == null && (scheduled == null ? void 0 : scheduled.durationMs) != null) {
2488
2587
  this.expectedAdBreakDurationMs = scheduled.durationMs;
2489
- this.currentAdBreakStartWallClockMs = this.currentAdBreakStartWallClockMs ?? Date.now();
2588
+ this.currentAdBreakStartWallClockMs = (_a = this.currentAdBreakStartWallClockMs) != null ? _a : Date.now();
2490
2589
  this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);
2491
2590
  }
2492
2591
  }
2493
2592
  findCurrentOrNextBreak(nowMs) {
2593
+ var _a;
2494
2594
  const schedule = [];
2495
2595
  let candidate;
2496
2596
  for (const b of schedule) {
2497
- const tol = this.config.driftToleranceMs ?? 1e3;
2597
+ const tol = (_a = this.config.driftToleranceMs) != null ? _a : 1e3;
2498
2598
  if (b.startTimeMs <= nowMs + tol && (candidate == null || b.startTimeMs > (candidate.startTimeMs || 0))) {
2499
2599
  candidate = b;
2500
2600
  }
@@ -2510,7 +2610,8 @@ var StormcloudVideoPlayer = class {
2510
2610
  }
2511
2611
  }
2512
2612
  async handleMidAdJoin(adBreak, nowMs) {
2513
- const durationMs = adBreak.durationMs ?? 0;
2613
+ var _a;
2614
+ const durationMs = (_a = adBreak.durationMs) != null ? _a : 0;
2514
2615
  const endMs = adBreak.startTimeMs + durationMs;
2515
2616
  if (durationMs > 0 && nowMs > adBreak.startTimeMs && nowMs < endMs) {
2516
2617
  const remainingMs = endMs - nowMs;
@@ -2611,6 +2712,7 @@ var StormcloudVideoPlayer = class {
2611
2712
  }
2612
2713
  }
2613
2714
  handleAdFailure() {
2715
+ var _a;
2614
2716
  if (this.config.debugAdTiming) {
2615
2717
  console.log(
2616
2718
  "[StormcloudVideoPlayer] Handling ad failure - resuming content",
@@ -2643,7 +2745,7 @@ var StormcloudVideoPlayer = class {
2643
2745
  if (this.config.debugAdTiming) {
2644
2746
  console.log("[StormcloudVideoPlayer] Resuming paused video");
2645
2747
  }
2646
- this.video.play()?.catch((error) => {
2748
+ (_a = this.video.play()) == null ? void 0 : _a.catch((error) => {
2647
2749
  if (this.config.debugAdTiming) {
2648
2750
  console.error(
2649
2751
  "[StormcloudVideoPlayer] Failed to resume video after ad failure:",
@@ -2658,8 +2760,9 @@ var StormcloudVideoPlayer = class {
2658
2760
  }
2659
2761
  }
2660
2762
  startAdFailsafeTimer() {
2763
+ var _a;
2661
2764
  this.clearAdFailsafeTimer();
2662
- const failsafeMs = this.config.adFailsafeTimeoutMs ?? 1e4;
2765
+ const failsafeMs = (_a = this.config.adFailsafeTimeoutMs) != null ? _a : 1e4;
2663
2766
  if (this.config.debugAdTiming) {
2664
2767
  console.log(
2665
2768
  `[StormcloudVideoPlayer] Starting failsafe timer (${failsafeMs}ms)`
@@ -2795,6 +2898,7 @@ var StormcloudVideoPlayer = class {
2795
2898
  }
2796
2899
  }
2797
2900
  destroy() {
2901
+ var _a, _b;
2798
2902
  this.clearAdStartTimer();
2799
2903
  this.clearAdStopTimer();
2800
2904
  this.clearAdFailsafeTimer();
@@ -2802,8 +2906,8 @@ var StormcloudVideoPlayer = class {
2802
2906
  clearInterval(this.heartbeatInterval);
2803
2907
  this.heartbeatInterval = void 0;
2804
2908
  }
2805
- this.hls?.destroy();
2806
- this.ima?.destroy();
2909
+ (_a = this.hls) == null ? void 0 : _a.destroy();
2910
+ (_b = this.ima) == null ? void 0 : _b.destroy();
2807
2911
  }
2808
2912
  };
2809
2913
 
@@ -2843,6 +2947,7 @@ var HlsPlayer = class extends import_react.Component {
2843
2947
  this.player = null;
2844
2948
  this.mounted = false;
2845
2949
  this.load = async () => {
2950
+ var _a, _b, _c, _d, _e, _f;
2846
2951
  if (!this.props.videoElement || !this.props.src) return;
2847
2952
  try {
2848
2953
  if (this.player) {
@@ -2879,27 +2984,29 @@ var HlsPlayer = class extends import_react.Component {
2879
2984
  if (this.props.adFailsafeTimeoutMs !== void 0)
2880
2985
  config.adFailsafeTimeoutMs = this.props.adFailsafeTimeoutMs;
2881
2986
  this.player = new StormcloudVideoPlayer(config);
2882
- this.props.onMount?.(this);
2987
+ (_b = (_a = this.props).onMount) == null ? void 0 : _b.call(_a, this);
2883
2988
  await this.player.load();
2884
2989
  if (this.mounted) {
2885
- this.props.onReady?.();
2990
+ (_d = (_c = this.props).onReady) == null ? void 0 : _d.call(_c);
2886
2991
  }
2887
2992
  } catch (error) {
2888
2993
  if (this.mounted) {
2889
- this.props.onError?.(error);
2994
+ (_f = (_e = this.props).onError) == null ? void 0 : _f.call(_e, error);
2890
2995
  }
2891
2996
  }
2892
2997
  };
2893
2998
  this.play = () => {
2999
+ var _a, _b;
2894
3000
  if (this.props.videoElement) {
2895
3001
  this.props.videoElement.play();
2896
- this.props.onPlay?.();
3002
+ (_b = (_a = this.props).onPlay) == null ? void 0 : _b.call(_a);
2897
3003
  }
2898
3004
  };
2899
3005
  this.pause = () => {
3006
+ var _a, _b;
2900
3007
  if (this.props.videoElement) {
2901
3008
  this.props.videoElement.pause();
2902
- this.props.onPause?.();
3009
+ (_b = (_a = this.props).onPause) == null ? void 0 : _b.call(_a);
2903
3010
  }
2904
3011
  };
2905
3012
  this.stop = () => {