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/lib/index.js CHANGED
@@ -14,7 +14,8 @@ function getWebKitVersion(ua) {
14
14
  return match && match[1] ? parseInt(match[1], 10) : 0;
15
15
  }
16
16
  function getPlatform() {
17
- if ("userAgentData" in navigator && navigator.userAgentData?.platform) {
17
+ var _a;
18
+ if ("userAgentData" in navigator && ((_a = navigator.userAgentData) == null ? void 0 : _a.platform)) {
18
19
  return navigator.userAgentData.platform;
19
20
  }
20
21
  const ua = navigator.userAgent;
@@ -208,6 +209,7 @@ function createImaController(video, options) {
208
209
  }
209
210
  }
210
211
  function ensureImaLoaded() {
212
+ var _a, _b, _c;
211
213
  if (!supportsGoogleIMA()) {
212
214
  console.warn(
213
215
  "[IMA] Google IMA SDK is not supported on this browser. Please use HLS ad player instead."
@@ -218,7 +220,7 @@ function createImaController(video, options) {
218
220
  }
219
221
  try {
220
222
  const frameEl = window.frameElement;
221
- const sandboxAttr = frameEl?.getAttribute?.("sandbox") || "";
223
+ const sandboxAttr = ((_a = frameEl == null ? void 0 : frameEl.getAttribute) == null ? void 0 : _a.call(frameEl, "sandbox")) || "";
222
224
  if (sandboxAttr) {
223
225
  const tokens = new Set(
224
226
  sandboxAttr.split(/\s+/).map((t) => t.trim()).filter((t) => t.length > 0)
@@ -232,13 +234,13 @@ function createImaController(video, options) {
232
234
  }
233
235
  } catch {
234
236
  }
235
- if (typeof window !== "undefined" && window.google?.ima)
237
+ if (typeof window !== "undefined" && ((_b = window.google) == null ? void 0 : _b.ima))
236
238
  return Promise.resolve();
237
239
  const existing = document.querySelector(
238
240
  'script[data-ima="true"]'
239
241
  );
240
242
  if (existing) {
241
- if (window.google?.ima) {
243
+ if ((_c = window.google) == null ? void 0 : _c.ima) {
242
244
  return Promise.resolve();
243
245
  }
244
246
  return new Promise((resolve, reject) => {
@@ -296,6 +298,7 @@ function createImaController(video, options) {
296
298
  return {
297
299
  initialize() {
298
300
  ensureImaLoaded().then(() => {
301
+ var _a, _b;
299
302
  const google = window.google;
300
303
  if (!adDisplayContainer) {
301
304
  const container = document.createElement("div");
@@ -309,14 +312,14 @@ function createImaController(video, options) {
309
312
  container.style.justifyContent = "center";
310
313
  container.style.pointerEvents = "none";
311
314
  container.style.zIndex = "2";
312
- video.parentElement?.appendChild(container);
315
+ (_a = video.parentElement) == null ? void 0 : _a.appendChild(container);
313
316
  adContainerEl = container;
314
317
  adDisplayContainer = new google.ima.AdDisplayContainer(
315
318
  container,
316
319
  video
317
320
  );
318
321
  try {
319
- adDisplayContainer.initialize?.();
322
+ (_b = adDisplayContainer.initialize) == null ? void 0 : _b.call(adDisplayContainer);
320
323
  } catch {
321
324
  }
322
325
  }
@@ -401,6 +404,7 @@ function createImaController(video, options) {
401
404
  adsManager.addEventListener(
402
405
  AdErrorEvent.AD_ERROR,
403
406
  (errorEvent) => {
407
+ var _a;
404
408
  console.error("[IMA] Ad error:", errorEvent.getError());
405
409
  destroyAdsManager();
406
410
  adPlaying = false;
@@ -431,10 +435,10 @@ function createImaController(video, options) {
431
435
  "[IMA] Max retries reached, emitting ad_error"
432
436
  );
433
437
  emit("ad_error");
434
- if (!options?.continueLiveStreamDuringAds) {
438
+ if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
435
439
  if (video.paused) {
436
440
  console.log("[IMA] Resuming paused video after ad error");
437
- video.play()?.catch(() => {
441
+ (_a = video.play()) == null ? void 0 : _a.catch(() => {
438
442
  });
439
443
  }
440
444
  }
@@ -445,7 +449,7 @@ function createImaController(video, options) {
445
449
  AdEvent.CONTENT_PAUSE_REQUESTED,
446
450
  () => {
447
451
  console.log("[IMA] Content pause requested");
448
- if (!options?.continueLiveStreamDuringAds) {
452
+ if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
449
453
  video.pause();
450
454
  console.log("[IMA] Video paused (VOD mode)");
451
455
  } else {
@@ -471,6 +475,7 @@ function createImaController(video, options) {
471
475
  adsManager.addEventListener(
472
476
  AdEvent.CONTENT_RESUME_REQUESTED,
473
477
  () => {
478
+ var _a;
474
479
  console.log("[IMA] Content resume requested");
475
480
  adPlaying = false;
476
481
  video.muted = originalMutedState;
@@ -481,8 +486,8 @@ function createImaController(video, options) {
481
486
  "[IMA] Ad container hidden - pointer events disabled"
482
487
  );
483
488
  }
484
- if (!options?.continueLiveStreamDuringAds) {
485
- video.play()?.catch(() => {
489
+ if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
490
+ (_a = video.play()) == null ? void 0 : _a.catch(() => {
486
491
  });
487
492
  console.log("[IMA] Video resumed (VOD mode)");
488
493
  } else {
@@ -504,7 +509,7 @@ function createImaController(video, options) {
504
509
  "[IMA] Ad container hidden after all ads completed"
505
510
  );
506
511
  }
507
- if (!options?.continueLiveStreamDuringAds) {
512
+ if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
508
513
  video.play().catch(() => {
509
514
  });
510
515
  console.log(
@@ -532,7 +537,7 @@ function createImaController(video, options) {
532
537
  adContainerEl.style.display = "none";
533
538
  console.log("[IMA] Ad container hidden after setup error");
534
539
  }
535
- if (!options?.continueLiveStreamDuringAds) {
540
+ if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
536
541
  if (video.paused) {
537
542
  console.log("[IMA] Resuming paused video after setup error");
538
543
  video.play().catch(() => {
@@ -560,7 +565,7 @@ function createImaController(video, options) {
560
565
  adContainerEl.style.display = "none";
561
566
  console.log("[IMA] Ad container hidden after loader error");
562
567
  }
563
- if (!options?.continueLiveStreamDuringAds) {
568
+ if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
564
569
  if (video.paused) {
565
570
  console.log("[IMA] Resuming paused video after loader error");
566
571
  video.play().catch(() => {
@@ -582,14 +587,15 @@ function createImaController(video, options) {
582
587
  return adsLoadedPromise;
583
588
  } catch (error) {
584
589
  console.error("[IMA] Failed to request ads:", error);
585
- currentReject?.(error);
590
+ currentReject == null ? void 0 : currentReject(error);
586
591
  adsLoadedReject = void 0;
587
592
  adsLoadedResolve = void 0;
588
593
  return Promise.reject(error);
589
594
  }
590
595
  },
591
596
  async play() {
592
- if (!window.google?.ima || !adDisplayContainer) {
597
+ var _a, _b;
598
+ if (!((_a = window.google) == null ? void 0 : _a.ima) || !adDisplayContainer) {
593
599
  console.warn(
594
600
  "[IMA] Cannot play ad: IMA SDK or ad container not available"
595
601
  );
@@ -611,14 +617,15 @@ function createImaController(video, options) {
611
617
  } catch (error) {
612
618
  console.error("[IMA] Error starting ad playback:", error);
613
619
  adPlaying = false;
614
- if (!options?.continueLiveStreamDuringAds) {
615
- video.play()?.catch(() => {
620
+ if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
621
+ (_b = video.play()) == null ? void 0 : _b.catch(() => {
616
622
  });
617
623
  }
618
624
  return Promise.reject(error);
619
625
  }
620
626
  },
621
627
  async stop() {
628
+ var _a;
622
629
  adPlaying = false;
623
630
  video.muted = originalMutedState;
624
631
  if (adContainerEl) {
@@ -627,11 +634,11 @@ function createImaController(video, options) {
627
634
  console.log("[IMA] Ad container hidden after stop");
628
635
  }
629
636
  try {
630
- adsManager?.stop?.();
637
+ (_a = adsManager == null ? void 0 : adsManager.stop) == null ? void 0 : _a.call(adsManager);
631
638
  } catch {
632
639
  }
633
640
  destroyAdsManager();
634
- if (!options?.continueLiveStreamDuringAds) {
641
+ if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
635
642
  video.play().catch(() => {
636
643
  });
637
644
  console.log("[IMA] Video resumed after stop (VOD mode)");
@@ -640,6 +647,7 @@ function createImaController(video, options) {
640
647
  }
641
648
  },
642
649
  destroy() {
650
+ var _a;
643
651
  destroyAdsManager();
644
652
  adPlaying = false;
645
653
  video.muted = originalMutedState;
@@ -648,10 +656,10 @@ function createImaController(video, options) {
648
656
  adContainerEl.style.display = "none";
649
657
  }
650
658
  try {
651
- adsLoader?.destroy?.();
659
+ (_a = adsLoader == null ? void 0 : adsLoader.destroy) == null ? void 0 : _a.call(adsLoader);
652
660
  } catch {
653
661
  }
654
- if (adContainerEl?.parentElement) {
662
+ if (adContainerEl == null ? void 0 : adContainerEl.parentElement) {
655
663
  adContainerEl.parentElement.removeChild(adContainerEl);
656
664
  }
657
665
  adContainerEl = void 0;
@@ -662,7 +670,8 @@ function createImaController(video, options) {
662
670
  return adPlaying;
663
671
  },
664
672
  resize(width, height) {
665
- if (!adsManager || !window.google?.ima) {
673
+ var _a;
674
+ if (!adsManager || !((_a = window.google) == null ? void 0 : _a.ima)) {
666
675
  console.warn(
667
676
  "[IMA] Cannot resize: No ads manager or IMA SDK available"
668
677
  );
@@ -680,7 +689,8 @@ function createImaController(video, options) {
680
689
  listeners.get(event).add(listener);
681
690
  },
682
691
  off(event, listener) {
683
- listeners.get(event)?.delete(listener);
692
+ var _a;
693
+ (_a = listeners.get(event)) == null ? void 0 : _a.delete(listener);
684
694
  },
685
695
  updateOriginalMutedState(muted) {
686
696
  originalMutedState = muted;
@@ -717,7 +727,8 @@ function createHlsAdPlayer(contentVideo, options) {
717
727
  let adPlaying = false;
718
728
  let originalMutedState = false;
719
729
  const listeners = /* @__PURE__ */ new Map();
720
- const licenseKey = options?.licenseKey;
730
+ const licenseKey = options == null ? void 0 : options.licenseKey;
731
+ const mainHlsInstance = options == null ? void 0 : options.mainHlsInstance;
721
732
  let adVideoElement;
722
733
  let adHls;
723
734
  let adContainerEl;
@@ -764,13 +775,80 @@ function createHlsAdPlayer(contentVideo, options) {
764
775
  }
765
776
  });
766
777
  }
778
+ function getMainStreamQuality() {
779
+ if (!mainHlsInstance || !mainHlsInstance.levels) {
780
+ return null;
781
+ }
782
+ const currentLevel = mainHlsInstance.currentLevel;
783
+ if (currentLevel === -1 || !mainHlsInstance.levels[currentLevel]) {
784
+ const autoLevel = mainHlsInstance.loadLevel;
785
+ if (autoLevel !== -1 && mainHlsInstance.levels[autoLevel]) {
786
+ const level2 = mainHlsInstance.levels[autoLevel];
787
+ return {
788
+ width: level2.width || 1920,
789
+ height: level2.height || 1080,
790
+ bitrate: level2.bitrate || 5e6
791
+ };
792
+ }
793
+ return null;
794
+ }
795
+ const level = mainHlsInstance.levels[currentLevel];
796
+ return {
797
+ width: level.width || 1920,
798
+ height: level.height || 1080,
799
+ bitrate: level.bitrate || 5e6
800
+ };
801
+ }
802
+ function selectBestMediaFile(mediaFiles) {
803
+ if (mediaFiles.length === 0) {
804
+ throw new Error("No media files available");
805
+ }
806
+ const firstFile = mediaFiles[0];
807
+ if (!firstFile) {
808
+ throw new Error("No media files available");
809
+ }
810
+ if (mediaFiles.length === 1) {
811
+ return firstFile;
812
+ }
813
+ const mainQuality = getMainStreamQuality();
814
+ if (!mainQuality) {
815
+ console.log("[HlsAdPlayer] No main stream quality info, using first media file");
816
+ return firstFile;
817
+ }
818
+ console.log("[HlsAdPlayer] Main stream quality:", mainQuality);
819
+ const scoredFiles = mediaFiles.map((file) => {
820
+ const widthDiff = Math.abs(file.width - mainQuality.width);
821
+ const heightDiff = Math.abs(file.height - mainQuality.height);
822
+ const resolutionDiff = widthDiff + heightDiff;
823
+ const fileBitrate = (file.bitrate || 5e3) * 1e3;
824
+ const bitrateDiff = Math.abs(fileBitrate - mainQuality.bitrate);
825
+ const score = resolutionDiff * 2 + bitrateDiff / 1e3;
826
+ return { file, score, resolutionDiff, bitrateDiff };
827
+ });
828
+ scoredFiles.sort((a, b) => a.score - b.score);
829
+ const bestMatch = scoredFiles[0];
830
+ if (!bestMatch) {
831
+ console.log("[HlsAdPlayer] No best match found, using first media file");
832
+ return firstFile;
833
+ }
834
+ console.log("[HlsAdPlayer] Selected media file:", {
835
+ url: bestMatch.file.url,
836
+ resolution: `${bestMatch.file.width}x${bestMatch.file.height}`,
837
+ bitrate: bestMatch.file.bitrate,
838
+ score: bestMatch.score,
839
+ resolutionDiff: bestMatch.resolutionDiff,
840
+ bitrateDiff: bestMatch.bitrateDiff
841
+ });
842
+ return bestMatch.file;
843
+ }
767
844
  function parseVastXml(xmlString) {
845
+ var _a, _b, _c, _d;
768
846
  try {
769
847
  const parser = new DOMParser();
770
848
  const xmlDoc = parser.parseFromString(xmlString, "text/xml");
771
849
  const parserError = xmlDoc.querySelector("parsererror");
772
850
  if (parserError) {
773
- console.error("[HlsAdPlayer] XML parsing error:", parserError.textContent);
851
+ console.error("[HlsAdPlayer] XML parsing error (malformed VAST XML):", parserError.textContent);
774
852
  return null;
775
853
  }
776
854
  const adElement = xmlDoc.querySelector("Ad");
@@ -779,28 +857,46 @@ function createHlsAdPlayer(contentVideo, options) {
779
857
  return null;
780
858
  }
781
859
  const adId = adElement.getAttribute("id") || "unknown";
782
- const title = xmlDoc.querySelector("AdTitle")?.textContent || "Ad";
783
- const durationText = xmlDoc.querySelector("Duration")?.textContent || "00:00:30";
860
+ const title = ((_a = xmlDoc.querySelector("AdTitle")) == null ? void 0 : _a.textContent) || "Ad";
861
+ const isNoAdAvailable = adId === "empty" || title.toLowerCase().includes("no ad available") || title.toLowerCase() === "no ad available";
862
+ const durationText = ((_b = xmlDoc.querySelector("Duration")) == null ? void 0 : _b.textContent) || "00:00:30";
784
863
  const durationParts = durationText.split(":");
785
864
  const duration = parseInt(durationParts[0] || "0", 10) * 3600 + parseInt(durationParts[1] || "0", 10) * 60 + parseInt(durationParts[2] || "0", 10);
786
865
  const mediaFileElements = xmlDoc.querySelectorAll("MediaFile");
787
866
  const mediaFiles = [];
788
- mediaFileElements.forEach((mf) => {
867
+ console.log(`[HlsAdPlayer] Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`);
868
+ mediaFileElements.forEach((mf, index) => {
869
+ var _a2;
789
870
  const type = mf.getAttribute("type") || "";
871
+ const url = ((_a2 = mf.textContent) == null ? void 0 : _a2.trim()) || "";
872
+ const width = mf.getAttribute("width") || "";
873
+ const height = mf.getAttribute("height") || "";
874
+ console.log(`[HlsAdPlayer] MediaFile ${index}: type="${type}", url="${url}", width="${width}", height="${height}"`);
790
875
  if (type === "application/x-mpegURL" || type.includes("m3u8")) {
876
+ if (!url) {
877
+ console.warn(`[HlsAdPlayer] MediaFile ${index} has HLS type but empty URL`);
878
+ return;
879
+ }
791
880
  const bitrateAttr = mf.getAttribute("bitrate");
792
881
  const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;
793
882
  mediaFiles.push({
794
- url: mf.textContent?.trim() || "",
883
+ url,
795
884
  type,
796
- width: parseInt(mf.getAttribute("width") || "1920", 10),
797
- height: parseInt(mf.getAttribute("height") || "1080", 10),
885
+ width: parseInt(width || "1920", 10),
886
+ height: parseInt(height || "1080", 10),
798
887
  bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : void 0
799
888
  });
889
+ console.log(`[HlsAdPlayer] Added HLS MediaFile: ${url}`);
890
+ } else {
891
+ console.log(`[HlsAdPlayer] MediaFile ${index} ignored (type="${type}" is not HLS)`);
800
892
  }
801
893
  });
802
894
  if (mediaFiles.length === 0) {
803
- console.warn("[HlsAdPlayer] No HLS media files found in VAST XML");
895
+ if (isNoAdAvailable) {
896
+ console.warn("[HlsAdPlayer] No ads available (VAST response indicates no ads)");
897
+ } else {
898
+ console.warn("[HlsAdPlayer] No HLS media files found in VAST XML");
899
+ }
804
900
  return null;
805
901
  }
806
902
  const trackingUrls = {
@@ -820,12 +916,14 @@ function createHlsAdPlayer(contentVideo, options) {
820
916
  error: []
821
917
  };
822
918
  xmlDoc.querySelectorAll("Impression").forEach((el) => {
823
- const url = el.textContent?.trim();
919
+ var _a2;
920
+ const url = (_a2 = el.textContent) == null ? void 0 : _a2.trim();
824
921
  if (url) trackingUrls.impression.push(url);
825
922
  });
826
923
  xmlDoc.querySelectorAll("Tracking").forEach((el) => {
924
+ var _a2;
827
925
  const event = el.getAttribute("event");
828
- const url = el.textContent?.trim();
926
+ const url = (_a2 = el.textContent) == null ? void 0 : _a2.trim();
829
927
  if (event && url) {
830
928
  const eventKey = event;
831
929
  if (trackingUrls[eventKey]) {
@@ -833,7 +931,7 @@ function createHlsAdPlayer(contentVideo, options) {
833
931
  }
834
932
  }
835
933
  });
836
- const clickThrough = xmlDoc.querySelector("ClickThrough")?.textContent?.trim();
934
+ const clickThrough = (_d = (_c = xmlDoc.querySelector("ClickThrough")) == null ? void 0 : _c.textContent) == null ? void 0 : _d.trim();
837
935
  return {
838
936
  id: adId,
839
937
  title,
@@ -925,7 +1023,7 @@ function createHlsAdPlayer(contentVideo, options) {
925
1023
  adContainerEl.style.display = "none";
926
1024
  adContainerEl.style.pointerEvents = "none";
927
1025
  }
928
- if (!options?.continueLiveStreamDuringAds) {
1026
+ if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
929
1027
  contentVideo.play().catch(() => {
930
1028
  });
931
1029
  console.log("[HlsAdPlayer] Content resumed (VOD mode)");
@@ -943,7 +1041,7 @@ function createHlsAdPlayer(contentVideo, options) {
943
1041
  adContainerEl.style.display = "none";
944
1042
  adContainerEl.style.pointerEvents = "none";
945
1043
  }
946
- if (!options?.continueLiveStreamDuringAds) {
1044
+ if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
947
1045
  if (contentVideo.paused) {
948
1046
  contentVideo.play().catch(() => {
949
1047
  });
@@ -953,6 +1051,7 @@ function createHlsAdPlayer(contentVideo, options) {
953
1051
  }
954
1052
  return {
955
1053
  initialize() {
1054
+ var _a;
956
1055
  console.log("[HlsAdPlayer] Initializing");
957
1056
  if (!adContainerEl) {
958
1057
  const container = document.createElement("div");
@@ -967,7 +1066,7 @@ function createHlsAdPlayer(contentVideo, options) {
967
1066
  container.style.pointerEvents = "none";
968
1067
  container.style.zIndex = "2";
969
1068
  container.style.backgroundColor = "#000";
970
- contentVideo.parentElement?.appendChild(container);
1069
+ (_a = contentVideo.parentElement) == null ? void 0 : _a.appendChild(container);
971
1070
  adContainerEl = container;
972
1071
  }
973
1072
  },
@@ -985,9 +1084,11 @@ function createHlsAdPlayer(contentVideo, options) {
985
1084
  }
986
1085
  const vastXml = await response.text();
987
1086
  console.log("[HlsAdPlayer] VAST XML received");
1087
+ console.log("[HlsAdPlayer] VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
988
1088
  const ad = parseVastXml(vastXml);
989
1089
  if (!ad) {
990
- throw new Error("Failed to parse VAST XML or no ads available");
1090
+ console.warn("[HlsAdPlayer] No ads available from VAST response");
1091
+ return Promise.resolve();
991
1092
  }
992
1093
  currentAd = ad;
993
1094
  console.log(`[HlsAdPlayer] Ad parsed: ${ad.title}, duration: ${ad.duration}s`);
@@ -1002,14 +1103,14 @@ function createHlsAdPlayer(contentVideo, options) {
1002
1103
  },
1003
1104
  async play() {
1004
1105
  if (!currentAd) {
1005
- console.warn("[HlsAdPlayer] Cannot play: No ad loaded");
1106
+ console.warn("[HlsAdPlayer] Cannot play: No ad loaded (no ads available)");
1006
1107
  return Promise.reject(new Error("No ad loaded"));
1007
1108
  }
1008
1109
  console.log("[HlsAdPlayer] Starting ad playback");
1009
1110
  try {
1010
1111
  if (!adVideoElement) {
1011
1112
  adVideoElement = createAdVideoElement();
1012
- adContainerEl?.appendChild(adVideoElement);
1113
+ adContainerEl == null ? void 0 : adContainerEl.appendChild(adVideoElement);
1013
1114
  setupAdEventListeners();
1014
1115
  }
1015
1116
  trackingFired = {
@@ -1020,7 +1121,7 @@ function createHlsAdPlayer(contentVideo, options) {
1020
1121
  thirdQuartile: false,
1021
1122
  complete: false
1022
1123
  };
1023
- if (!options?.continueLiveStreamDuringAds) {
1124
+ if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
1024
1125
  contentVideo.pause();
1025
1126
  console.log("[HlsAdPlayer] Content paused (VOD mode)");
1026
1127
  } else {
@@ -1033,7 +1134,7 @@ function createHlsAdPlayer(contentVideo, options) {
1033
1134
  adContainerEl.style.pointerEvents = "auto";
1034
1135
  }
1035
1136
  emit("content_pause");
1036
- const mediaFile = currentAd.mediaFiles[0];
1137
+ const mediaFile = selectBestMediaFile(currentAd.mediaFiles);
1037
1138
  if (!mediaFile) {
1038
1139
  throw new Error("No media file available for ad");
1039
1140
  }
@@ -1093,7 +1194,7 @@ function createHlsAdPlayer(contentVideo, options) {
1093
1194
  adVideoElement.pause();
1094
1195
  adVideoElement.src = "";
1095
1196
  }
1096
- if (!options?.continueLiveStreamDuringAds) {
1197
+ if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
1097
1198
  contentVideo.play().catch(() => {
1098
1199
  });
1099
1200
  }
@@ -1113,7 +1214,7 @@ function createHlsAdPlayer(contentVideo, options) {
1113
1214
  adVideoElement.remove();
1114
1215
  adVideoElement = void 0;
1115
1216
  }
1116
- if (adContainerEl?.parentElement) {
1217
+ if (adContainerEl == null ? void 0 : adContainerEl.parentElement) {
1117
1218
  adContainerEl.parentElement.removeChild(adContainerEl);
1118
1219
  }
1119
1220
  adContainerEl = void 0;
@@ -1139,7 +1240,8 @@ function createHlsAdPlayer(contentVideo, options) {
1139
1240
  listeners.get(event).add(listener);
1140
1241
  },
1141
1242
  off(event, listener) {
1142
- listeners.get(event)?.delete(listener);
1243
+ var _a;
1244
+ (_a = listeners.get(event)) == null ? void 0 : _a.delete(listener);
1143
1245
  },
1144
1246
  updateOriginalMutedState(muted) {
1145
1247
  originalMutedState = muted;
@@ -1164,6 +1266,7 @@ function createHlsAdPlayer(contentVideo, options) {
1164
1266
  // src/utils/tracking.ts
1165
1267
  var cachedBrowserId = null;
1166
1268
  function getClientInfo() {
1269
+ var _a, _b, _c, _d;
1167
1270
  const ua = navigator.userAgent;
1168
1271
  const platform = navigator.platform;
1169
1272
  const vendor = navigator.vendor || "";
@@ -1171,12 +1274,12 @@ function getClientInfo() {
1171
1274
  const memory = navigator.deviceMemory || null;
1172
1275
  const hardwareConcurrency = navigator.hardwareConcurrency || 1;
1173
1276
  const screenInfo = {
1174
- width: screen?.width,
1175
- height: screen?.height,
1176
- availWidth: screen?.availWidth,
1177
- availHeight: screen?.availHeight,
1178
- orientation: screen?.orientation?.type || "",
1179
- pixelDepth: screen?.pixelDepth
1277
+ width: screen == null ? void 0 : screen.width,
1278
+ height: screen == null ? void 0 : screen.height,
1279
+ availWidth: screen == null ? void 0 : screen.availWidth,
1280
+ availHeight: screen == null ? void 0 : screen.availHeight,
1281
+ orientation: ((_a = screen == null ? void 0 : screen.orientation) == null ? void 0 : _a.type) || "",
1282
+ pixelDepth: screen == null ? void 0 : screen.pixelDepth
1180
1283
  };
1181
1284
  let deviceType = "desktop";
1182
1285
  let brand = "Unknown";
@@ -1273,10 +1376,10 @@ function getClientInfo() {
1273
1376
  if (vendor.includes("Samsung") || ua.includes("SM-")) brand = "Samsung";
1274
1377
  }
1275
1378
  isWebView = /wv|WebView|Linux; U;/.test(ua);
1276
- if (window?.outerHeight === 0 && window?.outerWidth === 0) {
1379
+ if ((window == null ? void 0 : window.outerHeight) === 0 && (window == null ? void 0 : window.outerWidth) === 0) {
1277
1380
  isWebView = true;
1278
1381
  }
1279
- isWebApp = window.matchMedia("(display-mode: standalone)").matches || window.navigator.standalone === true || window.screen?.orientation?.angle !== void 0;
1382
+ isWebApp = window.matchMedia("(display-mode: standalone)").matches || window.navigator.standalone === true || ((_c = (_b = window.screen) == null ? void 0 : _b.orientation) == null ? void 0 : _c.angle) !== void 0;
1280
1383
  return {
1281
1384
  brand,
1282
1385
  os,
@@ -1297,7 +1400,7 @@ function getClientInfo() {
1297
1400
  deviceMemory: memory,
1298
1401
  maxTouchPoints,
1299
1402
  language: navigator.language,
1300
- languages: navigator.languages?.join(",") || "",
1403
+ languages: ((_d = navigator.languages) == null ? void 0 : _d.join(",")) || "",
1301
1404
  cookieEnabled: navigator.cookieEnabled,
1302
1405
  doNotTrack: navigator.doNotTrack || "",
1303
1406
  referrer: document.referrer,
@@ -1655,7 +1758,8 @@ var StormcloudVideoPlayer = class {
1655
1758
  }
1656
1759
  return createHlsAdPlayer(this.video, {
1657
1760
  continueLiveStreamDuringAds,
1658
- ...this.config.licenseKey ? { licenseKey: this.config.licenseKey } : {}
1761
+ ...this.config.licenseKey ? { licenseKey: this.config.licenseKey } : {},
1762
+ ...this.hls ? { mainHlsInstance: this.hls } : {}
1659
1763
  });
1660
1764
  } else {
1661
1765
  if (this.config.debugAdTiming) {
@@ -1667,6 +1771,7 @@ var StormcloudVideoPlayer = class {
1667
1771
  }
1668
1772
  }
1669
1773
  async load() {
1774
+ var _a, _b;
1670
1775
  if (!this.attached) {
1671
1776
  this.attach();
1672
1777
  }
@@ -1683,7 +1788,7 @@ var StormcloudVideoPlayer = class {
1683
1788
  this.initializeTracking();
1684
1789
  if (this.shouldUseNativeHls()) {
1685
1790
  this.video.src = this.config.src;
1686
- this.isLiveStream = this.config.lowLatencyMode ?? false;
1791
+ this.isLiveStream = (_a = this.config.lowLatencyMode) != null ? _a : false;
1687
1792
  if (this.config.debugAdTiming) {
1688
1793
  console.log(
1689
1794
  "[StormcloudVideoPlayer] allowNativeHls: true - VOD mode detected:",
@@ -1698,8 +1803,8 @@ var StormcloudVideoPlayer = class {
1698
1803
  this.ima = this.createAdPlayer(false);
1699
1804
  this.ima.initialize();
1700
1805
  if (this.config.autoplay) {
1701
- await this.video.play()?.catch(() => {
1702
- });
1806
+ await ((_b = this.video.play()) == null ? void 0 : _b.catch(() => {
1807
+ }));
1703
1808
  }
1704
1809
  return;
1705
1810
  }
@@ -1712,12 +1817,17 @@ var StormcloudVideoPlayer = class {
1712
1817
  ...this.config.lowLatencyMode ? { liveSyncDuration: 2 } : {}
1713
1818
  });
1714
1819
  this.hls.on(Hls2.Events.MEDIA_ATTACHED, () => {
1715
- this.hls?.loadSource(this.config.src);
1820
+ var _a2;
1821
+ (_a2 = this.hls) == null ? void 0 : _a2.loadSource(this.config.src);
1716
1822
  });
1717
1823
  this.hls.on(Hls2.Events.MANIFEST_PARSED, async (_, data) => {
1718
- this.isLiveStream = this.hls?.levels?.some(
1719
- (level) => level?.details?.live === true || level?.details?.type === "LIVE"
1720
- ) ?? false;
1824
+ var _a2, _b2, _c, _d;
1825
+ this.isLiveStream = (_c = (_b2 = (_a2 = this.hls) == null ? void 0 : _a2.levels) == null ? void 0 : _b2.some(
1826
+ (level) => {
1827
+ var _a3, _b3;
1828
+ 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";
1829
+ }
1830
+ )) != null ? _c : false;
1721
1831
  if (this.config.debugAdTiming) {
1722
1832
  const adBehavior = this.shouldContinueLiveStreamDuringAds() ? "live (main video continues muted during ads)" : "vod (main video pauses during ads)";
1723
1833
  console.log("[StormcloudVideoPlayer] Stream type detected:", {
@@ -1730,28 +1840,29 @@ var StormcloudVideoPlayer = class {
1730
1840
  this.ima = this.createAdPlayer(this.shouldContinueLiveStreamDuringAds());
1731
1841
  this.ima.initialize();
1732
1842
  if (this.config.autoplay) {
1733
- await this.video.play()?.catch(() => {
1734
- });
1843
+ await ((_d = this.video.play()) == null ? void 0 : _d.catch(() => {
1844
+ }));
1735
1845
  }
1736
1846
  });
1737
1847
  this.hls.on(Hls2.Events.FRAG_PARSING_METADATA, (_evt, data) => {
1738
- const id3Tags = (data?.samples || []).map((s) => ({
1848
+ const id3Tags = ((data == null ? void 0 : data.samples) || []).map((s) => ({
1739
1849
  key: "ID3",
1740
- value: s?.data,
1741
- ptsSeconds: s?.pts
1850
+ value: s == null ? void 0 : s.data,
1851
+ ptsSeconds: s == null ? void 0 : s.pts
1742
1852
  }));
1743
1853
  id3Tags.forEach((tag) => this.onId3Tag(tag));
1744
1854
  });
1745
1855
  this.hls.on(Hls2.Events.FRAG_CHANGED, (_evt, data) => {
1746
- const frag = data?.frag;
1747
- const tagList = frag?.tagList;
1856
+ var _a2, _b2, _c;
1857
+ const frag = data == null ? void 0 : data.frag;
1858
+ const tagList = frag == null ? void 0 : frag.tagList;
1748
1859
  if (!Array.isArray(tagList)) return;
1749
1860
  for (const entry of tagList) {
1750
1861
  let tag = "";
1751
1862
  let value = "";
1752
1863
  if (Array.isArray(entry)) {
1753
- tag = String(entry[0] ?? "");
1754
- value = String(entry[1] ?? "");
1864
+ tag = String((_a2 = entry[0]) != null ? _a2 : "");
1865
+ value = String((_b2 = entry[1]) != null ? _b2 : "");
1755
1866
  } else if (typeof entry === "string") {
1756
1867
  const idx = entry.indexOf(":");
1757
1868
  if (idx >= 0) {
@@ -1775,8 +1886,8 @@ var StormcloudVideoPlayer = class {
1775
1886
  const prog = this.parseCueOutCont(value);
1776
1887
  const marker = {
1777
1888
  type: "progress",
1778
- ...prog?.duration !== void 0 ? { durationSeconds: prog.duration } : {},
1779
- ...prog?.elapsed !== void 0 ? { ptsSeconds: prog.elapsed } : {},
1889
+ ...(prog == null ? void 0 : prog.duration) !== void 0 ? { durationSeconds: prog.duration } : {},
1890
+ ...(prog == null ? void 0 : prog.elapsed) !== void 0 ? { ptsSeconds: prog.elapsed } : {},
1780
1891
  raw: { tag, value }
1781
1892
  };
1782
1893
  this.onScte35Marker(marker);
@@ -1786,7 +1897,7 @@ var StormcloudVideoPlayer = class {
1786
1897
  const attrs = this.parseAttributeList(value);
1787
1898
  const hasScteOut = "SCTE35-OUT" in attrs || attrs["SCTE35-OUT"] !== void 0;
1788
1899
  const hasScteIn = "SCTE35-IN" in attrs || attrs["SCTE35-IN"] !== void 0;
1789
- const klass = String(attrs["CLASS"] ?? "");
1900
+ const klass = String((_c = attrs["CLASS"]) != null ? _c : "");
1790
1901
  const duration = this.toNumber(attrs["DURATION"]);
1791
1902
  if (hasScteOut || /com\.apple\.hls\.cue/i.test(klass)) {
1792
1903
  const marker = {
@@ -1803,13 +1914,14 @@ var StormcloudVideoPlayer = class {
1803
1914
  }
1804
1915
  });
1805
1916
  this.hls.on(Hls2.Events.ERROR, (_evt, data) => {
1806
- if (data?.fatal) {
1917
+ var _a2, _b2;
1918
+ if (data == null ? void 0 : data.fatal) {
1807
1919
  switch (data.type) {
1808
1920
  case Hls2.ErrorTypes.NETWORK_ERROR:
1809
- this.hls?.startLoad();
1921
+ (_a2 = this.hls) == null ? void 0 : _a2.startLoad();
1810
1922
  break;
1811
1923
  case Hls2.ErrorTypes.MEDIA_ERROR:
1812
- this.hls?.recoverMediaError();
1924
+ (_b2 = this.hls) == null ? void 0 : _b2.recoverMediaError();
1813
1925
  break;
1814
1926
  default:
1815
1927
  this.destroy();
@@ -1911,11 +2023,12 @@ var StormcloudVideoPlayer = class {
1911
2023
  }
1912
2024
  }
1913
2025
  parseScte35FromId3(tag) {
2026
+ var _a, _b, _c, _d;
1914
2027
  const text = this.decodeId3ValueToText(tag.value);
1915
2028
  if (!text) return void 0;
1916
2029
  const cueOutMatch = text.match(/EXT-X-CUE-OUT(?::([^\r\n]*))?/i) || text.match(/CUE-OUT(?::([^\r\n]*))?/i);
1917
2030
  if (cueOutMatch) {
1918
- const arg = (cueOutMatch[1] ?? "").trim();
2031
+ const arg = ((_a = cueOutMatch[1]) != null ? _a : "").trim();
1919
2032
  const dur = this.parseCueOutDuration(arg);
1920
2033
  const marker = {
1921
2034
  type: "start",
@@ -1927,12 +2040,12 @@ var StormcloudVideoPlayer = class {
1927
2040
  }
1928
2041
  const cueOutContMatch = text.match(/EXT-X-CUE-OUT-CONT:([^\r\n]*)/i);
1929
2042
  if (cueOutContMatch) {
1930
- const arg = (cueOutContMatch[1] ?? "").trim();
2043
+ const arg = ((_b = cueOutContMatch[1]) != null ? _b : "").trim();
1931
2044
  const cont = this.parseCueOutCont(arg);
1932
2045
  const marker = {
1933
2046
  type: "progress",
1934
2047
  ...tag.ptsSeconds !== void 0 ? { ptsSeconds: tag.ptsSeconds } : {},
1935
- ...cont?.duration !== void 0 ? { durationSeconds: cont.duration } : {},
2048
+ ...(cont == null ? void 0 : cont.duration) !== void 0 ? { durationSeconds: cont.duration } : {},
1936
2049
  raw: { id3: text }
1937
2050
  };
1938
2051
  return marker;
@@ -1948,10 +2061,10 @@ var StormcloudVideoPlayer = class {
1948
2061
  }
1949
2062
  const daterangeMatch = text.match(/EXT-X-DATERANGE:([^\r\n]*)/i);
1950
2063
  if (daterangeMatch) {
1951
- const attrs = this.parseAttributeList(daterangeMatch[1] ?? "");
2064
+ const attrs = this.parseAttributeList((_c = daterangeMatch[1]) != null ? _c : "");
1952
2065
  const hasScteOut = "SCTE35-OUT" in attrs || attrs["SCTE35-OUT"] !== void 0;
1953
2066
  const hasScteIn = "SCTE35-IN" in attrs || attrs["SCTE35-IN"] !== void 0;
1954
- const klass = String(attrs["CLASS"] ?? "");
2067
+ const klass = String((_d = attrs["CLASS"]) != null ? _d : "");
1955
2068
  const duration = this.toNumber(attrs["DURATION"]);
1956
2069
  if (hasScteOut || /com\.apple\.hls\.cue/i.test(klass)) {
1957
2070
  const marker = {
@@ -2008,6 +2121,7 @@ var StormcloudVideoPlayer = class {
2008
2121
  }
2009
2122
  }
2010
2123
  onScte35Marker(marker) {
2124
+ var _a, _b;
2011
2125
  if (this.config.debugAdTiming) {
2012
2126
  console.log("[StormcloudVideoPlayer] SCTE-35 marker detected:", {
2013
2127
  type: marker.type,
@@ -2023,7 +2137,7 @@ var StormcloudVideoPlayer = class {
2023
2137
  this.expectedAdBreakDurationMs = durationMs;
2024
2138
  this.currentAdBreakStartWallClockMs = Date.now();
2025
2139
  const isManifestMarker = this.isManifestBasedMarker(marker);
2026
- const forceImmediate = this.config.immediateManifestAds ?? true;
2140
+ const forceImmediate = (_a = this.config.immediateManifestAds) != null ? _a : true;
2027
2141
  if (this.config.debugAdTiming) {
2028
2142
  console.log("[StormcloudVideoPlayer] Ad start decision:", {
2029
2143
  isManifestMarker,
@@ -2040,7 +2154,7 @@ var StormcloudVideoPlayer = class {
2040
2154
  this.clearAdStartTimer();
2041
2155
  this.handleAdStart(marker);
2042
2156
  } else if (typeof marker.ptsSeconds === "number") {
2043
- const tol = this.config.driftToleranceMs ?? 1e3;
2157
+ const tol = (_b = this.config.driftToleranceMs) != null ? _b : 1e3;
2044
2158
  const nowMs = this.video.currentTime * 1e3;
2045
2159
  const estCurrentPtsMs = nowMs - this.ptsDriftEmaMs;
2046
2160
  const deltaMs = Math.floor(marker.ptsSeconds * 1e3 - estCurrentPtsMs);
@@ -2150,12 +2264,13 @@ var StormcloudVideoPlayer = class {
2150
2264
  return void 0;
2151
2265
  }
2152
2266
  parseAttributeList(value) {
2267
+ var _a, _b, _c;
2153
2268
  const attrs = {};
2154
2269
  const regex = /([A-Z0-9-]+)=(("[^"]*")|([^",]*))(?:,|$)/gi;
2155
2270
  let match;
2156
2271
  while ((match = regex.exec(value)) !== null) {
2157
- const key = match[1] ?? "";
2158
- let rawVal = match[3] ?? match[4] ?? "";
2272
+ const key = (_a = match[1]) != null ? _a : "";
2273
+ let rawVal = (_c = (_b = match[3]) != null ? _b : match[4]) != null ? _c : "";
2159
2274
  if (rawVal.startsWith('"') && rawVal.endsWith('"')) {
2160
2275
  rawVal = rawVal.slice(1, -1);
2161
2276
  }
@@ -2319,6 +2434,7 @@ var StormcloudVideoPlayer = class {
2319
2434
  }
2320
2435
  }
2321
2436
  async fetchAdConfiguration() {
2437
+ var _a, _b, _c;
2322
2438
  const vastMode = this.config.vastMode || "default";
2323
2439
  if (this.config.debugAdTiming) {
2324
2440
  console.log(
@@ -2339,7 +2455,7 @@ var StormcloudVideoPlayer = class {
2339
2455
  this.apiVastTagUrl = vastEndpoint;
2340
2456
  if (this.config.debugAdTiming) {
2341
2457
  console.log(
2342
- "[StormcloudVideoPlayer] Using AdStorm VAST endpoint:",
2458
+ "[StormcloudVideoPlayer] Using AdStorm VAST endpoint (adstorm mode):",
2343
2459
  vastEndpoint
2344
2460
  );
2345
2461
  }
@@ -2376,7 +2492,7 @@ var StormcloudVideoPlayer = class {
2376
2492
  return;
2377
2493
  }
2378
2494
  const data = await response.json();
2379
- const imaPayload = data.response?.ima?.["publisherdesk.ima"]?.payload;
2495
+ const imaPayload = (_c = (_b = (_a = data.response) == null ? void 0 : _a.ima) == null ? void 0 : _b["publisherdesk.ima"]) == null ? void 0 : _c.payload;
2380
2496
  if (imaPayload) {
2381
2497
  this.apiVastTagUrl = decodeURIComponent(imaPayload);
2382
2498
  if (this.config.debugAdTiming) {
@@ -2413,11 +2529,12 @@ var StormcloudVideoPlayer = class {
2413
2529
  return "other";
2414
2530
  }
2415
2531
  shouldShowNativeControls() {
2532
+ var _a, _b;
2416
2533
  const streamType = this.getStreamType();
2417
2534
  if (streamType === "other") {
2418
- return !(this.config.showCustomControls ?? false);
2535
+ return !((_a = this.config.showCustomControls) != null ? _a : false);
2419
2536
  }
2420
- return !!(this.config.allowNativeHls && !(this.config.showCustomControls ?? false));
2537
+ return !!(this.config.allowNativeHls && !((_b = this.config.showCustomControls) != null ? _b : false));
2421
2538
  }
2422
2539
  shouldContinueLiveStreamDuringAds() {
2423
2540
  if (this.config.allowNativeHls) {
@@ -2429,6 +2546,7 @@ var StormcloudVideoPlayer = class {
2429
2546
  return true;
2430
2547
  }
2431
2548
  async handleAdStart(_marker) {
2549
+ var _a;
2432
2550
  const scheduled = this.findCurrentOrNextBreak(
2433
2551
  this.video.currentTime * 1e3
2434
2552
  );
@@ -2479,17 +2597,18 @@ var StormcloudVideoPlayer = class {
2479
2597
  this.handleAdFailure();
2480
2598
  }
2481
2599
  }
2482
- if (this.expectedAdBreakDurationMs == null && scheduled?.durationMs != null) {
2600
+ if (this.expectedAdBreakDurationMs == null && (scheduled == null ? void 0 : scheduled.durationMs) != null) {
2483
2601
  this.expectedAdBreakDurationMs = scheduled.durationMs;
2484
- this.currentAdBreakStartWallClockMs = this.currentAdBreakStartWallClockMs ?? Date.now();
2602
+ this.currentAdBreakStartWallClockMs = (_a = this.currentAdBreakStartWallClockMs) != null ? _a : Date.now();
2485
2603
  this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);
2486
2604
  }
2487
2605
  }
2488
2606
  findCurrentOrNextBreak(nowMs) {
2607
+ var _a;
2489
2608
  const schedule = [];
2490
2609
  let candidate;
2491
2610
  for (const b of schedule) {
2492
- const tol = this.config.driftToleranceMs ?? 1e3;
2611
+ const tol = (_a = this.config.driftToleranceMs) != null ? _a : 1e3;
2493
2612
  if (b.startTimeMs <= nowMs + tol && (candidate == null || b.startTimeMs > (candidate.startTimeMs || 0))) {
2494
2613
  candidate = b;
2495
2614
  }
@@ -2505,7 +2624,8 @@ var StormcloudVideoPlayer = class {
2505
2624
  }
2506
2625
  }
2507
2626
  async handleMidAdJoin(adBreak, nowMs) {
2508
- const durationMs = adBreak.durationMs ?? 0;
2627
+ var _a;
2628
+ const durationMs = (_a = adBreak.durationMs) != null ? _a : 0;
2509
2629
  const endMs = adBreak.startTimeMs + durationMs;
2510
2630
  if (durationMs > 0 && nowMs > adBreak.startTimeMs && nowMs < endMs) {
2511
2631
  const remainingMs = endMs - nowMs;
@@ -2591,12 +2711,20 @@ var StormcloudVideoPlayer = class {
2591
2711
  this.startAdFailsafeTimer();
2592
2712
  try {
2593
2713
  await this.ima.requestAds(vastTagUrl);
2594
- if (this.config.debugAdTiming) {
2595
- console.log("[StormcloudVideoPlayer] Ad request successful, starting playback");
2596
- }
2597
- await this.ima.play();
2598
- if (this.config.debugAdTiming) {
2599
- console.log("[StormcloudVideoPlayer] Ad playback started successfully");
2714
+ try {
2715
+ if (this.config.debugAdTiming) {
2716
+ console.log("[StormcloudVideoPlayer] Ad request completed, attempting playback");
2717
+ }
2718
+ await this.ima.play();
2719
+ if (this.config.debugAdTiming) {
2720
+ console.log("[StormcloudVideoPlayer] Ad playback started successfully");
2721
+ }
2722
+ } catch (playError) {
2723
+ if (this.config.debugAdTiming) {
2724
+ console.log("[StormcloudVideoPlayer] No ads available, skipping playback");
2725
+ }
2726
+ this.handleAdFailure();
2727
+ return;
2600
2728
  }
2601
2729
  } catch (error) {
2602
2730
  if (this.config.debugAdTiming) {
@@ -2606,6 +2734,7 @@ var StormcloudVideoPlayer = class {
2606
2734
  }
2607
2735
  }
2608
2736
  handleAdFailure() {
2737
+ var _a;
2609
2738
  if (this.config.debugAdTiming) {
2610
2739
  console.log(
2611
2740
  "[StormcloudVideoPlayer] Handling ad failure - resuming content",
@@ -2638,7 +2767,7 @@ var StormcloudVideoPlayer = class {
2638
2767
  if (this.config.debugAdTiming) {
2639
2768
  console.log("[StormcloudVideoPlayer] Resuming paused video");
2640
2769
  }
2641
- this.video.play()?.catch((error) => {
2770
+ (_a = this.video.play()) == null ? void 0 : _a.catch((error) => {
2642
2771
  if (this.config.debugAdTiming) {
2643
2772
  console.error(
2644
2773
  "[StormcloudVideoPlayer] Failed to resume video after ad failure:",
@@ -2653,8 +2782,9 @@ var StormcloudVideoPlayer = class {
2653
2782
  }
2654
2783
  }
2655
2784
  startAdFailsafeTimer() {
2785
+ var _a;
2656
2786
  this.clearAdFailsafeTimer();
2657
- const failsafeMs = this.config.adFailsafeTimeoutMs ?? 1e4;
2787
+ const failsafeMs = (_a = this.config.adFailsafeTimeoutMs) != null ? _a : 1e4;
2658
2788
  if (this.config.debugAdTiming) {
2659
2789
  console.log(
2660
2790
  `[StormcloudVideoPlayer] Starting failsafe timer (${failsafeMs}ms)`
@@ -2790,6 +2920,7 @@ var StormcloudVideoPlayer = class {
2790
2920
  }
2791
2921
  }
2792
2922
  destroy() {
2923
+ var _a, _b;
2793
2924
  this.clearAdStartTimer();
2794
2925
  this.clearAdStopTimer();
2795
2926
  this.clearAdFailsafeTimer();
@@ -2797,8 +2928,8 @@ var StormcloudVideoPlayer = class {
2797
2928
  clearInterval(this.heartbeatInterval);
2798
2929
  this.heartbeatInterval = void 0;
2799
2930
  }
2800
- this.hls?.destroy();
2801
- this.ima?.destroy();
2931
+ (_a = this.hls) == null ? void 0 : _a.destroy();
2932
+ (_b = this.ima) == null ? void 0 : _b.destroy();
2802
2933
  }
2803
2934
  };
2804
2935
 
@@ -2819,7 +2950,8 @@ var CRITICAL_PROPS = [
2819
2950
  "allowNativeHls",
2820
2951
  "licenseKey",
2821
2952
  "lowLatencyMode",
2822
- "driftToleranceMs"
2953
+ "driftToleranceMs",
2954
+ "vastMode"
2823
2955
  ];
2824
2956
  var StormcloudVideoPlayerComponent = React.memo(
2825
2957
  (props) => {
@@ -2847,6 +2979,9 @@ var StormcloudVideoPlayerComponent = React.memo(
2847
2979
  poster,
2848
2980
  children,
2849
2981
  licenseKey,
2982
+ vastMode,
2983
+ vastTagUrl,
2984
+ adPlayerType,
2850
2985
  ...restVideoAttrs
2851
2986
  } = props;
2852
2987
  const videoRef = useRef(null);
@@ -2914,11 +3049,11 @@ var StormcloudVideoPlayerComponent = React.memo(
2914
3049
  }
2915
3050
  setShowSpeedMenu(false);
2916
3051
  };
2917
- const isHlsStream = src?.toLowerCase().includes(".m3u8") || src?.toLowerCase().includes("/hls/");
3052
+ const isHlsStream = (src == null ? void 0 : src.toLowerCase().includes(".m3u8")) || (src == null ? void 0 : src.toLowerCase().includes("/hls/"));
2918
3053
  const shouldShowEnhancedControls = showCustomControls && (isHlsStream ? allowNativeHls : true);
2919
3054
  const criticalPropsKey = useMemo(() => {
2920
3055
  return CRITICAL_PROPS.map((prop) => `${prop}:${props[prop]}`).join("|");
2921
- }, [src, allowNativeHls, licenseKey, lowLatencyMode, driftToleranceMs]);
3056
+ }, [src, allowNativeHls, licenseKey, lowLatencyMode, driftToleranceMs, vastMode]);
2922
3057
  useEffect(() => {
2923
3058
  if (typeof window === "undefined") return;
2924
3059
  const el = videoRef.current;
@@ -2959,18 +3094,21 @@ var StormcloudVideoPlayerComponent = React.memo(
2959
3094
  cfg.onFullscreenToggle = onFullscreenToggle;
2960
3095
  if (onControlClick !== void 0) cfg.onControlClick = onControlClick;
2961
3096
  if (licenseKey !== void 0) cfg.licenseKey = licenseKey;
3097
+ if (vastMode !== void 0) cfg.vastMode = vastMode;
3098
+ if (vastTagUrl !== void 0) cfg.vastTagUrl = vastTagUrl;
3099
+ if (adPlayerType !== void 0) cfg.adPlayerType = adPlayerType;
2962
3100
  const player = new StormcloudVideoPlayer(cfg);
2963
3101
  playerRef.current = player;
2964
3102
  player.load().then(() => {
2965
3103
  const showNative = player.shouldShowNativeControls();
2966
3104
  setShouldShowNativeControls(showNative);
2967
- onReady?.(player);
3105
+ onReady == null ? void 0 : onReady(player);
2968
3106
  }).catch((error) => {
2969
3107
  console.error(
2970
3108
  "StormcloudVideoPlayer: Failed to load player:",
2971
3109
  error
2972
3110
  );
2973
- onReady?.(player);
3111
+ onReady == null ? void 0 : onReady(player);
2974
3112
  });
2975
3113
  return () => {
2976
3114
  try {
@@ -3026,6 +3164,7 @@ var StormcloudVideoPlayerComponent = React.memo(
3026
3164
  useEffect(() => {
3027
3165
  if (!playerRef.current || !videoRef.current) return;
3028
3166
  const updateStates = () => {
3167
+ var _a;
3029
3168
  if (playerRef.current && videoRef.current) {
3030
3169
  setIsMuted(playerRef.current.isMuted());
3031
3170
  setIsPlaying(!videoRef.current.paused);
@@ -3043,13 +3182,14 @@ var StormcloudVideoPlayerComponent = React.memo(
3043
3182
  );
3044
3183
  }
3045
3184
  setIsFullscreen(
3046
- document.fullscreenElement === videoRef.current?.parentElement
3185
+ document.fullscreenElement === ((_a = videoRef.current) == null ? void 0 : _a.parentElement)
3047
3186
  );
3048
3187
  };
3049
3188
  const interval = setInterval(updateStates, 200);
3050
3189
  const handleFullscreenChange = () => {
3190
+ var _a;
3051
3191
  setIsFullscreen(
3052
- document.fullscreenElement === videoRef.current?.parentElement
3192
+ document.fullscreenElement === ((_a = videoRef.current) == null ? void 0 : _a.parentElement)
3053
3193
  );
3054
3194
  };
3055
3195
  document.addEventListener("fullscreenchange", handleFullscreenChange);
@@ -4492,6 +4632,7 @@ var HlsPlayer = class extends Component {
4492
4632
  this.player = null;
4493
4633
  this.mounted = false;
4494
4634
  this.load = async () => {
4635
+ var _a, _b, _c, _d, _e, _f;
4495
4636
  if (!this.props.videoElement || !this.props.src) return;
4496
4637
  try {
4497
4638
  if (this.player) {
@@ -4528,27 +4669,29 @@ var HlsPlayer = class extends Component {
4528
4669
  if (this.props.adFailsafeTimeoutMs !== void 0)
4529
4670
  config.adFailsafeTimeoutMs = this.props.adFailsafeTimeoutMs;
4530
4671
  this.player = new StormcloudVideoPlayer(config);
4531
- this.props.onMount?.(this);
4672
+ (_b = (_a = this.props).onMount) == null ? void 0 : _b.call(_a, this);
4532
4673
  await this.player.load();
4533
4674
  if (this.mounted) {
4534
- this.props.onReady?.();
4675
+ (_d = (_c = this.props).onReady) == null ? void 0 : _d.call(_c);
4535
4676
  }
4536
4677
  } catch (error) {
4537
4678
  if (this.mounted) {
4538
- this.props.onError?.(error);
4679
+ (_f = (_e = this.props).onError) == null ? void 0 : _f.call(_e, error);
4539
4680
  }
4540
4681
  }
4541
4682
  };
4542
4683
  this.play = () => {
4684
+ var _a, _b;
4543
4685
  if (this.props.videoElement) {
4544
4686
  this.props.videoElement.play();
4545
- this.props.onPlay?.();
4687
+ (_b = (_a = this.props).onPlay) == null ? void 0 : _b.call(_a);
4546
4688
  }
4547
4689
  };
4548
4690
  this.pause = () => {
4691
+ var _a, _b;
4549
4692
  if (this.props.videoElement) {
4550
4693
  this.props.videoElement.pause();
4551
- this.props.onPause?.();
4694
+ (_b = (_a = this.props).onPause) == null ? void 0 : _b.call(_a);
4552
4695
  }
4553
4696
  };
4554
4697
  this.stop = () => {
@@ -4643,37 +4786,44 @@ var FilePlayer = class extends Component2 {
4643
4786
  this.mounted = false;
4644
4787
  this.ready = false;
4645
4788
  this.load = () => {
4789
+ var _a, _b;
4646
4790
  if (!this.props.videoElement || !this.props.src) return;
4647
4791
  const video = this.props.videoElement;
4648
4792
  const handleLoadedMetadata = () => {
4793
+ var _a2, _b2;
4649
4794
  if (this.mounted && !this.ready) {
4650
4795
  this.ready = true;
4651
- this.props.onReady?.();
4796
+ (_b2 = (_a2 = this.props).onReady) == null ? void 0 : _b2.call(_a2);
4652
4797
  }
4653
4798
  };
4654
4799
  const handlePlay = () => {
4800
+ var _a2, _b2;
4655
4801
  if (this.mounted) {
4656
- this.props.onPlay?.();
4802
+ (_b2 = (_a2 = this.props).onPlay) == null ? void 0 : _b2.call(_a2);
4657
4803
  }
4658
4804
  };
4659
4805
  const handlePause = () => {
4806
+ var _a2, _b2;
4660
4807
  if (this.mounted) {
4661
- this.props.onPause?.();
4808
+ (_b2 = (_a2 = this.props).onPause) == null ? void 0 : _b2.call(_a2);
4662
4809
  }
4663
4810
  };
4664
4811
  const handleEnded = () => {
4812
+ var _a2, _b2;
4665
4813
  if (this.mounted) {
4666
- this.props.onEnded?.();
4814
+ (_b2 = (_a2 = this.props).onEnded) == null ? void 0 : _b2.call(_a2);
4667
4815
  }
4668
4816
  };
4669
4817
  const handleError = (error) => {
4818
+ var _a2, _b2;
4670
4819
  if (this.mounted) {
4671
- this.props.onError?.(error);
4820
+ (_b2 = (_a2 = this.props).onError) == null ? void 0 : _b2.call(_a2, error);
4672
4821
  }
4673
4822
  };
4674
4823
  const handleLoadedData = () => {
4824
+ var _a2, _b2;
4675
4825
  if (this.mounted) {
4676
- this.props.onLoaded?.();
4826
+ (_b2 = (_a2 = this.props).onLoaded) == null ? void 0 : _b2.call(_a2);
4677
4827
  }
4678
4828
  };
4679
4829
  video.addEventListener("loadedmetadata", handleLoadedMetadata);
@@ -4692,7 +4842,7 @@ var FilePlayer = class extends Component2 {
4692
4842
  if (this.props.preload !== void 0)
4693
4843
  video.preload = this.props.preload;
4694
4844
  if (this.props.poster !== void 0) video.poster = this.props.poster;
4695
- this.props.onMount?.(this);
4845
+ (_b = (_a = this.props).onMount) == null ? void 0 : _b.call(_a, this);
4696
4846
  return () => {
4697
4847
  video.removeEventListener("loadedmetadata", handleLoadedMetadata);
4698
4848
  video.removeEventListener("play", handlePlay);
@@ -4861,6 +5011,7 @@ var Player = class extends Component3 {
4861
5011
  return this.player.getInternalPlayer(key);
4862
5012
  };
4863
5013
  this.progress = () => {
5014
+ var _a, _b;
4864
5015
  if (this.props.src && this.player && this.isReady) {
4865
5016
  const playedSeconds = this.getCurrentTime() || 0;
4866
5017
  const loadedSeconds = this.getSecondsLoaded();
@@ -4877,7 +5028,7 @@ var Player = class extends Component3 {
4877
5028
  progress.loaded = loadedSeconds / duration;
4878
5029
  }
4879
5030
  if (progress.playedSeconds !== this.prevPlayed || progress.loadedSeconds !== this.prevLoaded) {
4880
- this.props.onProgress?.(progress);
5031
+ (_b = (_a = this.props).onProgress) == null ? void 0 : _b.call(_a, progress);
4881
5032
  }
4882
5033
  this.prevPlayed = progress.playedSeconds;
4883
5034
  this.prevLoaded = progress.loadedSeconds;
@@ -4913,10 +5064,10 @@ var Player = class extends Component3 {
4913
5064
  if (this.player.setPlaybackRate && playbackRate !== 1) {
4914
5065
  this.player.setPlaybackRate(playbackRate);
4915
5066
  }
4916
- onStart?.();
5067
+ onStart == null ? void 0 : onStart();
4917
5068
  this.startOnPlay = false;
4918
5069
  }
4919
- onPlay?.();
5070
+ onPlay == null ? void 0 : onPlay();
4920
5071
  if (this.seekOnPlay) {
4921
5072
  this.seekTo(this.seekOnPlay);
4922
5073
  this.seekOnPlay = null;
@@ -4924,9 +5075,10 @@ var Player = class extends Component3 {
4924
5075
  this.handleDurationCheck();
4925
5076
  };
4926
5077
  this.handlePause = (e) => {
5078
+ var _a, _b;
4927
5079
  this.isPlaying = false;
4928
5080
  if (!this.isLoading) {
4929
- this.props.onPause?.(e);
5081
+ (_b = (_a = this.props).onPause) == null ? void 0 : _b.call(_a, e);
4930
5082
  }
4931
5083
  };
4932
5084
  this.handleEnded = () => {
@@ -4936,19 +5088,21 @@ var Player = class extends Component3 {
4936
5088
  }
4937
5089
  if (!loop) {
4938
5090
  this.isPlaying = false;
4939
- onEnded?.();
5091
+ onEnded == null ? void 0 : onEnded();
4940
5092
  }
4941
5093
  };
4942
5094
  this.handleError = (...args) => {
5095
+ var _a, _b;
4943
5096
  this.isLoading = false;
4944
- this.props.onError?.(args[0], args[1], args[2], args[3]);
5097
+ (_b = (_a = this.props).onError) == null ? void 0 : _b.call(_a, args[0], args[1], args[2], args[3]);
4945
5098
  };
4946
5099
  this.handleDurationCheck = () => {
5100
+ var _a, _b;
4947
5101
  clearTimeout(this.durationCheckTimeout);
4948
5102
  const duration = this.getDuration();
4949
5103
  if (duration) {
4950
5104
  if (!this.onDurationCalled) {
4951
- this.props.onDuration?.(duration);
5105
+ (_b = (_a = this.props).onDuration) == null ? void 0 : _b.call(_a, duration);
4952
5106
  this.onDurationCalled = true;
4953
5107
  }
4954
5108
  } else {
@@ -5147,7 +5301,8 @@ var createStormcloudPlayer = (playerList, fallback) => {
5147
5301
  return omit(this.props, SUPPORTED_PROPS);
5148
5302
  };
5149
5303
  this.handleReady = () => {
5150
- this.props.onReady?.(this);
5304
+ var _a2, _b;
5305
+ (_b = (_a2 = this.props).onReady) == null ? void 0 : _b.call(_a2, this);
5151
5306
  };
5152
5307
  this.seekTo = (fraction, type, keepPlaying) => {
5153
5308
  if (!this.player) return null;