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.cjs CHANGED
@@ -1935,6 +1935,16 @@ function createHlsAdPlayer(contentVideo, options) {
1935
1935
  });
1936
1936
  return bestMatch.file;
1937
1937
  }
1938
+ function isHlsMediaFile(mediaFile) {
1939
+ var type = mediaFile.type.toLowerCase();
1940
+ var url = mediaFile.url.toLowerCase();
1941
+ return type === "application/x-mpegurl" || type === "application/vnd.apple.mpegurl" || type.includes("mpegurl") || url.includes(".m3u8");
1942
+ }
1943
+ function isProgressiveMediaFile(mediaFile) {
1944
+ var type = mediaFile.type.toLowerCase();
1945
+ var url = mediaFile.url.toLowerCase();
1946
+ return type.startsWith("video/") || url.endsWith(".mp4") || url.includes(".mp4?");
1947
+ }
1938
1948
  function parseVastXml(xmlString) {
1939
1949
  try {
1940
1950
  var _xmlDoc_querySelector, _xmlDoc_querySelector1, _xmlDoc_querySelector_textContent, _xmlDoc_querySelector2;
@@ -1966,30 +1976,32 @@ function createHlsAdPlayer(contentVideo, options) {
1966
1976
  var width = mf.getAttribute("width") || "";
1967
1977
  var height = mf.getAttribute("height") || "";
1968
1978
  console.log("[HlsAdPlayer] MediaFile ".concat(index, ': type="').concat(type, '", url="').concat(url, '", width="').concat(width, '", height="').concat(height, '"'));
1969
- if (type === "application/x-mpegURL" || type.includes("m3u8")) {
1970
- if (!url) {
1971
- console.warn("[HlsAdPlayer] MediaFile ".concat(index, " has HLS type but empty URL"));
1972
- return;
1973
- }
1974
- var bitrateAttr = mf.getAttribute("bitrate");
1975
- var bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;
1976
- mediaFiles.push({
1977
- url: url,
1978
- type: type,
1979
- width: parseInt(width || "1920", 10),
1980
- height: parseInt(height || "1080", 10),
1981
- bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : void 0
1982
- });
1983
- console.log("[HlsAdPlayer] Added HLS MediaFile: ".concat(url));
1979
+ var mediaFile = {
1980
+ url: url,
1981
+ type: type,
1982
+ width: parseInt(width || "1920", 10),
1983
+ height: parseInt(height || "1080", 10),
1984
+ bitrate: void 0
1985
+ };
1986
+ if (!url) {
1987
+ console.warn("[HlsAdPlayer] MediaFile ".concat(index, " has empty URL"));
1988
+ return;
1989
+ }
1990
+ var bitrateAttr = mf.getAttribute("bitrate");
1991
+ var bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;
1992
+ mediaFile.bitrate = bitrateValue && bitrateValue > 0 ? bitrateValue : void 0;
1993
+ if (isHlsMediaFile(mediaFile) || isProgressiveMediaFile(mediaFile)) {
1994
+ mediaFiles.push(mediaFile);
1995
+ console.log("[HlsAdPlayer] Added ".concat(isHlsMediaFile(mediaFile) ? "HLS" : "progressive", " MediaFile: ").concat(url));
1984
1996
  } else {
1985
- console.log("[HlsAdPlayer] MediaFile ".concat(index, ' ignored (type="').concat(type, '" is not HLS)'));
1997
+ console.log("[HlsAdPlayer] MediaFile ".concat(index, ' ignored (type="').concat(type, '" is not supported)'));
1986
1998
  }
1987
1999
  });
1988
2000
  if (mediaFiles.length === 0) {
1989
2001
  if (isNoAdAvailable) {
1990
2002
  console.warn("[HlsAdPlayer] No ads available (VAST response indicates no ads)");
1991
2003
  } else {
1992
- console.warn("[HlsAdPlayer] No HLS media files found in VAST XML");
2004
+ console.warn("[HlsAdPlayer] No supported media files found in VAST XML");
1993
2005
  }
1994
2006
  return null;
1995
2007
  }
@@ -2286,7 +2298,7 @@ function createHlsAdPlayer(contentVideo, options) {
2286
2298
  },
2287
2299
  play: function play() {
2288
2300
  return _async_to_generator(function() {
2289
- var contentVolume, adVolume, mediaFile;
2301
+ var contentVolume, adVolume, mediaFile, isHlsAd;
2290
2302
  return _ts_generator(this, function(_state) {
2291
2303
  if (!currentAd) {
2292
2304
  console.warn("[HlsAdPlayer] Cannot play: No ad loaded (no ads available)");
@@ -2338,8 +2350,9 @@ function createHlsAdPlayer(contentVideo, options) {
2338
2350
  if (!mediaFile) {
2339
2351
  throw new Error("No media file available for ad");
2340
2352
  }
2341
- console.log("[HlsAdPlayer] Loading ad from: ".concat(mediaFile.url));
2342
- if (import_hls.default.isSupported()) {
2353
+ isHlsAd = isHlsMediaFile(mediaFile);
2354
+ console.log("[HlsAdPlayer] Loading ".concat(isHlsAd ? "HLS" : "progressive", " ad from: ").concat(mediaFile.url));
2355
+ if (isHlsAd && import_hls.default.isSupported()) {
2343
2356
  if (adHls) {
2344
2357
  adHls.destroy();
2345
2358
  }
@@ -2362,14 +2375,25 @@ function createHlsAdPlayer(contentVideo, options) {
2362
2375
  handleAdError();
2363
2376
  }
2364
2377
  });
2365
- } else if (adVideoElement.canPlayType("application/vnd.apple.mpegurl")) {
2378
+ } else if (isHlsAd && adVideoElement.canPlayType("application/vnd.apple.mpegurl")) {
2366
2379
  adVideoElement.src = mediaFile.url;
2367
2380
  adVideoElement.play().catch(function(error) {
2368
2381
  console.error("[HlsAdPlayer] Error starting ad playback:", error);
2369
2382
  handleAdError();
2370
2383
  });
2384
+ } else if (!isHlsAd && isProgressiveMediaFile(mediaFile)) {
2385
+ if (adHls) {
2386
+ adHls.destroy();
2387
+ adHls = void 0;
2388
+ }
2389
+ adVideoElement.src = mediaFile.url;
2390
+ adVideoElement.load();
2391
+ adVideoElement.play().catch(function(error) {
2392
+ console.error("[HlsAdPlayer] Error starting progressive ad playback:", error);
2393
+ handleAdError();
2394
+ });
2371
2395
  } else {
2372
- throw new Error("HLS not supported");
2396
+ throw new Error("Unsupported ad media file type: ".concat(mediaFile.type));
2373
2397
  }
2374
2398
  return [
2375
2399
  2,
@@ -2810,40 +2834,66 @@ function getBrowserID(clientInfo) {
2810
2834
  });
2811
2835
  })();
2812
2836
  }
2813
- function sendInitialTracking(licenseKey) {
2837
+ var PLAYER_TRACKING_BASE_URL = "https://adstorm.co/api-adstorm-dev/adstorm/player-tracking";
2838
+ var TRACK_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/metrics/ingest");
2839
+ var HEARTBEAT_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/heartbeat");
2840
+ var IMPRESSIONS_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/impressions/ingest");
2841
+ function buildHeaders(licenseKey) {
2842
+ var headers = {
2843
+ "Content-Type": "application/json"
2844
+ };
2845
+ if (licenseKey) {
2846
+ headers["Authorization"] = "Bearer ".concat(licenseKey);
2847
+ }
2848
+ return headers;
2849
+ }
2850
+ function sendTrackRequest(licenseKey, body) {
2814
2851
  return _async_to_generator(function() {
2815
- var clientInfo, browserId, trackingData, headers, response, error;
2852
+ var response;
2816
2853
  return _ts_generator(this, function(_state) {
2817
2854
  switch(_state.label){
2818
2855
  case 0:
2819
- _state.trys.push([
2820
- 0,
2821
- 4,
2822
- ,
2823
- 5
2824
- ]);
2825
- clientInfo = getClientInfo();
2826
2856
  return [
2827
2857
  4,
2828
- getBrowserID(clientInfo)
2858
+ fetch(TRACK_URL, {
2859
+ method: "POST",
2860
+ headers: buildHeaders(licenseKey),
2861
+ body: JSON.stringify(body)
2862
+ })
2829
2863
  ];
2830
2864
  case 1:
2831
- browserId = _state.sent();
2832
- trackingData = _object_spread({
2833
- browserId: browserId
2834
- }, clientInfo);
2835
- headers = {
2836
- "Content-Type": "application/json"
2837
- };
2865
+ response = _state.sent();
2866
+ if (!response.ok) {
2867
+ throw new Error("HTTP error! status: ".concat(response.status));
2868
+ }
2869
+ return [
2870
+ 4,
2871
+ response.json()
2872
+ ];
2873
+ case 2:
2874
+ _state.sent();
2875
+ return [
2876
+ 2
2877
+ ];
2878
+ }
2879
+ });
2880
+ })();
2881
+ }
2882
+ function postJson(url, licenseKey, body) {
2883
+ return _async_to_generator(function() {
2884
+ var response;
2885
+ return _ts_generator(this, function(_state) {
2886
+ switch(_state.label){
2887
+ case 0:
2838
2888
  return [
2839
2889
  4,
2840
- fetch("https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track", {
2890
+ fetch(url, {
2841
2891
  method: "POST",
2842
- headers: headers,
2843
- body: JSON.stringify(trackingData)
2892
+ headers: buildHeaders(licenseKey),
2893
+ body: JSON.stringify(body)
2844
2894
  })
2845
2895
  ];
2846
- case 2:
2896
+ case 1:
2847
2897
  response = _state.sent();
2848
2898
  if (!response.ok) {
2849
2899
  throw new Error("HTTP error! status: ".concat(response.status));
@@ -2852,35 +2902,63 @@ function sendInitialTracking(licenseKey) {
2852
2902
  4,
2853
2903
  response.json()
2854
2904
  ];
2855
- case 3:
2905
+ case 2:
2856
2906
  _state.sent();
2857
2907
  return [
2858
- 3,
2859
- 5
2908
+ 2
2860
2909
  ];
2861
- case 4:
2862
- error = _state.sent();
2863
- console.error("[StormcloudVideoPlayer] Error sending initial tracking data:", error);
2910
+ }
2911
+ });
2912
+ })();
2913
+ }
2914
+ function buildPlayerMetricEvent(_0) {
2915
+ return _async_to_generator(function(licenseKey) {
2916
+ var context, flags, _flags_captureAt, clientInfo, browserId, captureAt;
2917
+ var _arguments = arguments;
2918
+ return _ts_generator(this, function(_state) {
2919
+ switch(_state.label){
2920
+ case 0:
2921
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2922
+ clientInfo = getClientInfo();
2864
2923
  return [
2865
- 3,
2866
- 5
2924
+ 4,
2925
+ getBrowserID(clientInfo)
2867
2926
  ];
2868
- case 5:
2927
+ case 1:
2928
+ browserId = _state.sent();
2929
+ captureAt = (_flags_captureAt = flags.captureAt) !== null && _flags_captureAt !== void 0 ? _flags_captureAt : /* @__PURE__ */ new Date().toISOString();
2869
2930
  return [
2870
- 2
2931
+ 2,
2932
+ {
2933
+ player_id: browserId,
2934
+ browserId: browserId,
2935
+ device_type: clientInfo.deviceType,
2936
+ deviceType: clientInfo.deviceType,
2937
+ input_stream_type: context.inputStreamType,
2938
+ os: clientInfo.os,
2939
+ ad_loaded: flags.adLoaded,
2940
+ ad_detect: flags.adDetect,
2941
+ license_key: licenseKey,
2942
+ capture_at: captureAt,
2943
+ timestamp: captureAt
2944
+ }
2871
2945
  ];
2872
2946
  }
2873
2947
  });
2874
- })();
2948
+ }).apply(this, arguments);
2875
2949
  }
2876
- function sendHeartbeat(licenseKey) {
2877
- return _async_to_generator(function() {
2878
- var clientInfo, browserId, heartbeatData, headers, response, error;
2950
+ function sendInitialTracking(_0) {
2951
+ return _async_to_generator(function(licenseKey) {
2952
+ var context, clientInfo, browserId, trackingData, error;
2953
+ var _arguments = arguments;
2879
2954
  return _ts_generator(this, function(_state) {
2880
2955
  switch(_state.label){
2881
2956
  case 0:
2957
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
2958
+ _state.label = 1;
2959
+ case 1:
2882
2960
  _state.trys.push([
2883
- 0,
2961
+ 1,
2884
2962
  4,
2885
2963
  ,
2886
2964
  5
@@ -2890,35 +2968,29 @@ function sendHeartbeat(licenseKey) {
2890
2968
  4,
2891
2969
  getBrowserID(clientInfo)
2892
2970
  ];
2893
- case 1:
2971
+ case 2:
2894
2972
  browserId = _state.sent();
2895
- heartbeatData = {
2896
- browserId: browserId,
2897
- timestamp: /* @__PURE__ */ new Date().toISOString()
2898
- };
2899
- headers = {
2900
- "Content-Type": "application/json"
2901
- };
2902
- if (licenseKey) {
2903
- headers["Authorization"] = "Bearer ".concat(licenseKey);
2904
- }
2973
+ trackingData = _object_spread({
2974
+ browserId: browserId
2975
+ }, clientInfo);
2905
2976
  return [
2906
2977
  4,
2907
- fetch("https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat", {
2908
- method: "POST",
2909
- headers: headers,
2910
- body: JSON.stringify(heartbeatData)
2978
+ sendTrackRequest(licenseKey, {
2979
+ events: [
2980
+ {
2981
+ player_id: browserId,
2982
+ device_type: clientInfo.deviceType,
2983
+ input_stream_type: context.inputStreamType,
2984
+ os: clientInfo.os,
2985
+ ad_loaded: false,
2986
+ ad_detect: false,
2987
+ license_key: licenseKey,
2988
+ capture_at: /* @__PURE__ */ new Date().toISOString()
2989
+ }
2990
+ ],
2991
+ trackingData: trackingData
2911
2992
  })
2912
2993
  ];
2913
- case 2:
2914
- response = _state.sent();
2915
- if (!response.ok) {
2916
- throw new Error("HTTP error! status: ".concat(response.status));
2917
- }
2918
- return [
2919
- 4,
2920
- response.json()
2921
- ];
2922
2994
  case 3:
2923
2995
  _state.sent();
2924
2996
  return [
@@ -2927,7 +2999,7 @@ function sendHeartbeat(licenseKey) {
2927
2999
  ];
2928
3000
  case 4:
2929
3001
  error = _state.sent();
2930
- console.error("[StormcloudVideoPlayer] Error sending heartbeat:", error);
3002
+ console.error("[StormcloudVideoPlayer] Error sending initial tracking data:", error);
2931
3003
  return [
2932
3004
  3,
2933
3005
  5
@@ -2938,95 +3010,74 @@ function sendHeartbeat(licenseKey) {
2938
3010
  ];
2939
3011
  }
2940
3012
  });
2941
- })();
2942
- }
2943
- var TRACK_API_URL = "https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track";
2944
- function mapToAdTrackingSource(source, adPlayerType) {
2945
- if (source === "prebid" || source === "ima" || source === "hls") {
2946
- return source;
2947
- }
2948
- if (source === "preload" || source === "ssp") {
2949
- return source === "ssp" ? "prebid" : "ima";
2950
- }
2951
- return adPlayerType === "hls" ? "hls" : "ima";
3013
+ }).apply(this, arguments);
2952
3014
  }
2953
- function postAdTracking(licenseKey, body) {
2954
- return _async_to_generator(function() {
2955
- var headers, response;
3015
+ function sendAdDetectTracking(_0, _1) {
3016
+ return _async_to_generator(function(licenseKey, adDetectInfo) {
3017
+ var context, error;
3018
+ var _arguments = arguments;
2956
3019
  return _ts_generator(this, function(_state) {
2957
3020
  switch(_state.label){
2958
3021
  case 0:
2959
- headers = {
2960
- "Content-Type": "application/json"
2961
- };
2962
- if (licenseKey) {
2963
- headers["Authorization"] = "Bearer ".concat(licenseKey);
2964
- }
2965
- return [
2966
- 4,
2967
- fetch(TRACK_API_URL, {
2968
- method: "POST",
2969
- headers: headers,
2970
- body: JSON.stringify(body)
2971
- })
2972
- ];
3022
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
3023
+ _state.label = 1;
2973
3024
  case 1:
2974
- response = _state.sent();
2975
- if (!response.ok) {
2976
- throw new Error("HTTP error! status: ".concat(response.status));
2977
- }
3025
+ _state.trys.push([
3026
+ 1,
3027
+ 3,
3028
+ ,
3029
+ 4
3030
+ ]);
2978
3031
  return [
2979
3032
  4,
2980
- response.json()
3033
+ sendHeartbeat(licenseKey, context, {
3034
+ adDetect: true,
3035
+ captureAt: adDetectInfo.timestamp
3036
+ })
2981
3037
  ];
2982
3038
  case 2:
2983
3039
  _state.sent();
3040
+ return [
3041
+ 3,
3042
+ 4
3043
+ ];
3044
+ case 3:
3045
+ error = _state.sent();
3046
+ console.error("[StormcloudVideoPlayer] Error sending ad detect tracking:", error);
3047
+ return [
3048
+ 3,
3049
+ 4
3050
+ ];
3051
+ case 4:
2984
3052
  return [
2985
3053
  2
2986
3054
  ];
2987
3055
  }
2988
3056
  });
2989
- })();
3057
+ }).apply(this, arguments);
2990
3058
  }
2991
- function sendAdDetectTracking(licenseKey, payload) {
2992
- return _async_to_generator(function() {
2993
- var _payload_source, _payload_timestamp, clientInfo, browserId, adDetectInfo, body, error;
3059
+ function sendAdLoadedTracking(_0, _1) {
3060
+ return _async_to_generator(function(licenseKey, adLoadedInfo) {
3061
+ var context, error;
3062
+ var _arguments = arguments;
2994
3063
  return _ts_generator(this, function(_state) {
2995
3064
  switch(_state.label){
2996
3065
  case 0:
3066
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
3067
+ _state.label = 1;
3068
+ case 1:
2997
3069
  _state.trys.push([
2998
- 0,
3070
+ 1,
2999
3071
  3,
3000
3072
  ,
3001
3073
  4
3002
3074
  ]);
3003
- clientInfo = getClientInfo();
3004
- return [
3005
- 4,
3006
- getBrowserID(clientInfo)
3007
- ];
3008
- case 1:
3009
- browserId = _state.sent();
3010
- adDetectInfo = _object_spread({
3011
- source: (_payload_source = payload.source) !== null && _payload_source !== void 0 ? _payload_source : "scte35",
3012
- timestamp: (_payload_timestamp = payload.timestamp) !== null && _payload_timestamp !== void 0 ? _payload_timestamp : /* @__PURE__ */ new Date().toISOString()
3013
- }, payload.durationSeconds != null && {
3014
- durationSeconds: payload.durationSeconds
3015
- }, payload.ptsSeconds != null && {
3016
- ptsSeconds: payload.ptsSeconds
3017
- }, payload.detectedAtFragmentSn != null && {
3018
- detectedAtFragmentSn: payload.detectedAtFragmentSn
3019
- });
3020
- body = _object_spread_props(_object_spread({
3021
- browserId: browserId
3022
- }, clientInfo, licenseKey && {
3023
- licenseKey: licenseKey
3024
- }), {
3025
- adDetectInfo: adDetectInfo
3026
- });
3027
3075
  return [
3028
3076
  4,
3029
- postAdTracking(licenseKey, body)
3077
+ sendHeartbeat(licenseKey, context, {
3078
+ adLoaded: true,
3079
+ captureAt: adLoadedInfo.timestamp
3080
+ })
3030
3081
  ];
3031
3082
  case 2:
3032
3083
  _state.sent();
@@ -3036,7 +3087,7 @@ function sendAdDetectTracking(licenseKey, payload) {
3036
3087
  ];
3037
3088
  case 3:
3038
3089
  error = _state.sent();
3039
- console.error("[StormcloudVideoPlayer] Error sending ad-detect tracking:", error);
3090
+ console.error("[StormcloudVideoPlayer] Error sending ad loaded tracking:", error);
3040
3091
  return [
3041
3092
  3,
3042
3093
  4
@@ -3047,126 +3098,116 @@ function sendAdDetectTracking(licenseKey, payload) {
3047
3098
  ];
3048
3099
  }
3049
3100
  });
3050
- })();
3101
+ }).apply(this, arguments);
3051
3102
  }
3052
- function sendAdLoadedTracking(licenseKey, payload, adPlayerType) {
3053
- return _async_to_generator(function() {
3054
- var clientInfo, browserId, source, adLoadedInfo, body, error;
3103
+ function sendAdImpressionTracking(_0, _1) {
3104
+ return _async_to_generator(function(licenseKey, adImpressionInfo) {
3105
+ var context, metricEvent, error;
3106
+ var _arguments = arguments;
3055
3107
  return _ts_generator(this, function(_state) {
3056
3108
  switch(_state.label){
3057
3109
  case 0:
3110
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
3111
+ _state.label = 1;
3112
+ case 1:
3058
3113
  _state.trys.push([
3059
- 0,
3060
- 3,
3114
+ 1,
3115
+ 4,
3061
3116
  ,
3062
- 4
3117
+ 5
3063
3118
  ]);
3064
- clientInfo = getClientInfo();
3065
3119
  return [
3066
3120
  4,
3067
- getBrowserID(clientInfo)
3121
+ buildPlayerMetricEvent(licenseKey, context, {
3122
+ captureAt: adImpressionInfo.timestamp
3123
+ })
3068
3124
  ];
3069
- case 1:
3070
- browserId = _state.sent();
3071
- source = mapToAdTrackingSource(payload.source, adPlayerType);
3072
- adLoadedInfo = _object_spread({
3073
- source: source,
3074
- timestamp: /* @__PURE__ */ new Date().toISOString()
3075
- }, payload.vastUrl != null && {
3076
- vastUrl: payload.vastUrl
3077
- }, payload.durationSeconds != null && {
3078
- durationSeconds: payload.durationSeconds
3079
- });
3080
- body = _object_spread_props(_object_spread({
3081
- browserId: browserId
3082
- }, clientInfo, licenseKey && {
3083
- licenseKey: licenseKey
3084
- }), {
3085
- adLoadedInfo: adLoadedInfo
3086
- });
3125
+ case 2:
3126
+ metricEvent = _state.sent();
3087
3127
  return [
3088
3128
  4,
3089
- postAdTracking(licenseKey, body)
3129
+ Promise.all([
3130
+ postJson(HEARTBEAT_URL, licenseKey, metricEvent),
3131
+ postJson(IMPRESSIONS_URL, licenseKey, {
3132
+ events: [
3133
+ {
3134
+ player_id: metricEvent.player_id,
3135
+ ad_played_count: 1,
3136
+ ad_url: adImpressionInfo.adUrl,
3137
+ license_key: licenseKey,
3138
+ capture_at: adImpressionInfo.timestamp
3139
+ }
3140
+ ]
3141
+ })
3142
+ ])
3090
3143
  ];
3091
- case 2:
3144
+ case 3:
3092
3145
  _state.sent();
3093
3146
  return [
3094
3147
  3,
3095
- 4
3148
+ 5
3096
3149
  ];
3097
- case 3:
3150
+ case 4:
3098
3151
  error = _state.sent();
3099
- console.error("[StormcloudVideoPlayer] Error sending ad-loaded tracking:", error);
3152
+ console.error("[StormcloudVideoPlayer] Error sending ad impression tracking:", error);
3100
3153
  return [
3101
3154
  3,
3102
- 4
3155
+ 5
3103
3156
  ];
3104
- case 4:
3157
+ case 5:
3105
3158
  return [
3106
3159
  2
3107
3160
  ];
3108
3161
  }
3109
3162
  });
3110
- })();
3163
+ }).apply(this, arguments);
3111
3164
  }
3112
- function sendAdImpressionTracking(licenseKey, payload, adPlayerType) {
3113
- return _async_to_generator(function() {
3114
- var clientInfo, browserId, source, adImpressionInfo, body, error;
3165
+ function sendHeartbeat(_0) {
3166
+ return _async_to_generator(function(licenseKey) {
3167
+ var context, flags, heartbeatData, error;
3168
+ var _arguments = arguments;
3115
3169
  return _ts_generator(this, function(_state) {
3116
3170
  switch(_state.label){
3117
3171
  case 0:
3172
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
3173
+ _state.label = 1;
3174
+ case 1:
3118
3175
  _state.trys.push([
3119
- 0,
3120
- 3,
3176
+ 1,
3177
+ 4,
3121
3178
  ,
3122
- 4
3179
+ 5
3123
3180
  ]);
3124
- clientInfo = getClientInfo();
3125
3181
  return [
3126
3182
  4,
3127
- getBrowserID(clientInfo)
3183
+ buildPlayerMetricEvent(licenseKey, context, flags)
3128
3184
  ];
3129
- case 1:
3130
- browserId = _state.sent();
3131
- source = mapToAdTrackingSource(payload.source, adPlayerType);
3132
- adImpressionInfo = _object_spread({
3133
- source: source,
3134
- adIndex: payload.adIndex,
3135
- timestamp: /* @__PURE__ */ new Date().toISOString()
3136
- }, payload.durationSeconds != null && {
3137
- durationSeconds: payload.durationSeconds
3138
- });
3139
- body = _object_spread_props(_object_spread({
3140
- browserId: browserId
3141
- }, clientInfo, licenseKey && {
3142
- licenseKey: licenseKey
3143
- }), {
3144
- adImpressionInfo: adImpressionInfo
3145
- });
3185
+ case 2:
3186
+ heartbeatData = _state.sent();
3146
3187
  return [
3147
3188
  4,
3148
- postAdTracking(licenseKey, body)
3189
+ postJson(HEARTBEAT_URL, licenseKey, heartbeatData)
3149
3190
  ];
3150
- case 2:
3191
+ case 3:
3151
3192
  _state.sent();
3152
3193
  return [
3153
3194
  3,
3154
- 4
3195
+ 5
3155
3196
  ];
3156
- case 3:
3197
+ case 4:
3157
3198
  error = _state.sent();
3158
- console.error("[StormcloudVideoPlayer] Error sending ad-impression tracking:", error);
3199
+ console.error("[StormcloudVideoPlayer] Error sending heartbeat:", error);
3159
3200
  return [
3160
3201
  3,
3161
- 4
3202
+ 5
3162
3203
  ];
3163
- case 4:
3204
+ case 5:
3164
3205
  return [
3165
3206
  2
3166
3207
  ];
3167
3208
  }
3168
3209
  });
3169
- })();
3210
+ }).apply(this, arguments);
3170
3211
  }
3171
3212
  // src/utils/polyfills.ts
3172
3213
  function polyfillURLSearchParams() {
@@ -3959,8 +4000,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3959
4000
  var _this = this;
3960
4001
  this.ima.on("all_ads_completed", function() {
3961
4002
  sendAdImpressionTracking(_this.config.licenseKey, {
3962
- adIndex: _this.currentAdIndex
3963
- }, _this.config.adPlayerType).catch(function() {});
4003
+ source: "ima",
4004
+ adIndex: _this.currentAdIndex,
4005
+ timestamp: /* @__PURE__ */ new Date().toISOString()
4006
+ }).catch(function() {});
3964
4007
  var remaining = _this.getRemainingAdMs();
3965
4008
  _this.consecutiveFailures = 0;
3966
4009
  if (_this.config.debugAdTiming) {
@@ -4021,8 +4064,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4021
4064
  });
4022
4065
  this.ima.on("content_resume", function() {
4023
4066
  sendAdImpressionTracking(_this.config.licenseKey, {
4024
- adIndex: _this.currentAdIndex
4025
- }, _this.config.adPlayerType).catch(function() {});
4067
+ source: "ima",
4068
+ adIndex: _this.currentAdIndex,
4069
+ timestamp: /* @__PURE__ */ new Date().toISOString()
4070
+ }).catch(function() {});
4026
4071
  if (!_this.video.muted) {
4027
4072
  _this.video.muted = true;
4028
4073
  _this.video.volume = 0;
@@ -4656,7 +4701,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4656
4701
  var detectPayload = {};
4657
4702
  if (marker.durationSeconds != null) detectPayload.durationSeconds = marker.durationSeconds;
4658
4703
  if (marker.ptsSeconds != null) detectPayload.ptsSeconds = marker.ptsSeconds;
4659
- sendAdDetectTracking(this.config.licenseKey, detectPayload).catch(function() {});
4704
+ sendAdDetectTracking(this.config.licenseKey, _object_spread({
4705
+ source: "scte35",
4706
+ timestamp: /* @__PURE__ */ new Date().toISOString()
4707
+ }, detectPayload)).catch(function() {});
4660
4708
  }
4661
4709
  var hasPrefetchedAds = this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0;
4662
4710
  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;
@@ -5898,7 +5946,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5898
5946
  if (marker.durationSeconds != null) detectPayload.durationSeconds = marker.durationSeconds;
5899
5947
  if (marker.ptsSeconds != null) detectPayload.ptsSeconds = marker.ptsSeconds;
5900
5948
  if (fragmentSn !== void 0) detectPayload.detectedAtFragmentSn = fragmentSn;
5901
- sendAdDetectTracking(this.config.licenseKey, detectPayload).catch(function() {});
5949
+ sendAdDetectTracking(this.config.licenseKey, _object_spread({
5950
+ source: "scte35",
5951
+ timestamp: /* @__PURE__ */ new Date().toISOString()
5952
+ }, detectPayload)).catch(function() {});
5902
5953
  if (this.config.debugAdTiming) {
5903
5954
  console.log("[PREFETCH] \uD83D\uDD04 Starting ad prefetch for upcoming ad break");
5904
5955
  console.log("[PREFETCH] \uD83D\uDCCB Pre-generated ".concat(generatedUrls.length, " VAST URLs"));
@@ -6379,9 +6430,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6379
6430
  preloadedController = preloaded.imaController;
6380
6431
  usePreloadedAd = true;
6381
6432
  sendAdLoadedTracking(this.config.licenseKey, {
6382
- source: "preload",
6383
- vastUrl: firstAdUrl
6384
- }, this.config.adPlayerType).catch(function() {});
6433
+ source: "ima",
6434
+ vastUrl: firstAdUrl,
6435
+ timestamp: /* @__PURE__ */ new Date().toISOString()
6436
+ }).catch(function() {});
6385
6437
  if (this.config.debugAdTiming) {
6386
6438
  console.log("[CONTINUOUS-FETCH] \uD83D\uDE80 Using preloaded ad from pool (preloaded in advance, ready immediately!)");
6387
6439
  console.log("[CONTINUOUS-FETCH] Pool still has ".concat(this.preloadPool.length, " preloaded ads ready"));
@@ -6471,9 +6523,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6471
6523
  case 5:
6472
6524
  _state.sent();
6473
6525
  sendAdLoadedTracking(this.config.licenseKey, {
6474
- source: "ssp",
6475
- vastUrl: firstAdUrl
6476
- }, this.config.adPlayerType).catch(function() {});
6526
+ source: "ima",
6527
+ vastUrl: firstAdUrl,
6528
+ timestamp: /* @__PURE__ */ new Date().toISOString()
6529
+ }).catch(function() {});
6477
6530
  if (this.config.debugAdTiming) {
6478
6531
  console.log("[CONTINUOUS-FETCH] \u2705 First ad request successful, starting playback");
6479
6532
  }
@@ -6869,9 +6922,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6869
6922
  console.log("[CONTINUOUS-FETCH] \uD83C\uDFAF Using preloaded ad from pool (".concat(this.preloadPool.length, " remaining in pool)"));
6870
6923
  }
6871
6924
  sendAdLoadedTracking(this.config.licenseKey, {
6872
- source: "preload",
6873
- vastUrl: preloaded.vastUrl
6874
- }, this.config.adPlayerType).catch(function() {});
6925
+ source: "ima",
6926
+ vastUrl: preloaded.vastUrl,
6927
+ timestamp: /* @__PURE__ */ new Date().toISOString()
6928
+ }).catch(function() {});
6875
6929
  _state.label = 1;
6876
6930
  case 1:
6877
6931
  _state.trys.push([
@@ -7623,9 +7677,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7623
7677
  case 3:
7624
7678
  _state.sent();
7625
7679
  sendAdLoadedTracking(this.config.licenseKey, {
7626
- source: "ssp",
7627
- vastUrl: vastTagUrl
7628
- }, this.config.adPlayerType).catch(function() {});
7680
+ source: "ima",
7681
+ vastUrl: vastTagUrl,
7682
+ timestamp: /* @__PURE__ */ new Date().toISOString()
7683
+ }).catch(function() {});
7629
7684
  this.clearAdRequestWatchdog();
7630
7685
  if (this.activeAdRequestToken !== requestToken) {
7631
7686
  return [