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.
@@ -1747,6 +1747,16 @@ function createHlsAdPlayer(contentVideo, options) {
1747
1747
  });
1748
1748
  return bestMatch.file;
1749
1749
  }
1750
+ function isHlsMediaFile(mediaFile) {
1751
+ var type = mediaFile.type.toLowerCase();
1752
+ var url = mediaFile.url.toLowerCase();
1753
+ return type === "application/x-mpegurl" || type === "application/vnd.apple.mpegurl" || type.includes("mpegurl") || url.includes(".m3u8");
1754
+ }
1755
+ function isProgressiveMediaFile(mediaFile) {
1756
+ var type = mediaFile.type.toLowerCase();
1757
+ var url = mediaFile.url.toLowerCase();
1758
+ return type.startsWith("video/") || url.endsWith(".mp4") || url.includes(".mp4?");
1759
+ }
1750
1760
  function parseVastXml(xmlString) {
1751
1761
  try {
1752
1762
  var _xmlDoc_querySelector, _xmlDoc_querySelector1, _xmlDoc_querySelector_textContent, _xmlDoc_querySelector2;
@@ -1778,30 +1788,32 @@ function createHlsAdPlayer(contentVideo, options) {
1778
1788
  var width = mf.getAttribute("width") || "";
1779
1789
  var height = mf.getAttribute("height") || "";
1780
1790
  console.log("[HlsAdPlayer] MediaFile ".concat(index, ': type="').concat(type, '", url="').concat(url, '", width="').concat(width, '", height="').concat(height, '"'));
1781
- if (type === "application/x-mpegURL" || type.includes("m3u8")) {
1782
- if (!url) {
1783
- console.warn("[HlsAdPlayer] MediaFile ".concat(index, " has HLS type but empty URL"));
1784
- return;
1785
- }
1786
- var bitrateAttr = mf.getAttribute("bitrate");
1787
- var bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;
1788
- mediaFiles.push({
1789
- url: url,
1790
- type: type,
1791
- width: parseInt(width || "1920", 10),
1792
- height: parseInt(height || "1080", 10),
1793
- bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : void 0
1794
- });
1795
- console.log("[HlsAdPlayer] Added HLS MediaFile: ".concat(url));
1791
+ var mediaFile = {
1792
+ url: url,
1793
+ type: type,
1794
+ width: parseInt(width || "1920", 10),
1795
+ height: parseInt(height || "1080", 10),
1796
+ bitrate: void 0
1797
+ };
1798
+ if (!url) {
1799
+ console.warn("[HlsAdPlayer] MediaFile ".concat(index, " has empty URL"));
1800
+ return;
1801
+ }
1802
+ var bitrateAttr = mf.getAttribute("bitrate");
1803
+ var bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;
1804
+ mediaFile.bitrate = bitrateValue && bitrateValue > 0 ? bitrateValue : void 0;
1805
+ if (isHlsMediaFile(mediaFile) || isProgressiveMediaFile(mediaFile)) {
1806
+ mediaFiles.push(mediaFile);
1807
+ console.log("[HlsAdPlayer] Added ".concat(isHlsMediaFile(mediaFile) ? "HLS" : "progressive", " MediaFile: ").concat(url));
1796
1808
  } else {
1797
- console.log("[HlsAdPlayer] MediaFile ".concat(index, ' ignored (type="').concat(type, '" is not HLS)'));
1809
+ console.log("[HlsAdPlayer] MediaFile ".concat(index, ' ignored (type="').concat(type, '" is not supported)'));
1798
1810
  }
1799
1811
  });
1800
1812
  if (mediaFiles.length === 0) {
1801
1813
  if (isNoAdAvailable) {
1802
1814
  console.warn("[HlsAdPlayer] No ads available (VAST response indicates no ads)");
1803
1815
  } else {
1804
- console.warn("[HlsAdPlayer] No HLS media files found in VAST XML");
1816
+ console.warn("[HlsAdPlayer] No supported media files found in VAST XML");
1805
1817
  }
1806
1818
  return null;
1807
1819
  }
@@ -2098,7 +2110,7 @@ function createHlsAdPlayer(contentVideo, options) {
2098
2110
  },
2099
2111
  play: function play() {
2100
2112
  return _async_to_generator(function() {
2101
- var contentVolume, adVolume, mediaFile;
2113
+ var contentVolume, adVolume, mediaFile, isHlsAd;
2102
2114
  return _ts_generator(this, function(_state) {
2103
2115
  if (!currentAd) {
2104
2116
  console.warn("[HlsAdPlayer] Cannot play: No ad loaded (no ads available)");
@@ -2150,8 +2162,9 @@ function createHlsAdPlayer(contentVideo, options) {
2150
2162
  if (!mediaFile) {
2151
2163
  throw new Error("No media file available for ad");
2152
2164
  }
2153
- console.log("[HlsAdPlayer] Loading ad from: ".concat(mediaFile.url));
2154
- if (import_hls.default.isSupported()) {
2165
+ isHlsAd = isHlsMediaFile(mediaFile);
2166
+ console.log("[HlsAdPlayer] Loading ".concat(isHlsAd ? "HLS" : "progressive", " ad from: ").concat(mediaFile.url));
2167
+ if (isHlsAd && import_hls.default.isSupported()) {
2155
2168
  if (adHls) {
2156
2169
  adHls.destroy();
2157
2170
  }
@@ -2174,14 +2187,25 @@ function createHlsAdPlayer(contentVideo, options) {
2174
2187
  handleAdError();
2175
2188
  }
2176
2189
  });
2177
- } else if (adVideoElement.canPlayType("application/vnd.apple.mpegurl")) {
2190
+ } else if (isHlsAd && adVideoElement.canPlayType("application/vnd.apple.mpegurl")) {
2178
2191
  adVideoElement.src = mediaFile.url;
2179
2192
  adVideoElement.play().catch(function(error) {
2180
2193
  console.error("[HlsAdPlayer] Error starting ad playback:", error);
2181
2194
  handleAdError();
2182
2195
  });
2196
+ } else if (!isHlsAd && isProgressiveMediaFile(mediaFile)) {
2197
+ if (adHls) {
2198
+ adHls.destroy();
2199
+ adHls = void 0;
2200
+ }
2201
+ adVideoElement.src = mediaFile.url;
2202
+ adVideoElement.load();
2203
+ adVideoElement.play().catch(function(error) {
2204
+ console.error("[HlsAdPlayer] Error starting progressive ad playback:", error);
2205
+ handleAdError();
2206
+ });
2183
2207
  } else {
2184
- throw new Error("HLS not supported");
2208
+ throw new Error("Unsupported ad media file type: ".concat(mediaFile.type));
2185
2209
  }
2186
2210
  return [
2187
2211
  2,
@@ -2622,40 +2646,66 @@ function getBrowserID(clientInfo) {
2622
2646
  });
2623
2647
  })();
2624
2648
  }
2625
- function sendInitialTracking(licenseKey) {
2649
+ var PLAYER_TRACKING_BASE_URL = "https://adstorm.co/api-adstorm-dev/adstorm/player-tracking";
2650
+ var TRACK_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/metrics/ingest");
2651
+ var HEARTBEAT_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/heartbeat");
2652
+ var IMPRESSIONS_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/impressions/ingest");
2653
+ function buildHeaders(licenseKey) {
2654
+ var headers = {
2655
+ "Content-Type": "application/json"
2656
+ };
2657
+ if (licenseKey) {
2658
+ headers["Authorization"] = "Bearer ".concat(licenseKey);
2659
+ }
2660
+ return headers;
2661
+ }
2662
+ function sendTrackRequest(licenseKey, body) {
2626
2663
  return _async_to_generator(function() {
2627
- var clientInfo, browserId, trackingData, headers, response, error;
2664
+ var response;
2628
2665
  return _ts_generator(this, function(_state) {
2629
2666
  switch(_state.label){
2630
2667
  case 0:
2631
- _state.trys.push([
2632
- 0,
2633
- 4,
2634
- ,
2635
- 5
2636
- ]);
2637
- clientInfo = getClientInfo();
2638
2668
  return [
2639
2669
  4,
2640
- getBrowserID(clientInfo)
2670
+ fetch(TRACK_URL, {
2671
+ method: "POST",
2672
+ headers: buildHeaders(licenseKey),
2673
+ body: JSON.stringify(body)
2674
+ })
2641
2675
  ];
2642
2676
  case 1:
2643
- browserId = _state.sent();
2644
- trackingData = _object_spread({
2645
- browserId: browserId
2646
- }, clientInfo);
2647
- headers = {
2648
- "Content-Type": "application/json"
2649
- };
2677
+ response = _state.sent();
2678
+ if (!response.ok) {
2679
+ throw new Error("HTTP error! status: ".concat(response.status));
2680
+ }
2681
+ return [
2682
+ 4,
2683
+ response.json()
2684
+ ];
2685
+ case 2:
2686
+ _state.sent();
2687
+ return [
2688
+ 2
2689
+ ];
2690
+ }
2691
+ });
2692
+ })();
2693
+ }
2694
+ function postJson(url, licenseKey, body) {
2695
+ return _async_to_generator(function() {
2696
+ var response;
2697
+ return _ts_generator(this, function(_state) {
2698
+ switch(_state.label){
2699
+ case 0:
2650
2700
  return [
2651
2701
  4,
2652
- fetch("https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track", {
2702
+ fetch(url, {
2653
2703
  method: "POST",
2654
- headers: headers,
2655
- body: JSON.stringify(trackingData)
2704
+ headers: buildHeaders(licenseKey),
2705
+ body: JSON.stringify(body)
2656
2706
  })
2657
2707
  ];
2658
- case 2:
2708
+ case 1:
2659
2709
  response = _state.sent();
2660
2710
  if (!response.ok) {
2661
2711
  throw new Error("HTTP error! status: ".concat(response.status));
@@ -2664,35 +2714,63 @@ function sendInitialTracking(licenseKey) {
2664
2714
  4,
2665
2715
  response.json()
2666
2716
  ];
2667
- case 3:
2717
+ case 2:
2668
2718
  _state.sent();
2669
2719
  return [
2670
- 3,
2671
- 5
2720
+ 2
2672
2721
  ];
2673
- case 4:
2674
- error = _state.sent();
2675
- console.error("[StormcloudVideoPlayer] Error sending initial tracking data:", error);
2722
+ }
2723
+ });
2724
+ })();
2725
+ }
2726
+ function buildPlayerMetricEvent(_0) {
2727
+ return _async_to_generator(function(licenseKey) {
2728
+ var context, flags, _flags_captureAt, clientInfo, browserId, captureAt;
2729
+ var _arguments = arguments;
2730
+ return _ts_generator(this, function(_state) {
2731
+ switch(_state.label){
2732
+ case 0:
2733
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2734
+ clientInfo = getClientInfo();
2676
2735
  return [
2677
- 3,
2678
- 5
2736
+ 4,
2737
+ getBrowserID(clientInfo)
2679
2738
  ];
2680
- case 5:
2739
+ case 1:
2740
+ browserId = _state.sent();
2741
+ captureAt = (_flags_captureAt = flags.captureAt) !== null && _flags_captureAt !== void 0 ? _flags_captureAt : /* @__PURE__ */ new Date().toISOString();
2681
2742
  return [
2682
- 2
2743
+ 2,
2744
+ {
2745
+ player_id: browserId,
2746
+ browserId: browserId,
2747
+ device_type: clientInfo.deviceType,
2748
+ deviceType: clientInfo.deviceType,
2749
+ input_stream_type: context.inputStreamType,
2750
+ os: clientInfo.os,
2751
+ ad_loaded: flags.adLoaded,
2752
+ ad_detect: flags.adDetect,
2753
+ license_key: licenseKey,
2754
+ capture_at: captureAt,
2755
+ timestamp: captureAt
2756
+ }
2683
2757
  ];
2684
2758
  }
2685
2759
  });
2686
- })();
2760
+ }).apply(this, arguments);
2687
2761
  }
2688
- function sendHeartbeat(licenseKey) {
2689
- return _async_to_generator(function() {
2690
- var clientInfo, browserId, heartbeatData, headers, response, error;
2762
+ function sendInitialTracking(_0) {
2763
+ return _async_to_generator(function(licenseKey) {
2764
+ var context, clientInfo, browserId, trackingData, error;
2765
+ var _arguments = arguments;
2691
2766
  return _ts_generator(this, function(_state) {
2692
2767
  switch(_state.label){
2693
2768
  case 0:
2769
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
2770
+ _state.label = 1;
2771
+ case 1:
2694
2772
  _state.trys.push([
2695
- 0,
2773
+ 1,
2696
2774
  4,
2697
2775
  ,
2698
2776
  5
@@ -2702,35 +2780,29 @@ function sendHeartbeat(licenseKey) {
2702
2780
  4,
2703
2781
  getBrowserID(clientInfo)
2704
2782
  ];
2705
- case 1:
2783
+ case 2:
2706
2784
  browserId = _state.sent();
2707
- heartbeatData = {
2708
- browserId: browserId,
2709
- timestamp: /* @__PURE__ */ new Date().toISOString()
2710
- };
2711
- headers = {
2712
- "Content-Type": "application/json"
2713
- };
2714
- if (licenseKey) {
2715
- headers["Authorization"] = "Bearer ".concat(licenseKey);
2716
- }
2785
+ trackingData = _object_spread({
2786
+ browserId: browserId
2787
+ }, clientInfo);
2717
2788
  return [
2718
2789
  4,
2719
- fetch("https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat", {
2720
- method: "POST",
2721
- headers: headers,
2722
- body: JSON.stringify(heartbeatData)
2790
+ sendTrackRequest(licenseKey, {
2791
+ events: [
2792
+ {
2793
+ player_id: browserId,
2794
+ device_type: clientInfo.deviceType,
2795
+ input_stream_type: context.inputStreamType,
2796
+ os: clientInfo.os,
2797
+ ad_loaded: false,
2798
+ ad_detect: false,
2799
+ license_key: licenseKey,
2800
+ capture_at: /* @__PURE__ */ new Date().toISOString()
2801
+ }
2802
+ ],
2803
+ trackingData: trackingData
2723
2804
  })
2724
2805
  ];
2725
- case 2:
2726
- response = _state.sent();
2727
- if (!response.ok) {
2728
- throw new Error("HTTP error! status: ".concat(response.status));
2729
- }
2730
- return [
2731
- 4,
2732
- response.json()
2733
- ];
2734
2806
  case 3:
2735
2807
  _state.sent();
2736
2808
  return [
@@ -2739,7 +2811,7 @@ function sendHeartbeat(licenseKey) {
2739
2811
  ];
2740
2812
  case 4:
2741
2813
  error = _state.sent();
2742
- console.error("[StormcloudVideoPlayer] Error sending heartbeat:", error);
2814
+ console.error("[StormcloudVideoPlayer] Error sending initial tracking data:", error);
2743
2815
  return [
2744
2816
  3,
2745
2817
  5
@@ -2750,95 +2822,74 @@ function sendHeartbeat(licenseKey) {
2750
2822
  ];
2751
2823
  }
2752
2824
  });
2753
- })();
2754
- }
2755
- var TRACK_API_URL = "https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track";
2756
- function mapToAdTrackingSource(source, adPlayerType) {
2757
- if (source === "prebid" || source === "ima" || source === "hls") {
2758
- return source;
2759
- }
2760
- if (source === "preload" || source === "ssp") {
2761
- return source === "ssp" ? "prebid" : "ima";
2762
- }
2763
- return adPlayerType === "hls" ? "hls" : "ima";
2825
+ }).apply(this, arguments);
2764
2826
  }
2765
- function postAdTracking(licenseKey, body) {
2766
- return _async_to_generator(function() {
2767
- var headers, response;
2827
+ function sendAdDetectTracking(_0, _1) {
2828
+ return _async_to_generator(function(licenseKey, adDetectInfo) {
2829
+ var context, error;
2830
+ var _arguments = arguments;
2768
2831
  return _ts_generator(this, function(_state) {
2769
2832
  switch(_state.label){
2770
2833
  case 0:
2771
- headers = {
2772
- "Content-Type": "application/json"
2773
- };
2774
- if (licenseKey) {
2775
- headers["Authorization"] = "Bearer ".concat(licenseKey);
2776
- }
2777
- return [
2778
- 4,
2779
- fetch(TRACK_API_URL, {
2780
- method: "POST",
2781
- headers: headers,
2782
- body: JSON.stringify(body)
2783
- })
2784
- ];
2834
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2835
+ _state.label = 1;
2785
2836
  case 1:
2786
- response = _state.sent();
2787
- if (!response.ok) {
2788
- throw new Error("HTTP error! status: ".concat(response.status));
2789
- }
2837
+ _state.trys.push([
2838
+ 1,
2839
+ 3,
2840
+ ,
2841
+ 4
2842
+ ]);
2790
2843
  return [
2791
2844
  4,
2792
- response.json()
2845
+ sendHeartbeat(licenseKey, context, {
2846
+ adDetect: true,
2847
+ captureAt: adDetectInfo.timestamp
2848
+ })
2793
2849
  ];
2794
2850
  case 2:
2795
2851
  _state.sent();
2852
+ return [
2853
+ 3,
2854
+ 4
2855
+ ];
2856
+ case 3:
2857
+ error = _state.sent();
2858
+ console.error("[StormcloudVideoPlayer] Error sending ad detect tracking:", error);
2859
+ return [
2860
+ 3,
2861
+ 4
2862
+ ];
2863
+ case 4:
2796
2864
  return [
2797
2865
  2
2798
2866
  ];
2799
2867
  }
2800
2868
  });
2801
- })();
2869
+ }).apply(this, arguments);
2802
2870
  }
2803
- function sendAdDetectTracking(licenseKey, payload) {
2804
- return _async_to_generator(function() {
2805
- var _payload_source, _payload_timestamp, clientInfo, browserId, adDetectInfo, body, error;
2871
+ function sendAdLoadedTracking(_0, _1) {
2872
+ return _async_to_generator(function(licenseKey, adLoadedInfo) {
2873
+ var context, error;
2874
+ var _arguments = arguments;
2806
2875
  return _ts_generator(this, function(_state) {
2807
2876
  switch(_state.label){
2808
2877
  case 0:
2878
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2879
+ _state.label = 1;
2880
+ case 1:
2809
2881
  _state.trys.push([
2810
- 0,
2882
+ 1,
2811
2883
  3,
2812
2884
  ,
2813
2885
  4
2814
2886
  ]);
2815
- clientInfo = getClientInfo();
2816
- return [
2817
- 4,
2818
- getBrowserID(clientInfo)
2819
- ];
2820
- case 1:
2821
- browserId = _state.sent();
2822
- adDetectInfo = _object_spread({
2823
- source: (_payload_source = payload.source) !== null && _payload_source !== void 0 ? _payload_source : "scte35",
2824
- timestamp: (_payload_timestamp = payload.timestamp) !== null && _payload_timestamp !== void 0 ? _payload_timestamp : /* @__PURE__ */ new Date().toISOString()
2825
- }, payload.durationSeconds != null && {
2826
- durationSeconds: payload.durationSeconds
2827
- }, payload.ptsSeconds != null && {
2828
- ptsSeconds: payload.ptsSeconds
2829
- }, payload.detectedAtFragmentSn != null && {
2830
- detectedAtFragmentSn: payload.detectedAtFragmentSn
2831
- });
2832
- body = _object_spread_props(_object_spread({
2833
- browserId: browserId
2834
- }, clientInfo, licenseKey && {
2835
- licenseKey: licenseKey
2836
- }), {
2837
- adDetectInfo: adDetectInfo
2838
- });
2839
2887
  return [
2840
2888
  4,
2841
- postAdTracking(licenseKey, body)
2889
+ sendHeartbeat(licenseKey, context, {
2890
+ adLoaded: true,
2891
+ captureAt: adLoadedInfo.timestamp
2892
+ })
2842
2893
  ];
2843
2894
  case 2:
2844
2895
  _state.sent();
@@ -2848,7 +2899,7 @@ function sendAdDetectTracking(licenseKey, payload) {
2848
2899
  ];
2849
2900
  case 3:
2850
2901
  error = _state.sent();
2851
- console.error("[StormcloudVideoPlayer] Error sending ad-detect tracking:", error);
2902
+ console.error("[StormcloudVideoPlayer] Error sending ad loaded tracking:", error);
2852
2903
  return [
2853
2904
  3,
2854
2905
  4
@@ -2859,126 +2910,116 @@ function sendAdDetectTracking(licenseKey, payload) {
2859
2910
  ];
2860
2911
  }
2861
2912
  });
2862
- })();
2913
+ }).apply(this, arguments);
2863
2914
  }
2864
- function sendAdLoadedTracking(licenseKey, payload, adPlayerType) {
2865
- return _async_to_generator(function() {
2866
- var clientInfo, browserId, source, adLoadedInfo, body, error;
2915
+ function sendAdImpressionTracking(_0, _1) {
2916
+ return _async_to_generator(function(licenseKey, adImpressionInfo) {
2917
+ var context, metricEvent, error;
2918
+ var _arguments = arguments;
2867
2919
  return _ts_generator(this, function(_state) {
2868
2920
  switch(_state.label){
2869
2921
  case 0:
2922
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2923
+ _state.label = 1;
2924
+ case 1:
2870
2925
  _state.trys.push([
2871
- 0,
2872
- 3,
2926
+ 1,
2927
+ 4,
2873
2928
  ,
2874
- 4
2929
+ 5
2875
2930
  ]);
2876
- clientInfo = getClientInfo();
2877
2931
  return [
2878
2932
  4,
2879
- getBrowserID(clientInfo)
2933
+ buildPlayerMetricEvent(licenseKey, context, {
2934
+ captureAt: adImpressionInfo.timestamp
2935
+ })
2880
2936
  ];
2881
- case 1:
2882
- browserId = _state.sent();
2883
- source = mapToAdTrackingSource(payload.source, adPlayerType);
2884
- adLoadedInfo = _object_spread({
2885
- source: source,
2886
- timestamp: /* @__PURE__ */ new Date().toISOString()
2887
- }, payload.vastUrl != null && {
2888
- vastUrl: payload.vastUrl
2889
- }, payload.durationSeconds != null && {
2890
- durationSeconds: payload.durationSeconds
2891
- });
2892
- body = _object_spread_props(_object_spread({
2893
- browserId: browserId
2894
- }, clientInfo, licenseKey && {
2895
- licenseKey: licenseKey
2896
- }), {
2897
- adLoadedInfo: adLoadedInfo
2898
- });
2937
+ case 2:
2938
+ metricEvent = _state.sent();
2899
2939
  return [
2900
2940
  4,
2901
- postAdTracking(licenseKey, body)
2941
+ Promise.all([
2942
+ postJson(HEARTBEAT_URL, licenseKey, metricEvent),
2943
+ postJson(IMPRESSIONS_URL, licenseKey, {
2944
+ events: [
2945
+ {
2946
+ player_id: metricEvent.player_id,
2947
+ ad_played_count: 1,
2948
+ ad_url: adImpressionInfo.adUrl,
2949
+ license_key: licenseKey,
2950
+ capture_at: adImpressionInfo.timestamp
2951
+ }
2952
+ ]
2953
+ })
2954
+ ])
2902
2955
  ];
2903
- case 2:
2956
+ case 3:
2904
2957
  _state.sent();
2905
2958
  return [
2906
2959
  3,
2907
- 4
2960
+ 5
2908
2961
  ];
2909
- case 3:
2962
+ case 4:
2910
2963
  error = _state.sent();
2911
- console.error("[StormcloudVideoPlayer] Error sending ad-loaded tracking:", error);
2964
+ console.error("[StormcloudVideoPlayer] Error sending ad impression tracking:", error);
2912
2965
  return [
2913
2966
  3,
2914
- 4
2967
+ 5
2915
2968
  ];
2916
- case 4:
2969
+ case 5:
2917
2970
  return [
2918
2971
  2
2919
2972
  ];
2920
2973
  }
2921
2974
  });
2922
- })();
2975
+ }).apply(this, arguments);
2923
2976
  }
2924
- function sendAdImpressionTracking(licenseKey, payload, adPlayerType) {
2925
- return _async_to_generator(function() {
2926
- var clientInfo, browserId, source, adImpressionInfo, body, error;
2977
+ function sendHeartbeat(_0) {
2978
+ return _async_to_generator(function(licenseKey) {
2979
+ var context, flags, heartbeatData, error;
2980
+ var _arguments = arguments;
2927
2981
  return _ts_generator(this, function(_state) {
2928
2982
  switch(_state.label){
2929
2983
  case 0:
2984
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2985
+ _state.label = 1;
2986
+ case 1:
2930
2987
  _state.trys.push([
2931
- 0,
2932
- 3,
2988
+ 1,
2989
+ 4,
2933
2990
  ,
2934
- 4
2991
+ 5
2935
2992
  ]);
2936
- clientInfo = getClientInfo();
2937
2993
  return [
2938
2994
  4,
2939
- getBrowserID(clientInfo)
2995
+ buildPlayerMetricEvent(licenseKey, context, flags)
2940
2996
  ];
2941
- case 1:
2942
- browserId = _state.sent();
2943
- source = mapToAdTrackingSource(payload.source, adPlayerType);
2944
- adImpressionInfo = _object_spread({
2945
- source: source,
2946
- adIndex: payload.adIndex,
2947
- timestamp: /* @__PURE__ */ new Date().toISOString()
2948
- }, payload.durationSeconds != null && {
2949
- durationSeconds: payload.durationSeconds
2950
- });
2951
- body = _object_spread_props(_object_spread({
2952
- browserId: browserId
2953
- }, clientInfo, licenseKey && {
2954
- licenseKey: licenseKey
2955
- }), {
2956
- adImpressionInfo: adImpressionInfo
2957
- });
2997
+ case 2:
2998
+ heartbeatData = _state.sent();
2958
2999
  return [
2959
3000
  4,
2960
- postAdTracking(licenseKey, body)
3001
+ postJson(HEARTBEAT_URL, licenseKey, heartbeatData)
2961
3002
  ];
2962
- case 2:
3003
+ case 3:
2963
3004
  _state.sent();
2964
3005
  return [
2965
3006
  3,
2966
- 4
3007
+ 5
2967
3008
  ];
2968
- case 3:
3009
+ case 4:
2969
3010
  error = _state.sent();
2970
- console.error("[StormcloudVideoPlayer] Error sending ad-impression tracking:", error);
3011
+ console.error("[StormcloudVideoPlayer] Error sending heartbeat:", error);
2971
3012
  return [
2972
3013
  3,
2973
- 4
3014
+ 5
2974
3015
  ];
2975
- case 4:
3016
+ case 5:
2976
3017
  return [
2977
3018
  2
2978
3019
  ];
2979
3020
  }
2980
3021
  });
2981
- })();
3022
+ }).apply(this, arguments);
2982
3023
  }
2983
3024
  // src/utils/polyfills.ts
2984
3025
  function polyfillURLSearchParams() {
@@ -3771,8 +3812,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3771
3812
  var _this = this;
3772
3813
  this.ima.on("all_ads_completed", function() {
3773
3814
  sendAdImpressionTracking(_this.config.licenseKey, {
3774
- adIndex: _this.currentAdIndex
3775
- }, _this.config.adPlayerType).catch(function() {});
3815
+ source: "ima",
3816
+ adIndex: _this.currentAdIndex,
3817
+ timestamp: /* @__PURE__ */ new Date().toISOString()
3818
+ }).catch(function() {});
3776
3819
  var remaining = _this.getRemainingAdMs();
3777
3820
  _this.consecutiveFailures = 0;
3778
3821
  if (_this.config.debugAdTiming) {
@@ -3833,8 +3876,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3833
3876
  });
3834
3877
  this.ima.on("content_resume", function() {
3835
3878
  sendAdImpressionTracking(_this.config.licenseKey, {
3836
- adIndex: _this.currentAdIndex
3837
- }, _this.config.adPlayerType).catch(function() {});
3879
+ source: "ima",
3880
+ adIndex: _this.currentAdIndex,
3881
+ timestamp: /* @__PURE__ */ new Date().toISOString()
3882
+ }).catch(function() {});
3838
3883
  if (!_this.video.muted) {
3839
3884
  _this.video.muted = true;
3840
3885
  _this.video.volume = 0;
@@ -4468,7 +4513,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4468
4513
  var detectPayload = {};
4469
4514
  if (marker.durationSeconds != null) detectPayload.durationSeconds = marker.durationSeconds;
4470
4515
  if (marker.ptsSeconds != null) detectPayload.ptsSeconds = marker.ptsSeconds;
4471
- sendAdDetectTracking(this.config.licenseKey, detectPayload).catch(function() {});
4516
+ sendAdDetectTracking(this.config.licenseKey, _object_spread({
4517
+ source: "scte35",
4518
+ timestamp: /* @__PURE__ */ new Date().toISOString()
4519
+ }, detectPayload)).catch(function() {});
4472
4520
  }
4473
4521
  var hasPrefetchedAds = this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0;
4474
4522
  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;
@@ -5710,7 +5758,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5710
5758
  if (marker.durationSeconds != null) detectPayload.durationSeconds = marker.durationSeconds;
5711
5759
  if (marker.ptsSeconds != null) detectPayload.ptsSeconds = marker.ptsSeconds;
5712
5760
  if (fragmentSn !== void 0) detectPayload.detectedAtFragmentSn = fragmentSn;
5713
- sendAdDetectTracking(this.config.licenseKey, detectPayload).catch(function() {});
5761
+ sendAdDetectTracking(this.config.licenseKey, _object_spread({
5762
+ source: "scte35",
5763
+ timestamp: /* @__PURE__ */ new Date().toISOString()
5764
+ }, detectPayload)).catch(function() {});
5714
5765
  if (this.config.debugAdTiming) {
5715
5766
  console.log("[PREFETCH] \uD83D\uDD04 Starting ad prefetch for upcoming ad break");
5716
5767
  console.log("[PREFETCH] \uD83D\uDCCB Pre-generated ".concat(generatedUrls.length, " VAST URLs"));
@@ -6191,9 +6242,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6191
6242
  preloadedController = preloaded.imaController;
6192
6243
  usePreloadedAd = true;
6193
6244
  sendAdLoadedTracking(this.config.licenseKey, {
6194
- source: "preload",
6195
- vastUrl: firstAdUrl
6196
- }, this.config.adPlayerType).catch(function() {});
6245
+ source: "ima",
6246
+ vastUrl: firstAdUrl,
6247
+ timestamp: /* @__PURE__ */ new Date().toISOString()
6248
+ }).catch(function() {});
6197
6249
  if (this.config.debugAdTiming) {
6198
6250
  console.log("[CONTINUOUS-FETCH] \uD83D\uDE80 Using preloaded ad from pool (preloaded in advance, ready immediately!)");
6199
6251
  console.log("[CONTINUOUS-FETCH] Pool still has ".concat(this.preloadPool.length, " preloaded ads ready"));
@@ -6283,9 +6335,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6283
6335
  case 5:
6284
6336
  _state.sent();
6285
6337
  sendAdLoadedTracking(this.config.licenseKey, {
6286
- source: "ssp",
6287
- vastUrl: firstAdUrl
6288
- }, this.config.adPlayerType).catch(function() {});
6338
+ source: "ima",
6339
+ vastUrl: firstAdUrl,
6340
+ timestamp: /* @__PURE__ */ new Date().toISOString()
6341
+ }).catch(function() {});
6289
6342
  if (this.config.debugAdTiming) {
6290
6343
  console.log("[CONTINUOUS-FETCH] \u2705 First ad request successful, starting playback");
6291
6344
  }
@@ -6681,9 +6734,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6681
6734
  console.log("[CONTINUOUS-FETCH] \uD83C\uDFAF Using preloaded ad from pool (".concat(this.preloadPool.length, " remaining in pool)"));
6682
6735
  }
6683
6736
  sendAdLoadedTracking(this.config.licenseKey, {
6684
- source: "preload",
6685
- vastUrl: preloaded.vastUrl
6686
- }, this.config.adPlayerType).catch(function() {});
6737
+ source: "ima",
6738
+ vastUrl: preloaded.vastUrl,
6739
+ timestamp: /* @__PURE__ */ new Date().toISOString()
6740
+ }).catch(function() {});
6687
6741
  _state.label = 1;
6688
6742
  case 1:
6689
6743
  _state.trys.push([
@@ -7435,9 +7489,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7435
7489
  case 3:
7436
7490
  _state.sent();
7437
7491
  sendAdLoadedTracking(this.config.licenseKey, {
7438
- source: "ssp",
7439
- vastUrl: vastTagUrl
7440
- }, this.config.adPlayerType).catch(function() {});
7492
+ source: "ima",
7493
+ vastUrl: vastTagUrl,
7494
+ timestamp: /* @__PURE__ */ new Date().toISOString()
7495
+ }).catch(function() {});
7441
7496
  this.clearAdRequestWatchdog();
7442
7497
  if (this.activeAdRequestToken !== requestToken) {
7443
7498
  return [