stormcloud-video-player 0.2.14 → 0.2.16

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.
@@ -850,7 +850,7 @@ function createHlsAdPlayer(contentVideo, options) {
850
850
  const xmlDoc = parser.parseFromString(xmlString, "text/xml");
851
851
  const parserError = xmlDoc.querySelector("parsererror");
852
852
  if (parserError) {
853
- console.error("[HlsAdPlayer] XML parsing error:", parserError.textContent);
853
+ console.error("[HlsAdPlayer] XML parsing error (malformed VAST XML):", parserError.textContent);
854
854
  return null;
855
855
  }
856
856
  const adElement = xmlDoc.querySelector("Ad");
@@ -860,28 +860,45 @@ function createHlsAdPlayer(contentVideo, options) {
860
860
  }
861
861
  const adId = adElement.getAttribute("id") || "unknown";
862
862
  const title = ((_a = xmlDoc.querySelector("AdTitle")) == null ? void 0 : _a.textContent) || "Ad";
863
+ const isNoAdAvailable = adId === "empty" || title.toLowerCase().includes("no ad available") || title.toLowerCase() === "no ad available";
863
864
  const durationText = ((_b = xmlDoc.querySelector("Duration")) == null ? void 0 : _b.textContent) || "00:00:30";
864
865
  const durationParts = durationText.split(":");
865
866
  const duration = parseInt(durationParts[0] || "0", 10) * 3600 + parseInt(durationParts[1] || "0", 10) * 60 + parseInt(durationParts[2] || "0", 10);
866
867
  const mediaFileElements = xmlDoc.querySelectorAll("MediaFile");
867
868
  const mediaFiles = [];
868
- mediaFileElements.forEach((mf) => {
869
+ console.log(`[HlsAdPlayer] Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`);
870
+ mediaFileElements.forEach((mf, index) => {
869
871
  var _a2;
870
872
  const type = mf.getAttribute("type") || "";
873
+ const url = ((_a2 = mf.textContent) == null ? void 0 : _a2.trim()) || "";
874
+ const width = mf.getAttribute("width") || "";
875
+ const height = mf.getAttribute("height") || "";
876
+ console.log(`[HlsAdPlayer] MediaFile ${index}: type="${type}", url="${url}", width="${width}", height="${height}"`);
871
877
  if (type === "application/x-mpegURL" || type.includes("m3u8")) {
878
+ if (!url) {
879
+ console.warn(`[HlsAdPlayer] MediaFile ${index} has HLS type but empty URL`);
880
+ return;
881
+ }
872
882
  const bitrateAttr = mf.getAttribute("bitrate");
873
883
  const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;
874
884
  mediaFiles.push({
875
- url: ((_a2 = mf.textContent) == null ? void 0 : _a2.trim()) || "",
885
+ url,
876
886
  type,
877
- width: parseInt(mf.getAttribute("width") || "1920", 10),
878
- height: parseInt(mf.getAttribute("height") || "1080", 10),
887
+ width: parseInt(width || "1920", 10),
888
+ height: parseInt(height || "1080", 10),
879
889
  bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : void 0
880
890
  });
891
+ console.log(`[HlsAdPlayer] Added HLS MediaFile: ${url}`);
892
+ } else {
893
+ console.log(`[HlsAdPlayer] MediaFile ${index} ignored (type="${type}" is not HLS)`);
881
894
  }
882
895
  });
883
896
  if (mediaFiles.length === 0) {
884
- console.warn("[HlsAdPlayer] No HLS media files found in VAST XML");
897
+ if (isNoAdAvailable) {
898
+ console.warn("[HlsAdPlayer] No ads available (VAST response indicates no ads)");
899
+ } else {
900
+ console.warn("[HlsAdPlayer] No HLS media files found in VAST XML");
901
+ }
885
902
  return null;
886
903
  }
887
904
  const trackingUrls = {
@@ -1069,9 +1086,11 @@ function createHlsAdPlayer(contentVideo, options) {
1069
1086
  }
1070
1087
  const vastXml = await response.text();
1071
1088
  console.log("[HlsAdPlayer] VAST XML received");
1089
+ console.log("[HlsAdPlayer] VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
1072
1090
  const ad = parseVastXml(vastXml);
1073
1091
  if (!ad) {
1074
- throw new Error("Failed to parse VAST XML or no ads available");
1092
+ console.warn("[HlsAdPlayer] No ads available from VAST response");
1093
+ return Promise.resolve();
1075
1094
  }
1076
1095
  currentAd = ad;
1077
1096
  console.log(`[HlsAdPlayer] Ad parsed: ${ad.title}, duration: ${ad.duration}s`);
@@ -1086,7 +1105,7 @@ function createHlsAdPlayer(contentVideo, options) {
1086
1105
  },
1087
1106
  async play() {
1088
1107
  if (!currentAd) {
1089
- console.warn("[HlsAdPlayer] Cannot play: No ad loaded");
1108
+ console.warn("[HlsAdPlayer] Cannot play: No ad loaded (no ads available)");
1090
1109
  return Promise.reject(new Error("No ad loaded"));
1091
1110
  }
1092
1111
  console.log("[HlsAdPlayer] Starting ad playback");
@@ -1717,6 +1736,8 @@ var StormcloudVideoPlayer = class {
1717
1736
  this.totalAdsInBreak = 0;
1718
1737
  this.showAds = false;
1719
1738
  this.isLiveStream = false;
1739
+ this.nativeHlsMode = false;
1740
+ this.videoSrcProtection = null;
1720
1741
  initializePolyfills();
1721
1742
  const browserOverrides = getBrowserConfigOverrides();
1722
1743
  this.config = { ...config, ...browserOverrides };
@@ -1737,7 +1758,9 @@ var StormcloudVideoPlayer = class {
1737
1758
  }
1738
1759
  if (adPlayerType === "hls") {
1739
1760
  if (this.config.debugAdTiming) {
1740
- console.log("[StormcloudVideoPlayer] Creating HLS ad player (AdStorm mode)");
1761
+ console.log(
1762
+ "[StormcloudVideoPlayer] Creating HLS ad player (AdStorm mode)"
1763
+ );
1741
1764
  }
1742
1765
  return createHlsAdPlayer(this.video, {
1743
1766
  continueLiveStreamDuringAds,
@@ -1746,7 +1769,9 @@ var StormcloudVideoPlayer = class {
1746
1769
  });
1747
1770
  } else {
1748
1771
  if (this.config.debugAdTiming) {
1749
- console.log("[StormcloudVideoPlayer] Creating Google IMA ad player (Default mode)");
1772
+ console.log(
1773
+ "[StormcloudVideoPlayer] Creating Google IMA ad player (Default mode)"
1774
+ );
1750
1775
  }
1751
1776
  return createImaController(this.video, {
1752
1777
  continueLiveStreamDuringAds
@@ -1770,11 +1795,13 @@ var StormcloudVideoPlayer = class {
1770
1795
  }
1771
1796
  this.initializeTracking();
1772
1797
  if (this.shouldUseNativeHls()) {
1798
+ this.nativeHlsMode = true;
1799
+ this.videoSrcProtection = this.config.src;
1773
1800
  this.video.src = this.config.src;
1774
1801
  this.isLiveStream = (_a = this.config.lowLatencyMode) != null ? _a : false;
1775
1802
  if (this.config.debugAdTiming) {
1776
1803
  console.log(
1777
- "[StormcloudVideoPlayer] allowNativeHls: true - VOD mode detected:",
1804
+ "[StormcloudVideoPlayer] Using native HLS playback - VOD mode:",
1778
1805
  {
1779
1806
  isLive: this.isLiveStream,
1780
1807
  allowNativeHls: this.config.allowNativeHls,
@@ -1922,7 +1949,9 @@ var StormcloudVideoPlayer = class {
1922
1949
  this.ima.initialize();
1923
1950
  this.ima.on("all_ads_completed", () => {
1924
1951
  if (this.config.debugAdTiming) {
1925
- console.log("[StormcloudVideoPlayer] IMA all_ads_completed event received");
1952
+ console.log(
1953
+ "[StormcloudVideoPlayer] IMA all_ads_completed event received"
1954
+ );
1926
1955
  }
1927
1956
  });
1928
1957
  this.ima.on("ad_error", () => {
@@ -1987,13 +2016,31 @@ var StormcloudVideoPlayer = class {
1987
2016
  this.video.addEventListener("timeupdate", () => {
1988
2017
  this.onTimeUpdate(this.video.currentTime);
1989
2018
  });
2019
+ this.video.addEventListener("emptied", () => {
2020
+ if (this.nativeHlsMode && this.videoSrcProtection && !this.ima.isAdPlaying()) {
2021
+ if (this.config.debugAdTiming) {
2022
+ console.log(
2023
+ "[StormcloudVideoPlayer] Video src was cleared, restoring:",
2024
+ this.videoSrcProtection
2025
+ );
2026
+ }
2027
+ const currentTime = this.video.currentTime;
2028
+ const wasPaused = this.video.paused;
2029
+ this.video.src = this.videoSrcProtection;
2030
+ this.video.currentTime = currentTime;
2031
+ if (!wasPaused) {
2032
+ this.video.play().catch(() => {
2033
+ });
2034
+ }
2035
+ }
2036
+ });
1990
2037
  }
1991
2038
  shouldUseNativeHls() {
1992
2039
  const streamType = this.getStreamType();
1993
2040
  if (streamType === "other") {
1994
2041
  return true;
1995
2042
  }
1996
- const canNative = this.video.canPlayType("application/vnd.apple.mpegURL");
2043
+ const canNative = this.video.canPlayType("application/vnd.apple.mpegurl");
1997
2044
  return !!(this.config.allowNativeHls && canNative);
1998
2045
  }
1999
2046
  onId3Tag(tag) {
@@ -2420,10 +2467,7 @@ var StormcloudVideoPlayer = class {
2420
2467
  var _a, _b, _c;
2421
2468
  const vastMode = this.config.vastMode || "default";
2422
2469
  if (this.config.debugAdTiming) {
2423
- console.log(
2424
- "[StormcloudVideoPlayer] VAST mode:",
2425
- vastMode
2426
- );
2470
+ console.log("[StormcloudVideoPlayer] VAST mode:", vastMode);
2427
2471
  }
2428
2472
  if (vastMode === "adstorm") {
2429
2473
  if (!this.config.licenseKey) {
@@ -2438,7 +2482,7 @@ var StormcloudVideoPlayer = class {
2438
2482
  this.apiVastTagUrl = vastEndpoint;
2439
2483
  if (this.config.debugAdTiming) {
2440
2484
  console.log(
2441
- "[StormcloudVideoPlayer] Using AdStorm VAST endpoint:",
2485
+ "[StormcloudVideoPlayer] Using AdStorm VAST endpoint (adstorm mode):",
2442
2486
  vastEndpoint
2443
2487
  );
2444
2488
  }
@@ -2541,10 +2585,7 @@ var StormcloudVideoPlayer = class {
2541
2585
  this.currentAdIndex = 0;
2542
2586
  this.totalAdsInBreak = 1;
2543
2587
  if (this.config.debugAdTiming) {
2544
- console.log(
2545
- "[StormcloudVideoPlayer] Using VAST endpoint:",
2546
- vastTagUrl
2547
- );
2588
+ console.log("[StormcloudVideoPlayer] Using VAST endpoint:", vastTagUrl);
2548
2589
  }
2549
2590
  } else if (tags && tags.length > 0) {
2550
2591
  vastTagUrl = tags[0];
@@ -2694,12 +2735,26 @@ var StormcloudVideoPlayer = class {
2694
2735
  this.startAdFailsafeTimer();
2695
2736
  try {
2696
2737
  await this.ima.requestAds(vastTagUrl);
2697
- if (this.config.debugAdTiming) {
2698
- console.log("[StormcloudVideoPlayer] Ad request successful, starting playback");
2699
- }
2700
- await this.ima.play();
2701
- if (this.config.debugAdTiming) {
2702
- console.log("[StormcloudVideoPlayer] Ad playback started successfully");
2738
+ try {
2739
+ if (this.config.debugAdTiming) {
2740
+ console.log(
2741
+ "[StormcloudVideoPlayer] Ad request completed, attempting playback"
2742
+ );
2743
+ }
2744
+ await this.ima.play();
2745
+ if (this.config.debugAdTiming) {
2746
+ console.log(
2747
+ "[StormcloudVideoPlayer] Ad playback started successfully"
2748
+ );
2749
+ }
2750
+ } catch (playError) {
2751
+ if (this.config.debugAdTiming) {
2752
+ console.log(
2753
+ "[StormcloudVideoPlayer] No ads available, skipping playback"
2754
+ );
2755
+ }
2756
+ this.handleAdFailure();
2757
+ return;
2703
2758
  }
2704
2759
  } catch (error) {
2705
2760
  if (this.config.debugAdTiming) {
@@ -2752,7 +2807,9 @@ var StormcloudVideoPlayer = class {
2752
2807
  });
2753
2808
  } else {
2754
2809
  if (this.config.debugAdTiming) {
2755
- console.log("[StormcloudVideoPlayer] Video is already playing, no resume needed");
2810
+ console.log(
2811
+ "[StormcloudVideoPlayer] Video is already playing, no resume needed"
2812
+ );
2756
2813
  }
2757
2814
  }
2758
2815
  }
@@ -2771,7 +2828,11 @@ var StormcloudVideoPlayer = class {
2771
2828
  if (this.config.debugAdTiming) {
2772
2829
  console.warn(
2773
2830
  "[StormcloudVideoPlayer] Failsafe timer triggered - forcing video resume",
2774
- { paused: this.video.paused, showAds: this.showAds, adPlaying: this.ima.isAdPlaying() }
2831
+ {
2832
+ paused: this.video.paused,
2833
+ showAds: this.showAds,
2834
+ adPlaying: this.ima.isAdPlaying()
2835
+ }
2775
2836
  );
2776
2837
  }
2777
2838
  this.handleAdFailure();