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.
package/lib/index.js CHANGED
@@ -372,6 +372,7 @@ import React, { useEffect, useRef, useMemo, useCallback } from "react";
372
372
  import Hls2 from "hls.js";
373
373
  // src/sdk/hlsAdPlayer.ts
374
374
  import Hls from "hls.js";
375
+ var MAX_VAST_WRAPPER_DEPTH = 5;
375
376
  function createHlsAdPlayer(contentVideo, options) {
376
377
  var adPlaying = false;
377
378
  var originalMutedState = false;
@@ -529,25 +530,91 @@ function createHlsAdPlayer(contentVideo, options) {
529
530
  var url = mediaFile.url.toLowerCase();
530
531
  return type.startsWith("video/") || url.endsWith(".mp4") || url.includes(".mp4?");
531
532
  }
533
+ function createEmptyTrackingUrls() {
534
+ return {
535
+ impression: [],
536
+ start: [],
537
+ firstQuartile: [],
538
+ midpoint: [],
539
+ thirdQuartile: [],
540
+ complete: [],
541
+ mute: [],
542
+ unmute: [],
543
+ pause: [],
544
+ resume: [],
545
+ fullscreen: [],
546
+ exitFullscreen: [],
547
+ skip: [],
548
+ error: []
549
+ };
550
+ }
551
+ function extractTrackingUrls(xmlDoc) {
552
+ var trackingUrls = createEmptyTrackingUrls();
553
+ xmlDoc.querySelectorAll("Impression").forEach(function(el) {
554
+ var _el_textContent;
555
+ var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
556
+ if (url) trackingUrls.impression.push(url);
557
+ });
558
+ xmlDoc.querySelectorAll("Tracking").forEach(function(el) {
559
+ var _el_textContent;
560
+ var event = el.getAttribute("event");
561
+ var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
562
+ if (event && url) {
563
+ var eventKey = event;
564
+ if (trackingUrls[eventKey]) {
565
+ trackingUrls[eventKey].push(url);
566
+ }
567
+ }
568
+ });
569
+ xmlDoc.querySelectorAll("Error").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.error.push(url);
573
+ });
574
+ return trackingUrls;
575
+ }
576
+ function mergeTrackingUrls(target, source) {
577
+ Object.keys(target).forEach(function(key) {
578
+ if (source[key] && source[key].length > 0) {
579
+ target[key] = target[key].concat(source[key]);
580
+ }
581
+ });
582
+ return target;
583
+ }
532
584
  function parseVastXml(xmlString) {
533
585
  try {
534
- var _xmlDoc_querySelector, _xmlDoc_querySelector1, _xmlDoc_querySelector_textContent, _xmlDoc_querySelector2;
586
+ var _xmlDoc_querySelector, _xmlDoc_querySelector_textContent, _xmlDoc_querySelector1, _xmlDoc_querySelector_textContent1, _xmlDoc_querySelector2, _xmlDoc_querySelector3;
535
587
  var parser = new DOMParser();
536
588
  var xmlDoc = parser.parseFromString(xmlString, "text/xml");
537
589
  var parserError = xmlDoc.querySelector("parsererror");
538
590
  if (parserError) {
539
591
  console.error("[HlsAdPlayer] XML parsing error (malformed VAST XML):", parserError.textContent);
540
- return null;
592
+ return {
593
+ type: "empty"
594
+ };
541
595
  }
542
596
  var adElement = xmlDoc.querySelector("Ad");
543
597
  if (!adElement) {
544
598
  console.warn("[HlsAdPlayer] No Ad element found in VAST XML");
545
- return null;
599
+ return {
600
+ type: "empty"
601
+ };
546
602
  }
547
603
  var adId = adElement.getAttribute("id") || "unknown";
548
604
  var title = ((_xmlDoc_querySelector = xmlDoc.querySelector("AdTitle")) === null || _xmlDoc_querySelector === void 0 ? void 0 : _xmlDoc_querySelector.textContent) || "Ad";
605
+ 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();
606
+ 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();
607
+ if (wrapperUri) {
608
+ console.log("[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ".concat(wrapperUri));
609
+ return {
610
+ type: "wrapper",
611
+ vastAdTagUri: wrapperUri,
612
+ trackingUrls: extractTrackingUrls(xmlDoc),
613
+ clickThrough: clickThrough
614
+ };
615
+ }
549
616
  var isNoAdAvailable = adId === "empty" || title.toLowerCase().includes("no ad available") || title.toLowerCase() === "no ad available";
550
- var durationText = ((_xmlDoc_querySelector1 = xmlDoc.querySelector("Duration")) === null || _xmlDoc_querySelector1 === void 0 ? void 0 : _xmlDoc_querySelector1.textContent) || "00:00:30";
617
+ var durationText = ((_xmlDoc_querySelector3 = xmlDoc.querySelector("Duration")) === null || _xmlDoc_querySelector3 === void 0 ? void 0 : _xmlDoc_querySelector3.textContent) || "00:00:30";
551
618
  var durationParts = durationText.split(":");
552
619
  var duration = parseInt(durationParts[0] || "0", 10) * 3600 + parseInt(durationParts[1] || "0", 10) * 60 + parseInt(durationParts[2] || "0", 10);
553
620
  var mediaFileElements = xmlDoc.querySelectorAll("MediaFile");
@@ -587,57 +654,31 @@ function createHlsAdPlayer(contentVideo, options) {
587
654
  } else {
588
655
  console.warn("[HlsAdPlayer] No supported media files found in VAST XML");
589
656
  }
590
- return null;
657
+ return {
658
+ type: "empty"
659
+ };
591
660
  }
592
- var trackingUrls = {
593
- impression: [],
594
- start: [],
595
- firstQuartile: [],
596
- midpoint: [],
597
- thirdQuartile: [],
598
- complete: [],
599
- mute: [],
600
- unmute: [],
601
- pause: [],
602
- resume: [],
603
- fullscreen: [],
604
- exitFullscreen: [],
605
- skip: [],
606
- error: []
607
- };
608
- xmlDoc.querySelectorAll("Impression").forEach(function(el) {
609
- var _el_textContent;
610
- var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
611
- if (url) trackingUrls.impression.push(url);
612
- });
613
- xmlDoc.querySelectorAll("Tracking").forEach(function(el) {
614
- var _el_textContent;
615
- var event = el.getAttribute("event");
616
- var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
617
- if (event && url) {
618
- var eventKey = event;
619
- if (trackingUrls[eventKey]) {
620
- trackingUrls[eventKey].push(url);
621
- }
622
- }
623
- });
624
- 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();
625
661
  return {
626
- id: adId,
627
- title: title,
628
- duration: duration,
629
- mediaFiles: mediaFiles,
630
- trackingUrls: trackingUrls,
631
- clickThrough: clickThrough
662
+ type: "inline",
663
+ ad: {
664
+ id: adId,
665
+ title: title,
666
+ duration: duration,
667
+ mediaFiles: mediaFiles,
668
+ trackingUrls: extractTrackingUrls(xmlDoc),
669
+ clickThrough: clickThrough
670
+ }
632
671
  };
633
672
  } catch (error) {
634
673
  console.error("[HlsAdPlayer] Error parsing VAST XML:", error);
635
- return null;
674
+ return {
675
+ type: "empty"
676
+ };
636
677
  }
