stormcloud-video-player 0.7.49 → 0.7.51

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.
@@ -1677,6 +1677,116 @@ function createAdStormPlayer(contentVideo, options) {
1677
1677
  }
1678
1678
  };
1679
1679
  }
1680
+ // src/utils/mqttClient.ts
1681
+ var import_mqtt = __toESM(require("mqtt"), 1);
1682
+ // src/utils/mqttConfig.ts
1683
+ var DEFAULT_MQTT_CONFIG = {
1684
+ enabled: true,
1685
+ brokerAddress: "vecbae77.ala.us-east-1.emqxsl.com",
1686
+ brokerPort: 8883,
1687
+ wsPort: 8084,
1688
+ username: "for-sonifi",
1689
+ password: "sonifi-mqtt",
1690
+ topicPrefix: "adstorm/players",
1691
+ qos: 1
1692
+ };
1693
+ var mqttConfig = _object_spread({}, DEFAULT_MQTT_CONFIG);
1694
+ function applyMQTTConfig(overrides) {
1695
+ Object.assign(mqttConfig, overrides);
1696
+ }
1697
+ function isMQTTEnabled() {
1698
+ return mqttConfig.enabled;
1699
+ }
1700
+ function buildMQTTBrokerUrl() {
1701
+ if (mqttConfig.brokerUrl) return mqttConfig.brokerUrl;
1702
+ return "wss://".concat(mqttConfig.brokerAddress, ":").concat(mqttConfig.wsPort, "/mqtt");
1703
+ }
1704
+ function buildPlayerTopic(licenseKey, channel) {
1705
+ return "".concat(mqttConfig.topicPrefix, "/").concat(licenseKey, "/").concat(channel);
1706
+ }
1707
+ // src/utils/mqttClient.ts
1708
+ var LOG = "[StormcloudVideoPlayer][MQTT]";
1709
+ var client = null;
1710
+ var status = "disconnected";
1711
+ function configureMQTT(overrides) {
1712
+ applyMQTTConfig(overrides);
1713
+ disconnectMQTT();
1714
+ }
1715
+ function initMQTTClient() {
1716
+ if (client || !isMQTTEnabled()) return;
1717
+ var url = buildMQTTBrokerUrl();
1718
+ status = "connecting";
1719
+ var clientId = "stormcloud-vp-".concat(Math.random().toString(36).slice(2, 9));
1720
+ try {
1721
+ client = import_mqtt.default.connect(url, {
1722
+ clientId: clientId,
1723
+ username: mqttConfig.username,
1724
+ password: mqttConfig.password,
1725
+ keepalive: 60,
1726
+ clean: true,
1727
+ reconnectPeriod: 5e3,
1728
+ connectTimeout: 1e4,
1729
+ queueQoSZero: false
1730
+ });
1731
+ } catch (err) {
1732
+ status = "error";
1733
+ console.warn("".concat(LOG, " connect() threw:"), err);
1734
+ return;
1735
+ }
1736
+ client.on("connect", function() {
1737
+ status = "connected";
1738
+ console.info("".concat(LOG, " connected to ").concat(url));
1739
+ });
1740
+ client.on("reconnect", function() {
1741
+ status = "connecting";
1742
+ console.info("".concat(LOG, " reconnecting..."));
1743
+ });
1744
+ client.on("offline", function() {
1745
+ if (status !== "error") {
1746
+ status = "disconnected";
1747
+ }
1748
+ console.warn("".concat(LOG, " offline"));
1749
+ });
1750
+ client.on("error", function(err) {
1751
+ status = "error";
1752
+ console.warn("".concat(LOG, " error:"), err.message);
1753
+ });
1754
+ client.on("close", function() {
1755
+ if (status === "connected" || status === "connecting") {
1756
+ status = "disconnected";
1757
+ }
1758
+ });
1759
+ }
1760
+ function ensureMQTTClient() {
1761
+ if (isMQTTEnabled() && !client) {
1762
+ initMQTTClient();
1763
+ }
1764
+ }
1765
+ function publishMQTT(topic, payload) {
1766
+ if (!isMQTTEnabled()) {
1767
+ return false;
1768
+ }
1769
+ ensureMQTTClient();
1770
+ if (!client) {
1771
+ return false;
1772
+ }
1773
+ try {
1774
+ client.publish(topic, JSON.stringify(payload), {
1775
+ qos: mqttConfig.qos
1776
+ });
1777
+ return true;
1778
+ } catch (err) {
1779
+ console.warn("".concat(LOG, " publish failed on ").concat(topic, ":"), err);
1780
+ return false;
1781
+ }
1782
+ }
1783
+ function disconnectMQTT() {
1784
+ if (client) {
1785
+ client.end(true);
1786
+ client = null;
1787
+ status = "disconnected";
1788
+ }
1789
+ }
1680
1790
  // src/utils/tracking.ts
