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.
@@ -350,6 +350,7 @@ module.exports = __toCommonJS(StormcloudVideoPlayer_exports);
350
350
  var import_hls2 = __toESM(require("hls.js"), 1);
351
351
  // src/sdk/hlsAdPlayer.ts
352
352
  var import_hls = __toESM(require("hls.js"), 1);
353
+ var MAX_VAST_WRAPPER_DEPTH = 5;
353
354
  function createHlsAdPlayer(contentVideo, options) {
354
355
  var adPlaying = false;
355
356
  var originalMutedState = false;
@@ -507,25 +508,91 @@ function createHlsAdPlayer(contentVideo, options) {
507
508
  var url = mediaFile.url.toLowerCase();
508
509
  return type.startsWith("video/") || url.endsWith(".mp4") || url.includes(".mp4?");
509
510
  }
511
+ function createEmptyTrackingUrls() {
512
+ return {
513
+ impression: [],
514
+ start: [],
515
+ firstQuartile: [],
516
+ midpoint: [],
517
+ thirdQuartile: [],
518
+ complete: [],
519
+ mute: [],
520
+ unmute: [],
521
+ pause: [],
522
+ resume: [],
523
+ fullscreen: [],
524
+ exitFullscreen: [],
525
+ skip: [],
526
+ error: []
527
+ };
528
+ }
529
+ function extractTrackingUrls(xmlDoc) {
530
+ var trackingUrls = createEmptyTrackingUrls();
531
+ xmlDoc.querySelectorAll("Impression").forEach(function(el) {
532
+ var _el_textContent;
533
+ var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
534
+ if (url) trackingUrls.impression.push(url);
535
+ });
536
+ xmlDoc.querySelectorAll("Tracking").forEach(function(el) {
537
+ var _el_textContent;
538
+ var event = el.getAttribute("event");
539
+ var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
540
+ if (event && url) {
541
+ var eventKey = event;
542
+ if (trackingUrls[eventKey]) {
543
+ trackingUrls[eventKey].push(url);
544
+ }
545
+ }
546
+ });
547
+ xmlDoc.querySelectorAll("Error").forEach(function(el) {
548
+ var _el_textContent;
549
+ var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
550
+ if (url) trackingUrls.error.push(url);
551
+ });
552
+ return trackingUrls;
553
+ }
554
+ function mergeTrackingUrls(target, source) {
555
+ Object.keys(target).forEach(function(key) {
556
+ if (source[key] && source[key].length > 0) {
557
+ target[key] = target[key].concat(source[key]);
558
+ }
559
+ });
560
+ return target;
561
+ }
510
562
  function parseVastXml(xmlString) {
511
563
  try {
512
- var _xmlDoc_querySelector, _xmlDoc_querySelector1, _xmlDoc_querySelector_textContent, _xmlDoc_querySelector2;
564
+ var _xmlDoc_querySelector, _xmlDoc_querySelector_textContent, _xmlDoc_querySelector1, _xmlDoc_querySelector_textContent1, _xmlDoc_querySelector2, _xmlDoc_querySelector3;
513
565
  var parser = new DOMParser();
514
566
  var xmlDoc = parser.parseFromString(xmlString, "text/xml");
515
567
  var parserError = xmlDoc.querySelector("parsererror");
516
568
  if (parserError) {
517
569
  console.error("[HlsAdPlayer] XML parsing error (malformed VAST XML):", parserError.textContent);
518
- return null;
570
+ return {
571
+ type: "empty"
572
+ };
519
573
  }
520
574
  var adElement = xmlDoc.querySelector("Ad");
521
575
  if (!adElement) {
522
576
  console.warn("[HlsAdPlayer] No Ad element found in VAST XML");
523
- return null;
577
+ return {
578
+ type: "empty"
579
+ };
524
580
  }
525
581
  var adId = adElement.getAttribute("id") || "unknown";
526
582
  var title = ((_xmlDoc_querySelector = xmlDoc.querySelector("AdTitle")) === null || _xmlDoc_querySelector === void 0 ? void 0 : _xmlDoc_querySelector.textContent) || "Ad";
583
+ 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();
584
+ 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();
585
+ if (wrapperUri) {
586
+ console.log("[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ".concat(wrapperUri));
587
+ return {
588
+ type: "wrapper",
589
+ vastAdTagUri: wrapperUri,
590
+ trackingUrls: extractTrackingUrls(xmlDoc),
591
+ clickThrough: clickThrough
592
+ };
593
+ }
527
594
  var isNoAdAvailable = adId === "empty" || title.toLowerCase().includes("no ad available") || title.toLowerCase() === "no ad available";
528
- var durationText = ((_xmlDoc_querySelector1 = xmlDoc.querySelector("Duration")) === null || _xmlDoc_querySelector1 === void 0 ? void 0 : _xmlDoc_querySelector1.textContent) || "00:00:30";
595
+ var durationText = ((_xmlDoc_querySelector3 = xmlDoc.querySelector("Duration")) === null || _xmlDoc_querySelector3 === void 0 ? void 0 : _xmlDoc_querySelector3.textContent) || "00:00:30";
529
596
  var durationParts = durationText.split(":");
530
597
  var duration = parseInt(durationParts[0] || "0", 10) * 3600 + parseInt(durationParts[1] || "0", 10) * 60 + parseInt(durationParts[2] || "0", 10);
531
598
  var mediaFileElements = xmlDoc.querySelectorAll("MediaFile");
@@ -565,57 +632,31 @@ function createHlsAdPlayer(contentVideo, options) {
565
632
  } else {
566
633
  console.warn("[HlsAdPlayer] No supported media files found in VAST XML");
567
634
  }
568
- return null;
569
- }
570
- var trackingUrls = {
571
- impression: [],
572
- start: [],
573
- firstQuartile: [],
574
- midpoint: [],
575
- thirdQuartile: [],
576
- complete: [],
577
- mute: [],
578
- unmute: [],
579
- pause: [],
580
- resume: [],
581
- fullscreen: [],
582
- exitFullscreen: [],
583
- skip: [],
584
- error: []
585
- };
586
- xmlDoc.querySelectorAll("Impression").forEach(function(el) {
587
- var _el_textContent;
588
- var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
589
- if (url) trackingUrls.impression.push(url);
590
- });
591
- xmlDoc.querySelectorAll("Tracking").forEach(function(el) {
592
- var _el_textContent;
593
- var event = el.getAttribute("event");
594
- var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
595
- if (event && url) {
596
- var eventKey = event;
597
- if (trackingUrls[eventKey]) {
598
- trackingUrls[eventKey].push(url);
599
- }
600
- }
601
- });
602
- 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();
635
+ return {
636
+ type: "empty"
637
+ };
638
+ }
603
639
  return {
604
- id: adId,
605
- title: title,
606
- duration: duration,
607
- mediaFiles: mediaFiles,
608
- trackingUrls: trackingUrls,
609
- clickThrough: clickThrough
640
+ type: "inline",
641
+ ad: {
642
+ id: adId,
643
+ title: title,
644
+ duration: duration,
645
+ mediaFiles: mediaFiles,
646
+ trackingUrls: extractTrackingUrls(xmlDoc),
647
+ clickThrough: clickThrough
648
+ }
610
649
  };
611
650
  } catch (error) {
612
651
  console.error("[HlsAdPlayer] Error parsing VAST XML:", error);
613
- return null;
652
+ return {
653
+ type: "empty"
654
+ };
614
655
  }
