stormcloud-video-player 0.7.50 → 0.7.52

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
@@ -428,6 +428,9 @@ var __toCommonJS = function __toCommonJS(mod) {
428
428
  // src/index.ts
429
429
  var index_exports = {};
430
430
  __export(index_exports, {
431
+ DEFAULT_MQTT_CONFIG: function DEFAULT_MQTT_CONFIG1() {
432
+ return DEFAULT_MQTT_CONFIG;
433
+ },
431
434
  IS_BROWSER: function IS_BROWSER1() {
432
435
  return IS_BROWSER;
433
436
  },
@@ -440,6 +443,9 @@ __export(index_exports, {
440
443
  IS_SAFARI: function IS_SAFARI1() {
441
444
  return IS_SAFARI;
442
445
  },
446
+ MQTT_CA_CERT_FILE: function MQTT_CA_CERT_FILE1() {
447
+ return MQTT_CA_CERT_FILE;
448
+ },
443
449
  OVERLAY_API_BASE: function OVERLAY_API_BASE1() {
444
450
  return OVERLAY_API_BASE;
445
451
  },
@@ -458,9 +464,21 @@ __export(index_exports, {
458
464
  StormcloudVideoPlayerComponent: function StormcloudVideoPlayerComponent1() {
459
465
  return StormcloudVideoPlayerComponent;
460
466
  },
467
+ applyMQTTConfig: function applyMQTTConfig1() {
468
+ return applyMQTTConfig;
469
+ },
470
+ buildMQTTBrokerUrl: function buildMQTTBrokerUrl1() {
471
+ return buildMQTTBrokerUrl;
472
+ },
473
+ buildPlayerTopic: function buildPlayerTopic1() {
474
+ return buildPlayerTopic;
475
+ },
461
476
  canPlay: function canPlay1() {
462
477
  return canPlay;
463
478
  },
479
+ configureMQTT: function configureMQTT1() {
480
+ return configureMQTT;
481
+ },
464
482
  createAdStormPlayer: function createAdStormPlayer1() {
465
483
  return createAdStormPlayer;
466
484
  },
@@ -473,6 +491,12 @@ __export(index_exports, {
473
491
  detectBrowser: function detectBrowser1() {
474
492
  return detectBrowser;
475
493
  },
494
+ disconnectMQTT: function disconnectMQTT1() {
495
+ return disconnectMQTT;
496
+ },
497
+ ensureMQTTClient: function ensureMQTTClient1() {
498
+ return ensureMQTTClient;
499
+ },
476
500
  fetchProjectOverlays: function fetchProjectOverlays1() {
477
501
  return fetchProjectOverlays;
478
502
  },
@@ -485,9 +509,24 @@ __export(index_exports, {
485
509
  getClientInfo: function getClientInfo1() {
486
510
  return getClientInfo;
487
511
  },
512
+ getMQTTStatus: function getMQTTStatus1() {
513
+ return getMQTTStatus;
514
+ },
515
+ initMQTTClient: function initMQTTClient1() {
516
+ return initMQTTClient;
517
+ },
488
518
  initializePolyfills: function initializePolyfills1() {
489
519
  return initializePolyfills;
490
520
  },
521
+ isMQTTConfigured: function isMQTTConfigured1() {
522
+ return isMQTTConfigured;
523
+ },
524
+ isMQTTConnected: function isMQTTConnected1() {
525
+ return isMQTTConnected;
526
+ },
527
+ isMQTTEnabled: function isMQTTEnabled1() {
528
+ return isMQTTEnabled;
529
+ },
491
530
  isMediaStream: function isMediaStream1() {
492
531
  return isMediaStream;
493
532
  },
@@ -503,6 +542,9 @@ __export(index_exports, {
503
542
  merge: function merge1() {
504
543
  return merge;
505
544
  },
545
+ mqttConfig: function mqttConfig1() {
546
+ return mqttConfig;
547
+ },
506
548
  normalizeSwirlOverlay: function normalizeSwirlOverlay1() {
507
549
  return normalizeSwirlOverlay;
508
550
  },
@@ -515,12 +557,24 @@ __export(index_exports, {
515
557
  players: function players() {
516
558
  return players_default;
517
559
  },
560
+ publishMQTT: function publishMQTT1() {
561
+ return publishMQTT;
562
+ },
518
563
  randomString: function randomString1() {
519
564
  return randomString;
520
565
  },
521
566
  resolveImageUrl: function resolveImageUrl1() {
522
567
  return resolveImageUrl;
523
568
  },
569
+ sendAdDetectTracking: function sendAdDetectTracking1() {
570
+ return sendAdDetectTracking;
571
+ },
572
+ sendAdImpressionTracking: function sendAdImpressionTracking1() {
573
+ return sendAdImpressionTracking;
574
+ },
575
+ sendAdLoadedTracking: function sendAdLoadedTracking1() {
576
+ return sendAdLoadedTracking;
577
+ },
524
578
  sendHeartbeat: function sendHeartbeat1() {
525
579
  return sendHeartbeat;
526
580
  },
@@ -1874,6 +1928,126 @@ function createAdStormPlayer(contentVideo, options) {
1874
1928
  }
1875
1929
  };
1876
1930
  }
1931
+ // src/utils/mqttClient.ts
1932
+ var import_mqtt = __toESM(require("mqtt"), 1);
1933
+ // src/utils/mqttConfig.ts
1934
+ var MQTT_CA_CERT_FILE = "src/certs/emqxsl-ca.crt";
1935
+ var DEFAULT_MQTT_CONFIG = {
1936
+ enabled: true,
1937
+ brokerAddress: "vecbae77.ala.us-east-1.emqxsl.com",
1938
+ brokerPort: 8883,
1939
+ wsPort: 8084,
1940
+ username: "for-sonifi",
1941
+ password: "sonifi-mqtt",
1942
+ topicPrefix: "adstorm/players",
1943
+ qos: 1
1944
+ };
1945
+ var mqttConfig = _object_spread({}, DEFAULT_MQTT_CONFIG);
1946
+ function applyMQTTConfig(overrides) {
1947
+ Object.assign(mqttConfig, overrides);
1948
+ }
1949
+ function isMQTTEnabled() {
1950
+ return mqttConfig.enabled;
1951
+ }
1952
+ function buildMQTTBrokerUrl() {
1953
+ if (mqttConfig.brokerUrl) return mqttConfig.brokerUrl;
1954
+ return "wss://".concat(mqttConfig.brokerAddress, ":").concat(mqttConfig.wsPort, "/mqtt");
1955
+ }
1956
+ function buildPlayerTopic(licenseKey, channel) {
1957
+ return "".concat(mqttConfig.topicPrefix, "/").concat(licenseKey, "/").concat(channel);
1958
+ }
1959
+ // src/utils/mqttClient.ts
1960
+ var LOG = "[StormcloudVideoPlayer][MQTT]";
1961
+ var client = null;
1962
+ var status = "disconnected";
1963
+ function getMQTTStatus() {
1964
+ return status;
1965
+ }
1966
+ function isMQTTConnected() {
1967
+ return status === "connected" && client !== null && client.connected;
1968
+ }
1969
+ function isMQTTConfigured() {
1970
+ return isMQTTEnabled();
1971
+ }
1972
+ function configureMQTT(overrides) {
1973
+ applyMQTTConfig(overrides);
1974
+ disconnectMQTT();
1975
+ }
1976
+ function initMQTTClient() {
1977
+ if (client || !isMQTTEnabled()) return;
1978
+ var url = buildMQTTBrokerUrl();
1979
+ status = "connecting";
1980
+ var clientId = "stormcloud-vp-".concat(Math.random().toString(36).slice(2, 9));
1981
+ try {
1982
+ client = import_mqtt.default.connect(url, {
1983
+ clientId: clientId,
1984
+ username: mqttConfig.username,
1985
+ password: mqttConfig.password,
1986
+ keepalive: 60,
1987
+ clean: true,
1988
+ reconnectPeriod: 5e3,
1989
+ connectTimeout: 1e4,
1990
+ queueQoSZero: false
1991
+ });
1992
+ } catch (err) {
1993
+ status = "error";
1994
+ console.warn("".concat(LOG, " connect() threw:"), err);
1995
+ return;
1996
+ }
1997
+ client.on("connect", function() {
1998
+ status = "connected";
1999
+ console.info("".concat(LOG, " connected to ").concat(url));
2000
+ });
2001
+ client.on("reconnect", function() {
2002
+ status = "connecting";
2003
+ console.info("".concat(LOG, " reconnecting..."));
2004
+ });
2005
+ client.on("offline", function() {
2006
+ if (status !== "error") {
2007
+ status = "disconnected";
2008
+ }
2009
+ console.warn("".concat(LOG, " offline"));
2010
+ });
2011
+ client.on("error", function(err) {
2012
+ status = "error";
2013
+ console.warn("".concat(LOG, " error:"), err.message);
2014
+ });
2015
+ client.on("close", function() {
2016
+ if (status === "connected" || status === "connecting") {
2017
+ status = "disconnected";
2018
+ }
2019
+ });
2020
+ }
2021
+ function ensureMQTTClient() {
2022
+ if (isMQTTEnabled() && !client) {
2023
+ initMQTTClient();
2024
+ }
2025
+ }
2026
+ function publishMQTT(topic, payload) {
2027
+ if (!isMQTTEnabled()) {
2028
+ return false;
2029
+ }
2030
+ ensureMQTTClient();
2031
+ if (!client) {
2032
+ return false;
2033
+ }
2034
+ try {
2035
+ client.publish(topic, JSON.stringify(payload), {
2036
+ qos: mqttConfig.qos
2037
+ });
2038
+ return true;
2039
+ } catch (err) {
2040
+ console.warn("".concat(LOG, " publish failed on ").concat(topic, ":"), err);
2041
+ return false;
2042
+ }
2043
+ }
2044
+ function disconnectMQTT() {
2045
+ if (client) {
2046
+ client.end(true);
2047
+ client = null;
2048
+ status = "disconnected";
2049
+ }
2050
+ }
1877
2051
  // src/utils/tracking.ts
1878
2052
  var cachedBrowserId = null;
1879
2053
  function getClientInfo() {
@@ -2104,139 +2278,164 @@ function getBrowserID(clientInfo) {
2104
2278
  });
2105
2279
  })();
2106
2280
  }
2107
- var TRACK_URL = "https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track";
2108
- function sendTrackRequest(licenseKey, body) {
2281
+ function canPublish(licenseKey) {
2282
+ return Boolean(isMQTTEnabled() && licenseKey);
2283
+ }
2284
+ function buildPlayerMetricEvent() {
2109
2285
  return _async_to_generator(function() {
2110
- var headers, response;
2286
+ var context, flags, _flags_captureAt, _flags_adLoaded, _flags_adDetect, clientInfo, playerId, captureAt;
2287
+ var _arguments = arguments;
2111
2288
  return _ts_generator(this, function(_state) {
2112
2289
  switch(_state.label){
2113
2290
  case 0:
2114
- headers = {
2115
- "Content-Type": "application/json"
2116
- };
2117
- if (licenseKey) {
2118
- headers["Authorization"] = "Bearer ".concat(licenseKey);
2119
- }
2291
+ context = _arguments.length > 0 && _arguments[0] !== void 0 ? _arguments[0] : {}, flags = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
2292
+ clientInfo = getClientInfo();
2120
2293
  return [
2121
2294
  4,
2122
- fetch(TRACK_URL, {
2123
- method: "POST",
2124
- headers: headers,
2125
- body: JSON.stringify(body)
2126
- })
2295
+ getBrowserID(clientInfo)
2127
2296
  ];
2128
2297
  case 1:
2129
- response = _state.sent();
2130
- if (!response.ok) {
2131
- throw new Error("HTTP error! status: ".concat(response.status));
2132
- }
2298
+ playerId = _state.sent();
2299
+ captureAt = (_flags_captureAt = flags.captureAt) !== null && _flags_captureAt !== void 0 ? _flags_captureAt : /* @__PURE__ */ new Date().toISOString();
2300
+ return [
2301
+ 2,
2302
+ _object_spread({
2303
+ player_id: playerId,
2304
+ device_type: clientInfo.deviceType,
2305
+ os: clientInfo.os.toLowerCase(),
2306
+ ad_loaded: (_flags_adLoaded = flags.adLoaded) !== null && _flags_adLoaded !== void 0 ? _flags_adLoaded : false,
2307
+ ad_detect: (_flags_adDetect = flags.adDetect) !== null && _flags_adDetect !== void 0 ? _flags_adDetect : false,
2308
+ capture_at: captureAt
2309
+ }, context.inputStreamType ? {
2310
+ input_stream_type: context.inputStreamType
2311
+ } : {})
2312
+ ];
2313
+ }
2314
+ });
2315
+ }).apply(this, arguments);
2316
+ }
2317
+ function publishTracking(licenseKey, channel, body) {
2318
+ ensureMQTTClient();
2319
+ publishMQTT(buildPlayerTopic(licenseKey, channel), body);
2320
+ }
2321
+ function sendInitialTracking(_0) {
2322
+ return _async_to_generator(function(licenseKey) {
2323
+ var context, metricEvent, error;
2324
+ var _arguments = arguments;
2325
+ return _ts_generator(this, function(_state) {
2326
+ switch(_state.label){
2327
+ case 0:
2328
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
2329
+ if (!canPublish(licenseKey)) return [
2330
+ 2
2331
+ ];
2332
+ _state.label = 1;
2333
+ case 1:
2334
+ _state.trys.push([
2335
+ 1,
2336
+ 3,
2337
+ ,
2338
+ 4
2339
+ ]);
2133
2340
  return [
2134
2341
  4,
2135
- response.json()
2342
+ buildPlayerMetricEvent(context, {
2343
+ adLoaded: false,
2344
+ adDetect: false
2345
+ })
2136
2346
  ];
2137
2347
  case 2:
2138
- _state.sent();
2348
+ metricEvent = _state.sent();
2349
+ publishTracking(licenseKey, "metrics", {
2350
+ events: [
2351
+ metricEvent
2352
+ ]
2353
+ });
2354
+ return [
2355
+ 3,
2356
+ 4
2357
+ ];
2358
+ case 3:
2359
+ error = _state.sent();
2360
+ console.error("[StormcloudVideoPlayer] Error sending initial tracking data:", error);
2361
+ return [
2362
+ 3,
2363
+ 4
2364
+ ];
2365
+ case 4:
2139
2366
  return [
2140
2367
  2
2141
2368
  ];
2142
2369
  }
2143
2370
  });
2144
- })();
2371
+ }).apply(this, arguments);
2145
2372
  }
2146
- function sendInitialTracking(licenseKey) {
2147
- return _async_to_generator(function() {
2148
- var clientInfo, browserId, trackingData, headers, response, error;
2373
+ function sendAdDetectTracking(_0, _1) {
2374
+ return _async_to_generator(function(licenseKey, adDetectInfo) {
2375
+ var context, error;
2376
+ var _arguments = arguments;
2149
2377
  return _ts_generator(this, function(_state) {
2150
2378
  switch(_state.label){
2151
2379
  case 0:
2380
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2381
+ _state.label = 1;
2382
+ case 1:
2152
2383
  _state.trys.push([
2153
- 0,
2154
- 4,
2384
+ 1,
2385
+ 3,
2155
2386
  ,
2156
- 5
2387
+ 4
2157
2388
  ]);
2158
- clientInfo = getClientInfo();
2159
2389
  return [
2160
2390
  4,
2161
- getBrowserID(clientInfo)
2162
- ];
2163
- case 1:
2164
- browserId = _state.sent();
2165
- trackingData = _object_spread({
2166
- browserId: browserId
2167
- }, clientInfo);
2168
- headers = {
2169
- "Content-Type": "application/json"
2170
- };
2171
- if (licenseKey) {
2172
- headers["Authorization"] = "Bearer ".concat(licenseKey);
2173
- }
2174
- return [
2175
- 4,
2176
- fetch(TRACK_URL, {
2177
- method: "POST",
2178
- headers: headers,
2179
- body: JSON.stringify(trackingData)
2391
+ sendHeartbeat(licenseKey, context, {
2392
+ adDetect: true,
2393
+ captureAt: adDetectInfo.timestamp
2180
2394
  })
2181
2395
  ];
2182
2396
  case 2:
2183
- response = _state.sent();
2184
- if (!response.ok) {
2185
- throw new Error("HTTP error! status: ".concat(response.status));
2186
- }
2187
- return [
2188
- 4,
2189
- response.json()
2190
- ];
2191
- case 3:
2192
2397
  _state.sent();
2193
2398
  return [
2194
2399
  3,
2195
- 5
2400
+ 4
2196
2401
  ];
2197
- case 4:
2402
+ case 3:
2198
2403
  error = _state.sent();
2199
- console.error("[StormcloudVideoPlayer] Error sending initial tracking data:", error);
2404
+ console.error("[StormcloudVideoPlayer] Error sending ad detect tracking:", error);
2200
2405
  return [
2201
2406
  3,
2202
- 5
2407
+ 4
2203
2408
  ];
2204
- case 5:
2409
+ case 4:
2205
2410
  return [
2206
2411
  2
2207
2412
  ];
2208
2413
  }
2209
2414
  });
2210
- })();
2415
+ }).apply(this, arguments);
2211
2416
  }
2212
- function sendAdLoadedTracking(licenseKey, adLoadedInfo) {
2213
- return _async_to_generator(function() {
2214
- var clientInfo, browserId, trackingData, error;
2417
+ function sendAdLoadedTracking(_0, _1) {
2418
+ return _async_to_generator(function(licenseKey, adLoadedInfo) {
2419
+ var context, error;
2420
+ var _arguments = arguments;
2215
2421
  return _ts_generator(this, function(_state) {
2216
2422
  switch(_state.label){
2217
2423
  case 0:
2424
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2425
+ _state.label = 1;
2426
+ case 1:
2218
2427
  _state.trys.push([
2219
- 0,
2428
+ 1,
2220
2429
  3,
2221
2430
  ,
2222
2431
  4
2223
2432
  ]);
2224
- clientInfo = getClientInfo();
2225
2433
  return [
2226
2434
  4,
2227
- getBrowserID(clientInfo)
2228
- ];
2229
- case 1:
2230
- browserId = _state.sent();
2231
- trackingData = _object_spread({
2232
- browserId: browserId
2233
- }, clientInfo);
2234
- return [
2235
- 4,
2236
- sendTrackRequest(licenseKey, _object_spread_props(_object_spread({}, trackingData), {
2237
- licenseKey: licenseKey,
2238
- adLoadedInfo: adLoadedInfo
2239
- }))
2435
+ sendHeartbeat(licenseKey, context, {
2436
+ adLoaded: true,
2437
+ captureAt: adLoadedInfo.timestamp
2438
+ })
2240
2439
  ];
2241
2440
  case 2:
2242
2441
  _state.sent();
@@ -2257,39 +2456,46 @@ function sendAdLoadedTracking(licenseKey, adLoadedInfo) {
2257
2456
  ];
2258
2457
  }
2259
2458
  });
2260
- })();
2459
+ }).apply(this, arguments);
2261
2460
  }
2262
- function sendAdImpressionTracking(licenseKey, adImpressionInfo) {
2263
- return _async_to_generator(function() {
2264
- var clientInfo, browserId, trackingData, error;
2461
+ function sendAdImpressionTracking(_0, _1) {
2462
+ return _async_to_generator(function(licenseKey, adImpressionInfo) {
2463
+ var context, metricEvent, error;
2464
+ var _arguments = arguments;
2265
2465
  return _ts_generator(this, function(_state) {
2266
2466
  switch(_state.label){
2267
2467
  case 0:
2468
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2469
+ if (!canPublish(licenseKey)) return [
2470
+ 2
2471
+ ];
2472
+ _state.label = 1;
2473
+ case 1:
2268
2474
  _state.trys.push([
2269
- 0,
2475
+ 1,
2270
2476
  3,
2271
2477
  ,
2272
2478
  4
2273
2479
  ]);
2274
- clientInfo = getClientInfo();
2275
2480
  return [
2276
2481
  4,
2277
- getBrowserID(clientInfo)
2278
- ];
2279
- case 1:
2280
- browserId = _state.sent();
2281
- trackingData = _object_spread({
2282
- browserId: browserId
2283
- }, clientInfo);
2284
- return [
2285
- 4,
2286
- sendTrackRequest(licenseKey, _object_spread_props(_object_spread({}, trackingData), {
2287
- licenseKey: licenseKey,
2288
- adImpressionInfo: adImpressionInfo
2289
- }))
2482
+ buildPlayerMetricEvent(context, {
2483
+ captureAt: adImpressionInfo.timestamp
2484
+ })
2290
2485
  ];
2291
2486
  case 2:
2292
- _state.sent();
2487
+ metricEvent = _state.sent();
2488
+ publishTracking(licenseKey, "heartbeat", metricEvent);
2489
+ publishTracking(licenseKey, "impressions", {
2490
+ events: [
2491
+ {
2492
+ player_id: metricEvent.player_id,
2493
+ ad_played_count: 1,
2494
+ ad_url: adImpressionInfo.adUrl,
2495
+ capture_at: adImpressionInfo.timestamp
2496
+ }
2497
+ ]
2498
+ });
2293
2499
  return [
2294
2500
  3,
2295
2501
  4
@@ -2307,74 +2513,52 @@ function sendAdImpressionTracking(licenseKey, adImpressionInfo) {
2307
2513
  ];
2308
2514
  }
2309
2515
  });
2310
- })();
2516
+ }).apply(this, arguments);
2311
2517
  }
2312
- function sendHeartbeat(licenseKey) {
2313
- return _async_to_generator(function() {
2314
- var clientInfo, browserId, heartbeatData, headers, response, error;
2518
+ function sendHeartbeat(_0) {
2519
+ return _async_to_generator(function(licenseKey) {
2520
+ var context, flags, heartbeatData, error;
2521
+ var _arguments = arguments;
2315
2522
  return _ts_generator(this, function(_state) {
2316
2523
  switch(_state.label){
2317
2524
  case 0:
2525
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2526
+ if (!canPublish(licenseKey)) return [
2527
+ 2
2528
+ ];
2529
+ _state.label = 1;
2530
+ case 1:
2318
2531
  _state.trys.push([
2319
- 0,
2320
- 4,
2532
+ 1,
2533
+ 3,
2321
2534
  ,
2322
- 5
2535
+ 4
2323
2536
  ]);
2324
- clientInfo = getClientInfo();
2325
2537
  return [
2326
2538
  4,
2327
- getBrowserID(clientInfo)
2328
- ];
2329
- case 1:
2330
- browserId = _state.sent();
2331
- heartbeatData = {
2332
- browserId: browserId,
2333
- timestamp: /* @__PURE__ */ new Date().toISOString()
2334
- };
2335
- headers = {
2336
- "Content-Type": "application/json"
2337
- };
2338
- if (licenseKey) {
2339
- headers["Authorization"] = "Bearer ".concat(licenseKey);
2340
- }
2341
- return [
2342
- 4,
2343
- fetch("https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat", {
2344
- method: "POST",
2345
- headers: headers,
2346
- body: JSON.stringify(heartbeatData)
2347
- })
2539
+ buildPlayerMetricEvent(context, flags)
2348
2540
  ];
2349
2541
  case 2:
2350
- response = _state.sent();
2351
- if (!response.ok) {
2352
- throw new Error("HTTP error! status: ".concat(response.status));
2353
- }
2354
- return [
2355
- 4,
2356
- response.json()
2357
- ];
2358
- case 3:
2359
- _state.sent();
2542
+ heartbeatData = _state.sent();
2543
+ publishTracking(licenseKey, "heartbeat", heartbeatData);
2360
2544
  return [
2361
2545
  3,
2362
- 5
2546
+ 4
2363
2547
  ];
2364
- case 4:
2548
+ case 3:
2365
2549
  error = _state.sent();
2366
2550
  console.error("[StormcloudVideoPlayer] Error sending heartbeat:", error);
2367
2551
  return [
2368
2552
  3,
2369
- 5
2553
+ 4
2370
2554
  ];
2371
- case 5:
2555
+ case 4:
2372
2556
  return [
2373
2557
  2
2374
2558
  ];
2375
2559
  }
2376
2560
  });
2377
- })();
2561
+ }).apply(this, arguments);
2378
2562
  }
2379
2563
  // src/utils/polyfills.ts
2380
2564
  function polyfillURLSearchParams() {
@@ -2961,6 +3145,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
2961
3145
  this.config = _object_spread({}, browserOverrides, config);
2962
3146
  this.video = config.videoElement;
2963
3147
  this.adTransitionGapMs = (_this_config_adTransitionGapMs = this.config.adTransitionGapMs) !== null && _this_config_adTransitionGapMs !== void 0 ? _this_config_adTransitionGapMs : 100;
3148
+ if (this.config.mqttConfig) {
3149
+ configureMQTT(this.config.mqttConfig);
3150
+ }
2964
3151
  logBrowserInfo(config.debugAdTiming);
2965
3152
  var browserForAdLayer = detectBrowser();
2966
3153
  var isSinglePipeline = browserForAdLayer.isSmartTV || !!this.config.singlePipelineMode;
@@ -3328,7 +3515,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3328
3515
  source: _this.getAdSource(),
3329
3516
  adIndex: _this.currentAdIndex,
3330
3517
  timestamp: /* @__PURE__ */ new Date().toISOString()
3331
- });
3518
+ }, _this.getPlayerAnalyticsContext());
3332
3519
  }
3333
3520
  });
3334
3521
  this.adLayer.on("ad_error", function(errorPayload) {
@@ -3633,7 +3820,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3633
3820
  key: "initializeTracking",
3634
3821
  value: function initializeTracking() {
3635
3822
  var _this = this;
3636
- sendInitialTracking(this.config.licenseKey).then(function() {
3823
+ sendInitialTracking(this.config.licenseKey, this.getPlayerAnalyticsContext()).then(function() {
3637
3824
  _this.heartbeatInterval = window.setInterval(function() {
3638
3825
  _this.sendHeartbeatIfNeeded();
3639
3826
  }, 5e3);
@@ -3654,7 +3841,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3654
3841
  var now = Date.now();
3655
3842
  if (!this.lastHeartbeatTime || now - this.lastHeartbeatTime > 3e4) {
3656
3843
  this.lastHeartbeatTime = now;
3657
- sendHeartbeat(this.config.licenseKey).catch(function(error) {
3844
+ sendHeartbeat(this.config.licenseKey, this.getPlayerAnalyticsContext()).catch(function(error) {
3658
3845
  if (_this.config.debugAdTiming) {
3659
3846
  console.warn("[StormcloudVideoPlayer] Failed to send heartbeat:", error);
3660
3847
  }
@@ -3748,6 +3935,14 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3748
3935
  return "other";
3749
3936
  }
3750
3937
  },
3938
+ {
3939
+ key: "getPlayerAnalyticsContext",
3940
+ value: function getPlayerAnalyticsContext() {
3941
+ return {
3942
+ inputStreamType: this.getStreamType()
3943
+ };
3944
+ }
3945
+ },
3751
3946
  {
3752
3947
  key: "shouldShowNativeControls",
3753
3948
  value: function shouldShowNativeControls() {
@@ -4402,7 +4597,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4402
4597
  sendAdLoadedTracking(_this.config.licenseKey, {
4403
4598
  source: _this.getAdSource(),
4404
4599
  timestamp: /* @__PURE__ */ new Date().toISOString()
4405
- });
4600
+ }, _this.getPlayerAnalyticsContext());
4406
4601
  }
4407
4602
  return [
4408
4603
  4,
@@ -4512,7 +4707,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4512
4707
  sendAdLoadedTracking(_this.config.licenseKey, {
4513
4708
  source: _this.getAdSource(),
4514
4709
  timestamp: /* @__PURE__ */ new Date().toISOString()
4515
- });
4710
+ }, _this.getPlayerAnalyticsContext());
4516
4711
  }
4517
4712
  return [
4518
4713
  4,
@@ -4679,7 +4874,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4679
4874
  sendAdLoadedTracking(this.config.licenseKey, {
4680
4875
  source: this.getAdSource(),
4681
4876
  timestamp: /* @__PURE__ */ new Date().toISOString()
4682
- });
4877
+ }, this.getPlayerAnalyticsContext());
4683
4878
  }
4684
4879
  _state.label = 1;
4685
4880
  case 1:
@@ -4878,7 +5073,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4878
5073
  sendAdLoadedTracking(this.config.licenseKey, {
4879
5074
  source: this.getAdSource(),
4880
5075
  timestamp: /* @__PURE__ */ new Date().toISOString()
4881
- });
5076
+ }, this.getPlayerAnalyticsContext());
4882
5077
  }
4883
5078
  return [
4884
5079
  4,
@@ -5823,6 +6018,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5823
6018
  clearInterval(this.heartbeatInterval);
5824
6019
  this.heartbeatInterval = void 0;
5825
6020
  }
6021
+ if (isMQTTEnabled()) {
6022
+ disconnectMQTT();
6023
+ }
5826
6024
  (_this_hls = this.hls) === null || _this_hls === void 0 ? void 0 : _this_hls.destroy();
5827
6025
  (_this_adLayer = this.adLayer) === null || _this_adLayer === void 0 ? void 0 : _this_adLayer.destroy();
5828
6026
  this.consecutiveFailures = 0;
@@ -6072,7 +6270,7 @@ function cachedFetchRSSItems(rssUrl, maxItems) {
6072
6270
  }
6073
6271
  function fetchRSSItems(rssUrl, maxItems) {
6074
6272
  return _async_to_generator(function() {
6075
- var encoded, origin, resp, text, unused, resp1, data, unused1, resp2, text1, unused2;
6273
+ var encoded, resp, text, unused, resp1, data, unused1, resp2, text1, unused2;
6076
6274
  return _ts_generator(this, function(_state) {
6077
6275
  switch(_state.label){
6078
6276
  case 0:
@@ -6085,10 +6283,9 @@ function fetchRSSItems(rssUrl, maxItems) {
6085
6283
  ,
6086
6284
  6
6087
6285
  ]);
6088
- origin = typeof window !== "undefined" ? window.location.origin : "";
6089
6286
  return [
6090
6287
  4,
6091
- fetch("".concat(origin, "/api/rss-proxy?url=").concat(encoded))
6288
+ fetch("https://adstorm.co/api/rss-proxy?url=".concat(encoded))
6092
6289
  ];
6093
6290
  case 2:
6094
6291
  resp = _state.sent();
@@ -8021,7 +8218,18 @@ var CRITICAL_PROPS = [
8021
8218
  "licenseKey",
8022
8219
  "lowLatencyMode",
8023
8220
  "driftToleranceMs",
8024
- "debugAdTiming"
8221
+ "immediateManifestAds",
8222
+ "debugAdTiming",
8223
+ "showCustomControls",
8224
+ "adFailsafeTimeoutMs",
8225
+ "minSegmentsBeforePlay",
8226
+ "disableAds",
8227
+ "disableFiller",
8228
+ "singlePipelineMode",
8229
+ "mqttConfig",
8230
+ "adBreakCheckIntervalMs",
8231
+ "maxAdBreakExtensionMs",
8232
+ "adTransitionGapMs"
8025
8233
  ];
8026
8234
  var CONTROLS_HIDE_DELAY = 3e3;
8027
8235
  var DEFAULT_PLAYER_ASPECT_RATIO = 16 / 9;
@@ -8032,7 +8240,7 @@ var PANEL_BASE_RIGHT_OFFSET = 10;
8032
8240
  var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props) {
8033
8241
  var _ref;
8034
8242
  var _aiLiveContext_context;
8035
- var src = props.src, autoplay = props.autoplay, muted = props.muted, lowLatencyMode = props.lowLatencyMode, allowNativeHls = props.allowNativeHls, driftToleranceMs = props.driftToleranceMs, immediateManifestAds = props.immediateManifestAds, debugAdTiming = props.debugAdTiming, showCustomControls = props.showCustomControls, hideLoadingIndicator = props.hideLoadingIndicator, onVolumeToggle = props.onVolumeToggle, onFullscreenToggle = props.onFullscreenToggle, onControlClick = props.onControlClick, onReady = props.onReady, wrapperClassName = props.wrapperClassName, wrapperStyle = props.wrapperStyle, className = props.className, style = props.style, controls = props.controls, playsInline = props.playsInline, preload = props.preload, poster = props.poster, children = props.children, licenseKey = props.licenseKey, minSegmentsBeforePlay = props.minSegmentsBeforePlay, disableAds = props.disableAds, disableFiller = props.disableFiller, swirlProjectId = props.swirlProjectId, swirlShowcaseDemo = props.swirlShowcaseDemo, swirlOverlayApiBaseUrl = props.swirlOverlayApiBaseUrl, swirlOverlayCoordinateSpace = props.swirlOverlayCoordinateSpace, adcisionChannelId = props.adcisionChannelId, disableOverlays = props.disableOverlays, showAdsControl = props.showAdsControl, showOverlaysControl = props.showOverlaysControl, showAiContextControl = props.showAiContextControl, showDebugControl = props.showDebugControl, restVideoAttrs = _object_without_properties(props, [
8243
+ var src = props.src, autoplay = props.autoplay, muted = props.muted, lowLatencyMode = props.lowLatencyMode, allowNativeHls = props.allowNativeHls, driftToleranceMs = props.driftToleranceMs, immediateManifestAds = props.immediateManifestAds, debugAdTiming = props.debugAdTiming, showCustomControls = props.showCustomControls, hideLoadingIndicator = props.hideLoadingIndicator, onVolumeToggle = props.onVolumeToggle, onFullscreenToggle = props.onFullscreenToggle, onControlClick = props.onControlClick, onReady = props.onReady, wrapperClassName = props.wrapperClassName, wrapperStyle = props.wrapperStyle, className = props.className, style = props.style, controls = props.controls, playsInline = props.playsInline, preload = props.preload, poster = props.poster, children = props.children, licenseKey = props.licenseKey, adFailsafeTimeoutMs = props.adFailsafeTimeoutMs, minSegmentsBeforePlay = props.minSegmentsBeforePlay, disableAds = props.disableAds, disableFiller = props.disableFiller, singlePipelineMode = props.singlePipelineMode, mqttConfig2 = props.mqttConfig, adBreakCheckIntervalMs = props.adBreakCheckIntervalMs, maxAdBreakExtensionMs = props.maxAdBreakExtensionMs, adTransitionGapMs = props.adTransitionGapMs, swirlProjectId = props.swirlProjectId, swirlShowcaseDemo = props.swirlShowcaseDemo, swirlOverlayApiBaseUrl = props.swirlOverlayApiBaseUrl, swirlOverlayCoordinateSpace = props.swirlOverlayCoordinateSpace, adcisionChannelId = props.adcisionChannelId, disableOverlays = props.disableOverlays, showAdsControl = props.showAdsControl, showOverlaysControl = props.showOverlaysControl, showAiContextControl = props.showAiContextControl, showDebugControl = props.showDebugControl, restVideoAttrs = _object_without_properties(props, [
8036
8244
  "src",
8037
8245
  "autoplay",
8038
8246
  "muted",
@@ -8057,9 +8265,15 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
8057
8265
  "poster",
8058
8266
  "children",
8059
8267
  "licenseKey",
8268
+ "adFailsafeTimeoutMs",
8060
8269
  "minSegmentsBeforePlay",
8061
8270
  "disableAds",
8062
8271
  "disableFiller",
8272
+ "singlePipelineMode",
8273
+ "mqttConfig",
8274
+ "adBreakCheckIntervalMs",
8275
+ "maxAdBreakExtensionMs",
8276
+ "adTransitionGapMs",
8063
8277
  "swirlProjectId",
8064
8278
  "swirlShowcaseDemo",
8065
8279
  "swirlOverlayApiBaseUrl",
@@ -8300,7 +8514,7 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
8300
8514
  var debugPanelBottomOffset = shouldShowEnhancedControls ? Math.max(74, 92 * responsiveScale) : Math.max(52, 58 * responsiveScale);
8301
8515
  var criticalPropsKey = (0, import_react2.useMemo)(function() {
8302
8516
  var baseParts = CRITICAL_PROPS.map(function(prop) {
8303
- return prop === "src" ? "src:".concat(effectiveSrc) : "".concat(prop, ":").concat(props[prop]);
8517
+ return prop === "src" ? "src:".concat(effectiveSrc) : "".concat(prop, ":").concat(JSON.stringify(props[prop]));
8304
8518
  }).join("|");
8305
8519
  return "".concat(baseParts, "|adcisionChannelId:").concat(adcisionChannelId !== null && adcisionChannelId !== void 0 ? adcisionChannelId : "");
8306
8520
  }, [
@@ -8309,8 +8523,19 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
8309
8523
  licenseKey,
8310
8524
  lowLatencyMode,
8311
8525
  driftToleranceMs,
8526
+ immediateManifestAds,
8312
8527
  adcisionChannelId,
8313
- debugAdTiming
8528
+ debugAdTiming,
8529
+ showCustomControls,
8530
+ adFailsafeTimeoutMs,
8531
+ minSegmentsBeforePlay,
8532
+ disableAds,
8533
+ disableFiller,
8534
+ singlePipelineMode,
8535
+ mqttConfig2,
8536
+ adBreakCheckIntervalMs,
8537
+ maxAdBreakExtensionMs,
8538
+ adTransitionGapMs
8314
8539
  ]);
8315
8540
  (0, import_react2.useEffect)(function() {
8316
8541
  if (typeof window === "undefined") return;
@@ -8344,9 +8569,15 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
8344
8569
  if (onFullscreenToggle !== void 0) cfg.onFullscreenToggle = onFullscreenToggle;
8345
8570
  if (onControlClick !== void 0) cfg.onControlClick = onControlClick;
8346
8571
  if (licenseKey !== void 0) cfg.licenseKey = licenseKey;
8572
+ if (adFailsafeTimeoutMs !== void 0) cfg.adFailsafeTimeoutMs = adFailsafeTimeoutMs;
8347
8573
  if (minSegmentsBeforePlay !== void 0) cfg.minSegmentsBeforePlay = minSegmentsBeforePlay;
8348
8574
  if (disableAds !== void 0) cfg.disableAds = disableAds;
8349
8575
  cfg.disableFiller = disableFiller !== null && disableFiller !== void 0 ? disableFiller : true;
8576
+ if (singlePipelineMode !== void 0) cfg.singlePipelineMode = singlePipelineMode;
8577
+ if (mqttConfig2 !== void 0) cfg.mqttConfig = mqttConfig2;
8578
+ if (adBreakCheckIntervalMs !== void 0) cfg.adBreakCheckIntervalMs = adBreakCheckIntervalMs;
8579
+ if (maxAdBreakExtensionMs !== void 0) cfg.maxAdBreakExtensionMs = maxAdBreakExtensionMs;
8580
+ if (adTransitionGapMs !== void 0) cfg.adTransitionGapMs = adTransitionGapMs;
8350
8581
  if (adcisionChannelId !== void 0) {
8351
8582
  cfg.projectId = String(adcisionChannelId);
8352
8583
  cfg.channelId = adcisionChannelId;
@@ -11485,36 +11716,54 @@ var StormcloudPlayer = createStormcloudPlayer(players_default, players_default[p
11485
11716
  var StormcloudPlayer_default = StormcloudPlayer;
11486
11717
  // Annotate the CommonJS export names for ESM import in node:
11487
11718
  0 && (module.exports = {
11719
+ DEFAULT_MQTT_CONFIG: DEFAULT_MQTT_CONFIG,
11488
11720
  IS_BROWSER: IS_BROWSER,
11489
11721
  IS_GLOBAL: IS_GLOBAL,
11490
11722
  IS_IOS: IS_IOS,
11491
11723
  IS_SAFARI: IS_SAFARI,
11724
+ MQTT_CA_CERT_FILE: MQTT_CA_CERT_FILE,
11492
11725
  OVERLAY_API_BASE: OVERLAY_API_BASE,
11493
11726
  SUPPORTS_DASH: SUPPORTS_DASH,
11494
11727
  SUPPORTS_HLS: SUPPORTS_HLS,
11495
11728
  StormcloudPlayer: StormcloudPlayer,
11496
11729
  StormcloudVideoPlayer: StormcloudVideoPlayer,
11497
11730
  StormcloudVideoPlayerComponent: StormcloudVideoPlayerComponent,
11731
+ applyMQTTConfig: applyMQTTConfig,
11732
+ buildMQTTBrokerUrl: buildMQTTBrokerUrl,
11733
+ buildPlayerTopic: buildPlayerTopic,
11498
11734
  canPlay: canPlay,
11735
+ configureMQTT: configureMQTT,
11499
11736
  createAdStormPlayer: createAdStormPlayer,
11500
11737
  createStormcloudPlayer: createStormcloudPlayer,
11501
11738
  detectBrowser: detectBrowser,
11739
+ disconnectMQTT: disconnectMQTT,
11740
+ ensureMQTTClient: ensureMQTTClient,
11502
11741
  fetchProjectOverlays: fetchProjectOverlays,
11503
11742
  getBrowserConfigOverrides: getBrowserConfigOverrides,
11504
11743
  getBrowserID: getBrowserID,
11505
11744
  getClientInfo: getClientInfo,
11745
+ getMQTTStatus: getMQTTStatus,
11746
+ initMQTTClient: initMQTTClient,
11506
11747
  initializePolyfills: initializePolyfills,
11748
+ isMQTTConfigured: isMQTTConfigured,
11749
+ isMQTTConnected: isMQTTConnected,
11750
+ isMQTTEnabled: isMQTTEnabled,
11507
11751
  isMediaStream: isMediaStream,
11508
11752
  isOverlayActive: isOverlayActive,
11509
11753
  lazy: lazy,
11510
11754
  logBrowserInfo: logBrowserInfo,
11511
11755
  merge: merge,
11756
+ mqttConfig: mqttConfig,
11512
11757
  normalizeSwirlOverlay: normalizeSwirlOverlay,
11513
11758
  omit: omit,
11514
11759
  parseQuery: parseQuery,
11515
11760
  players: players,
11761
+ publishMQTT: publishMQTT,
11516
11762
  randomString: randomString,
11517
11763
  resolveImageUrl: resolveImageUrl,
11764
+ sendAdDetectTracking: sendAdDetectTracking,
11765
+ sendAdImpressionTracking: sendAdImpressionTracking,
11766
+ sendAdLoadedTracking: sendAdLoadedTracking,
11518
11767
  sendHeartbeat: sendHeartbeat,
11519
11768
  sendInitialTracking: sendInitialTracking,
11520
11769
  supportsFeature: supportsFeature,