stormcloud-video-player 0.8.5 → 0.8.6

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.
@@ -438,6 +438,7 @@ var import_react2 = require("react");
438
438
  var import_hls2 = __toESM(require("hls.js"), 1);
439
439
  // src/sdk/hlsAdPlayer.ts
440
440
  var import_hls = __toESM(require("hls.js"), 1);
441
+ var MAX_VAST_WRAPPER_DEPTH = 5;
441
442
  function createHlsAdPlayer(contentVideo, options) {
442
443
  var adPlaying = false;
443
444
  var originalMutedState = false;
@@ -595,25 +596,91 @@ function createHlsAdPlayer(contentVideo, options) {
595
596
  var url = mediaFile.url.toLowerCase();
596
597
  return type.startsWith("video/") || url.endsWith(".mp4") || url.includes(".mp4?");
597
598
  }
599
+ function createEmptyTrackingUrls() {
600
+ return {
601
+ impression: [],
602
+ start: [],
603
+ firstQuartile: [],
604
+ midpoint: [],
605
+ thirdQuartile: [],
606
+ complete: [],
607
+ mute: [],
608
+ unmute: [],
609
+ pause: [],
610
+ resume: [],
611
+ fullscreen: [],
612
+ exitFullscreen: [],
613
+ skip: [],
614
+ error: []
615
+ };
616
+ }
617
+ function extractTrackingUrls(xmlDoc) {
618
+ var trackingUrls = createEmptyTrackingUrls();
619
+ xmlDoc.querySelectorAll("Impression").forEach(function(el) {
620
+ var _el_textContent;
621
+ var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
622
+ if (url) trackingUrls.impression.push(url);
623
+ });
624
+ xmlDoc.querySelectorAll("Tracking").forEach(function(el) {
625
+ var _el_textContent;
626
+ var event = el.getAttribute("event");
627
+ var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
628
+ if (event && url) {
629
+ var eventKey = event;
630
+ if (trackingUrls[eventKey]) {
631
+ trackingUrls[eventKey].push(url);
632
+ }
633
+ }
634
+ });
635
+ xmlDoc.querySelectorAll("Error").forEach(function(el) {
636
+ var _el_textContent;
637
+ var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
638
+ if (url) trackingUrls.error.push(url);
639
+ });
640
+ return trackingUrls;
641
+ }
642
+ function mergeTrackingUrls(target, source) {
643
+ Object.keys(target).forEach(function(key) {
644
+ if (source[key] && source[key].length > 0) {
645
+ target[key] = target[key].concat(source[key]);
646
+ }
647
+ });
648
+ return target;
649
+ }
598
650
  function parseVastXml(xmlString) {
599
651
  try {
600
- var _xmlDoc_querySelector, _xmlDoc_querySelector1, _xmlDoc_querySelector_textContent, _xmlDoc_querySelector2;
652
+ var _xmlDoc_querySelector, _xmlDoc_querySelector_textContent, _xmlDoc_querySelector1, _xmlDoc_querySelector_textContent1, _xmlDoc_querySelector2, _xmlDoc_querySelector3;
601
653
  var parser = new DOMParser();
602
654
  var xmlDoc = parser.parseFromString(xmlString, "text/xml");
603
655
  var parserError = xmlDoc.querySelector("parsererror");
604
656
  if (parserError) {
605
657
  console.error("[HlsAdPlayer] XML parsing error (malformed VAST XML):", parserError.textContent);
606
- return null;
658
+ return {
659
+ type: "empty"
660
+ };
607
661
  }
608
662
  var adElement = xmlDoc.querySelector("Ad");
609
663
  if (!adElement) {
610
664
  console.warn("[HlsAdPlayer] No Ad element found in VAST XML");
611
- return null;
665
+ return {
666
+ type: "empty"
667
+ };
612
668
  }
613
669
  var adId = adElement.getAttribute("id") || "unknown";
614
670
  var title = ((_xmlDoc_querySelector = xmlDoc.querySelector("AdTitle")) === null || _xmlDoc_querySelector === void 0 ? void 0 : _xmlDoc_querySelector.textContent) || "Ad";
671
+ var clickThrough = (_xmlDoc_querySelector1 = xmlDoc.querySelector("ClickThrough")) === null || _xmlDoc_querySelector1 === void 0 ? void 0 : (_xmlDoc_querySelector_textContent = _xmlDoc_querySelector1.textContent) === null || _xmlDoc_querySelector_textContent === void 0 ? void 0 : _xmlDoc_querySelector_textContent.trim();
672
+ var wrapperUri = (_xmlDoc_querySelector2 = xmlDoc.querySelector("VASTAdTagURI")) === null || _xmlDoc_querySelector2 === void 0 ? void 0 : (_xmlDoc_querySelector_textContent1 = _xmlDoc_querySelector2.textContent) === null || _xmlDoc_querySelector_textContent1 === void 0 ? void 0 : _xmlDoc_querySelector_textContent1.trim();
673
+ if (wrapperUri) {
674
+ console.log("[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ".concat(wrapperUri));
675
+ return {
676
+ type: "wrapper",
677
+ vastAdTagUri: wrapperUri,
678
+ trackingUrls: extractTrackingUrls(xmlDoc),
679
+ clickThrough: clickThrough
680
+ };
681
+ }
615
682
  var isNoAdAvailable = adId === "empty" || title.toLowerCase().includes("no ad available") || title.toLowerCase() === "no ad available";
616
- var durationText = ((_xmlDoc_querySelector1 = xmlDoc.querySelector("Duration")) === null || _xmlDoc_querySelector1 === void 0 ? void 0 : _xmlDoc_querySelector1.textContent) || "00:00:30";
683
+ var durationText = ((_xmlDoc_querySelector3 = xmlDoc.querySelector("Duration")) === null || _xmlDoc_querySelector3 === void 0 ? void 0 : _xmlDoc_querySelector3.textContent) || "00:00:30";
617
684
  var durationParts = durationText.split(":");
618
685
  var duration = parseInt(durationParts[0] || "0", 10) * 3600 + parseInt(durationParts[1] || "0", 10) * 60 + parseInt(durationParts[2] || "0", 10);
619
686
  var mediaFileElements = xmlDoc.querySelectorAll("MediaFile");
@@ -653,57 +720,31 @@ function createHlsAdPlayer(contentVideo, options) {
653
720
  } else {
654
721
  console.warn("[HlsAdPlayer] No supported media files found in VAST XML");
655
722
  }
656
- return null;
723
+ return {
724
+ type: "empty"
725
+ };
657
726
  }
658
- var trackingUrls = {
659
- impression: [],
660
- start: [],
661
- firstQuartile: [],
662
- midpoint: [],
663
- thirdQuartile: [],
664
- complete: [],
665
- mute: [],
666
- unmute: [],
667
- pause: [],
668
- resume: [],
669
- fullscreen: [],
670
- exitFullscreen: [],
671
- skip: [],
672
- error: []
673
- };
674
- xmlDoc.querySelectorAll("Impression").forEach(function(el) {
675
- var _el_textContent;
676
- var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
677
- if (url) trackingUrls.impression.push(url);
678
- });
679
- xmlDoc.querySelectorAll("Tracking").forEach(function(el) {
680
- var _el_textContent;
681
- var event = el.getAttribute("event");
682
- var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
683
- if (event && url) {
684
- var eventKey = event;
685
- if (trackingUrls[eventKey]) {
686
- trackingUrls[eventKey].push(url);
687
- }
688
- }
689
- });
690
- var clickThrough = (_xmlDoc_querySelector2 = xmlDoc.querySelector("ClickThrough")) === null || _xmlDoc_querySelector2 === void 0 ? void 0 : (_xmlDoc_querySelector_textContent = _xmlDoc_querySelector2.textContent) === null || _xmlDoc_querySelector_textContent === void 0 ? void 0 : _xmlDoc_querySelector_textContent.trim();
691
727
  return {
692
- id: adId,
693
- title: title,
694
- duration: duration,
695
- mediaFiles: mediaFiles,
696
- trackingUrls: trackingUrls,
697
- clickThrough: clickThrough
728
+ type: "inline",
729
+ ad: {
730
+ id: adId,
731
+ title: title,
732
+ duration: duration,
733
+ mediaFiles: mediaFiles,
734
+ trackingUrls: extractTrackingUrls(xmlDoc),
735
+ clickThrough: clickThrough
736
+ }
698
737
  };
699
738
  } catch (error) {
700
739
  console.error("[HlsAdPlayer] Error parsing VAST XML:", error);
701
- return null;
740
+ return {
741
+ type: "empty"
742
+ };
702
743
  }
703
744
  }
