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.
@@ -1797,6 +1797,16 @@ function createHlsAdPlayer(contentVideo, options) {
1797
1797
  });
1798
1798
  return bestMatch.file;
1799
1799
  }
1800
+ function isHlsMediaFile(mediaFile) {
1801
+ var type = mediaFile.type.toLowerCase();
1802
+ var url = mediaFile.url.toLowerCase();
1803
+ return type === "application/x-mpegurl" || type === "application/vnd.apple.mpegurl" || type.includes("mpegurl") || url.includes(".m3u8");
1804
+ }
1805
+ function isProgressiveMediaFile(mediaFile) {
1806
+ var type = mediaFile.type.toLowerCase();
1807
+ var url = mediaFile.url.toLowerCase();
1808
+ return type.startsWith("video/") || url.endsWith(".mp4") || url.includes(".mp4?");
1809
+ }
1800
1810
  function parseVastXml(xmlString) {
1801
1811
  try {
1802
1812
  var _xmlDoc_querySelector, _xmlDoc_querySelector1, _xmlDoc_querySelector_textContent, _xmlDoc_querySelector2;
@@ -1828,30 +1838,32 @@ function createHlsAdPlayer(contentVideo, options) {
1828
1838
  var width = mf.getAttribute("width") || "";
1829
1839
  var height = mf.getAttribute("height") || "";
1830
1840
  console.log("[HlsAdPlayer] MediaFile ".concat(index, ': type="').concat(type, '", url="').concat(url, '", width="').concat(width, '", height="').concat(height, '"'));
1831
- if (type === "application/x-mpegURL" || type.includes("m3u8")) {
1832
- if (!url) {
1833
- console.warn("[HlsAdPlayer] MediaFile ".concat(index, " has HLS type but empty URL"));
1834
- return;
1835
- }
1836
- var bitrateAttr = mf.getAttribute("bitrate");
1837
- var bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;
1838
- mediaFiles.push({
1839
- url: url,
1840
- type: type,
1841
- width: parseInt(width || "1920", 10),
1842
- height: parseInt(height || "1080", 10),
1843
- bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : void 0
1844
- });
1845
- console.log("[HlsAdPlayer] Added HLS MediaFile: ".concat(url));
1841
+ var mediaFile = {
1842
+ url: url,
1843
+ type: type,
1844
+ width: parseInt(width || "1920", 10),
1845
+ height: parseInt(height || "1080", 10),
1846
+ bitrate: void 0
1847
+ };
1848
+ if (!url) {
1849
+ console.warn("[HlsAdPlayer] MediaFile ".concat(index, " has empty URL"));
1850
+ return;
1851
+ }
1852
+ var bitrateAttr = mf.getAttribute("bitrate");
1853
+ var bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;
1854
+ mediaFile.bitrate = bitrateValue && bitrateValue > 0 ? bitrateValue : void 0;
1855
+ if (isHlsMediaFile(mediaFile) || isProgressiveMediaFile(mediaFile)) {
1856
+ mediaFiles.push(mediaFile);
1857
+ console.log("[HlsAdPlayer] Added ".concat(isHlsMediaFile(mediaFile) ? "HLS" : "progressive", " MediaFile: ").concat(url));
1846
1858
  } else {
1847
- console.log("[HlsAdPlayer] MediaFile ".concat(index, ' ignored (type="').concat(type, '" is not HLS)'));
1859
+ console.log("[HlsAdPlayer] MediaFile ".concat(index, ' ignored (type="').concat(type, '" is not supported)'));
1848
1860
  }
1849
1861
  });
1850
1862
  if (mediaFiles.length === 0) {
1851
1863
  if (isNoAdAvailable) {
1852
1864
  console.warn("[HlsAdPlayer] No ads available (VAST response indicates no ads)");
1853
1865
  } else {
1854
- console.warn("[HlsAdPlayer] No HLS media files found in VAST XML");
1866
+ console.warn("[HlsAdPlayer] No supported media files found in VAST XML");
1855
1867
  }
1856
1868
  return null;
1857
1869
  }
@@ -2148,7 +2160,7 @@ function createHlsAdPlayer(contentVideo, options) {
2148
2160
  },
2149
2161
  play: function play() {
2150
2162
  return _async_to_generator(function() {
2151
- var contentVolume, adVolume, mediaFile;
2163
+ var contentVolume, adVolume, mediaFile, isHlsAd;
2152
2164
  return _ts_generator(this, function(_state) {
2153
2165
  if (!currentAd) {
2154
2166
  console.warn("[HlsAdPlayer] Cannot play: No ad loaded (no ads available)");
@@ -2200,8 +2212,9 @@ function createHlsAdPlayer(contentVideo, options) {
2200
2212
  if (!mediaFile) {
2201
2213
  throw new Error("No media file available for ad");
2202
2214
  }
2203
- console.log("[HlsAdPlayer] Loading ad from: ".concat(mediaFile.url));
2204
- if (import_hls.default.isSupported()) {
2215
+ isHlsAd = isHlsMediaFile(mediaFile);
2216
+ console.log("[HlsAdPlayer] Loading ".concat(isHlsAd ? "HLS" : "progressive", " ad from: ").concat(mediaFile.url));
2217
+ if (isHlsAd && import_hls.default.isSupported()) {
2205
2218
  if (adHls) {
2206
2219
  adHls.destroy();
2207
2220
  }
@@ -2224,14 +2237,25 @@ function createHlsAdPlayer(contentVideo, options) {
2224
2237
  handleAdError();
2225
2238
  }
2226
2239
  });
2227
- } else if (adVideoElement.canPlayType("application/vnd.apple.mpegurl")) {
2240
+ } else if (isHlsAd && adVideoElement.canPlayType("application/vnd.apple.mpegurl")) {
2228
2241
  adVideoElement.src = mediaFile.url;
2229
2242
  adVideoElement.play().catch(function(error) {
2230
2243
  console.error("[HlsAdPlayer] Error starting ad playback:", error);
2231
2244
  handleAdError();
2232
2245
  });
2246
+ } else if (!isHlsAd && isProgressiveMediaFile(mediaFile)) {
2247
+ if (adHls) {
2248
+ adHls.destroy();
2249
+ adHls = void 0;
2250
+ }
2251
+ adVideoElement.src = mediaFile.url;
2252
+ adVideoElement.load();
2253
+ adVideoElement.play().catch(function(error) {
2254
+ console.error("[HlsAdPlayer] Error starting progressive ad playback:", error);
2255
+ handleAdError();
2256
+ });
2233
2257
  } else {
2234
- throw new Error("HLS not supported");
2258
+ throw new Error("Unsupported ad media file type: ".concat(mediaFile.type));
2235
2259
  }
2236
2260
  return [
2237
2261
  2,
@@ -2672,40 +2696,66 @@ function getBrowserID(clientInfo) {
2672
2696
  });
2673
2697
  })();
2674
2698
  }
2675
- function sendInitialTracking(licenseKey) {
2699
+ var PLAYER_TRACKING_BASE_URL = "https://adstorm.co/api-adstorm-dev/adstorm/player-tracking";
2700
+ var TRACK_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/metrics/ingest");
2701
+ var HEARTBEAT_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/heartbeat");
2702
+ var IMPRESSIONS_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/impressions/ingest");
2703
+ function buildHeaders(licenseKey) {
2704
+ var headers = {
2705
+ "Content-Type": "application/json"
2706
+ };
2707
+ if (licenseKey) {
2708
+ headers["Authorization"] = "Bearer ".concat(licenseKey);
2709
+ }
2710
+ return headers;
2711
+ }
2712
+ function sendTrackRequest(licenseKey, body) {
2676
2713
  return _async_to_generator(function() {
2677
- var clientInfo, browserId, trackingData, headers, response, error;
2714
+ var response;
2678
2715
  return _ts_generator(this, function(_state) {
2679
2716
  switch(_state.label){
2680
2717
  case 0:
2681
- _state.trys.push([
2682
- 0,
2683
- 4,
2684
- ,
2685
- 5
2686
- ]);
2687
- clientInfo = getClientInfo();
2688
2718
  return [
2689
2719
  4,
2690
- getBrowserID(clientInfo)
2720
+ fetch(TRACK_URL, {
2721
+ method: "POST",
2722
+ headers: buildHeaders(licenseKey),
2723
+ body: JSON.stringify(body)
2724
+ })
2691
2725
  ];
2692
2726
  case 1:
2693
- browserId = _state.sent();
2694
- trackingData = _object_spread({
2695
- browserId: browserId
2696
- }, clientInfo);
2697
- headers = {
2698
- "Content-Type": "application/json"
2699
- };
2727
+ response = _state.sent();
2728
+ if (!response.ok) {
2729
+ throw new Error("HTTP error! status: ".concat(response.status));
2730
+ }
2731
+ return [
2732
+ 4,
2733
+ response.json()
2734
+ ];
2735
+ case 2:
2736
+ _state.sent();
2737
+ return [
2738
+ 2
2739
+ ];
2740
+ }
2741
+ });
2742
+ })();
2743
+ }
2744
+ function postJson(url, licenseKey, body) {
2745
+ return _async_to_generator(function() {
2746
+ var response;
2747
+ return _ts_generator(this, function(_state) {
2748
+ switch(_state.label){
2749
+ case 0:
2700
2750
  return [
2701
2751
  4,
2702
- fetch("https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track", {
2752
+ fetch(url, {
2703
2753
  method: "POST",
2704
- headers: headers,
2705
- body: JSON.stringify(trackingData)
2754
+ headers: buildHeaders(licenseKey),
2755
+ body: JSON.stringify(body)
2706
2756
  })
2707
2757
  ];
2708
- case 2:
2758
+ case 1:
2709
2759
  response = _state.sent();
2710
2760
  if (!response.ok) {
2711
2761
  throw new Error("HTTP error! status: ".concat(response.status));
@@ -2714,35 +2764,63 @@ function sendInitialTracking(licenseKey) {
2714
2764
  4,
2715
2765
  response.json()
2716
2766
  ];
2717
- case 3:
2767
+ case 2:
2718
2768
  _state.sent();
2719
2769
  return [
2720
- 3,
2721
- 5
2770
+ 2
2722
2771
  ];
2723
- case 4:
2724
- error = _state.sent();
2725
- console.error("[StormcloudVideoPlayer] Error sending initial tracking data:", error);
2772
+ }
2773
+ });
2774
+ })();
2775
+ }
2776
+ function buildPlayerMetricEvent(_0) {
2777
+ return _async_to_generator(function(licenseKey) {
2778
+ var context, flags, _flags_captureAt, clientInfo, browserId, captureAt;
2779
+ var _arguments = arguments;
2780
+ return _ts_generator(this, function(_state) {
2781
+ switch(_state.label){
2782
+ case 0:
2783
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2784
+ clientInfo = getClientInfo();
2726
2785
  return [
2727
- 3,
2728
- 5
2786
+ 4,
2787
+ getBrowserID(clientInfo)
2729
2788
  ];
2730
- case 5:
2789
+ case 1:
2790
+ browserId = _state.sent();
2791
+ captureAt = (_flags_captureAt = flags.captureAt) !== null && _flags_captureAt !== void 0 ? _flags_captureAt : /* @__PURE__ */ new Date().toISOString();
2731
2792
  return [
2732
- 2
2793
+ 2,
2794
+ {
2795
+ player_id: browserId,
2796
+ browserId: browserId,
2797
+ device_type: clientInfo.deviceType,
2798
+ deviceType: clientInfo.deviceType,
2799
+ input_stream_type: context.inputStreamType,
2800
+ os: clientInfo.os,
2801
+ ad_loaded: flags.adLoaded,
2802
+ ad_detect: flags.adDetect,
2803
+ license_key: licenseKey,
2804
+ capture_at: captureAt,
2805
+ timestamp: captureAt
2806
+ }
2733
2807
  ];
2734
2808
  }
2735
2809
  });
2736
- })();
2810
+ }).apply(this, arguments);
2737
2811
  }
2738
- function sendHeartbeat(licenseKey) {
2739
- return _async_to_generator(function() {
2740
- var clientInfo, browserId, heartbeatData, headers, response, error;
2812
+ function sendInitialTracking(_0) {
2813
+ return _async_to_generator(function(licenseKey) {
2814
+ var context, clientInfo, browserId, trackingData, error;
2815
+ var _arguments = arguments;
2741
2816
  return _ts_generator(this, function(_state) {
2742
2817
  switch(_state.label){
2743
2818
  case 0:
2819
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
2820
+ _state.label = 1;
2821
+ case 1:
2744
2822
  _state.trys.push([
2745
- 0,
2823
+ 1,
2746
2824
  4,
2747
2825
  ,
2748
2826
  5
@@ -2752,35 +2830,29 @@ function sendHeartbeat(licenseKey) {
2752
2830
  4,
2753
2831
  getBrowserID(clientInfo)
2754
2832
  ];
2755
- case 1:
2833
+ case 2:
2756
2834
  browserId = _state.sent();
2757
- heartbeatData = {
2758
- browserId: browserId,
2759
- timestamp: /* @__PURE__ */ new Date().toISOString()
2760
- };
2761
- headers = {
2762
- "Content-Type": "application/json"
2763
- };
2764
- if (licenseKey) {
2765
- headers["Authorization"] = "Bearer ".concat(licenseKey);
2766
- }
2835
+ trackingData = _object_spread({
2836
+ browserId: browserId
2837
+ }, clientInfo);
2767
2838
  return [
2768
2839
  4,
2769
- fetch("https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat", {
2770
- method: "POST",
2771
- headers: headers,
2772
- body: JSON.stringify(heartbeatData)
2840
+ sendTrackRequest(licenseKey, {
2841
+ events: [
2842
+ {
2843
+ player_id: browserId,
2844
+ device_type: clientInfo.deviceType,
2845
+ input_stream_type: context.inputStreamType,
2846
+ os: clientInfo.os,
2847
+ ad_loaded: false,
2848
+ ad_detect: false,
2849
+ license_key: licenseKey,
2850
+ capture_at: /* @__PURE__ */ new Date().toISOString()
2851
+ }
2852
+ ],
2853
+ trackingData: trackingData
2773
2854
  })
2774
2855
  ];
2775
- case 2:
2776
- response = _state.sent();
2777
- if (!response.ok) {
2778
- throw new Error("HTTP error! status: ".concat(response.status));
2779
- }
2780
- return [
2781
- 4,
2782
- response.json()
2783
- ];
2784
2856
  case 3:
2785
2857
  _state.sent();
2786
2858
  return [
@@ -2789,7 +2861,7 @@ function sendHeartbeat(licenseKey) {
2789
2861
  ];
2790
2862
  case 4:
2791
2863
  error = _state.sent();
2792
- console.error("[StormcloudVideoPlayer] Error sending heartbeat:", error);
2864
+ console.error("[StormcloudVideoPlayer] Error sending initial tracking data:", error);
2793
2865
  return [
2794
2866
  3,
2795
2867
  5
@@ -2800,95 +2872,74 @@ function sendHeartbeat(licenseKey) {
2800
2872
  ];
2801
2873
  }
2802
2874
  });
2803
- })();
2875
+ }).apply(this, arguments);
2804
2876
  }
2805
- var TRACK_API_URL = "https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track";
2806
- function mapToAdTrackingSource(source, adPlayerType) {
2807
- if (source === "prebid" || source === "ima" || source === "hls") {
2808
- return source;
2809
- }
2810
- if (source === "preload" || source === "ssp") {
2811
- return source === "ssp" ? "prebid" : "ima";
2812
- }
2813
- return adPlayerType === "hls" ? "hls" : "ima";
2814
- }
2815
- function postAdTracking(licenseKey, body) {
2816
- return _async_to_generator(function() {
2817
- var headers, response;
2877
+ function sendAdDetectTracking(_0, _1) {
2878
+ return _async_to_generator(function(licenseKey, adDetectInfo) {
2879
+ var context, error;
2880
+ var _arguments = arguments;
2818
2881
  return _ts_generator(this, function(_state) {
2819
2882
  switch(_state.label){
2820
2883
  case 0:
2821
- headers = {
2822
- "Content-Type": "application/json"
2823
- };
2824
- if (licenseKey) {
2825
- headers["Authorization"] = "Bearer ".concat(licenseKey);
2826
- }
2827
- return [
2828
- 4,
2829
- fetch(TRACK_API_URL, {
2830
- method: "POST",
2831
- headers: headers,
2832
- body: JSON.stringify(body)
2833
- })
2834
- ];
2884
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2885
+ _state.label = 1;
2835
2886
  case 1:
2836
- response = _state.sent();
2837
- if (!response.ok) {
2838
- throw new Error("HTTP error! status: ".concat(response.status));
2839
- }
2887
+ _state.trys.push([
2888
+ 1,
2889
+ 3,
2890
+ ,
2891
+ 4
2892
+ ]);
2840
2893
  return [
2841
2894
  4,
2842
- response.json()
2895
+ sendHeartbeat(licenseKey, context, {
2896
+ adDetect: true,
2897
+ captureAt: adDetectInfo.timestamp
2898
+ })
2843
2899
  ];
2844
2900
  case 2:
2845
2901
  _state.sent();
2902
+ return [
2903
+ 3,
2904
+ 4
2905
+ ];
2906
+ case 3:
2907
+ error = _state.sent();
2908
+ console.error("[StormcloudVideoPlayer] Error sending ad detect tracking:", error);
2909
+ return [
2910
+ 3,
2911
+ 4
2912
+ ];
2913
+ case 4:
2846
2914
  return [
2847
2915
  2
2848
2916
  ];
2849
2917
  }
2850
2918
  });
2851
- })();
2919
+ }).apply(this, arguments);
2852
2920
  }
2853
- function sendAdDetectTracking(licenseKey, payload) {
2854
- return _async_to_generator(function() {
2855
- var _payload_source, _payload_timestamp, clientInfo, browserId, adDetectInfo, body, error;
2921
+ function sendAdLoadedTracking(_0, _1) {
2922
+ return _async_to_generator(function(licenseKey, adLoadedInfo) {
2923
+ var context, error;
2924
+ var _arguments = arguments;
2856
2925
  return _ts_generator(this, function(_state) {
2857
2926
  switch(_state.label){
2858
2927
  case 0:
2928
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2929
+ _state.label = 1;
2930
+ case 1:
2859
2931
  _state.trys.push([
2860
- 0,
2932
+ 1,
2861
2933
  3,
2862
2934
  ,
2863
2935
  4
2864
2936
  ]);
2865
- clientInfo = getClientInfo();
2866
- return [
2867
- 4,
2868
- getBrowserID(clientInfo)
2869
- ];
2870
- case 1:
2871
- browserId = _state.sent();
2872
- adDetectInfo = _object_spread({
2873
- source: (_payload_source = payload.source) !== null && _payload_source !== void 0 ? _payload_source : "scte35",
2874
- timestamp: (_payload_timestamp = payload.timestamp) !== null && _payload_timestamp !== void 0 ? _payload_timestamp : /* @__PURE__ */ new Date().toISOString()
2875
- }, payload.durationSeconds != null && {
2876
- durationSeconds: payload.durationSeconds
2877
- }, payload.ptsSeconds != null && {
2878
- ptsSeconds: payload.ptsSeconds
2879
- }, payload.detectedAtFragmentSn != null && {
2880
- detectedAtFragmentSn: payload.detectedAtFragmentSn
2881
- });
2882
- body = _object_spread_props(_object_spread({
2883
- browserId: browserId
2884
- }, clientInfo, licenseKey && {
2885
- licenseKey: licenseKey
2886
- }), {
2887
- adDetectInfo: adDetectInfo
2888
- });
2889
2937
  return [
2890
2938
  4,
2891
- postAdTracking(licenseKey, body)
2939
+ sendHeartbeat(licenseKey, context, {
2940
+ adLoaded: true,
2941
+ captureAt: adLoadedInfo.timestamp
2942
+ })
2892
2943
  ];
2893
2944
  case 2:
2894
2945
  _state.sent();
@@ -2898,7 +2949,7 @@ function sendAdDetectTracking(licenseKey, payload) {
2898
2949
  ];
2899
2950
  case 3:
2900
2951
  error = _state.sent();
2901
- console.error("[StormcloudVideoPlayer] Error sending ad-detect tracking:", error);
2952
+ console.error("[StormcloudVideoPlayer] Error sending ad loaded tracking:", error);
2902
2953
  return [
2903
2954
  3,
2904
2955
  4
@@ -2909,126 +2960,116 @@ function sendAdDetectTracking(licenseKey, payload) {
2909
2960
  ];
2910
2961
  }
2911
2962
  });
2912
- })();
2963
+ }).apply(this, arguments);
2913
2964
  }
2914
- function sendAdLoadedTracking(licenseKey, payload, adPlayerType) {
2915
- return _async_to_generator(function() {
2916
- var clientInfo, browserId, source, adLoadedInfo, body, error;
2965
+ function sendAdImpressionTracking(_0, _1) {
2966
+ return _async_to_generator(function(licenseKey, adImpressionInfo) {
2967
+ var context, metricEvent, error;
2968
+ var _arguments = arguments;
2917
2969
  return _ts_generator(this, function(_state) {
2918
2970
  switch(_state.label){
2919
2971
  case 0:
2972
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2973
+ _state.label = 1;
2974
+ case 1:
2920
2975
  _state.trys.push([
2921
- 0,
2922
- 3,
2976
+ 1,
2977
+ 4,
2923
2978
  ,
2924
- 4
2979
+ 5
2925
2980
  ]);
2926
- clientInfo = getClientInfo();
2927
2981
  return [
2928
2982
  4,
2929
- getBrowserID(clientInfo)
2983
+ buildPlayerMetricEvent(licenseKey, context, {
2984
+ captureAt: adImpressionInfo.timestamp
2985
+ })
2930
2986
  ];
2931
- case 1:
2932
- browserId = _state.sent();
2933
- source = mapToAdTrackingSource(payload.source, adPlayerType);
2934
- adLoadedInfo = _object_spread({
2935
- source: source,
2936
- timestamp: /* @__PURE__ */ new Date().toISOString()
2937
- }, payload.vastUrl != null && {
2938
- vastUrl: payload.vastUrl
2939
- }, payload.durationSeconds != null && {
2940
- durationSeconds: payload.durationSeconds
2941
- });
2942
- body = _object_spread_props(_object_spread({
2943
- browserId: browserId
2944
- }, clientInfo, licenseKey && {
2945
- licenseKey: licenseKey
2946
- }), {
2947
- adLoadedInfo: adLoadedInfo
2948
- });
2987
+ case 2:
2988
+ metricEvent = _state.sent();
2949
2989
  return [
2950
2990
  4,
2951
- postAdTracking(licenseKey, body)
2991
+ Promise.all([
2992
+ postJson(HEARTBEAT_URL, licenseKey, metricEvent),
2993
+ postJson(IMPRESSIONS_URL, licenseKey, {
2994
+ events: [
2995
+ {
2996
+ player_id: metricEvent.player_id,
2997
+ ad_played_count: 1,
2998
+ ad_url: adImpressionInfo.adUrl,
2999
+ license_key: licenseKey,
3000
+ capture_at: adImpressionInfo.timestamp
3001
+ }
3002
+ ]
3003
+ })
3004
+ ])
2952
3005
  ];
2953
- case 2:
3006
+ case 3:
2954
3007
  _state.sent();
2955
3008
  return [
2956
3009
  3,
2957
- 4
3010
+ 5
2958
3011
  ];
2959
- case 3:
3012
+ case 4:
2960
3013
  error = _state.sent();
2961
- console.error("[StormcloudVideoPlayer] Error sending ad-loaded tracking:", error);
3014
+ console.error("[StormcloudVideoPlayer] Error sending ad impression tracking:", error);
2962
3015
  return [
2963
3016
  3,
2964
- 4
3017
+ 5
2965
3018
  ];
2966
- case 4:
3019
+ case 5:
2967
3020
  return [
2968
3021
  2
2969
3022
  ];
2970
3023
  }
2971
3024
  });
2972
- })();
3025
+ }).apply(this, arguments);
2973
3026
  }
2974
- function sendAdImpressionTracking(licenseKey, payload, adPlayerType) {
2975
- return _async_to_generator(function() {
2976
- var clientInfo, browserId, source, adImpressionInfo, body, error;
3027
+ function sendHeartbeat(_0) {
3028
+ return _async_to_generator(function(licenseKey) {
3029
+ var context, flags, heartbeatData, error;
3030
+ var _arguments = arguments;
2977
3031
  return _ts_generator(this, function(_state) {
2978
3032
  switch(_state.label){
2979
3033
  case 0:
3034
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
3035
+ _state.label = 1;
3036
+ case 1:
2980
3037
  _state.trys.push([
2981
- 0,
2982
- 3,
3038
+ 1,
3039
+ 4,
2983
3040
  ,
2984
- 4
3041
+ 5
2985
3042
  ]);
2986
- clientInfo = getClientInfo();
2987
3043
  return [
2988
3044
  4,
2989
- getBrowserID(clientInfo)
3045
+ buildPlayerMetricEvent(licenseKey, context, flags)
2990
3046
  ];
2991
- case 1:
2992
- browserId = _state.sent();
2993
- source = mapToAdTrackingSource(payload.source, adPlayerType);
2994
- adImpressionInfo = _object_spread({
2995
- source: source,
2996
- adIndex: payload.adIndex,
2997
- timestamp: /* @__PURE__ */ new Date().toISOString()
2998
- }, payload.durationSeconds != null && {
2999
- durationSeconds: payload.durationSeconds
3000
- });
3001
- body = _object_spread_props(_object_spread({
3002
- browserId: browserId
3003
- }, clientInfo, licenseKey && {
3004
- licenseKey: licenseKey
3005
- }), {
3006
- adImpressionInfo: adImpressionInfo
3007
- });
3047
+ case 2:
3048
+ heartbeatData = _state.sent();
3008
3049
  return [
3009
3050
  4,
3010
- postAdTracking(licenseKey, body)
3051
+ postJson(HEARTBEAT_URL, licenseKey, heartbeatData)
3011
3052
  ];
3012
- case 2:
3053
+ case 3:
3013
3054
  _state.sent();
3014
3055
  return [
3015
3056
  3,
3016
- 4
3057
+ 5
3017
3058
  ];
3018
- case 3:
3059
+ case 4:
3019
3060
  error = _state.sent();
3020
- console.error("[StormcloudVideoPlayer] Error sending ad-impression tracking:", error);
3061
+ console.error("[StormcloudVideoPlayer] Error sending heartbeat:", error);
3021
3062
  return [
3022
3063
  3,
3023
- 4
3064
+ 5
3024
3065
  ];
3025
- case 4:
3066
+ case 5:
3026
3067
  return [
3027
3068
  2
3028
3069
  ];
3029
3070
  }
3030
3071
  });
3031
- })();
3072
+ }).apply(this, arguments);
3032
3073
  }
3033
3074
  // src/utils/polyfills.ts
3034
3075
  function polyfillURLSearchParams() {
@@ -3821,8 +3862,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3821
3862
  var _this = this;
3822
3863
  this.ima.on("all_ads_completed", function() {
3823
3864
  sendAdImpressionTracking(_this.config.licenseKey, {
3824
- adIndex: _this.currentAdIndex
3825
- }, _this.config.adPlayerType).catch(function() {});
3865
+ source: "ima",
3866
+ adIndex: _this.currentAdIndex,
3867
+ timestamp: /* @__PURE__ */ new Date().toISOString()
3868
+ }).catch(function() {});
3826
3869
  var remaining = _this.getRemainingAdMs();
3827
3870
  _this.consecutiveFailures = 0;
3828
3871
  if (_this.config.debugAdTiming) {
@@ -3883,8 +3926,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3883
3926
  });
3884
3927
  this.ima.on("content_resume", function() {
3885
3928
  sendAdImpressionTracking(_this.config.licenseKey, {
3886
- adIndex: _this.currentAdIndex
3887
- }, _this.config.adPlayerType).catch(function() {});
3929
+ source: "ima",
3930
+ adIndex: _this.currentAdIndex,
3931
+ timestamp: /* @__PURE__ */ new Date().toISOString()
3932
+ }).catch(function() {});
3888
3933
  if (!_this.video.muted) {
3889
3934
  _this.video.muted = true;
3890
3935
  _this.video.volume = 0;
@@ -4518,7 +4563,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4518
4563
  var detectPayload = {};
4519
4564
  if (marker.durationSeconds != null) detectPayload.durationSeconds = marker.durationSeconds;
4520
4565
  if (marker.ptsSeconds != null) detectPayload.ptsSeconds = marker.ptsSeconds;
4521
- sendAdDetectTracking(this.config.licenseKey, detectPayload).catch(function() {});
4566
+ sendAdDetectTracking(this.config.licenseKey, _object_spread({
4567
+ source: "scte35",
4568
+ timestamp: /* @__PURE__ */ new Date().toISOString()
4569
+ }, detectPayload)).catch(function() {});
4522
4570
  }
4523
4571
  var hasPrefetchedAds = this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0;
4524
4572
  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;
@@ -5760,7 +5808,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5760
5808
  if (marker.durationSeconds != null) detectPayload.durationSeconds = marker.durationSeconds;
5761
5809
  if (marker.ptsSeconds != null) detectPayload.ptsSeconds = marker.ptsSeconds;
5762
5810
  if (fragmentSn !== void 0) detectPayload.detectedAtFragmentSn = fragmentSn;
5763
- sendAdDetectTracking(this.config.licenseKey, detectPayload).catch(function() {});
5811
+ sendAdDetectTracking(this.config.licenseKey, _object_spread({
5812
+ source: "scte35",
5813
+ timestamp: /* @__PURE__ */ new Date().toISOString()
5814
+ }, detectPayload)).catch(function() {});
5764
5815
  if (this.config.debugAdTiming) {
5765
5816
  console.log("[PREFETCH] \uD83D\uDD04 Starting ad prefetch for upcoming ad break");
5766
5817
  console.log("[PREFETCH] \uD83D\uDCCB Pre-generated ".concat(generatedUrls.length, " VAST URLs"));
@@ -6241,9 +6292,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6241
6292
  preloadedController = preloaded.imaController;
6242
6293
  usePreloadedAd = true;
6243
6294
  sendAdLoadedTracking(this.config.licenseKey, {
6244
- source: "preload",
6245
- vastUrl: firstAdUrl
6246
- }, this.config.adPlayerType).catch(function() {});
6295
+ source: "ima",
6296
+ vastUrl: firstAdUrl,
6297
+ timestamp: /* @__PURE__ */ new Date().toISOString()
6298
+ }).catch(function() {});
6247
6299
  if (this.config.debugAdTiming) {
6248
6300
  console.log("[CONTINUOUS-FETCH] \uD83D\uDE80 Using preloaded ad from pool (preloaded in advance, ready immediately!)");
6249
6301
  console.log("[CONTINUOUS-FETCH] Pool still has ".concat(this.preloadPool.length, " preloaded ads ready"));
@@ -6333,9 +6385,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6333
6385
  case 5:
6334
6386
  _state.sent();
6335
6387
  sendAdLoadedTracking(this.config.licenseKey, {
6336
- source: "ssp",
6337
- vastUrl: firstAdUrl
6338
- }, this.config.adPlayerType).catch(function() {});
6388
+ source: "ima",
6389
+ vastUrl: firstAdUrl,
6390
+ timestamp: /* @__PURE__ */ new Date().toISOString()
6391
+ }).catch(function() {});
6339
6392
  if (this.config.debugAdTiming) {
6340
6393
  console.log("[CONTINUOUS-FETCH] \u2705 First ad request successful, starting playback");
6341
6394
  }
@@ -6731,9 +6784,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6731
6784
  console.log("[CONTINUOUS-FETCH] \uD83C\uDFAF Using preloaded ad from pool (".concat(this.preloadPool.length, " remaining in pool)"));
6732
6785
  }
6733
6786
  sendAdLoadedTracking(this.config.licenseKey, {
6734
- source: "preload",
6735
- vastUrl: preloaded.vastUrl
6736
- }, this.config.adPlayerType).catch(function() {});
6787
+ source: "ima",
6788
+ vastUrl: preloaded.vastUrl,
6789
+ timestamp: /* @__PURE__ */ new Date().toISOString()
6790
+ }).catch(function() {});
6737
6791
  _state.label = 1;
6738
6792
  case 1:
6739
6793
  _state.trys.push([
@@ -7485,9 +7539,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7485
7539
  case 3:
7486
7540
  _state.sent();
7487
7541
  sendAdLoadedTracking(this.config.licenseKey, {
7488
- source: "ssp",
7489
- vastUrl: vastTagUrl
7490
- }, this.config.adPlayerType).catch(function() {});
7542
+ source: "ima",
7543
+ vastUrl: vastTagUrl,
7544
+ timestamp: /* @__PURE__ */ new Date().toISOString()
7545
+ }).catch(function() {});
7491
7546
  this.clearAdRequestWatchdog();
7492
7547
  if (this.activeAdRequestToken !== requestToken) {
7493
7548
  return [