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.
@@ -1709,6 +1709,16 @@ function createHlsAdPlayer(contentVideo, options) {
1709
1709
  });
1710
1710
  return bestMatch.file;
1711
1711
  }
1712
+ function isHlsMediaFile(mediaFile) {
1713
+ var type = mediaFile.type.toLowerCase();
1714
+ var url = mediaFile.url.toLowerCase();
1715
+ return type === "application/x-mpegurl" || type === "application/vnd.apple.mpegurl" || type.includes("mpegurl") || url.includes(".m3u8");
1716
+ }
1717
+ function isProgressiveMediaFile(mediaFile) {
1718
+ var type = mediaFile.type.toLowerCase();
1719
+ var url = mediaFile.url.toLowerCase();
1720
+ return type.startsWith("video/") || url.endsWith(".mp4") || url.includes(".mp4?");
1721
+ }
1712
1722
  function parseVastXml(xmlString) {
1713
1723
  try {
1714
1724
  var _xmlDoc_querySelector, _xmlDoc_querySelector1, _xmlDoc_querySelector_textContent, _xmlDoc_querySelector2;
@@ -1740,30 +1750,32 @@ function createHlsAdPlayer(contentVideo, options) {
1740
1750
  var width = mf.getAttribute("width") || "";
1741
1751
  var height = mf.getAttribute("height") || "";
1742
1752
  console.log("[HlsAdPlayer] MediaFile ".concat(index, ': type="').concat(type, '", url="').concat(url, '", width="').concat(width, '", height="').concat(height, '"'));
1743
- if (type === "application/x-mpegURL" || type.includes("m3u8")) {
1744
- if (!url) {
1745
- console.warn("[HlsAdPlayer] MediaFile ".concat(index, " has HLS type but empty URL"));
1746
- return;
1747
- }
1748
- var bitrateAttr = mf.getAttribute("bitrate");
1749
- var bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;
1750
- mediaFiles.push({
1751
- url: url,
1752
- type: type,
1753
- width: parseInt(width || "1920", 10),
1754
- height: parseInt(height || "1080", 10),
1755
- bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : void 0
1756
- });
1757
- console.log("[HlsAdPlayer] Added HLS MediaFile: ".concat(url));
1753
+ var mediaFile = {
1754
+ url: url,
1755
+ type: type,
1756
+ width: parseInt(width || "1920", 10),
1757
+ height: parseInt(height || "1080", 10),
1758
+ bitrate: void 0
1759
+ };
1760
+ if (!url) {
1761
+ console.warn("[HlsAdPlayer] MediaFile ".concat(index, " has empty URL"));
1762
+ return;
1763
+ }
1764
+ var bitrateAttr = mf.getAttribute("bitrate");
1765
+ var bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;
1766
+ mediaFile.bitrate = bitrateValue && bitrateValue > 0 ? bitrateValue : void 0;
1767
+ if (isHlsMediaFile(mediaFile) || isProgressiveMediaFile(mediaFile)) {
1768
+ mediaFiles.push(mediaFile);
1769
+ console.log("[HlsAdPlayer] Added ".concat(isHlsMediaFile(mediaFile) ? "HLS" : "progressive", " MediaFile: ").concat(url));
1758
1770
  } else {
1759
- console.log("[HlsAdPlayer] MediaFile ".concat(index, ' ignored (type="').concat(type, '" is not HLS)'));
1771
+ console.log("[HlsAdPlayer] MediaFile ".concat(index, ' ignored (type="').concat(type, '" is not supported)'));
1760
1772
  }
1761
1773
  });
1762
1774
  if (mediaFiles.length === 0) {
1763
1775
  if (isNoAdAvailable) {
1764
1776
  console.warn("[HlsAdPlayer] No ads available (VAST response indicates no ads)");
1765
1777
  } else {
1766
- console.warn("[HlsAdPlayer] No HLS media files found in VAST XML");
1778
+ console.warn("[HlsAdPlayer] No supported media files found in VAST XML");
1767
1779
  }
1768
1780
  return null;
1769
1781
  }
@@ -2060,7 +2072,7 @@ function createHlsAdPlayer(contentVideo, options) {
2060
2072
  },
2061
2073
  play: function play() {
2062
2074
  return _async_to_generator(function() {
2063
- var contentVolume, adVolume, mediaFile;
2075
+ var contentVolume, adVolume, mediaFile, isHlsAd;
2064
2076
  return _ts_generator(this, function(_state) {
2065
2077
  if (!currentAd) {
2066
2078
  console.warn("[HlsAdPlayer] Cannot play: No ad loaded (no ads available)");
@@ -2112,8 +2124,9 @@ function createHlsAdPlayer(contentVideo, options) {
2112
2124
  if (!mediaFile) {
2113
2125
  throw new Error("No media file available for ad");
2114
2126
  }
2115
- console.log("[HlsAdPlayer] Loading ad from: ".concat(mediaFile.url));
2116
- if (import_hls.default.isSupported()) {
2127
+ isHlsAd = isHlsMediaFile(mediaFile);
2128
+ console.log("[HlsAdPlayer] Loading ".concat(isHlsAd ? "HLS" : "progressive", " ad from: ").concat(mediaFile.url));
2129
+ if (isHlsAd && import_hls.default.isSupported()) {
2117
2130
  if (adHls) {
2118
2131
  adHls.destroy();
2119
2132
  }
@@ -2136,14 +2149,25 @@ function createHlsAdPlayer(contentVideo, options) {
2136
2149
  handleAdError();
2137
2150
  }
2138
2151
  });
2139
- } else if (adVideoElement.canPlayType("application/vnd.apple.mpegurl")) {
2152
+ } else if (isHlsAd && adVideoElement.canPlayType("application/vnd.apple.mpegurl")) {
2140
2153
  adVideoElement.src = mediaFile.url;
2141
2154
  adVideoElement.play().catch(function(error) {
2142
2155
  console.error("[HlsAdPlayer] Error starting ad playback:", error);
2143
2156
  handleAdError();
2144
2157
  });
2158
+ } else if (!isHlsAd && isProgressiveMediaFile(mediaFile)) {
2159
+ if (adHls) {
2160
+ adHls.destroy();
2161
+ adHls = void 0;
2162
+ }
2163
+ adVideoElement.src = mediaFile.url;
2164
+ adVideoElement.load();
2165
+ adVideoElement.play().catch(function(error) {
2166
+ console.error("[HlsAdPlayer] Error starting progressive ad playback:", error);
2167
+ handleAdError();
2168
+ });
2145
2169
  } else {
2146
- throw new Error("HLS not supported");
2170
+ throw new Error("Unsupported ad media file type: ".concat(mediaFile.type));
2147
2171
  }
2148
2172
  return [
2149
2173
  2,
@@ -2584,40 +2608,66 @@ function getBrowserID(clientInfo) {
2584
2608
  });
2585
2609
  })();
2586
2610
  }
2587
- function sendInitialTracking(licenseKey) {
2611
+ var PLAYER_TRACKING_BASE_URL = "https://adstorm.co/api-adstorm-dev/adstorm/player-tracking";
2612
+ var TRACK_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/metrics/ingest");
2613
+ var HEARTBEAT_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/heartbeat");
2614
+ var IMPRESSIONS_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/impressions/ingest");
2615
+ function buildHeaders(licenseKey) {
2616
+ var headers = {
2617
+ "Content-Type": "application/json"
2618
+ };
2619
+ if (licenseKey) {
2620
+ headers["Authorization"] = "Bearer ".concat(licenseKey);
2621
+ }
2622
+ return headers;
2623
+ }
2624
+ function sendTrackRequest(licenseKey, body) {
2588
2625
  return _async_to_generator(function() {
2589
- var clientInfo, browserId, trackingData, headers, response, error;
2626
+ var response;
2590
2627
  return _ts_generator(this, function(_state) {
2591
2628
  switch(_state.label){
2592
2629
  case 0:
2593
- _state.trys.push([
2594
- 0,
2595
- 4,
2596
- ,
2597
- 5
2598
- ]);
2599
- clientInfo = getClientInfo();
2600
2630
  return [
2601
2631
  4,
2602
- getBrowserID(clientInfo)
2632
+ fetch(TRACK_URL, {
2633
+ method: "POST",
2634
+ headers: buildHeaders(licenseKey),
2635
+ body: JSON.stringify(body)
2636
+ })
2603
2637
  ];
2604
2638
  case 1:
2605
- browserId = _state.sent();
2606
- trackingData = _object_spread({
2607
- browserId: browserId
2608
- }, clientInfo);
2609
- headers = {
2610
- "Content-Type": "application/json"
2611
- };
2639
+ response = _state.sent();
2640
+ if (!response.ok) {
2641
+ throw new Error("HTTP error! status: ".concat(response.status));
2642
+ }
2643
+ return [
2644
+ 4,
2645
+ response.json()
2646
+ ];
2647
+ case 2:
2648
+ _state.sent();
2649
+ return [
2650
+ 2
2651
+ ];
2652
+ }
2653
+ });
2654
+ })();
2655
+ }
2656
+ function postJson(url, licenseKey, body) {
2657
+ return _async_to_generator(function() {
2658
+ var response;
2659
+ return _ts_generator(this, function(_state) {
2660
+ switch(_state.label){
2661
+ case 0:
2612
2662
  return [
2613
2663
  4,
2614
- fetch("https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track", {
2664
+ fetch(url, {
2615
2665
  method: "POST",
2616
- headers: headers,
2617
- body: JSON.stringify(trackingData)
2666
+ headers: buildHeaders(licenseKey),
2667
+ body: JSON.stringify(body)
2618
2668
  })
2619
2669
  ];
2620
- case 2:
2670
+ case 1:
2621
2671
  response = _state.sent();
2622
2672
  if (!response.ok) {
2623
2673
  throw new Error("HTTP error! status: ".concat(response.status));
@@ -2626,35 +2676,63 @@ function sendInitialTracking(licenseKey) {
2626
2676
  4,
2627
2677
  response.json()
2628
2678
  ];
2629
- case 3:
2679
+ case 2:
2630
2680
  _state.sent();
2631
2681
  return [
2632
- 3,
2633
- 5
2682
+ 2
2634
2683
  ];
2635
- case 4:
2636
- error = _state.sent();
2637
- console.error("[StormcloudVideoPlayer] Error sending initial tracking data:", error);
2684
+ }
2685
+ });
2686
+ })();
2687
+ }
2688
+ function buildPlayerMetricEvent(_0) {
2689
+ return _async_to_generator(function(licenseKey) {
2690
+ var context, flags, _flags_captureAt, clientInfo, browserId, captureAt;
2691
+ var _arguments = arguments;
2692
+ return _ts_generator(this, function(_state) {
2693
+ switch(_state.label){
2694
+ case 0:
2695
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2696
+ clientInfo = getClientInfo();
2638
2697
  return [
2639
- 3,
2640
- 5
2698
+ 4,
2699
+ getBrowserID(clientInfo)
2641
2700
  ];
2642
- case 5:
2701
+ case 1:
2702
+ browserId = _state.sent();
2703
+ captureAt = (_flags_captureAt = flags.captureAt) !== null && _flags_captureAt !== void 0 ? _flags_captureAt : /* @__PURE__ */ new Date().toISOString();
2643
2704
  return [
2644
- 2
2705
+ 2,
2706
+ {
2707
+ player_id: browserId,
2708
+ browserId: browserId,
2709
+ device_type: clientInfo.deviceType,
2710
+ deviceType: clientInfo.deviceType,
2711
+ input_stream_type: context.inputStreamType,
2712
+ os: clientInfo.os,
2713
+ ad_loaded: flags.adLoaded,
2714
+ ad_detect: flags.adDetect,
2715
+ license_key: licenseKey,
2716
+ capture_at: captureAt,
2717
+ timestamp: captureAt
2718
+ }
2645
2719
  ];
2646
2720
  }
2647
2721
  });
2648
- })();
2722
+ }).apply(this, arguments);
2649
2723
  }
2650
- function sendHeartbeat(licenseKey) {
2651
- return _async_to_generator(function() {
2652
- var clientInfo, browserId, heartbeatData, headers, response, error;
2724
+ function sendInitialTracking(_0) {
2725
+ return _async_to_generator(function(licenseKey) {
2726
+ var context, clientInfo, browserId, trackingData, error;
2727
+ var _arguments = arguments;
2653
2728
  return _ts_generator(this, function(_state) {
2654
2729
  switch(_state.label){
2655
2730
  case 0:
2731
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
2732
+ _state.label = 1;
2733
+ case 1:
2656
2734
  _state.trys.push([
2657
- 0,
2735
+ 1,
2658
2736
  4,
2659
2737
  ,
2660
2738
  5
@@ -2664,35 +2742,29 @@ function sendHeartbeat(licenseKey) {
2664
2742
  4,
2665
2743
  getBrowserID(clientInfo)
2666
2744
  ];
2667
- case 1:
2745
+ case 2:
2668
2746
  browserId = _state.sent();
2669
- heartbeatData = {
2670
- browserId: browserId,
2671
- timestamp: /* @__PURE__ */ new Date().toISOString()
2672
- };
2673
- headers = {
2674
- "Content-Type": "application/json"
2675
- };
2676
- if (licenseKey) {
2677
- headers["Authorization"] = "Bearer ".concat(licenseKey);
2678
- }
2747
+ trackingData = _object_spread({
2748
+ browserId: browserId
2749
+ }, clientInfo);
2679
2750
  return [
2680
2751
  4,
2681
- fetch("https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat", {
2682
- method: "POST",
2683
- headers: headers,
2684
- body: JSON.stringify(heartbeatData)
2752
+ sendTrackRequest(licenseKey, {
2753
+ events: [
2754
+ {
2755
+ player_id: browserId,
2756
+ device_type: clientInfo.deviceType,
2757
+ input_stream_type: context.inputStreamType,
2758
+ os: clientInfo.os,
2759
+ ad_loaded: false,
2760
+ ad_detect: false,
2761
+ license_key: licenseKey,
2762
+ capture_at: /* @__PURE__ */ new Date().toISOString()
2763
+ }
2764
+ ],
2765
+ trackingData: trackingData
2685
2766
  })
2686
2767
  ];
2687
- case 2:
2688
- response = _state.sent();
2689
- if (!response.ok) {
2690
- throw new Error("HTTP error! status: ".concat(response.status));
2691
- }
2692
- return [
2693
- 4,
2694
- response.json()
2695
- ];
2696
2768
  case 3:
2697
2769
  _state.sent();
2698
2770
  return [
@@ -2701,7 +2773,7 @@ function sendHeartbeat(licenseKey) {
2701
2773
  ];
2702
2774
  case 4:
2703
2775
  error = _state.sent();
2704
- console.error("[StormcloudVideoPlayer] Error sending heartbeat:", error);
2776
+ console.error("[StormcloudVideoPlayer] Error sending initial tracking data:", error);
2705
2777
  return [
2706
2778
  3,
2707
2779
  5
@@ -2712,95 +2784,74 @@ function sendHeartbeat(licenseKey) {
2712
2784
  ];
2713
2785
  }
2714
2786
  });
2715
- })();
2787
+ }).apply(this, arguments);
2716
2788
  }
2717
- var TRACK_API_URL = "https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track";
2718
- function mapToAdTrackingSource(source, adPlayerType) {
2719
- if (source === "prebid" || source === "ima" || source === "hls") {
2720
- return source;
2721
- }
2722
- if (source === "preload" || source === "ssp") {
2723
- return source === "ssp" ? "prebid" : "ima";
2724
- }
2725
- return adPlayerType === "hls" ? "hls" : "ima";
2726
- }
2727
- function postAdTracking(licenseKey, body) {
2728
- return _async_to_generator(function() {
2729
- var headers, response;
2789
+ function sendAdDetectTracking(_0, _1) {
2790
+ return _async_to_generator(function(licenseKey, adDetectInfo) {
2791
+ var context, error;
2792
+ var _arguments = arguments;
2730
2793
  return _ts_generator(this, function(_state) {
2731
2794
  switch(_state.label){
2732
2795
  case 0:
2733
- headers = {
2734
- "Content-Type": "application/json"
2735
- };
2736
- if (licenseKey) {
2737
- headers["Authorization"] = "Bearer ".concat(licenseKey);
2738
- }
2739
- return [
2740
- 4,
2741
- fetch(TRACK_API_URL, {
2742
- method: "POST",
2743
- headers: headers,
2744
- body: JSON.stringify(body)
2745
- })
2746
- ];
2796
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2797
+ _state.label = 1;
2747
2798
  case 1:
2748
- response = _state.sent();
2749
- if (!response.ok) {
2750
- throw new Error("HTTP error! status: ".concat(response.status));
2751
- }
2799
+ _state.trys.push([
2800
+ 1,
2801
+ 3,
2802
+ ,
2803
+ 4
2804
+ ]);
2752
2805
  return [
2753
2806
  4,
2754
- response.json()
2807
+ sendHeartbeat(licenseKey, context, {
2808
+ adDetect: true,
2809
+ captureAt: adDetectInfo.timestamp
2810
+ })
2755
2811
  ];
2756
2812
  case 2:
2757
2813
  _state.sent();
2814
+ return [
2815
+ 3,
2816
+ 4
2817
+ ];
2818
+ case 3:
2819
+ error = _state.sent();
2820
+ console.error("[StormcloudVideoPlayer] Error sending ad detect tracking:", error);
2821
+ return [
2822
+ 3,
2823
+ 4
2824
+ ];
2825
+ case 4:
2758
2826
  return [
2759
2827
  2
2760
2828
  ];
2761
2829
  }
2762
2830
  });
2763
- })();
2831
+ }).apply(this, arguments);
2764
2832
  }
2765
- function sendAdDetectTracking(licenseKey, payload) {
2766
- return _async_to_generator(function() {
2767
- var _payload_source, _payload_timestamp, clientInfo, browserId, adDetectInfo, body, error;
2833
+ function sendAdLoadedTracking(_0, _1) {
2834
+ return _async_to_generator(function(licenseKey, adLoadedInfo) {
2835
+ var context, error;
2836
+ var _arguments = arguments;
2768
2837
  return _ts_generator(this, function(_state) {
2769
2838
  switch(_state.label){
2770
2839
  case 0:
2840
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2841
+ _state.label = 1;
2842
+ case 1:
2771
2843
  _state.trys.push([
2772
- 0,
2844
+ 1,
2773
2845
  3,
2774
2846
  ,
2775
2847
  4
2776
2848
  ]);
2777
- clientInfo = getClientInfo();
2778
- return [
2779
- 4,
2780
- getBrowserID(clientInfo)
2781
- ];
2782
- case 1:
2783
- browserId = _state.sent();
2784
- adDetectInfo = _object_spread({
2785
- source: (_payload_source = payload.source) !== null && _payload_source !== void 0 ? _payload_source : "scte35",
2786
- timestamp: (_payload_timestamp = payload.timestamp) !== null && _payload_timestamp !== void 0 ? _payload_timestamp : /* @__PURE__ */ new Date().toISOString()
2787
- }, payload.durationSeconds != null && {
2788
- durationSeconds: payload.durationSeconds
2789
- }, payload.ptsSeconds != null && {
2790
- ptsSeconds: payload.ptsSeconds
2791
- }, payload.detectedAtFragmentSn != null && {
2792
- detectedAtFragmentSn: payload.detectedAtFragmentSn
2793
- });
2794
- body = _object_spread_props(_object_spread({
2795
- browserId: browserId
2796
- }, clientInfo, licenseKey && {
2797
- licenseKey: licenseKey
2798
- }), {
2799
- adDetectInfo: adDetectInfo
2800
- });
2801
2849
  return [
2802
2850
  4,
2803
- postAdTracking(licenseKey, body)
2851
+ sendHeartbeat(licenseKey, context, {
2852
+ adLoaded: true,
2853
+ captureAt: adLoadedInfo.timestamp
2854
+ })
2804
2855
  ];
2805
2856
  case 2:
2806
2857
  _state.sent();
@@ -2810,7 +2861,7 @@ function sendAdDetectTracking(licenseKey, payload) {
2810
2861
  ];
2811
2862
  case 3:
2812
2863
  error = _state.sent();
2813
- console.error("[StormcloudVideoPlayer] Error sending ad-detect tracking:", error);
2864
+ console.error("[StormcloudVideoPlayer] Error sending ad loaded tracking:", error);
2814
2865
  return [
2815
2866
  3,
2816
2867
  4
@@ -2821,126 +2872,116 @@ function sendAdDetectTracking(licenseKey, payload) {
2821
2872
  ];
2822
2873
  }
2823
2874
  });
2824
- })();
2875
+ }).apply(this, arguments);
2825
2876
  }
2826
- function sendAdLoadedTracking(licenseKey, payload, adPlayerType) {
2827
- return _async_to_generator(function() {
2828
- var clientInfo, browserId, source, adLoadedInfo, body, error;
2877
+ function sendAdImpressionTracking(_0, _1) {
2878
+ return _async_to_generator(function(licenseKey, adImpressionInfo) {
2879
+ var context, metricEvent, error;
2880
+ var _arguments = arguments;
2829
2881
  return _ts_generator(this, function(_state) {
2830
2882
  switch(_state.label){
2831
2883
  case 0:
2884
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2885
+ _state.label = 1;
2886
+ case 1:
2832
2887
  _state.trys.push([
2833
- 0,
2834
- 3,
2888
+ 1,
2889
+ 4,
2835
2890
  ,
2836
- 4
2891
+ 5
2837
2892
  ]);
2838
- clientInfo = getClientInfo();
2839
2893
  return [
2840
2894
  4,
2841
- getBrowserID(clientInfo)
2895
+ buildPlayerMetricEvent(licenseKey, context, {
2896
+ captureAt: adImpressionInfo.timestamp
2897
+ })
2842
2898
  ];
2843
- case 1:
2844
- browserId = _state.sent();
2845
- source = mapToAdTrackingSource(payload.source, adPlayerType);
2846
- adLoadedInfo = _object_spread({
2847
- source: source,
2848
- timestamp: /* @__PURE__ */ new Date().toISOString()
2849
- }, payload.vastUrl != null && {
2850
- vastUrl: payload.vastUrl
2851
- }, payload.durationSeconds != null && {
2852
- durationSeconds: payload.durationSeconds
2853
- });
2854
- body = _object_spread_props(_object_spread({
2855
- browserId: browserId
2856
- }, clientInfo, licenseKey && {
2857
- licenseKey: licenseKey
2858
- }), {
2859
- adLoadedInfo: adLoadedInfo
2860
- });
2899
+ case 2:
2900
+ metricEvent = _state.sent();
2861
2901
  return [
2862
2902
  4,
2863
- postAdTracking(licenseKey, body)
2903
+ Promise.all([
2904
+ postJson(HEARTBEAT_URL, licenseKey, metricEvent),
2905
+ postJson(IMPRESSIONS_URL, licenseKey, {
2906
+ events: [
2907
+ {
2908
+ player_id: metricEvent.player_id,
2909
+ ad_played_count: 1,
2910
+ ad_url: adImpressionInfo.adUrl,
2911
+ license_key: licenseKey,
2912
+ capture_at: adImpressionInfo.timestamp
2913
+ }
2914
+ ]
2915
+ })
2916
+ ])
2864
2917
  ];
2865
- case 2:
2918
+ case 3:
2866
2919
  _state.sent();
2867
2920
  return [
2868
2921
  3,
2869
- 4
2922
+ 5
2870
2923
  ];
2871
- case 3:
2924
+ case 4:
2872
2925
  error = _state.sent();
2873
- console.error("[StormcloudVideoPlayer] Error sending ad-loaded tracking:", error);
2926
+ console.error("[StormcloudVideoPlayer] Error sending ad impression tracking:", error);
2874
2927
  return [
2875
2928
  3,
2876
- 4
2929
+ 5
2877
2930
  ];
2878
- case 4:
2931
+ case 5:
2879
2932
  return [
2880
2933
  2
2881
2934
  ];
2882
2935
  }
2883
2936
  });
2884
- })();
2937
+ }).apply(this, arguments);
2885
2938
  }
2886
- function sendAdImpressionTracking(licenseKey, payload, adPlayerType) {
2887
- return _async_to_generator(function() {
2888
- var clientInfo, browserId, source, adImpressionInfo, body, error;
2939
+ function sendHeartbeat(_0) {
2940
+ return _async_to_generator(function(licenseKey) {
2941
+ var context, flags, heartbeatData, error;
2942
+ var _arguments = arguments;
2889
2943
  return _ts_generator(this, function(_state) {
2890
2944
  switch(_state.label){
2891
2945
  case 0:
2946
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2947
+ _state.label = 1;
2948
+ case 1:
2892
2949
  _state.trys.push([
2893
- 0,
2894
- 3,
2950
+ 1,
2951
+ 4,
2895
2952
  ,
2896
- 4
2953
+ 5
2897
2954
  ]);
2898
- clientInfo = getClientInfo();
2899
2955
  return [
2900
2956
  4,
2901
- getBrowserID(clientInfo)
2957
+ buildPlayerMetricEvent(licenseKey, context, flags)
2902
2958
  ];
2903
- case 1:
2904
- browserId = _state.sent();
2905
- source = mapToAdTrackingSource(payload.source, adPlayerType);
2906
- adImpressionInfo = _object_spread({
2907
- source: source,
2908
- adIndex: payload.adIndex,
2909
- timestamp: /* @__PURE__ */ new Date().toISOString()
2910
- }, payload.durationSeconds != null && {
2911
- durationSeconds: payload.durationSeconds
2912
- });
2913
- body = _object_spread_props(_object_spread({
2914
- browserId: browserId
2915
- }, clientInfo, licenseKey && {
2916
- licenseKey: licenseKey
2917
- }), {
2918
- adImpressionInfo: adImpressionInfo
2919
- });
2959
+ case 2:
2960
+ heartbeatData = _state.sent();
2920
2961
  return [
2921
2962
  4,
2922
- postAdTracking(licenseKey, body)
2963
+ postJson(HEARTBEAT_URL, licenseKey, heartbeatData)
2923
2964
  ];
2924
- case 2:
2965
+ case 3:
2925
2966
  _state.sent();
2926
2967
  return [
2927
2968
  3,
2928
- 4
2969
+ 5
2929
2970
  ];
2930
- case 3:
2971
+ case 4:
2931
2972
  error = _state.sent();
2932
- console.error("[StormcloudVideoPlayer] Error sending ad-impression tracking:", error);
2973
+ console.error("[StormcloudVideoPlayer] Error sending heartbeat:", error);
2933
2974
  return [
2934
2975
  3,
2935
- 4
2976
+ 5
2936
2977
  ];
2937
- case 4:
2978
+ case 5:
2938
2979
  return [
2939
2980
  2
2940
2981
  ];
2941
2982
  }
2942
2983
  });
2943
- })();
2984
+ }).apply(this, arguments);
2944
2985
  }
2945
2986
  // src/utils/polyfills.ts
2946
2987
  function polyfillURLSearchParams() {
@@ -3733,8 +3774,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3733
3774
  var _this = this;
3734
3775
  this.ima.on("all_ads_completed", function() {
3735
3776
  sendAdImpressionTracking(_this.config.licenseKey, {
3736
- adIndex: _this.currentAdIndex
3737
- }, _this.config.adPlayerType).catch(function() {});
3777
+ source: "ima",
3778
+ adIndex: _this.currentAdIndex,
3779
+ timestamp: /* @__PURE__ */ new Date().toISOString()
3780
+ }).catch(function() {});
3738
3781
  var remaining = _this.getRemainingAdMs();
3739
3782
  _this.consecutiveFailures = 0;
3740
3783
  if (_this.config.debugAdTiming) {
@@ -3795,8 +3838,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3795
3838
  });
3796
3839
  this.ima.on("content_resume", function() {
3797
3840
  sendAdImpressionTracking(_this.config.licenseKey, {
3798
- adIndex: _this.currentAdIndex
3799
- }, _this.config.adPlayerType).catch(function() {});
3841
+ source: "ima",
3842
+ adIndex: _this.currentAdIndex,
3843
+ timestamp: /* @__PURE__ */ new Date().toISOString()
3844
+ }).catch(function() {});
3800
3845
  if (!_this.video.muted) {
3801
3846
  _this.video.muted = true;
3802
3847
  _this.video.volume = 0;
@@ -4430,7 +4475,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4430
4475
  var detectPayload = {};
4431
4476
  if (marker.durationSeconds != null) detectPayload.durationSeconds = marker.durationSeconds;
4432
4477
  if (marker.ptsSeconds != null) detectPayload.ptsSeconds = marker.ptsSeconds;
4433
- sendAdDetectTracking(this.config.licenseKey, detectPayload).catch(function() {});
4478
+ sendAdDetectTracking(this.config.licenseKey, _object_spread({
4479
+ source: "scte35",
4480
+ timestamp: /* @__PURE__ */ new Date().toISOString()
4481
+ }, detectPayload)).catch(function() {});
4434
4482
  }
4435
4483
  var hasPrefetchedAds = this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0;
4436
4484
  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;
@@ -5672,7 +5720,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5672
5720
  if (marker.durationSeconds != null) detectPayload.durationSeconds = marker.durationSeconds;
5673
5721
  if (marker.ptsSeconds != null) detectPayload.ptsSeconds = marker.ptsSeconds;
5674
5722
  if (fragmentSn !== void 0) detectPayload.detectedAtFragmentSn = fragmentSn;
5675
- sendAdDetectTracking(this.config.licenseKey, detectPayload).catch(function() {});
5723
+ sendAdDetectTracking(this.config.licenseKey, _object_spread({
5724
+ source: "scte35",
5725
+ timestamp: /* @__PURE__ */ new Date().toISOString()
5726
+ }, detectPayload)).catch(function() {});
5676
5727
  if (this.config.debugAdTiming) {
5677
5728
  console.log("[PREFETCH] \uD83D\uDD04 Starting ad prefetch for upcoming ad break");
5678
5729
  console.log("[PREFETCH] \uD83D\uDCCB Pre-generated ".concat(generatedUrls.length, " VAST URLs"));
@@ -6153,9 +6204,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6153
6204
  preloadedController = preloaded.imaController;
6154
6205
  usePreloadedAd = true;
6155
6206
  sendAdLoadedTracking(this.config.licenseKey, {
6156
- source: "preload",
6157
- vastUrl: firstAdUrl
6158
- }, this.config.adPlayerType).catch(function() {});
6207
+ source: "ima",
6208
+ vastUrl: firstAdUrl,
6209
+ timestamp: /* @__PURE__ */ new Date().toISOString()
6210
+ }).catch(function() {});
6159
6211
  if (this.config.debugAdTiming) {
6160
6212
  console.log("[CONTINUOUS-FETCH] \uD83D\uDE80 Using preloaded ad from pool (preloaded in advance, ready immediately!)");
6161
6213
  console.log("[CONTINUOUS-FETCH] Pool still has ".concat(this.preloadPool.length, " preloaded ads ready"));
@@ -6245,9 +6297,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6245
6297
  case 5:
6246
6298
  _state.sent();
6247
6299
  sendAdLoadedTracking(this.config.licenseKey, {
6248
- source: "ssp",
6249
- vastUrl: firstAdUrl
6250
- }, this.config.adPlayerType).catch(function() {});
6300
+ source: "ima",
6301
+ vastUrl: firstAdUrl,
6302
+ timestamp: /* @__PURE__ */ new Date().toISOString()
6303
+ }).catch(function() {});
6251
6304
  if (this.config.debugAdTiming) {
6252
6305
  console.log("[CONTINUOUS-FETCH] \u2705 First ad request successful, starting playback");
6253
6306
  }
@@ -6643,9 +6696,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6643
6696
  console.log("[CONTINUOUS-FETCH] \uD83C\uDFAF Using preloaded ad from pool (".concat(this.preloadPool.length, " remaining in pool)"));
6644
6697
  }
6645
6698
  sendAdLoadedTracking(this.config.licenseKey, {
6646
- source: "preload",
6647
- vastUrl: preloaded.vastUrl
6648
- }, this.config.adPlayerType).catch(function() {});
6699
+ source: "ima",
6700
+ vastUrl: preloaded.vastUrl,
6701
+ timestamp: /* @__PURE__ */ new Date().toISOString()
6702
+ }).catch(function() {});
6649
6703
  _state.label = 1;
6650
6704
  case 1:
6651
6705
  _state.trys.push([
@@ -7397,9 +7451,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7397
7451
  case 3:
7398
7452
  _state.sent();
7399
7453
  sendAdLoadedTracking(this.config.licenseKey, {
7400
- source: "ssp",
7401
- vastUrl: vastTagUrl
7402
- }, this.config.adPlayerType).catch(function() {});
7454
+ source: "ima",
7455
+ vastUrl: vastTagUrl,
7456
+ timestamp: /* @__PURE__ */ new Date().toISOString()
7457
+ }).catch(function() {});
7403
7458
  this.clearAdRequestWatchdog();
7404
7459
  if (this.activeAdRequestToken !== requestToken) {
7405
7460
  return [