1681
1791
  var cachedBrowserId = null;
1682
1792
  function getClientInfo() {
@@ -1907,139 +2017,120 @@ function getBrowserID(clientInfo) {
1907
2017
  });
1908
2018
  })();
1909
2019
  }
1910
- var TRACK_URL = "https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track";
1911
- function sendTrackRequest(licenseKey, body) {
2020
+ function canPublish(licenseKey) {
2021
+ return Boolean(isMQTTEnabled() && licenseKey);
2022
+ }
2023
+ function buildPlayerMetricEvent() {
1912
2024
  return _async_to_generator(function() {
1913
- var headers, response;
2025
+ var context, flags, _flags_captureAt, _flags_adLoaded, _flags_adDetect, clientInfo, playerId, captureAt;
2026
+ var _arguments = arguments;
1914
2027
  return _ts_generator(this, function(_state) {
1915
2028
  switch(_state.label){
1916
2029
  case 0:
1917
- headers = {
1918
- "Content-Type": "application/json"
1919
- };
1920
- if (licenseKey) {
1921
- headers["Authorization"] = "Bearer ".concat(licenseKey);
1922
- }
2030
+ context = _arguments.length > 0 && _arguments[0] !== void 0 ? _arguments[0] : {}, flags = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
2031
+ clientInfo = getClientInfo();
1923
2032
  return [
1924
2033
  4,
1925
- fetch(TRACK_URL, {
1926
- method: "POST",
1927
- headers: headers,
1928
- body: JSON.stringify(body)
1929
- })
2034
+ getBrowserID(clientInfo)
1930
2035
  ];
1931
2036
  case 1:
1932
- response = _state.sent();
1933
- if (!response.ok) {
1934
- throw new Error("HTTP error! status: ".concat(response.status));
1935
- }
1936
- return [
1937
- 4,
1938
- response.json()
1939
- ];
1940
- case 2:
1941
- _state.sent();
2037
+ playerId = _state.sent();
2038
+ captureAt = (_flags_captureAt = flags.captureAt) !== null && _flags_captureAt !== void 0 ? _flags_captureAt : /* @__PURE__ */ new Date().toISOString();
1942
2039
  return [
1943
- 2
2040
+ 2,
2041
+ _object_spread({
2042
+ player_id: playerId,
2043
+ device_type: clientInfo.deviceType,
2044
+ os: clientInfo.os.toLowerCase(),
2045
+ ad_loaded: (_flags_adLoaded = flags.adLoaded) !== null && _flags_adLoaded !== void 0 ? _flags_adLoaded : false,
2046
+ ad_detect: (_flags_adDetect = flags.adDetect) !== null && _flags_adDetect !== void 0 ? _flags_adDetect : false,
2047
+ capture_at: captureAt
2048
+ }, context.inputStreamType ? {
2049
+ input_stream_type: context.inputStreamType
2050
+ } : {})
1944
2051
  ];
1945
2052
  }
1946
2053
  });
1947
- })();
2054
+ }).apply(this, arguments);
1948
2055
  }
