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.
@@ -402,6 +402,7 @@ var import_react = require("react");
402
402
  var import_hls2 = __toESM(require("hls.js"), 1);
403
403
  // src/sdk/hlsAdPlayer.ts
404
404
  var import_hls = __toESM(require("hls.js"), 1);
405
+ var MAX_VAST_WRAPPER_DEPTH = 5;
405
406
  function createHlsAdPlayer(contentVideo, options) {
406
407
  var adPlaying = false;
407
408
  var originalMutedState = false;
@@ -559,25 +560,91 @@ function createHlsAdPlayer(contentVideo, options) {
559
560
  var url = mediaFile.url.toLowerCase();
560
561
  return type.startsWith("video/") || url.endsWith(".mp4") || url.includes(".mp4?");
561
562
  }
563
+ function createEmptyTrackingUrls() {
564
+ return {
565
+ impression: [],
566
+ start: [],
567
+ firstQuartile: [],
568
+ midpoint: [],
569
+ thirdQuartile: [],
570
+ complete: [],
571
+ mute: [],
572
+ unmute: [],
573
+ pause: [],
574
+ resume: [],
575
+ fullscreen: [],
576
+ exitFullscreen: [],
577
+ skip: [],
578
+ error: []
579
+ };
580
+ }
581
+ function extractTrackingUrls(xmlDoc) {
582
+ var trackingUrls = createEmptyTrackingUrls();
583
+ xmlDoc.querySelectorAll("Impression").forEach(function(el) {
584
+ var _el_textContent;
585
+ var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
586
+ if (url) trackingUrls.impression.push(url);
587
+ });
588
+ xmlDoc.querySelectorAll("Tracking").forEach(function(el) {
589
+ var _el_textContent;
590
+ var event = el.getAttribute("event");
591
+ var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
592
+ if (event && url) {
593
+ var eventKey = event;
594
+ if (trackingUrls[eventKey]) {
595
+ trackingUrls[eventKey].push(url);
596
+ }
597
+ }
598
+ });
599
+ xmlDoc.querySelectorAll("Error").forEach(function(el) {
600
+ var _el_textContent;
601
+ var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
602
+ if (url) trackingUrls.error.push(url);
603
+ });
604
+ return trackingUrls;
605
+ }
606
+ function mergeTrackingUrls(target, source) {
607
+ Object.keys(target).forEach(function(key) {
608
+ if (source[key] && source[key].length > 0) {
609
+ target[key] = target[key].concat(source[key]);
610
+ }
611
+ });
612
+ return target;
613
+ }
562
614
  function parseVastXml(xmlString) {
563
615
  try {
564
- var _xmlDoc_querySelector, _xmlDoc_querySelector1, _xmlDoc_querySelector_textContent, _xmlDoc_querySelector2;
616
+ var _xmlDoc_querySelector, _xmlDoc_querySelector_textContent, _xmlDoc_querySelector1, _xmlDoc_querySelector_textContent1, _xmlDoc_querySelector2, _xmlDoc_querySelector3;
565
617
  var parser = new DOMParser();
566
618
  var xmlDoc = parser.parseFromString(xmlString, "text/xml");
567
619
  var parserError = xmlDoc.querySelector("parsererror");
568
620
  if (parserError) {
569
621
  console.error("[HlsAdPlayer] XML parsing error (malformed VAST XML):", parserError.textContent);
570
- return null;
622
+ return {
623
+ type: "empty"
624
+ };
571
625
  }
572
626
  var adElement = xmlDoc.querySelector("Ad");
573
627
  if (!adElement) {
574
628
  console.warn("[HlsAdPlayer] No Ad element found in VAST XML");
575
- return null;
629
+ return {
630
+ type: "empty"
631
+ };
576
632
  }
577
633
  var adId = adElement.getAttribute("id") || "unknown";
578
634
  var title = ((_xmlDoc_querySelector = xmlDoc.querySelector("AdTitle")) === null || _xmlDoc_querySelector === void 0 ? void 0 : _xmlDoc_querySelector.textContent) || "Ad";
635
+ 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();
636
+ 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();
637
+ if (wrapperUri) {
638
+ console.log("[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ".concat(wrapperUri));
639
+ return {
640
+ type: "wrapper",
641
+ vastAdTagUri: wrapperUri,
642
+ trackingUrls: extractTrackingUrls(xmlDoc),
643
+ clickThrough: clickThrough
644
+ };
645
+ }
579
646
  var isNoAdAvailable = adId === "empty" || title.toLowerCase().includes("no ad available") || title.toLowerCase() === "no ad available";
580
- var durationText = ((_xmlDoc_querySelector1 = xmlDoc.querySelector("Duration")) === null || _xmlDoc_querySelector1 === void 0 ? void 0 : _xmlDoc_querySelector1.textContent) || "00:00:30";
647
+ var durationText = ((_xmlDoc_querySelector3 = xmlDoc.querySelector("Duration")) === null || _xmlDoc_querySelector3 === void 0 ? void 0 : _xmlDoc_querySelector3.textContent) || "00:00:30";
581
648
  var durationParts = durationText.split(":");
582
649
  var duration = parseInt(durationParts[0] || "0", 10) * 3600 + parseInt(durationParts[1] || "0", 10) * 60 + parseInt(durationParts[2] || "0", 10);
583
650
  var mediaFileElements = xmlDoc.querySelectorAll("MediaFile");
@@ -617,57 +684,31 @@ function createHlsAdPlayer(contentVideo, options) {
617
684
  } else {
618
685
  console.warn("[HlsAdPlayer] No supported media files found in VAST XML");
619
686
  }
620
- return null;
687
+ return {
688
+ type: "empty"
689
+ };
621
690
  }
622
- var trackingUrls = {
623
- impression: [],
624
- start: [],
625
- firstQuartile: [],
626
- midpoint: [],
627
- thirdQuartile: [],
628
- complete: [],
629
- mute: [],
630
- unmute: [],
631
- pause: [],
632
- resume: [],
633
- fullscreen: [],
634
- exitFullscreen: [],
635
- skip: [],
636
- error: []
637
- };
638
- xmlDoc.querySelectorAll("Impression").forEach(function(el) {
639
- var _el_textContent;
640
- var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
641
- if (url) trackingUrls.impression.push(url);
642
- });
643
- xmlDoc.querySelectorAll("Tracking").forEach(function(el) {
644
- var _el_textContent;
645
- var event = el.getAttribute("event");
646
- var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
647
- if (event && url) {
648
- var eventKey = event;
649
- if (trackingUrls[eventKey]) {
650
- trackingUrls[eventKey].push(url);
651
- }
652
- }
653
- });
654
- 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();
655
691
  return {
656
- id: adId,
657
- title: title,
658
- duration: duration,
659
- mediaFiles: mediaFiles,
660
- trackingUrls: trackingUrls,
661
- clickThrough: clickThrough
692
+ type: "inline",
693
+ ad: {
694
+ id: adId,
695
+ title: title,
696
+ duration: duration,
697
+ mediaFiles: mediaFiles,
698
+ trackingUrls: extractTrackingUrls(xmlDoc),
699
+ clickThrough: clickThrough
700
+ }
662
701
  };
663
702
  } catch (error) {
664
703
  console.error("[HlsAdPlayer] Error parsing VAST XML:", error);
665
- return null;
704
+ return {
705
+ type: "empty"
706
+ };
666
707
  }
667
708
  }
