stormcloud-video-player 0.8.5 → 0.8.7

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.cjs CHANGED
@@ -586,6 +586,7 @@ var import_react = __toESM(require("react"), 1);
586
586
  var import_hls2 = __toESM(require("hls.js"), 1);
587
587
  // src/sdk/hlsAdPlayer.ts
588
588
  var import_hls = __toESM(require("hls.js"), 1);
589
+ var MAX_VAST_WRAPPER_DEPTH = 5;
589
590
  function createHlsAdPlayer(contentVideo, options) {
590
591
  var adPlaying = false;
591
592
  var originalMutedState = false;
@@ -743,25 +744,91 @@ function createHlsAdPlayer(contentVideo, options) {
743
744
  var url = mediaFile.url.toLowerCase();
744
745
  return type.startsWith("video/") || url.endsWith(".mp4") || url.includes(".mp4?");
745
746
  }
747
+ function createEmptyTrackingUrls() {
748
+ return {
749
+ impression: [],
750
+ start: [],
751
+ firstQuartile: [],
752
+ midpoint: [],
753
+ thirdQuartile: [],
754
+ complete: [],
755
+ mute: [],
756
+ unmute: [],
757
+ pause: [],
758
+ resume: [],
759
+ fullscreen: [],
760
+ exitFullscreen: [],
761
+ skip: [],
762
+ error: []
763
+ };
764
+ }
765
+ function extractTrackingUrls(xmlDoc) {
766
+ var trackingUrls = createEmptyTrackingUrls();
767
+ xmlDoc.querySelectorAll("Impression").forEach(function(el) {
768
+ var _el_textContent;
769
+ var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
770
+ if (url) trackingUrls.impression.push(url);
771
+ });
772
+ xmlDoc.querySelectorAll("Tracking").forEach(function(el) {
773
+ var _el_textContent;
774
+ var event = el.getAttribute("event");
775
+ var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
776
+ if (event && url) {
777
+ var eventKey = event;
778
+ if (trackingUrls[eventKey]) {
779
+ trackingUrls[eventKey].push(url);
780
+ }
781
+ }
782
+ });
783
+ xmlDoc.querySelectorAll("Error").forEach(function(el) {
784
+ var _el_textContent;
785
+ var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
786
+ if (url) trackingUrls.error.push(url);
787
+ });
788
+ return trackingUrls;
789
+ }
790
+ function mergeTrackingUrls(target, source) {
791
+ Object.keys(target).forEach(function(key) {
792
+ if (source[key] && source[key].length > 0) {
793
+ target[key] = target[key].concat(source[key]);
794
+ }
795
+ });
796
+ return target;
797
+ }
746
798
  function parseVastXml(xmlString) {
747
799
  try {
748
- var _xmlDoc_querySelector, _xmlDoc_querySelector1, _xmlDoc_querySelector_textContent, _xmlDoc_querySelector2;
800
+ var _xmlDoc_querySelector, _xmlDoc_querySelector_textContent, _xmlDoc_querySelector1, _xmlDoc_querySelector_textContent1, _xmlDoc_querySelector2, _xmlDoc_querySelector3;
749
801
  var parser = new DOMParser();
750
802
  var xmlDoc = parser.parseFromString(xmlString, "text/xml");
751
803
  var parserError = xmlDoc.querySelector("parsererror");
752
804
  if (parserError) {
753
805
  console.error("[HlsAdPlayer] XML parsing error (malformed VAST XML):", parserError.textContent);
754
- return null;
806
+ return {
807
+ type: "empty"
808
+ };
755
809
  }
756
810
  var adElement = xmlDoc.querySelector("Ad");
757
811
  if (!adElement) {
758
812
  console.warn("[HlsAdPlayer] No Ad element found in VAST XML");
759
- return null;
813
+ return {
814
+ type: "empty"
815
+ };
760
816
  }
761
817
  var adId = adElement.getAttribute("id") || "unknown";
762
818
  var title = ((_xmlDoc_querySelector = xmlDoc.querySelector("AdTitle")) === null || _xmlDoc_querySelector === void 0 ? void 0 : _xmlDoc_querySelector.textContent) || "Ad";
819
+ 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();
820
+ 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();
821
+ if (wrapperUri) {
822
+ console.log("[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ".concat(wrapperUri));
823
+ return {
824
+ type: "wrapper",
825
+ vastAdTagUri: wrapperUri,
826
+ trackingUrls: extractTrackingUrls(xmlDoc),
827
+ clickThrough: clickThrough
828
+ };
829
+ }
763
830
  var isNoAdAvailable = adId === "empty" || title.toLowerCase().includes("no ad available") || title.toLowerCase() === "no ad available";
764
- var durationText = ((_xmlDoc_querySelector1 = xmlDoc.querySelector("Duration")) === null || _xmlDoc_querySelector1 === void 0 ? void 0 : _xmlDoc_querySelector1.textContent) || "00:00:30";
831
+ var durationText = ((_xmlDoc_querySelector3 = xmlDoc.querySelector("Duration")) === null || _xmlDoc_querySelector3 === void 0 ? void 0 : _xmlDoc_querySelector3.textContent) || "00:00:30";
765
832
  var durationParts = durationText.split(":");
766
833
  var duration = parseInt(durationParts[0] || "0", 10) * 3600 + parseInt(durationParts[1] || "0", 10) * 60 + parseInt(durationParts[2] || "0", 10);
767
834
  var mediaFileElements = xmlDoc.querySelectorAll("MediaFile");
@@ -801,57 +868,31 @@ function createHlsAdPlayer(contentVideo, options) {
801
868
  } else {
802
869
  console.warn("[HlsAdPlayer] No supported media files found in VAST XML");
803
870
  }
804
- return null;
871
+ return {
872
+ type: "empty"
873
+ };
805
874
  }
806
- var trackingUrls = {
807
- impression: [],
808
- start: [],
809
- firstQuartile: [],
810
- midpoint: [],
811
- thirdQuartile: [],
812
- complete: [],
813
- mute: [],
814
- unmute: [],
815
- pause: [],
816
- resume: [],
817
- fullscreen: [],
818
- exitFullscreen: [],
819
- skip: [],
820
- error: []
821
- };
822
- xmlDoc.querySelectorAll("Impression").forEach(function(el) {
823
- var _el_textContent;
824
- var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
825
- if (url) trackingUrls.impression.push(url);
826
- });
827
- xmlDoc.querySelectorAll("Tracking").forEach(function(el) {
828
- var _el_textContent;
829
- var event = el.getAttribute("event");
830
- var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
831
- if (event && url) {
832
- var eventKey = event;
833
- if (trackingUrls[eventKey]) {
834
- trackingUrls[eventKey].push(url);
835
- }
836
- }
837
- });
838
- 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();
839
875
  return {
840
- id: adId,
841
- title: title,
842
- duration: duration,
843
- mediaFiles: mediaFiles,
844
- trackingUrls: trackingUrls,
845
- clickThrough: clickThrough
876
+ type: "inline",
877
+ ad: {
878
+ id: adId,
879
+ title: title,
880
+ duration: duration,
881
+ mediaFiles: mediaFiles,
882
+ trackingUrls: extractTrackingUrls(xmlDoc),
883
+ clickThrough: clickThrough
884
+ }
846
885
  };
847
886
  } catch (error) {
848
887
  console.error("[HlsAdPlayer] Error parsing VAST XML:", error);
849
- return null;
888
+ return {
889
+ type: "empty"
890
+ };
850
891
  }
851
892
  }