1949
- function sendInitialTracking(licenseKey) {
1950
- return _async_to_generator(function() {
1951
- var clientInfo, browserId, trackingData, headers, response, error;
2056
+ function publishTracking(licenseKey, channel, body) {
2057
+ ensureMQTTClient();
2058
+ publishMQTT(buildPlayerTopic(licenseKey, channel), body);
2059
+ }
2060
+ function sendInitialTracking(_0) {
2061
+ return _async_to_generator(function(licenseKey) {
2062
+ var context, metricEvent, error;
2063
+ var _arguments = arguments;
1952
2064
  return _ts_generator(this, function(_state) {
1953
2065
  switch(_state.label){
1954
2066
  case 0:
2067
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
2068
+ if (!canPublish(licenseKey)) return [
2069
+ 2
2070
+ ];
2071
+ _state.label = 1;
2072
+ case 1:
1955
2073
  _state.trys.push([
1956
- 0,
1957
- 4,
2074
+ 1,
2075
+ 3,
1958
2076
  ,
1959
- 5
2077
+ 4
1960
2078
  ]);
1961
- clientInfo = getClientInfo();
1962
- return [
1963
- 4,
1964
- getBrowserID(clientInfo)
1965
- ];
1966
- case 1:
1967
- browserId = _state.sent();
1968
- trackingData = _object_spread({
1969
- browserId: browserId
1970
- }, clientInfo);
1971
- headers = {
1972
- "Content-Type": "application/json"
1973
- };
1974
- if (licenseKey) {
1975
- headers["Authorization"] = "Bearer ".concat(licenseKey);
1976
- }
1977
2079
  return [
1978
2080
  4,
1979
- fetch(TRACK_URL, {
1980
- method: "POST",
1981
- headers: headers,
1982
- body: JSON.stringify(trackingData)
2081
+ buildPlayerMetricEvent(context, {
2082
+ adLoaded: false,
2083
+ adDetect: false
1983
2084
  })
1984
2085
  ];
1985
2086
  case 2:
1986
- response = _state.sent();
1987
- if (!response.ok) {
1988
- throw new Error("HTTP error! status: ".concat(response.status));
1989
- }
1990
- return [
1991
- 4,
1992
- response.json()
1993
- ];
1994
- case 3:
1995
- _state.sent();
2087
+ metricEvent = _state.sent();
2088
+ publishTracking(licenseKey, "metrics", {
2089
+ events: [
2090
+ metricEvent
2091
+ ]
2092
+ });
1996
2093
  return [
1997
2094
  3,
1998
- 5
2095
+ 4
1999
2096
  ];
2000
- case 4:
2097
+ case 3:
2001
2098
  error = _state.sent();
2002
2099
  console.error("[StormcloudVideoPlayer] Error sending initial tracking data:", error);
2003
2100
  return [
2004
2101
  3,
2005
- 5
2102
+ 4
2006
2103
  ];
2007
- case 5:
2104
+ case 4:
2008
2105
  return [
2009
2106
  2
2010
2107
  ];
2011
2108
  }
2012
2109
  });
2013
- })();
2110
+ }).apply(this, arguments);
2014
2111
  }
2015
- function sendAdLoadedTracking(licenseKey, adLoadedInfo) {
2016
- return _async_to_generator(function() {
2017
- var clientInfo, browserId, trackingData, error;
2112
+ function sendAdLoadedTracking(_0, _1) {
2113
+ return _async_to_generator(function(licenseKey, adLoadedInfo) {
2114
+ var context, error;
2115
+ var _arguments = arguments;
2018
2116
  return _ts_generator(this, function(_state) {
2019
2117
  switch(_state.label){
2020
2118
  case 0:
2119
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2120
+ _state.label = 1;
2121
+ case 1:
2021
2122
  _state.trys.push([
2022
- 0,
2123
+ 1,
2023
2124
  3,
2024
2125
  ,
2025
2126
  4
2026
2127
  ]);
2027
- clientInfo = getClientInfo();
2028
2128
  return [
2029
2129
  4,
2030
- getBrowserID(clientInfo)
2031
- ];
2032
- case 1:
2033
- browserId = _state.sent();
2034
- trackingData = _object_spread({
2035
- browserId: browserId
2036
- }, clientInfo);
2037
- return [
2038
- 4,
2039
- sendTrackRequest(licenseKey, _object_spread_props(_object_spread({}, trackingData), {
2040
- licenseKey: licenseKey,
2041
- adLoadedInfo: adLoadedInfo
2042
- }))
2130
+ sendHeartbeat(licenseKey, context, {
2131
+ adLoaded: true,
2132
+ captureAt: adLoadedInfo.timestamp
2133
+ })
2043
2134
  ];
2044
2135
  case 2:
2045
2136
  _state.sent();
@@ -2060,39 +2151,46 @@ function sendAdLoadedTracking(licenseKey, adLoadedInfo) {
2060
2151
  ];
2061
2152
  }
2062
2153
  });
2063
- })();
2154
+ }).apply(this, arguments);
2064
2155
  }
2065
- function sendAdImpressionTracking(licenseKey, adImpressionInfo) {
2066
- return _async_to_generator(function() {
2067
- var clientInfo, browserId, trackingData, error;
2156
+ function sendAdImpressionTracking(_0, _1) {
2157
+ return _async_to_generator(function(licenseKey, adImpressionInfo) {
2158
+ var context, metricEvent, error;
2159
+ var _arguments = arguments;
2068
2160
  return _ts_generator(this, function(_state) {
2069
2161
  switch(_state.label){
2070
2162
  case 0:
2163
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2164
+ if (!canPublish(licenseKey)) return [
2165
+ 2
2166
+ ];
2167
+ _state.label = 1;
2168
+ case 1:
2071
2169
  _state.trys.push([
2072
- 0,
2170
+ 1,
2073
2171
  3,
2074
2172
  ,
2075
2173
  4
2076
2174
  ]);
2077
- clientInfo = getClientInfo();
2078
- return [
2079
- 4,
2080
- getBrowserID(clientInfo)
2081
- ];
2082
- case 1:
2083
- browserId = _state.sent();
2084
- trackingData = _object_spread({
2085
- browserId: browserId
2086
- }, clientInfo);
2087
2175
  return [
2088
2176
  4,
2089
- sendTrackRequest(licenseKey, _object_spread_props(_object_spread({}, trackingData), {
2090
- licenseKey: licenseKey,
2091
- adImpressionInfo: adImpressionInfo
2092
- }))
2177
+ buildPlayerMetricEvent(context, {
2178
+ captureAt: adImpressionInfo.timestamp
2179
+ })
2093
2180
  ];
2094
2181
  case 2:
2095
- _state.sent();
2182
+ metricEvent = _state.sent();
2183
+ publishTracking(licenseKey, "heartbeat", metricEvent);
2184
+ publishTracking(licenseKey, "impressions", {
2185
+ events: [
2186
+ {
2187
+ player_id: metricEvent.player_id,
2188
+ ad_played_count: 1,
2189
+ ad_url: adImpressionInfo.adUrl,
2190
+ capture_at: adImpressionInfo.timestamp
2191
+ }
2192
+ ]
2193
+ });
2096
2194
  return [
2097
2195
  3,
2098
2196
  4
@@ -2110,74 +2208,52 @@ function sendAdImpressionTracking(licenseKey, adImpressionInfo) {
2110
2208
  ];
2111
2209
  }
2112
2210
  });
2113
- })();
2211
+ }).apply(this, arguments);
2114
2212
  }
2115
- function sendHeartbeat(licenseKey) {
2116
- return _async_to_generator(function() {
2117
- var clientInfo, browserId, heartbeatData, headers, response, error;
2213
+ function sendHeartbeat(_0) {
2214
+ return _async_to_generator(function(licenseKey) {
2215
+ var context, flags, heartbeatData, error;
2216
+ var _arguments = arguments;
2118
2217
  return _ts_generator(this, function(_state) {
2119
2218
  switch(_state.label){
2120
2219
  case 0:
2220
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2221
+ if (!canPublish(licenseKey)) return [
2222
+ 2
2223
+ ];
2224
+ _state.label = 1;
2225
+ case 1:
2121
2226
  _state.trys.push([
2122
- 0,
2123
- 4,
2227
+ 1,
2228
+ 3,
2124
2229
  ,
2125
- 5
2230
+ 4
2126
2231
  ]);
2127
- clientInfo = getClientInfo();
2128
- return [
2129
- 4,
2130
- getBrowserID(clientInfo)
2131
- ];
2132
- case 1:
2133
- browserId = _state.sent();
2134
- heartbeatData = {
2135
- browserId: browserId,
2136
- timestamp: /* @__PURE__ */ new Date().toISOString()
2137
- };
2138
- headers = {
2139
- "Content-Type": "application/json"
2140
- };
2141
- if (licenseKey) {
2142
- headers["Authorization"] = "Bearer ".concat(licenseKey);
2143
- }
2144
2232
  return [
2145
2233
  4,
2146
- fetch("https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat", {
2147
- method: "POST",
2148
- headers: headers,
2149
- body: JSON.stringify(heartbeatData)
2150
- })
2234
+ buildPlayerMetricEvent(context, flags)
2151
2235
  ];
2152
2236
  case 2:
2153
- response = _state.sent();
2154
- if (!response.ok) {
2155
- throw new Error("HTTP error! status: ".concat(response.status));
2156
- }
2157
- return [
2158
- 4,
2159
- response.json()
2160
- ];
2161
- case 3:
2162
- _state.sent();
2237
+ heartbeatData = _state.sent();
2238
+ publishTracking(licenseKey, "heartbeat", heartbeatData);
2163
2239
  return [
2164
2240
  3,
2165
- 5
2241
+ 4
2166
2242
  ];
2167
- case 4:
2243
+ case 3:
2168
2244
  error = _state.sent();
2169
2245
  console.error("[StormcloudVideoPlayer] Error sending heartbeat:", error);
2170
2246
  return [
2171
2247
  3,
2172
- 5
2248
+ 4
2173
2249
  ];
2174
- case 5:
2250
+ case 4:
2175
2251
  return [
2176
2252
  2
2177
2253
  ];
2178
2254
  }
2179
2255
  });
2180
- })();
2256
+ }).apply(this, arguments);
2181
2257
  }
2182
2258
  // src/utils/polyfills.ts
2183
2259
  function polyfillURLSearchParams() {
@@ -2739,6 +2815,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
2739
2815
  this.config = _object_spread({}, browserOverrides, config);
2740
2816
  this.video = config.videoElement;
2741
2817
  this.adTransitionGapMs = (_this_config_adTransitionGapMs = this.config.adTransitionGapMs) !== null && _this_config_adTransitionGapMs !== void 0 ? _this_config_adTransitionGapMs : 100;
2818
+ if (this.config.mqttConfig) {
2819
+ configureMQTT(this.config.mqttConfig);
2820
+ }
2742
2821
  logBrowserInfo(config.debugAdTiming);
2743
2822
  var browserForAdLayer = detectBrowser();
2744
2823
  var isSinglePipeline = browserForAdLayer.isSmartTV || !!this.config.singlePipelineMode;
@@ -3106,7 +3185,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3106
3185
  source: _this.getAdSource(),
3107
3186
  adIndex: _this.currentAdIndex,
3108
3187
  timestamp: /* @__PURE__ */ new Date().toISOString()
3109
- });
3188
+ }, _this.getPlayerAnalyticsContext());
3110
3189
  }
3111
3190
  });
3112
3191
  this.adLayer.on("ad_error", function(errorPayload) {
@@ -3411,7 +3490,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3411
3490
  key: "initializeTracking",
3412
3491
  value: function initializeTracking() {
3413
3492
  var _this = this;
3414
- sendInitialTracking(this.config.licenseKey).then(function() {
3493
+ sendInitialTracking(this.config.licenseKey, this.getPlayerAnalyticsContext()).then(function() {
3415
3494
  _this.heartbeatInterval = window.setInterval(function() {
3416
3495
  _this.sendHeartbeatIfNeeded();
3417
3496
  }, 5e3);
@@ -3432,7 +3511,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3432
3511
  var now = Date.now();
3433
3512
  if (!this.lastHeartbeatTime || now - this.lastHeartbeatTime > 3e4) {
3434
3513
  this.lastHeartbeatTime = now;
3435
- sendHeartbeat(this.config.licenseKey).catch(function(error) {
3514
+ sendHeartbeat(this.config.licenseKey, this.getPlayerAnalyticsContext()).catch(function(error) {
3436
3515
  if (_this.config.debugAdTiming) {
3437
3516
  console.warn("[StormcloudVideoPlayer] Failed to send heartbeat:", error);
3438
3517
  }
@@ -3526,6 +3605,14 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3526
3605
  return "other";
3527
3606
  }
3528
3607
  },
3608
+ {
3609
+ key: "getPlayerAnalyticsContext",
3610
+ value: function getPlayerAnalyticsContext() {
3611
+ return {
3612
+ inputStreamType: this.getStreamType()
3613
+ };
3614
+ }
3615
+ },
3529
3616
  {
3530
3617
  key: "shouldShowNativeControls",
3531
3618
  value: function shouldShowNativeControls() {
@@ -4180,7 +4267,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4180
4267
  sendAdLoadedTracking(_this.config.licenseKey, {
4181
4268
  source: _this.getAdSource(),
4182
4269
  timestamp: /* @__PURE__ */ new Date().toISOString()
4183
- });
4270
+ }, _this.getPlayerAnalyticsContext());
4184
4271
  }
4185
4272
  return [
4186
4273
  4,
@@ -4290,7 +4377,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4290
4377
  sendAdLoadedTracking(_this.config.licenseKey, {
4291
4378
  source: _this.getAdSource(),
4292
4379
  timestamp: /* @__PURE__ */ new Date().toISOString()
4293
- });
4380
+ }, _this.getPlayerAnalyticsContext());
4294
4381
  }
4295
4382
  return [
4296
4383
  4,
@@ -4457,7 +4544,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4457
4544
  sendAdLoadedTracking(this.config.licenseKey, {
4458
4545
  source: this.getAdSource(),
4459
4546
  timestamp: /* @__PURE__ */ new Date().toISOString()
4460
- });
4547
+ }, this.getPlayerAnalyticsContext());
4461
4548
  }
4462
4549
  _state.label = 1;
4463
4550
  case 1:
@@ -4656,7 +4743,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4656
4743
  sendAdLoadedTracking(this.config.licenseKey, {
4657
4744
  source: this.getAdSource(),
4658
4745
  timestamp: /* @__PURE__ */ new Date().toISOString()
4659
- });
4746
+ }, this.getPlayerAnalyticsContext());
4660
4747
  }
4661
4748
  return [
4662
4749
  4,
@@ -5601,6 +5688,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5601
5688
  clearInterval(this.heartbeatInterval);
5602
5689
  this.heartbeatInterval = void 0;
5603
5690
  }
5691
+ if (isMQTTEnabled()) {
5692
+ disconnectMQTT();
5693
+ }
5604
5694
  (_this_hls = this.hls) === null || _this_hls === void 0 ? void 0 : _this_hls.destroy();
5605
5695
  (_this_adLayer = this.adLayer) === null || _this_adLayer === void 0 ? void 0 : _this_adLayer.destroy();
5606
5696
  this.consecutiveFailures = 0;