615
656
  }
616
- function fetchAndParseVastAd(vastTagUrl) {
657
+ function fetchVastXml(vastTagUrl) {
617
658
  return _async_to_generator(function() {
618
- var response, vastXml;
659
+ var response;
619
660
  return _ts_generator(this, function(_state) {
620
661
  switch(_state.label){
621
662
  case 0:
@@ -636,20 +677,58 @@ function createHlsAdPlayer(contentVideo, options) {
636
677
  throw new Error("Failed to fetch VAST: ".concat(response.statusText));
637
678
  }
638
679
  return [
639
- 4,
680
+ 2,
640
681
  response.text()
641
682
  ];
642
- case 2:
683
+ }
684
+ });
685
+ })();
686
+ }
687
+ function fetchAndParseVastAd(_0) {
688
+ return _async_to_generator(function(vastTagUrl) {
689
+ var depth, accumulatedTracking, vastXml, parsed;
690
+ var _arguments = arguments;
691
+ return _ts_generator(this, function(_state) {
692
+ switch(_state.label){
693
+ case 0:
694
+ depth = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : 0, accumulatedTracking = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : createEmptyTrackingUrls();
695
+ return [
696
+ 4,
697
+ fetchVastXml(vastTagUrl)
698
+ ];
699
+ case 1:
643
700
  vastXml = _state.sent();
644
701
  console.log("[HlsAdPlayer] VAST XML received");
645
702
  console.log("[HlsAdPlayer] VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
703
+ parsed = parseVastXml(vastXml);
704
+ if (parsed.type === "empty") {
705
+ return [
706
+ 2,
707
+ null
708
+ ];
709
+ }
710
+ if (parsed.type === "wrapper") {
711
+ if (depth >= MAX_VAST_WRAPPER_DEPTH) {
712
+ console.warn("[HlsAdPlayer] VAST wrapper depth limit (".concat(MAX_VAST_WRAPPER_DEPTH, ") reached, aborting redirect chain"));
713
+ return [
714
+ 2,
715
+ null
716
+ ];
717
+ }
718
+ mergeTrackingUrls(accumulatedTracking, parsed.trackingUrls);
719
+ return [
720
+ 2,
721
+ fetchAndParseVastAd(parsed.vastAdTagUri, depth + 1, accumulatedTracking)
722
+ ];
723
+ }
724
+ mergeTrackingUrls(parsed.ad.trackingUrls, accumulatedTracking);
646
725
  return [
647
726
  2,
648
- parseVastXml(vastXml)
727
+ parsed.ad
649
728
  ];
650
729
  }
651
730
  });
652
- })();
731
+ }).apply(this, arguments);
653
732
  }
654
733
  function createAdVideoElement() {
655
734
  var video = document.createElement("video");