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.
@@ -388,6 +388,7 @@ var import_react = __toESM(require("react"), 1);
388
388
  var import_hls2 = __toESM(require("hls.js"), 1);
389
389
  // src/sdk/hlsAdPlayer.ts
390
390
  var import_hls = __toESM(require("hls.js"), 1);
391
+ var MAX_VAST_WRAPPER_DEPTH = 5;
391
392
  function createHlsAdPlayer(contentVideo, options) {
392
393
  var adPlaying = false;
393
394
  var originalMutedState = false;
@@ -545,25 +546,91 @@ function createHlsAdPlayer(contentVideo, options) {
545
546
  var url = mediaFile.url.toLowerCase();
546
547
  return type.startsWith("video/") || url.endsWith(".mp4") || url.includes(".mp4?");
547
548
  }
549
+ function createEmptyTrackingUrls() {
550
+ return {
551
+ impression: [],
552
+ start: [],
553
+ firstQuartile: [],
554
+ midpoint: [],
555
+ thirdQuartile: [],
556
+ complete: [],
557
+ mute: [],
558
+ unmute: [],
559
+ pause: [],
560
+ resume: [],
561
+ fullscreen: [],
562
+ exitFullscreen: [],
563
+ skip: [],
564
+ error: []
565
+ };
566
+ }
567
+ function extractTrackingUrls(xmlDoc) {
568
+ var trackingUrls = createEmptyTrackingUrls();
569
+ xmlDoc.querySelectorAll("Impression").forEach(function(el) {
570
+ var _el_textContent;
571
+ var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
572
+ if (url) trackingUrls.impression.push(url);
573
+ });
574
+ xmlDoc.querySelectorAll("Tracking").forEach(function(el) {
575
+ var _el_textContent;
576
+ var event = el.getAttribute("event");
577
+ var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
578
+ if (event && url) {
579
+ var eventKey = event;
580
+ if (trackingUrls[eventKey]) {
581
+ trackingUrls[eventKey].push(url);
582
+ }
583
+ }
584
+ });
585
+ xmlDoc.querySelectorAll("Error").forEach(function(el) {
586
+ var _el_textContent;
587
+ var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
588
+ if (url) trackingUrls.error.push(url);
589
+ });
590
+ return trackingUrls;
591
+ }
592
+ function mergeTrackingUrls(target, source) {
593
+ Object.keys(target).forEach(function(key) {
594
+ if (source[key] && source[key].length > 0) {
595
+ target[key] = target[key].concat(source[key]);
596
+ }
597
+ });
598
+ return target;
599
+ }
548
600
  function parseVastXml(xmlString) {
549
601
  try {
550
- var _xmlDoc_querySelector, _xmlDoc_querySelector1, _xmlDoc_querySelector_textContent, _xmlDoc_querySelector2;
602
+ var _xmlDoc_querySelector, _xmlDoc_querySelector_textContent, _xmlDoc_querySelector1, _xmlDoc_querySelector_textContent1, _xmlDoc_querySelector2, _xmlDoc_querySelector3;
551
603
  var parser = new DOMParser();
552
604
  var xmlDoc = parser.parseFromString(xmlString, "text/xml");
553
605
  var parserError = xmlDoc.querySelector("parsererror");
554
606
  if (parserError) {
555
607
  console.error("[HlsAdPlayer] XML parsing error (malformed VAST XML):", parserError.textContent);
556
- return null;
608
+ return {
609
+ type: "empty"
610
+ };
557
611
  }
558
612
  var adElement = xmlDoc.querySelector("Ad");
559
613
  if (!adElement) {
560
614
  console.warn("[HlsAdPlayer] No Ad element found in VAST XML");
561
- return null;
615
+ return {
616
+ type: "empty"
617
+ };
562
618
  }
563
619
  var adId = adElement.getAttribute("id") || "unknown";
564
620
  var title = ((_xmlDoc_querySelector = xmlDoc.querySelector("AdTitle")) === null || _xmlDoc_querySelector === void 0 ? void 0 : _xmlDoc_querySelector.textContent) || "Ad";
621
+ 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();
622
+ 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();
623
+ if (wrapperUri) {
624
+ console.log("[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ".concat(wrapperUri));
625
+ return {
626
+ type: "wrapper",
627
+ vastAdTagUri: wrapperUri,
628
+ trackingUrls: extractTrackingUrls(xmlDoc),
629
+ clickThrough: clickThrough
630
+ };
631
+ }
565
632
  var isNoAdAvailable = adId === "empty" || title.toLowerCase().includes("no ad available") || title.toLowerCase() === "no ad available";
566
- var durationText = ((_xmlDoc_querySelector1 = xmlDoc.querySelector("Duration")) === null || _xmlDoc_querySelector1 === void 0 ? void 0 : _xmlDoc_querySelector1.textContent) || "00:00:30";
633
+ var durationText = ((_xmlDoc_querySelector3 = xmlDoc.querySelector("Duration")) === null || _xmlDoc_querySelector3 === void 0 ? void 0 : _xmlDoc_querySelector3.textContent) || "00:00:30";
567
634
  var durationParts = durationText.split(":");
568
635
  var duration = parseInt(durationParts[0] || "0", 10) * 3600 + parseInt(durationParts[1] || "0", 10) * 60 + parseInt(durationParts[2] || "0", 10);
569
636
  var mediaFileElements = xmlDoc.querySelectorAll("MediaFile");
@@ -603,57 +670,31 @@ function createHlsAdPlayer(contentVideo, options) {
603
670
  } else {
604
671
  console.warn("[HlsAdPlayer] No supported media files found in VAST XML");
605
672
  }
606
- return null;
607
- }
608
- var trackingUrls = {
609
- impression: [],
610
- start: [],
611
- firstQuartile: [],
612
- midpoint: [],
613
- thirdQuartile: [],
614
- complete: [],
615
- mute: [],
616
- unmute: [],
617
- pause: [],
618
- resume: [],
619
- fullscreen: [],
620
- exitFullscreen: [],
621
- skip: [],
622
- error: []
623
- };
624
- xmlDoc.querySelectorAll("Impression").forEach(function(el) {
625
- var _el_textContent;
626
- var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
627
- if (url) trackingUrls.impression.push(url);
628
- });
629
- xmlDoc.querySelectorAll("Tracking").forEach(function(el) {
630
- var _el_textContent;
631
- var event = el.getAttribute("event");
632
- var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
633
- if (event && url) {
634
- var eventKey = event;
635
- if (trackingUrls[eventKey]) {
636
- trackingUrls[eventKey].push(url);
637
- }
638
- }
639
- });
640
- 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();
673
+ return {
674
+ type: "empty"
675
+ };
676
+ }
641
677
  return {
642
- id: adId,
643
- title: title,
644
- duration: duration,
645
- mediaFiles: mediaFiles,
646
- trackingUrls: trackingUrls,
647
- clickThrough: clickThrough
678
+ type: "inline",
679
+ ad: {
680
+ id: adId,
681
+ title: title,
682
+ duration: duration,
683
+ mediaFiles: mediaFiles,
684
+ trackingUrls: extractTrackingUrls(xmlDoc),
685
+ clickThrough: clickThrough
686
+ }
648
687
  };
649
688
  } catch (error) {
650
689
  console.error("[HlsAdPlayer] Error parsing VAST XML:", error);
651
- return null;
690
+ return {
691
+ type: "empty"
692
+ };
652
693
  }