668
- function fetchAndParseVastAd(vastTagUrl) {
709
+ function fetchVastXml(vastTagUrl) {
669
710
  return _async_to_generator(function() {
670
- var response, vastXml;
711
+ var response;
671
712
  return _ts_generator(this, function(_state) {
672
713
  switch(_state.label){
673
714
  case 0:
@@ -688,20 +729,58 @@ function createHlsAdPlayer(contentVideo, options) {
688
729
  throw new Error("Failed to fetch VAST: ".concat(response.statusText));
689
730
  }
690
731
  return [
691
- 4,
732
+ 2,
692
733
  response.text()
693
734
  ];
694
- case 2:
735
+ }
736
+ });
737
+ })();
738
+ }
739
+ function fetchAndParseVastAd(_0) {
740
+ return _async_to_generator(function(vastTagUrl) {
741
+ var depth, accumulatedTracking, vastXml, parsed;
742
+ var _arguments = arguments;
743
+ return _ts_generator(this, function(_state) {
744
+ switch(_state.label){
745
+ case 0:
746
+ depth = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : 0, accumulatedTracking = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : createEmptyTrackingUrls();
747
+ return [
748
+ 4,
749
+ fetchVastXml(vastTagUrl)
750
+ ];
751
+ case 1:
695
752
  vastXml = _state.sent();
696
753
  console.log("[HlsAdPlayer] VAST XML received");
697
754
  console.log("[HlsAdPlayer] VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
755
+ parsed = parseVastXml(vastXml);
756
+ if (parsed.type === "empty") {
757
+ return [
758
+ 2,
759
+ null
760
+ ];
761
+ }
762
+ if (parsed.type === "wrapper") {
763
+ if (depth >= MAX_VAST_WRAPPER_DEPTH) {
764
+ console.warn("[HlsAdPlayer] VAST wrapper depth limit (".concat(MAX_VAST_WRAPPER_DEPTH, ") reached, aborting redirect chain"));
765
+ return [
766
+ 2,
767
+ null
768
+ ];
769
+ }
770
+ mergeTrackingUrls(accumulatedTracking, parsed.trackingUrls);
771
+ return [
772
+ 2,
773
+ fetchAndParseVastAd(parsed.vastAdTagUri, depth + 1, accumulatedTracking)
774
+ ];
775
+ }
776
+ mergeTrackingUrls(parsed.ad.trackingUrls, accumulatedTracking);
698
777
  return [
699
778
  2,
700
- parseVastXml(vastXml)
779
+ parsed.ad
701
780
  ];
702
781
  }
703
782
  });
704
- })();
783
+ }).apply(this, arguments);
705
784
  }
706
785
  function createAdVideoElement() {
707
786
  var video = document.createElement("video");