stormcloud-video-player 0.3.63 → 0.3.64

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.
@@ -2378,6 +2378,99 @@ function createHlsAdPlayer(contentVideo, options) {
2378
2378
  }
2379
2379
  };
2380
2380
  }
2381
+ // src/utils/mqttConfig.ts
2382
+ var DEFAULT_MQTT_CONFIG = {
2383
+ enabled: true,
2384
+ brokerAddress: "vecbae77.ala.us-east-1.emqxsl.com",
2385
+ brokerPort: 8883,
2386
+ wsPort: 8084,
2387
+ username: "for-sonifi",
2388
+ password: "sonifi-mqtt",
2389
+ topicPrefix: "adstorm/players",
2390
+ qos: 1
2391
+ };
2392
+ var mqttConfig = _object_spread({}, DEFAULT_MQTT_CONFIG);
2393
+ function isMQTTEnabled() {
2394
+ return mqttConfig.enabled;
2395
+ }
2396
+ function buildMQTTBrokerUrl() {
2397
+ if (mqttConfig.brokerUrl) return mqttConfig.brokerUrl;
2398
+ return "wss://".concat(mqttConfig.brokerAddress, ":").concat(mqttConfig.wsPort, "/mqtt");
2399
+ }
2400
+ function buildPlayerTopic(licenseKey, channel) {
2401
+ return "".concat(mqttConfig.topicPrefix, "/").concat(licenseKey, "/").concat(channel);
2402
+ }
2403
+ // src/utils/mqttClient.ts
2404
+ var import_mqtt = __toESM(require("mqtt"), 1);
2405
+ var LOG = "[StormcloudVideoPlayer][MQTT]";
2406
+ var client = null;
2407
+ var status = "disconnected";
2408
+ function initMQTTClient() {
2409
+ if (client || !isMQTTEnabled()) return;
2410
+ var url = buildMQTTBrokerUrl();
2411
+ status = "connecting";
2412
+ var clientId = "stormcloud-vp-".concat(Math.random().toString(36).slice(2, 9));
2413
+ try {
2414
+ client = import_mqtt.default.connect(url, {
2415
+ clientId: clientId,
2416
+ username: mqttConfig.username,
2417
+ password: mqttConfig.password,
2418
+ keepalive: 60,
2419
+ clean: true,
2420
+ reconnectPeriod: 5e3,
2421
+ connectTimeout: 1e4,
2422
+ queueQoSZero: false
2423
+ });
2424
+ } catch (err) {
2425
+ status = "error";
2426
+ console.warn("".concat(LOG, " connect() threw:"), err);
2427
+ return;
2428
+ }
2429
+ client.on("connect", function() {
2430
+ status = "connected";
2431
+ console.info("".concat(LOG, " connected to ").concat(url));
2432
+ });
2433
+ client.on("reconnect", function() {
2434
+ status = "connecting";
2435
+ console.info("".concat(LOG, " reconnecting…"));
2436
+ });
2437
+ client.on("offline", function() {
2438
+ status = "disconnected";
2439
+ console.warn("".concat(LOG, " offline"));
2440
+ });
2441
+ client.on("error", function(err) {
2442
+ status = "error";
2443
+ console.warn("".concat(LOG, " error:"), err.message);
2444
+ });
2445
+ client.on("close", function() {
2446
+ if (status === "connected") {
2447
+ status = "disconnected";
2448
+ }
2449
+ });
2450
+ }
2451
+ function ensureMQTTClient() {
2452
+ if (isMQTTEnabled() && !client) {
2453
+ initMQTTClient();
2454
+ }
2455
+ }
2456
+ function publishMQTT(topic, payload) {
2457
+ if (!isMQTTEnabled()) {
2458
+ return false;
2459
+ }
2460
+ ensureMQTTClient();
2461
+ if (!client) {
2462
+ return false;
2463
+ }
2464
+ try {
2465
+ client.publish(topic, JSON.stringify(payload), {
2466
+ qos: mqttConfig.qos
2467
+ });
2468
+ return true;
2469
+ } catch (err) {
2470
+ console.warn("".concat(LOG, " publish failed on ").concat(topic, ":"), err);
2471
+ return false;
2472
+ }
2473
+ }
2381
2474
  // src/utils/tracking.ts