653
694
  }
654
- function fetchAndParseVastAd(vastTagUrl) {
695
+ function fetchVastXml(vastTagUrl) {
655
696
  return _async_to_generator(function() {
656
- var response, vastXml;
697
+ var response;
657
698
  return _ts_generator(this, function(_state) {
658
699
  switch(_state.label){
659
700
  case 0:
@@ -674,20 +715,58 @@ function createHlsAdPlayer(contentVideo, options) {
674
715
  throw new Error("Failed to fetch VAST: ".concat(response.statusText));
675
716
  }
676
717
  return [
677
- 4,
718
+ 2,
678
719
  response.text()
679
720
  ];
680
- case 2:
721
+ }
722
+ });
723
+ })();
724
+ }
725
+ function fetchAndParseVastAd(_0) {
726
+ return _async_to_generator(function(vastTagUrl) {
727
+ var depth, accumulatedTracking, vastXml, parsed;
728
+ var _arguments = arguments;
729
+ return _ts_generator(this, function(_state) {
730
+ switch(_state.label){
731
+ case 0:
732
+ depth = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : 0, accumulatedTracking = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : createEmptyTrackingUrls();
733
+ return [
734
+ 4,
735
+ fetchVastXml(vastTagUrl)
736
+ ];
737
+ case 1:
681
738
  vastXml = _state.sent();
682
739
  console.log("[HlsAdPlayer] VAST XML received");
683
740
  console.log("[HlsAdPlayer] VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
741
+ parsed = parseVastXml(vastXml);
742
+ if (parsed.type === "empty") {
743
+ return [
744
+ 2,
745
+ null
746
+ ];
747
+ }
748
+ if (parsed.type === "wrapper") {
749
+ if (depth >= MAX_VAST_WRAPPER_DEPTH) {
750
+ console.warn("[HlsAdPlayer] VAST wrapper depth limit (".concat(MAX_VAST_WRAPPER_DEPTH, ") reached, aborting redirect chain"));
751
+ return [
752
+ 2,
753
+ null
754
+ ];
755
+ }
756
+ mergeTrackingUrls(accumulatedTracking, parsed.trackingUrls);
757
+ return [
758
+ 2,
759
+ fetchAndParseVastAd(parsed.vastAdTagUri, depth + 1, accumulatedTracking)
760
+ ];
761
+ }
762
+ mergeTrackingUrls(parsed.ad.trackingUrls, accumulatedTracking);
684
763
  return [
685
764
  2,
686
- parseVastXml(vastXml)
765
+ parsed.ad
687
766
  ];
688
767
  }
689
768
  });
690
- })();
769
+ }).apply(this, arguments);
691
770
  }