852
- function fetchAndParseVastAd(vastTagUrl) {
893
+ function fetchVastXml(vastTagUrl) {
853
894
  return _async_to_generator(function() {
854
- var response, vastXml;
895
+ var response;
855
896
  return _ts_generator(this, function(_state) {
856
897
  switch(_state.label){
857
898
  case 0:
@@ -872,20 +913,58 @@ function createHlsAdPlayer(contentVideo, options) {
872
913
  throw new Error("Failed to fetch VAST: ".concat(response.statusText));
873
914
  }
874
915
  return [
875
- 4,
916
+ 2,
876
917
  response.text()
877
918
  ];
878
- case 2:
919
+ }
920
+ });
921
+ })();
922
+ }
923
+ function fetchAndParseVastAd(_0) {
924
+ return _async_to_generator(function(vastTagUrl) {
925
+ var depth, accumulatedTracking, vastXml, parsed;
926
+ var _arguments = arguments;
927
+ return _ts_generator(this, function(_state) {
928
+ switch(_state.label){
929
+ case 0:
930
+ depth = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : 0, accumulatedTracking = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : createEmptyTrackingUrls();
931
+ return [
932
+ 4,
933
+ fetchVastXml(vastTagUrl)
934
+ ];
935
+ case 1:
879
936
  vastXml = _state.sent();
880
937
  console.log("[HlsAdPlayer] VAST XML received");
881
938
  console.log("[HlsAdPlayer] VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
939
+ parsed = parseVastXml(vastXml);
940
+ if (parsed.type === "empty") {
941
+ return [
942
+ 2,
943
+ null
944
+ ];
945
+ }
946
+ if (parsed.type === "wrapper") {
947
+ if (depth >= MAX_VAST_WRAPPER_DEPTH) {
948
+ console.warn("[HlsAdPlayer] VAST wrapper depth limit (".concat(MAX_VAST_WRAPPER_DEPTH, ") reached, aborting redirect chain"));
949
+ return [
950
+ 2,
951
+ null
952
+ ];
953
+ }
954
+ mergeTrackingUrls(accumulatedTracking, parsed.trackingUrls);
955
+ return [
956
+ 2,
957
+ fetchAndParseVastAd(parsed.vastAdTagUri, depth + 1, accumulatedTracking)
958
+ ];
959
+ }
960
+ mergeTrackingUrls(parsed.ad.trackingUrls, accumulatedTracking);
882
961
  return [
883
962
  2,
884
- parseVastXml(vastXml)
963
+ parsed.ad
885
964
  ];
886
965
  }
887
966
  });
888
- })();
967
+ }).apply(this, arguments);
889
968
  }