704
- function fetchAndParseVastAd(vastTagUrl) {
745
+ function fetchVastXml(vastTagUrl) {
705
746
  return _async_to_generator(function() {
706
- var response, vastXml;
747
+ var response;
707
748
  return _ts_generator(this, function(_state) {
708
749
  switch(_state.label){
709
750
  case 0:
@@ -724,20 +765,58 @@ function createHlsAdPlayer(contentVideo, options) {
724
765
  throw new Error("Failed to fetch VAST: ".concat(response.statusText));
725
766
  }
726
767
  return [
727
- 4,
768
+ 2,
728
769
  response.text()
729
770
  ];
730
- case 2:
771
+ }
772
+ });
773
+ })();
774
+ }
775
+ function fetchAndParseVastAd(_0) {
776
+ return _async_to_generator(function(vastTagUrl) {
777
+ var depth, accumulatedTracking, vastXml, parsed;
778
+ var _arguments = arguments;
779
+ return _ts_generator(this, function(_state) {
780
+ switch(_state.label){
781
+ case 0:
782
+ depth = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : 0, accumulatedTracking = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : createEmptyTrackingUrls();
783
+ return [
784
+ 4,
785
+ fetchVastXml(vastTagUrl)
786
+ ];
787
+ case 1:
731
788
  vastXml = _state.sent();
732
789
  console.log("[HlsAdPlayer] VAST XML received");
733
790
  console.log("[HlsAdPlayer] VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
791
+ parsed = parseVastXml(vastXml);
792
+ if (parsed.type === "empty") {
793
+ return [
794
+ 2,
795
+ null
796
+ ];
797
+ }
798
+ if (parsed.type === "wrapper") {
799
+ if (depth >= MAX_VAST_WRAPPER_DEPTH) {
800
+ console.warn("[HlsAdPlayer] VAST wrapper depth limit (".concat(MAX_VAST_WRAPPER_DEPTH, ") reached, aborting redirect chain"));
801
+ return [
802
+ 2,
803
+ null
804
+ ];
805
+ }
806
+ mergeTrackingUrls(accumulatedTracking, parsed.trackingUrls);
807
+ return [
808
+ 2,
809
+ fetchAndParseVastAd(parsed.vastAdTagUri, depth + 1, accumulatedTracking)
810
+ ];
811
+ }
812
+ mergeTrackingUrls(parsed.ad.trackingUrls, accumulatedTracking);
734
813
  return [
735
814
  2,
736
- parseVastXml(vastXml)
815
+ parsed.ad
737
816
  ];
738
817
  }
739
818
  });
740
- })();
819
+ }).apply(this, arguments);
741
820
  }
742
821
  function createAdVideoElement() {
743
822
  var video = document.createElement("video");