637
678
  }
638
- function fetchAndParseVastAd(vastTagUrl) {
679
+ function fetchVastXml(vastTagUrl) {
639
680
  return _async_to_generator(function() {
640
- var response, vastXml;
681
+ var response;
641
682
  return _ts_generator(this, function(_state) {
642
683
  switch(_state.label){
643
684
  case 0:
@@ -658,20 +699,58 @@ function createHlsAdPlayer(contentVideo, options) {
658
699
  throw new Error("Failed to fetch VAST: ".concat(response.statusText));
659
700
  }
660
701
  return [
661
- 4,
702
+ 2,
662
703
  response.text()
663
704
  ];
664
- case 2:
705
+ }
706
+ });
707
+ })();
708
+ }
709
+ function fetchAndParseVastAd(_0) {
710
+ return _async_to_generator(function(vastTagUrl) {
711
+ var depth, accumulatedTracking, vastXml, parsed;
712
+ var _arguments = arguments;
713
+ return _ts_generator(this, function(_state) {
714
+ switch(_state.label){
715
+ case 0:
716
+ depth = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : 0, accumulatedTracking = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : createEmptyTrackingUrls();
717
+ return [
718
+ 4,
719
+ fetchVastXml(vastTagUrl)
720
+ ];
721
+ case 1:
665
722
  vastXml = _state.sent();
666
723
  console.log("[HlsAdPlayer] VAST XML received");
667
724
  console.log("[HlsAdPlayer] VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
725
+ parsed = parseVastXml(vastXml);
726
+ if (parsed.type === "empty") {
727
+ return [
728
+ 2,
729
+ null
730
+ ];
731
+ }
732
+ if (parsed.type === "wrapper") {
733
+ if (depth >= MAX_VAST_WRAPPER_DEPTH) {
734
+ console.warn("[HlsAdPlayer] VAST wrapper depth limit (".concat(MAX_VAST_WRAPPER_DEPTH, ") reached, aborting redirect chain"));
735
+ return [
736
+ 2,
737
+ null
738
+ ];
739
+ }
740
+ mergeTrackingUrls(accumulatedTracking, parsed.trackingUrls);
741
+ return [
742
+ 2,
743
+ fetchAndParseVastAd(parsed.vastAdTagUri, depth + 1, accumulatedTracking)
744
+ ];
745
+ }
746
+ mergeTrackingUrls(parsed.ad.trackingUrls, accumulatedTracking);
668
747
  return [
669
748
  2,
670
- parseVastXml(vastXml)
749
+ parsed.ad
671
750
  ];
672
751
  }
673
752
  });
674
- })();
753
+ }).apply(this, arguments);
675
754
  }
676
755
  function createAdVideoElement() {
677
756
  var video = document.createElement("video");