890
969
  function createAdVideoElement() {
891
970
  var video = document.createElement("video");
@@ -1461,7 +1540,7 @@ function createPalNonceManager() {
1461
1540
  return {
1462
1541
  generateNonce: function generateNonce() {
1463
1542
  return _async_to_generator(function() {
1464
- var options, _options_adWillAutoPlay, _options_adWillPlayMuted, _options_continuousPlayback, loader, goog, request, manager, error;
1543
+ var options, _options_adWillAutoPlay, _options_adWillPlayMuted, _options_playerVolume, _options_continuousPlayback, loader, goog, request, manager, error;
1465
1544
  var _arguments = arguments;
1466
1545
  return _ts_generator(this, function(_state) {
1467
1546
  switch(_state.label){
@@ -1486,6 +1565,7 @@ function createPalNonceManager() {
1486
1565
  request = new goog.pal.NonceRequest();
1487
1566
  request.adWillAutoPlay = (_options_adWillAutoPlay = options.adWillAutoPlay) !== null && _options_adWillAutoPlay !== void 0 ? _options_adWillAutoPlay : true;
1488
1567
  request.adWillPlayMuted = (_options_adWillPlayMuted = options.adWillPlayMuted) !== null && _options_adWillPlayMuted !== void 0 ? _options_adWillPlayMuted : false;
1568
+ request.playerVolume = (_options_playerVolume = options.playerVolume) !== null && _options_playerVolume !== void 0 ? _options_playerVolume : request.adWillPlayMuted ? 0 : 1;
1489
1569
  request.continuousPlayback = (_options_continuousPlayback = options.continuousPlayback) !== null && _options_continuousPlayback !== void 0 ? _options_continuousPlayback : true;
1490
1570
  request.descriptionUrl = options.descriptionUrl || (typeof window !== "undefined" ? window.location.href : "");
1491
1571
  request.iconsSupported = true;
@@ -2930,7 +3010,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
2930
3010
  videoWidth: this.video.offsetWidth || this.video.clientWidth || 640,
2931
3011
  videoHeight: this.video.offsetHeight || this.video.clientHeight || 480,
2932
3012
  adWillAutoPlay: !!this.config.autoplay,
2933
- adWillPlayMuted: !!this.config.muted,
3013
+ adWillPlayMuted: true,
3014
+ playerVolume: 0,
2934
3015
  continuousPlayback: (_this_config_lowLatencyMode = this.config.lowLatencyMode) !== null && _this_config_lowLatencyMode !== void 0 ? _this_config_lowLatencyMode : false
2935
3016
  }).catch(function() {});
2936
3017
  fetchConsentSignals().then(function(signals) {