stormcloud-video-player 0.3.59 → 0.3.61

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
@@ -1760,6 +1760,16 @@ function createHlsAdPlayer(contentVideo, options) {
1760
1760
  });
1761
1761
  return bestMatch.file;
1762
1762
  }
1763
+ function isHlsMediaFile(mediaFile) {
1764
+ var type = mediaFile.type.toLowerCase();
1765
+ var url = mediaFile.url.toLowerCase();
1766
+ return type === "application/x-mpegurl" || type === "application/vnd.apple.mpegurl" || type.includes("mpegurl") || url.includes(".m3u8");
1767
+ }
1768
+ function isProgressiveMediaFile(mediaFile) {
1769
+ var type = mediaFile.type.toLowerCase();
1770
+ var url = mediaFile.url.toLowerCase();
1771
+ return type.startsWith("video/") || url.endsWith(".mp4") || url.includes(".mp4?");
1772
+ }
1763
1773
  function parseVastXml(xmlString) {
1764
1774
  try {
1765
1775
  var _xmlDoc_querySelector, _xmlDoc_querySelector1, _xmlDoc_querySelector_textContent, _xmlDoc_querySelector2;
@@ -1791,30 +1801,32 @@ function createHlsAdPlayer(contentVideo, options) {
1791
1801
  var width = mf.getAttribute("width") || "";
1792
1802
  var height = mf.getAttribute("height") || "";
1793
1803
  console.log("[HlsAdPlayer] MediaFile ".concat(index, ': type="').concat(type, '", url="').concat(url, '", width="').concat(width, '", height="').concat(height, '"'));
1794
- if (type === "application/x-mpegURL" || type.includes("m3u8")) {
1795
- if (!url) {
1796
- console.warn("[HlsAdPlayer] MediaFile ".concat(index, " has HLS type but empty URL"));
1797
- return;
1798
- }
1799
- var bitrateAttr = mf.getAttribute("bitrate");
1800
- var bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;
1801
- mediaFiles.push({
1802
- url: url,
1803
- type: type,
1804
- width: parseInt(width || "1920", 10),
1805
- height: parseInt(height || "1080", 10),
1806
- bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : void 0
1807
- });
1808
- console.log("[HlsAdPlayer] Added HLS MediaFile: ".concat(url));
1804
+ var mediaFile = {
1805
+ url: url,
1806
+ type: type,
1807
+ width: parseInt(width || "1920", 10),
1808
+ height: parseInt(height || "1080", 10),
1809
+ bitrate: void 0
1810
+ };
1811
+ if (!url) {
1812
+ console.warn("[HlsAdPlayer] MediaFile ".concat(index, " has empty URL"));
1813
+ return;
1814
+ }
1815
+ var bitrateAttr = mf.getAttribute("bitrate");
1816
+ var bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;
1817
+ mediaFile.bitrate = bitrateValue && bitrateValue > 0 ? bitrateValue : void 0;
1818
+ if (isHlsMediaFile(mediaFile) || isProgressiveMediaFile(mediaFile)) {
1819
+ mediaFiles.push(mediaFile);
1820
+ console.log("[HlsAdPlayer] Added ".concat(isHlsMediaFile(mediaFile) ? "HLS" : "progressive", " MediaFile: ").concat(url));
1809
1821
  } else {
1810
- console.log("[HlsAdPlayer] MediaFile ".concat(index, ' ignored (type="').concat(type, '" is not HLS)'));
1822
+ console.log("[HlsAdPlayer] MediaFile ".concat(index, ' ignored (type="').concat(type, '" is not supported)'));
1811
1823
  }
1812
1824
  });
1813
1825
  if (mediaFiles.length === 0) {
1814
1826
  if (isNoAdAvailable) {
1815
1827
  console.warn("[HlsAdPlayer] No ads available (VAST response indicates no ads)");
1816
1828
  } else {
1817
- console.warn("[HlsAdPlayer] No HLS media files found in VAST XML");
1829
+ console.warn("[HlsAdPlayer] No supported media files found in VAST XML");
1818
1830
  }
1819
1831
  return null;
1820
1832
  }
@@ -2111,7 +2123,7 @@ function createHlsAdPlayer(contentVideo, options) {
2111
2123
  },
2112
2124
  play: function play() {
2113
2125
  return _async_to_generator(function() {
2114
- var contentVolume, adVolume, mediaFile;
2126
+ var contentVolume, adVolume, mediaFile, isHlsAd;
2115
2127
  return _ts_generator(this, function(_state) {
2116
2128
  if (!currentAd) {
2117
2129
  console.warn("[HlsAdPlayer] Cannot play: No ad loaded (no ads available)");
@@ -2163,8 +2175,9 @@ function createHlsAdPlayer(contentVideo, options) {
2163
2175
  if (!mediaFile) {
2164
2176
  throw new Error("No media file available for ad");
2165
2177
  }
2166
- console.log("[HlsAdPlayer] Loading ad from: ".concat(mediaFile.url));
2167
- if (Hls.isSupported()) {
2178
+ isHlsAd = isHlsMediaFile(mediaFile);
2179
+ console.log("[HlsAdPlayer] Loading ".concat(isHlsAd ? "HLS" : "progressive", " ad from: ").concat(mediaFile.url));
2180
+ if (isHlsAd && Hls.isSupported()) {
2168
2181
  if (adHls) {
2169
2182
  adHls.destroy();
2170
2183
  }
@@ -2187,14 +2200,25 @@ function createHlsAdPlayer(contentVideo, options) {
2187
2200
  handleAdError();
2188
2201
  }
2189
2202
  });
2190
- } else if (adVideoElement.canPlayType("application/vnd.apple.mpegurl")) {
2203
+ } else if (isHlsAd && adVideoElement.canPlayType("application/vnd.apple.mpegurl")) {
2191
2204
  adVideoElement.src = mediaFile.url;
2192
2205
  adVideoElement.play().catch(function(error) {
2193
2206
  console.error("[HlsAdPlayer] Error starting ad playback:", error);
2194
2207
  handleAdError();
2195
2208
  });
2209
+ } else if (!isHlsAd && isProgressiveMediaFile(mediaFile)) {
2210
+ if (adHls) {
2211
+ adHls.destroy();
2212
+ adHls = void 0;
2213
+ }
2214
+ adVideoElement.src = mediaFile.url;
2215
+ adVideoElement.load();
2216
+ adVideoElement.play().catch(function(error) {
2217
+ console.error("[HlsAdPlayer] Error starting progressive ad playback:", error);
2218
+ handleAdError();
2219
+ });
2196
2220
  } else {
2197
- throw new Error("HLS not supported");
2221
+ throw new Error("Unsupported ad media file type: ".concat(mediaFile.type));
2198
2222
  }
2199
2223
  return [
2200
2224
  2,
@@ -2635,40 +2659,66 @@ function getBrowserID(clientInfo) {
2635
2659
  });
2636
2660
  })();
2637
2661
  }
2638
- function sendInitialTracking(licenseKey) {
2662
+ var PLAYER_TRACKING_BASE_URL = "https://adstorm.co/api-adstorm-dev/adstorm/player-tracking";
2663
+ var TRACK_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/metrics/ingest");
2664
+ var HEARTBEAT_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/heartbeat");
2665
+ var IMPRESSIONS_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/impressions/ingest");
2666
+ function buildHeaders(licenseKey) {
2667
+ var headers = {
2668
+ "Content-Type": "application/json"
2669
+ };
2670
+ if (licenseKey) {
2671
+ headers["Authorization"] = "Bearer ".concat(licenseKey);
2672
+ }
2673
+ return headers;
2674
+ }
2675
+ function sendTrackRequest(licenseKey, body) {
2639
2676
  return _async_to_generator(function() {
2640
- var clientInfo, browserId, trackingData, headers, response, error;
2677
+ var response;
2641
2678
  return _ts_generator(this, function(_state) {
2642
2679
  switch(_state.label){
2643
2680
  case 0:
2644
- _state.trys.push([
2645
- 0,
2646
- 4,
2647
- ,
2648
- 5
2649
- ]);
2650
- clientInfo = getClientInfo();
2651
2681
  return [
2652
2682
  4,
2653
- getBrowserID(clientInfo)
2683
+ fetch(TRACK_URL, {
2684
+ method: "POST",
2685
+ headers: buildHeaders(licenseKey),
2686
+ body: JSON.stringify(body)
2687
+ })
2654
2688
  ];
2655
2689
  case 1:
2656
- browserId = _state.sent();
2657
- trackingData = _object_spread({
2658
- browserId: browserId
2659
- }, clientInfo);
2660
- headers = {
2661
- "Content-Type": "application/json"
2662
- };
2690
+ response = _state.sent();
2691
+ if (!response.ok) {
2692
+ throw new Error("HTTP error! status: ".concat(response.status));
2693
+ }
2694
+ return [
2695
+ 4,
2696
+ response.json()
2697
+ ];
2698
+ case 2:
2699
+ _state.sent();
2700
+ return [
2701
+ 2
2702
+ ];
2703
+ }
2704
+ });
2705
+ })();
2706
+ }
2707
+ function postJson(url, licenseKey, body) {
2708
+ return _async_to_generator(function() {
2709
+ var response;
2710
+ return _ts_generator(this, function(_state) {
2711
+ switch(_state.label){
2712
+ case 0:
2663
2713
  return [
2664
2714
  4,
2665
- fetch("https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track", {
2715
+ fetch(url, {
2666
2716
  method: "POST",
2667
- headers: headers,
2668
- body: JSON.stringify(trackingData)
2717
+ headers: buildHeaders(licenseKey),
2718
+ body: JSON.stringify(body)
2669
2719
  })
2670
2720
  ];
2671
- case 2:
2721
+ case 1:
2672
2722
  response = _state.sent();
2673
2723
  if (!response.ok) {
2674
2724
  throw new Error("HTTP error! status: ".concat(response.status));
@@ -2677,35 +2727,63 @@ function sendInitialTracking(licenseKey) {
2677
2727
  4,
2678
2728
  response.json()
2679
2729
  ];
2680
- case 3:
2730
+ case 2:
2681
2731
  _state.sent();
2682
2732
  return [
2683
- 3,
2684
- 5
2733
+ 2
2685
2734
  ];
2686
- case 4:
2687
- error = _state.sent();
2688
- console.error("[StormcloudVideoPlayer] Error sending initial tracking data:", error);
2735
+ }
2736
+ });
2737
+ })();
2738
+ }
2739
+ function buildPlayerMetricEvent(_0) {
2740
+ return _async_to_generator(function(licenseKey) {
2741
+ var context, flags, _flags_captureAt, clientInfo, browserId, captureAt;
2742
+ var _arguments = arguments;
2743
+ return _ts_generator(this, function(_state) {
2744
+ switch(_state.label){
2745
+ case 0:
2746
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2747
+ clientInfo = getClientInfo();
2689
2748
  return [
2690
- 3,
2691
- 5
2749
+ 4,
2750
+ getBrowserID(clientInfo)
2692
2751
  ];
2693
- case 5:
2752
+ case 1:
2753
+ browserId = _state.sent();
2754
+ captureAt = (_flags_captureAt = flags.captureAt) !== null && _flags_captureAt !== void 0 ? _flags_captureAt : /* @__PURE__ */ new Date().toISOString();
2694
2755
  return [
2695
- 2
2756
+ 2,
2757
+ {
2758
+ player_id: browserId,
2759
+ browserId: browserId,
2760
+ device_type: clientInfo.deviceType,
2761
+ deviceType: clientInfo.deviceType,
2762
+ input_stream_type: context.inputStreamType,
2763
+ os: clientInfo.os,
2764
+ ad_loaded: flags.adLoaded,
2765
+ ad_detect: flags.adDetect,
2766
+ license_key: licenseKey,
2767
+ capture_at: captureAt,
2768
+ timestamp: captureAt
2769
+ }
2696
2770
  ];
2697
2771
  }
2698
2772
  });
2699
- })();
2773
+ }).apply(this, arguments);
2700
2774
  }
2701
- function sendHeartbeat(licenseKey) {
2702
- return _async_to_generator(function() {
2703
- var clientInfo, browserId, heartbeatData, headers, response, error;
2775
+ function sendInitialTracking(_0) {
2776
+ return _async_to_generator(function(licenseKey) {
2777
+ var context, clientInfo, browserId, trackingData, error;
2778
+ var _arguments = arguments;
2704
2779
  return _ts_generator(this, function(_state) {
2705
2780
  switch(_state.label){
2706
2781
  case 0:
2782
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
2783
+ _state.label = 1;
2784
+ case 1:
2707
2785
  _state.trys.push([
2708
- 0,
2786
+ 1,
2709
2787
  4,
2710
2788
  ,
2711
2789
  5
@@ -2715,35 +2793,29 @@ function sendHeartbeat(licenseKey) {
2715
2793
  4,
2716
2794
  getBrowserID(clientInfo)
2717
2795
  ];
2718
- case 1:
2796
+ case 2:
2719
2797
  browserId = _state.sent();
2720
- heartbeatData = {
2721
- browserId: browserId,
2722
- timestamp: /* @__PURE__ */ new Date().toISOString()
2723
- };
2724
- headers = {
2725
- "Content-Type": "application/json"
2726
- };
2727
- if (licenseKey) {
2728
- headers["Authorization"] = "Bearer ".concat(licenseKey);
2729
- }
2798
+ trackingData = _object_spread({
2799
+ browserId: browserId
2800
+ }, clientInfo);
2730
2801
  return [
2731
2802
  4,
2732
- fetch("https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat", {
2733
- method: "POST",
2734
- headers: headers,
2735
- body: JSON.stringify(heartbeatData)
2803
+ sendTrackRequest(licenseKey, {
2804
+ events: [
2805
+ {
2806
+ player_id: browserId,
2807
+ device_type: clientInfo.deviceType,
2808
+ input_stream_type: context.inputStreamType,
2809
+ os: clientInfo.os,
2810
+ ad_loaded: false,
2811
+ ad_detect: false,
2812
+ license_key: licenseKey,
2813
+ capture_at: /* @__PURE__ */ new Date().toISOString()
2814
+ }
2815
+ ],
2816
+ trackingData: trackingData
2736
2817
  })
2737
2818
  ];
2738
- case 2:
2739
- response = _state.sent();
2740
- if (!response.ok) {
2741
- throw new Error("HTTP error! status: ".concat(response.status));
2742
- }
2743
- return [
2744
- 4,
2745
- response.json()
2746
- ];
2747
2819
  case 3:
2748
2820
  _state.sent();
2749
2821
  return [
@@ -2752,7 +2824,7 @@ function sendHeartbeat(licenseKey) {
2752
2824
  ];
2753
2825
  case 4:
2754
2826
  error = _state.sent();
2755
- console.error("[StormcloudVideoPlayer] Error sending heartbeat:", error);
2827
+ console.error("[StormcloudVideoPlayer] Error sending initial tracking data:", error);
2756
2828
  return [
2757
2829
  3,
2758
2830
  5
@@ -2763,95 +2835,74 @@ function sendHeartbeat(licenseKey) {
2763
2835
  ];
2764
2836
  }
2765
2837
  });
2766
- })();
2767
- }
2768
- var TRACK_API_URL = "https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track";
2769
- function mapToAdTrackingSource(source, adPlayerType) {
2770
- if (source === "prebid" || source === "ima" || source === "hls") {
2771
- return source;
2772
- }
2773
- if (source === "preload" || source === "ssp") {
2774
- return source === "ssp" ? "prebid" : "ima";
2775
- }
2776
- return adPlayerType === "hls" ? "hls" : "ima";
2838
+ }).apply(this, arguments);
2777
2839
  }
2778
- function postAdTracking(licenseKey, body) {
2779
- return _async_to_generator(function() {
2780
- var headers, response;
2840
+ function sendAdDetectTracking(_0, _1) {
2841
+ return _async_to_generator(function(licenseKey, adDetectInfo) {
2842
+ var context, error;
2843
+ var _arguments = arguments;
2781
2844
  return _ts_generator(this, function(_state) {
2782
2845
  switch(_state.label){
2783
2846
  case 0:
2784
- headers = {
2785
- "Content-Type": "application/json"
2786
- };
2787
- if (licenseKey) {
2788
- headers["Authorization"] = "Bearer ".concat(licenseKey);
2789
- }
2790
- return [
2791
- 4,
2792
- fetch(TRACK_API_URL, {
2793
- method: "POST",
2794
- headers: headers,
2795
- body: JSON.stringify(body)
2796
- })
2797
- ];
2847
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2848
+ _state.label = 1;
2798
2849
  case 1:
2799
- response = _state.sent();
2800
- if (!response.ok) {
2801
- throw new Error("HTTP error! status: ".concat(response.status));
2802
- }
2850
+ _state.trys.push([
2851
+ 1,
2852
+ 3,
2853
+ ,
2854
+ 4
2855
+ ]);
2803
2856
  return [
2804
2857
  4,
2805
- response.json()
2858
+ sendHeartbeat(licenseKey, context, {
2859
+ adDetect: true,
2860
+ captureAt: adDetectInfo.timestamp
2861
+ })
2806
2862
  ];
2807
2863
  case 2:
2808
2864
  _state.sent();
2865
+ return [
2866
+ 3,
2867
+ 4
2868
+ ];
2869
+ case 3:
2870
+ error = _state.sent();
2871
+ console.error("[StormcloudVideoPlayer] Error sending ad detect tracking:", error);
2872
+ return [
2873
+ 3,
2874
+ 4
2875
+ ];
2876
+ case 4:
2809
2877
  return [
2810
2878
  2
2811
2879
  ];
2812
2880
  }
2813
2881
  });
2814
- })();
2882
+ }).apply(this, arguments);
2815
2883
  }
2816
- function sendAdDetectTracking(licenseKey, payload) {
2817
- return _async_to_generator(function() {
2818
- var _payload_source, _payload_timestamp, clientInfo, browserId, adDetectInfo, body, error;
2884
+ function sendAdLoadedTracking(_0, _1) {
2885
+ return _async_to_generator(function(licenseKey, adLoadedInfo) {
2886
+ var context, error;
2887
+ var _arguments = arguments;
2819
2888
  return _ts_generator(this, function(_state) {
2820
2889
  switch(_state.label){
2821
2890
  case 0:
2891
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2892
+ _state.label = 1;
2893
+ case 1:
2822
2894
  _state.trys.push([
2823
- 0,
2895
+ 1,
2824
2896
  3,
2825
2897
  ,
2826
2898
  4
2827
2899
  ]);
2828
- clientInfo = getClientInfo();
2829
- return [
2830
- 4,
2831
- getBrowserID(clientInfo)
2832
- ];
2833
- case 1:
2834
- browserId = _state.sent();
2835
- adDetectInfo = _object_spread({
2836
- source: (_payload_source = payload.source) !== null && _payload_source !== void 0 ? _payload_source : "scte35",
2837
- timestamp: (_payload_timestamp = payload.timestamp) !== null && _payload_timestamp !== void 0 ? _payload_timestamp : /* @__PURE__ */ new Date().toISOString()
2838
- }, payload.durationSeconds != null && {
2839
- durationSeconds: payload.durationSeconds
2840
- }, payload.ptsSeconds != null && {
2841
- ptsSeconds: payload.ptsSeconds
2842
- }, payload.detectedAtFragmentSn != null && {
2843
- detectedAtFragmentSn: payload.detectedAtFragmentSn
2844
- });
2845
- body = _object_spread_props(_object_spread({
2846
- browserId: browserId
2847
- }, clientInfo, licenseKey && {
2848
- licenseKey: licenseKey
2849
- }), {
2850
- adDetectInfo: adDetectInfo
2851
- });
2852
2900
  return [
2853
2901
  4,
2854
- postAdTracking(licenseKey, body)
2902
+ sendHeartbeat(licenseKey, context, {
2903
+ adLoaded: true,
2904
+ captureAt: adLoadedInfo.timestamp
2905
+ })
2855
2906
  ];
2856
2907
  case 2:
2857
2908
  _state.sent();
@@ -2861,7 +2912,7 @@ function sendAdDetectTracking(licenseKey, payload) {
2861
2912
  ];
2862
2913
  case 3:
2863
2914
  error = _state.sent();
2864
- console.error("[StormcloudVideoPlayer] Error sending ad-detect tracking:", error);
2915
+ console.error("[StormcloudVideoPlayer] Error sending ad loaded tracking:", error);
2865
2916
  return [
2866
2917
  3,
2867
2918
  4
@@ -2872,126 +2923,116 @@ function sendAdDetectTracking(licenseKey, payload) {
2872
2923
  ];
2873
2924
  }
2874
2925
  });
2875
- })();
2926
+ }).apply(this, arguments);
2876
2927
  }
2877
- function sendAdLoadedTracking(licenseKey, payload, adPlayerType) {
2878
- return _async_to_generator(function() {
2879
- var clientInfo, browserId, source, adLoadedInfo, body, error;
2928
+ function sendAdImpressionTracking(_0, _1) {
2929
+ return _async_to_generator(function(licenseKey, adImpressionInfo) {
2930
+ var context, metricEvent, error;
2931
+ var _arguments = arguments;
2880
2932
  return _ts_generator(this, function(_state) {
2881
2933
  switch(_state.label){
2882
2934
  case 0:
2935
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2936
+ _state.label = 1;
2937
+ case 1:
2883
2938
  _state.trys.push([
2884
- 0,
2885
- 3,
2939
+ 1,
2940
+ 4,
2886
2941
  ,
2887
- 4
2942
+ 5
2888
2943
  ]);
2889
- clientInfo = getClientInfo();
2890
2944
  return [
2891
2945
  4,
2892
- getBrowserID(clientInfo)
2946
+ buildPlayerMetricEvent(licenseKey, context, {
2947
+ captureAt: adImpressionInfo.timestamp
2948
+ })
2893
2949
  ];
2894
- case 1:
2895
- browserId = _state.sent();
2896
- source = mapToAdTrackingSource(payload.source, adPlayerType);
2897
- adLoadedInfo = _object_spread({
2898
- source: source,
2899
- timestamp: /* @__PURE__ */ new Date().toISOString()
2900
- }, payload.vastUrl != null && {
2901
- vastUrl: payload.vastUrl
2902
- }, payload.durationSeconds != null && {
2903
- durationSeconds: payload.durationSeconds
2904
- });
2905
- body = _object_spread_props(_object_spread({
2906
- browserId: browserId
2907
- }, clientInfo, licenseKey && {
2908
- licenseKey: licenseKey
2909
- }), {
2910
- adLoadedInfo: adLoadedInfo
2911
- });
2950
+ case 2:
2951
+ metricEvent = _state.sent();
2912
2952
  return [
2913
2953
  4,
2914
- postAdTracking(licenseKey, body)
2954
+ Promise.all([
2955
+ postJson(HEARTBEAT_URL, licenseKey, metricEvent),
2956
+ postJson(IMPRESSIONS_URL, licenseKey, {
2957
+ events: [
2958
+ {
2959
+ player_id: metricEvent.player_id,
2960
+ ad_played_count: 1,
2961
+ ad_url: adImpressionInfo.adUrl,
2962
+ license_key: licenseKey,
2963
+ capture_at: adImpressionInfo.timestamp
2964
+ }
2965
+ ]
2966
+ })
2967
+ ])
2915
2968
  ];
2916
- case 2:
2969
+ case 3:
2917
2970
  _state.sent();
2918
2971
  return [
2919
2972
  3,
2920
- 4
2973
+ 5
2921
2974
  ];
2922
- case 3:
2975
+ case 4:
2923
2976
  error = _state.sent();
2924
- console.error("[StormcloudVideoPlayer] Error sending ad-loaded tracking:", error);
2977
+ console.error("[StormcloudVideoPlayer] Error sending ad impression tracking:", error);
2925
2978
  return [
2926
2979
  3,
2927
- 4
2980
+ 5
2928
2981
  ];
2929
- case 4:
2982
+ case 5:
2930
2983
  return [
2931
2984
  2
2932
2985
  ];
2933
2986
  }
2934
2987
  });
2935
- })();
2988
+ }).apply(this, arguments);
2936
2989
  }
2937
- function sendAdImpressionTracking(licenseKey, payload, adPlayerType) {
2938
- return _async_to_generator(function() {
2939
- var clientInfo, browserId, source, adImpressionInfo, body, error;
2990
+ function sendHeartbeat(_0) {
2991
+ return _async_to_generator(function(licenseKey) {
2992
+ var context, flags, heartbeatData, error;
2993
+ var _arguments = arguments;
2940
2994
  return _ts_generator(this, function(_state) {
2941
2995
  switch(_state.label){
2942
2996
  case 0:
2997
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2998
+ _state.label = 1;
2999
+ case 1:
2943
3000
  _state.trys.push([
2944
- 0,
2945
- 3,
3001
+ 1,
3002
+ 4,
2946
3003
  ,
2947
- 4
3004
+ 5
2948
3005
  ]);
2949
- clientInfo = getClientInfo();
2950
3006
  return [
2951
3007
  4,
2952
- getBrowserID(clientInfo)
3008
+ buildPlayerMetricEvent(licenseKey, context, flags)
2953
3009
  ];
2954
- case 1:
2955
- browserId = _state.sent();
2956
- source = mapToAdTrackingSource(payload.source, adPlayerType);
2957
- adImpressionInfo = _object_spread({
2958
- source: source,
2959
- adIndex: payload.adIndex,
2960
- timestamp: /* @__PURE__ */ new Date().toISOString()
2961
- }, payload.durationSeconds != null && {
2962
- durationSeconds: payload.durationSeconds
2963
- });
2964
- body = _object_spread_props(_object_spread({
2965
- browserId: browserId
2966
- }, clientInfo, licenseKey && {
2967
- licenseKey: licenseKey
2968
- }), {
2969
- adImpressionInfo: adImpressionInfo
2970
- });
3010
+ case 2:
3011
+ heartbeatData = _state.sent();
2971
3012
  return [
2972
3013
  4,
2973
- postAdTracking(licenseKey, body)
3014
+ postJson(HEARTBEAT_URL, licenseKey, heartbeatData)
2974
3015
  ];
2975
- case 2:
3016
+ case 3:
2976
3017
  _state.sent();
2977
3018
  return [
2978
3019
  3,
2979
- 4
3020
+ 5
2980
3021
  ];
2981
- case 3:
3022
+ case 4:
2982
3023
  error = _state.sent();
2983
- console.error("[StormcloudVideoPlayer] Error sending ad-impression tracking:", error);
3024
+ console.error("[StormcloudVideoPlayer] Error sending heartbeat:", error);
2984
3025
  return [
2985
3026
  3,
2986
- 4
3027
+ 5
2987
3028
  ];
2988
- case 4:
3029
+ case 5:
2989
3030
  return [
2990
3031
  2
2991
3032
  ];
2992
3033
  }
2993
3034
  });
2994
- })();
3035
+ }).apply(this, arguments);
2995
3036
  }
2996
3037
  // src/utils/polyfills.ts
2997
3038
  function polyfillURLSearchParams() {
@@ -3787,8 +3828,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3787
3828
  var _this = this;
3788
3829
  this.ima.on("all_ads_completed", function() {
3789
3830
  sendAdImpressionTracking(_this.config.licenseKey, {
3790
- adIndex: _this.currentAdIndex
3791
- }, _this.config.adPlayerType).catch(function() {});
3831
+ source: "ima",
3832
+ adIndex: _this.currentAdIndex,
3833
+ timestamp: /* @__PURE__ */ new Date().toISOString()
3834
+ }).catch(function() {});
3792
3835
  var remaining = _this.getRemainingAdMs();
3793
3836
  _this.consecutiveFailures = 0;
3794
3837
  if (_this.config.debugAdTiming) {
@@ -3849,8 +3892,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3849
3892
  });
3850
3893
  this.ima.on("content_resume", function() {
3851
3894
  sendAdImpressionTracking(_this.config.licenseKey, {
3852
- adIndex: _this.currentAdIndex
3853
- }, _this.config.adPlayerType).catch(function() {});
3895
+ source: "ima",
3896
+ adIndex: _this.currentAdIndex,
3897
+ timestamp: /* @__PURE__ */ new Date().toISOString()
3898
+ }).catch(function() {});
3854
3899
  if (!_this.video.muted) {
3855
3900
  _this.video.muted = true;
3856
3901
  _this.video.volume = 0;
@@ -4484,7 +4529,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4484
4529
  var detectPayload = {};
4485
4530
  if (marker.durationSeconds != null) detectPayload.durationSeconds = marker.durationSeconds;
4486
4531
  if (marker.ptsSeconds != null) detectPayload.ptsSeconds = marker.ptsSeconds;
4487
- sendAdDetectTracking(this.config.licenseKey, detectPayload).catch(function() {});
4532
+ sendAdDetectTracking(this.config.licenseKey, _object_spread({
4533
+ source: "scte35",
4534
+ timestamp: /* @__PURE__ */ new Date().toISOString()
4535
+ }, detectPayload)).catch(function() {});
4488
4536
  }
4489
4537
  var hasPrefetchedAds = this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0;
4490
4538
  var durationMs = marker.durationSeconds != null ? marker.durationSeconds * 1e3 : ((_this_pendingAdBreak = this.pendingAdBreak) === null || _this_pendingAdBreak === void 0 ? void 0 : _this_pendingAdBreak.marker.durationSeconds) != null ? this.pendingAdBreak.marker.durationSeconds * 1e3 : void 0;
@@ -5726,7 +5774,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5726
5774
  if (marker.durationSeconds != null) detectPayload.durationSeconds = marker.durationSeconds;
5727
5775
  if (marker.ptsSeconds != null) detectPayload.ptsSeconds = marker.ptsSeconds;
5728
5776
  if (fragmentSn !== void 0) detectPayload.detectedAtFragmentSn = fragmentSn;
5729
- sendAdDetectTracking(this.config.licenseKey, detectPayload).catch(function() {});
5777
+ sendAdDetectTracking(this.config.licenseKey, _object_spread({
5778
+ source: "scte35",
5779
+ timestamp: /* @__PURE__ */ new Date().toISOString()
5780
+ }, detectPayload)).catch(function() {});
5730
5781
  if (this.config.debugAdTiming) {
5731
5782
  console.log("[PREFETCH] \uD83D\uDD04 Starting ad prefetch for upcoming ad break");
5732
5783
  console.log("[PREFETCH] \uD83D\uDCCB Pre-generated ".concat(generatedUrls.length, " VAST URLs"));
@@ -6207,9 +6258,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6207
6258
  preloadedController = preloaded.imaController;
6208
6259
  usePreloadedAd = true;
6209
6260
  sendAdLoadedTracking(this.config.licenseKey, {
6210
- source: "preload",
6211
- vastUrl: firstAdUrl
6212
- }, this.config.adPlayerType).catch(function() {});
6261
+ source: "ima",
6262
+ vastUrl: firstAdUrl,
6263
+ timestamp: /* @__PURE__ */ new Date().toISOString()
6264
+ }).catch(function() {});
6213
6265
  if (this.config.debugAdTiming) {
6214
6266
  console.log("[CONTINUOUS-FETCH] \uD83D\uDE80 Using preloaded ad from pool (preloaded in advance, ready immediately!)");
6215
6267
  console.log("[CONTINUOUS-FETCH] Pool still has ".concat(this.preloadPool.length, " preloaded ads ready"));
@@ -6299,9 +6351,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6299
6351
  case 5:
6300
6352
  _state.sent();
6301
6353
  sendAdLoadedTracking(this.config.licenseKey, {
6302
- source: "ssp",
6303
- vastUrl: firstAdUrl
6304
- }, this.config.adPlayerType).catch(function() {});
6354
+ source: "ima",
6355
+ vastUrl: firstAdUrl,
6356
+ timestamp: /* @__PURE__ */ new Date().toISOString()
6357
+ }).catch(function() {});
6305
6358
  if (this.config.debugAdTiming) {
6306
6359
  console.log("[CONTINUOUS-FETCH] \u2705 First ad request successful, starting playback");
6307
6360
  }
@@ -6697,9 +6750,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6697
6750
  console.log("[CONTINUOUS-FETCH] \uD83C\uDFAF Using preloaded ad from pool (".concat(this.preloadPool.length, " remaining in pool)"));
6698
6751
  }
6699
6752
  sendAdLoadedTracking(this.config.licenseKey, {
6700
- source: "preload",
6701
- vastUrl: preloaded.vastUrl
6702
- }, this.config.adPlayerType).catch(function() {});
6753
+ source: "ima",
6754
+ vastUrl: preloaded.vastUrl,
6755
+ timestamp: /* @__PURE__ */ new Date().toISOString()
6756
+ }).catch(function() {});
6703
6757
  _state.label = 1;
6704
6758
  case 1:
6705
6759
  _state.trys.push([
@@ -7451,9 +7505,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7451
7505
  case 3:
7452
7506
  _state.sent();
7453
7507
  sendAdLoadedTracking(this.config.licenseKey, {
7454
- source: "ssp",
7455
- vastUrl: vastTagUrl
7456
- }, this.config.adPlayerType).catch(function() {});
7508
+ source: "ima",
7509
+ vastUrl: vastTagUrl,
7510
+ timestamp: /* @__PURE__ */ new Date().toISOString()
7511
+ }).catch(function() {});
7457
7512
  this.clearAdRequestWatchdog();
7458
7513
  if (this.activeAdRequestToken !== requestToken) {
7459
7514
  return [