2382
2475
  var cachedBrowserId = null;
2383
2476
  function getClientInfo() {
@@ -2524,7 +2617,7 @@ function getClientInfo() {
2524
2617
  }
2525
2618
  function getBrowserID(clientInfo) {
2526
2619
  return _async_to_generator(function() {
2527
- var fingerprintString, encodedData, utf8, buffer, i, hashBuffer, hashArray, hashHex, error, hash, i1, char, fallbackHash, timestamp, random;
2620
+ var _crypto_subtle, fingerprintString, encodedData, utf8, buffer, i, hashBuffer, hashHex, unused, hash, i1, char, fallbackHash, timestamp, random;
2528
2621
  return _ts_generator(this, function(_state) {
2529
2622
  switch(_state.label){
2530
2623
  case 0:
@@ -2535,7 +2628,7 @@ function getBrowserID(clientInfo) {
2535
2628
  ];
2536
2629
  }
2537
2630
  fingerprintString = JSON.stringify(clientInfo);
2538
- if (!(typeof crypto !== "undefined" && crypto.subtle && crypto.subtle.digest)) return [
2631
+ if (!(typeof crypto !== "undefined" && ((_crypto_subtle = crypto.subtle) === null || _crypto_subtle === void 0 ? void 0 : _crypto_subtle.digest))) return [
2539
2632
  3,
2540
2633
  5
2541
2634
  ];
@@ -2573,8 +2666,7 @@ function getBrowserID(clientInfo) {
2573
2666
  ];
2574
2667
  case 3:
2575
2668
  hashBuffer = _state.sent();
2576
- hashArray = Array.from(new Uint8Array(hashBuffer));
2577
- hashHex = hashArray.map(function(b) {
2669
+ hashHex = Array.from(new Uint8Array(hashBuffer)).map(function(b) {
2578
2670
  return b.toString(16).padStart(2, "0");
2579
2671
  }).join("");
2580
2672
  cachedBrowserId = hashHex;
@@ -2583,8 +2675,8 @@ function getBrowserID(clientInfo) {
2583
2675
  hashHex
2584
2676
  ];
2585
2677
  case 4:
2586
- error = _state.sent();
2587
- console.warn("[StormcloudVideoPlayer] crypto.subtle.digest not supported, using fallback hash");
2678
+ unused = _state.sent();
2679
+ console.warn("[StormcloudVideoPlayer] crypto.subtle not supported, using fallback hash");
2588
2680
  return [
2589
2681
  3,
2590
2682
  5
@@ -2608,177 +2700,91 @@ function getBrowserID(clientInfo) {
2608
2700
  });
2609
2701
  })();
2610
2702
  }
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) {
2625
- return _async_to_generator(function() {
2626
- var response;
2627
- return _ts_generator(this, function(_state) {
2628
- switch(_state.label){
2629
- case 0:
2630
- return [
2631
- 4,
2632
- fetch(TRACK_URL, {
2633
- method: "POST",
2634
- headers: buildHeaders(licenseKey),
2635
- body: JSON.stringify(body)
2636
- })
2637
- ];
2638
- case 1:
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
- })();
2703
+ function canPublish(licenseKey) {
2704
+ return Boolean(isMQTTEnabled() && licenseKey);
2655
2705
  }
2656
- function postJson(url, licenseKey, body) {
2706
+ function buildPlayerMetricEvent() {
2657
2707
  return _async_to_generator(function() {
2658
- var response;
2659
- return _ts_generator(this, function(_state) {
2660
- switch(_state.label){
2661
- case 0:
2662
- return [
2663
- 4,
2664
- fetch(url, {
2665
- method: "POST",
2666
- headers: buildHeaders(licenseKey),
2667
- body: JSON.stringify(body)
2668
- })
2669
- ];
2670
- case 1:
2671
- response = _state.sent();
2672
- if (!response.ok) {
2673
- throw new Error("HTTP error! status: ".concat(response.status));
2674
- }
2675
- return [
2676
- 4,
2677
- response.json()
2678
- ];
2679
- case 2:
2680
- _state.sent();
2681
- return [
2682
- 2
2683
- ];
2684
- }
2685
- });
2686
- })();
2687
- }
2688
- function buildPlayerMetricEvent(_0) {
2689
- return _async_to_generator(function(licenseKey) {
2690
- var context, flags, _flags_captureAt, clientInfo, browserId, captureAt;
2708
+ var context, flags, _flags_captureAt, _flags_adLoaded, _flags_adDetect, clientInfo, playerId, captureAt;
2691
2709
  var _arguments = arguments;
2692
2710
  return _ts_generator(this, function(_state) {
2693
2711
  switch(_state.label){
2694
2712
  case 0:
2695
- context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2713
+ context = _arguments.length > 0 && _arguments[0] !== void 0 ? _arguments[0] : {}, flags = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
2696
2714
  clientInfo = getClientInfo();
2697
2715
  return [
2698
2716
  4,
2699
2717
  getBrowserID(clientInfo)
2700
2718
  ];
2701
2719
  case 1:
2702
- browserId = _state.sent();
2720
+ playerId = _state.sent();
2703
2721
  captureAt = (_flags_captureAt = flags.captureAt) !== null && _flags_captureAt !== void 0 ? _flags_captureAt : /* @__PURE__ */ new Date().toISOString();
2704
2722
  return [
2705
2723
  2,
2706
- {
2707
- player_id: browserId,
2708
- browserId: browserId,
2724
+ _object_spread({
2725
+ player_id: playerId,
2709
2726
  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
- }
2727
+ os: clientInfo.os.toLowerCase(),
2728
+ ad_loaded: (_flags_adLoaded = flags.adLoaded) !== null && _flags_adLoaded !== void 0 ? _flags_adLoaded : false,
2729
+ ad_detect: (_flags_adDetect = flags.adDetect) !== null && _flags_adDetect !== void 0 ? _flags_adDetect : false,
2730
+ capture_at: captureAt
2731
+ }, context.inputStreamType ? {
2732
+ input_stream_type: context.inputStreamType
2733
+ } : {})
2719
2734
  ];
2720
2735
  }
2721
2736
  });
2722
2737
  }).apply(this, arguments);
2723
2738
  }
2739
+ function publishTracking(licenseKey, channel, body) {
2740
+ ensureMQTTClient();
2741
+ publishMQTT(buildPlayerTopic(licenseKey, channel), body);
2742
+ }
2724
2743
  function sendInitialTracking(_0) {
2725
2744
  return _async_to_generator(function(licenseKey) {
2726
- var context, clientInfo, browserId, trackingData, error;
2745
+ var context, metricEvent, error;
2727
2746
  var _arguments = arguments;
2728
2747
  return _ts_generator(this, function(_state) {
2729
2748
  switch(_state.label){
2730
2749
  case 0:
2731
2750
  context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
2751
+ if (!canPublish(licenseKey)) return [
2752
+ 2
2753
+ ];
2732
2754
  _state.label = 1;
2733
2755
  case 1:
2734
2756
  _state.trys.push([
2735
2757
  1,
2736
- 4,
2758
+ 3,
2737
2759
  ,
2738
- 5
2760
+ 4
2739
2761
  ]);
2740
- clientInfo = getClientInfo();
2741
2762
  return [
2742
2763
  4,
2743
- getBrowserID(clientInfo)
2744
- ];
2745
- case 2:
2746
- browserId = _state.sent();
2747
- trackingData = _object_spread({
2748
- browserId: browserId
2749
- }, clientInfo);
2750
- return [
2751
- 4,
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
2764
+ buildPlayerMetricEvent(context, {
2765
+ adLoaded: false,
2766
+ adDetect: false
2766
2767
  })
2767
2768
  ];
2768
- case 3:
2769
- _state.sent();
2769
+ case 2:
2770
+ metricEvent = _state.sent();
2771
+ publishTracking(licenseKey, "metrics", {
2772
+ events: [
2773
+ metricEvent
2774
+ ]
2775
+ });
2770
2776
  return [
2771
2777
  3,
2772
- 5
2778
+ 4
2773
2779
  ];
2774
- case 4:
2780
+ case 3:
2775
2781
  error = _state.sent();
2776
2782
  console.error("[StormcloudVideoPlayer] Error sending initial tracking data:", error);
2777
2783
  return [
2778
2784
  3,
2779
- 5
2785
+ 4
2780
2786
  ];
2781
- case 5:
2787
+ case 4:
2782
2788
  return [
2783
2789
  2
2784
2790
  ];
@@ -2882,53 +2888,48 @@ function sendAdImpressionTracking(_0, _1) {
2882
2888
  switch(_state.label){
2883
2889
  case 0:
2884
2890
  context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2891
+ if (!canPublish(licenseKey)) return [
2892
+ 2
2893
+ ];
2885
2894
  _state.label = 1;
2886
2895
  case 1:
2887
2896
  _state.trys.push([
2888
2897
  1,
2889
- 4,
2898
+ 3,
2890
2899
  ,
2891
- 5
2900
+ 4
2892
2901
  ]);
2893
2902
  return [
2894
2903
  4,
2895
- buildPlayerMetricEvent(licenseKey, context, {
2904
+ buildPlayerMetricEvent(context, {
2896
2905
  captureAt: adImpressionInfo.timestamp
2897
2906
  })
2898
2907
  ];
2899
2908
  case 2:
2900
2909
  metricEvent = _state.sent();
2901
- return [
2902
- 4,
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
- ])
2917
- ];
2918
- case 3:
2919
- _state.sent();
2910
+ publishTracking(licenseKey, "heartbeat", metricEvent);
2911
+ publishTracking(licenseKey, "impressions", {
2912
+ events: [
2913
+ {
2914
+ player_id: metricEvent.player_id,
2915
+ ad_played_count: 1,
2916
+ ad_url: adImpressionInfo.adUrl,
2917
+ capture_at: adImpressionInfo.timestamp
2918
+ }
2919
+ ]
2920
+ });
2920
2921
  return [
2921
2922
  3,
2922
- 5
2923
+ 4
2923
2924
  ];
2924
- case 4:
2925
+ case 3:
2925
2926
  error = _state.sent();
2926
2927
  console.error("[StormcloudVideoPlayer] Error sending ad impression tracking:", error);
2927
2928
  return [
2928
2929
  3,
2929
- 5
2930
+ 4
2930
2931
  ];
2931
- case 5:
2932
+ case 4:
2932
2933
  return [
2933
2934
  2
2934
2935
  ];
@@ -2944,38 +2945,36 @@ function sendHeartbeat(_0) {
2944
2945
  switch(_state.label){
2945
2946
  case 0:
2946
2947
  context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2948
+ if (!canPublish(licenseKey)) return [
2949
+ 2
2950
+ ];
2947
2951
  _state.label = 1;
2948
2952
  case 1:
2949
2953
  _state.trys.push([
2950
2954
  1,
2951
- 4,
2955
+ 3,
2952
2956
  ,
2953
- 5
2957
+ 4
2954
2958
  ]);
2955
2959
  return [
2956
2960
  4,
2957
- buildPlayerMetricEvent(licenseKey, context, flags)
2961
+ buildPlayerMetricEvent(context, flags)
2958
2962
  ];
2959
2963
  case 2:
2960
2964
  heartbeatData = _state.sent();
2961
- return [
2962
- 4,
2963
- postJson(HEARTBEAT_URL, licenseKey, heartbeatData)
2964
- ];
2965
- case 3:
2966
- _state.sent();
2965
+ publishTracking(licenseKey, "heartbeat", heartbeatData);
2967
2966
  return [
2968
2967
  3,
2969
- 5
2968
+ 4
2970
2969
  ];
2971
- case 4:
2970
+ case 3:
2972
2971
  error = _state.sent();
2973
2972
  console.error("[StormcloudVideoPlayer] Error sending heartbeat:", error);
2974
2973
  return [
2975
2974
  3,
2976
- 5
2975
+ 4
2977
2976
  ];
2978
- case 5:
2977
+ case 4:
2979
2978
  return [
2980
2979
  2
2981
2980
  ];