692
771
  function createAdVideoElement() {
693
772
  var video = document.createElement("video");
@@ -1263,7 +1342,7 @@ function createPalNonceManager() {
1263
1342
  return {
1264
1343
  generateNonce: function generateNonce() {
1265
1344
  return _async_to_generator(function() {
1266
- var options, _options_adWillAutoPlay, _options_adWillPlayMuted, _options_continuousPlayback, loader, goog, request, manager, error;
1345
+ var options, _options_adWillAutoPlay, _options_adWillPlayMuted, _options_playerVolume, _options_continuousPlayback, loader, goog, request, manager, error;
1267
1346
  var _arguments = arguments;
1268
1347
  return _ts_generator(this, function(_state) {
1269
1348
  switch(_state.label){
@@ -1288,6 +1367,7 @@ function createPalNonceManager() {
1288
1367
  request = new goog.pal.NonceRequest();
1289
1368
  request.adWillAutoPlay = (_options_adWillAutoPlay = options.adWillAutoPlay) !== null && _options_adWillAutoPlay !== void 0 ? _options_adWillAutoPlay : true;
1290
1369
  request.adWillPlayMuted = (_options_adWillPlayMuted = options.adWillPlayMuted) !== null && _options_adWillPlayMuted !== void 0 ? _options_adWillPlayMuted : false;
1370
+ request.playerVolume = (_options_playerVolume = options.playerVolume) !== null && _options_playerVolume !== void 0 ? _options_playerVolume : request.adWillPlayMuted ? 0 : 1;
1291
1371
  request.continuousPlayback = (_options_continuousPlayback = options.continuousPlayback) !== null && _options_continuousPlayback !== void 0 ? _options_continuousPlayback : true;
1292
1372
  request.descriptionUrl = options.descriptionUrl || (typeof window !== "undefined" ? window.location.href : "");
1293
1373
  request.iconsSupported = true;
@@ -2685,7 +2765,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
2685
2765
  videoWidth: this.video.offsetWidth || this.video.clientWidth || 640,
2686
2766
  videoHeight: this.video.offsetHeight || this.video.clientHeight || 480,
2687
2767
  adWillAutoPlay: !!this.config.autoplay,
2688
- adWillPlayMuted: !!this.config.muted,
2768
+ adWillPlayMuted: true,
2769
+ playerVolume: 0,
2689
2770
  continuousPlayback: (_this_config_lowLatencyMode = this.config.lowLatencyMode) !== null && _this_config_lowLatencyMode !== void 0 ? _this_config_lowLatencyMode : false
2690
2771
  }).catch(function() {});
2691
2772
  fetchConsentSignals().then(function(signals) {