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.
@@ -2466,6 +2466,99 @@ function createHlsAdPlayer(contentVideo, options) {
2466
2466
  }
2467
2467
  };
2468
2468
  }
2469
+ // src/utils/mqttConfig.ts
2470
+ var DEFAULT_MQTT_CONFIG = {
2471
+ enabled: true,
2472
+ brokerAddress: "vecbae77.ala.us-east-1.emqxsl.com",
2473
+ brokerPort: 8883,
2474
+ wsPort: 8084,
2475
+ username: "for-sonifi",
2476
+ password: "sonifi-mqtt",
2477
+ topicPrefix: "adstorm/players",
2478
+ qos: 1
2479
+ };
2480
+ var mqttConfig = _object_spread({}, DEFAULT_MQTT_CONFIG);
2481
+ function isMQTTEnabled() {
2482
+ return mqttConfig.enabled;
2483
+ }
2484
+ function buildMQTTBrokerUrl() {
2485
+ if (mqttConfig.brokerUrl) return mqttConfig.brokerUrl;
2486
+ return "wss://".concat(mqttConfig.brokerAddress, ":").concat(mqttConfig.wsPort, "/mqtt");
2487
+ }
2488
+ function buildPlayerTopic(licenseKey, channel) {
2489
+ return "".concat(mqttConfig.topicPrefix, "/").concat(licenseKey, "/").concat(channel);
2490
+ }
2491
+ // src/utils/mqttClient.ts
2492
+ var import_mqtt = __toESM(require("mqtt"), 1);
2493
+ var LOG = "[StormcloudVideoPlayer][MQTT]";
2494
+ var client = null;
2495
+ var status = "disconnected";
2496
+ function initMQTTClient() {
2497
+ if (client || !isMQTTEnabled()) return;
2498
+ var url = buildMQTTBrokerUrl();
2499
+ status = "connecting";
2500
+ var clientId = "stormcloud-vp-".concat(Math.random().toString(36).slice(2, 9));
2501
+ try {
2502
+ client = import_mqtt.default.connect(url, {
2503
+ clientId: clientId,
2504
+ username: mqttConfig.username,
2505
+ password: mqttConfig.password,
2506
+ keepalive: 60,
2507
+ clean: true,
2508
+ reconnectPeriod: 5e3,
2509
+ connectTimeout: 1e4,
2510
+ queueQoSZero: false
2511
+ });
2512
+ } catch (err) {
2513
+ status = "error";
2514
+ console.warn("".concat(LOG, " connect() threw:"), err);
2515
+ return;
2516
+ }
2517
+ client.on("connect", function() {
2518
+ status = "connected";
2519
+ console.info("".concat(LOG, " connected to ").concat(url));
2520
+ });
2521
+ client.on("reconnect", function() {
2522
+ status = "connecting";
2523
+ console.info("".concat(LOG, " reconnecting…"));
2524
+ });
2525
+ client.on("offline", function() {
2526
+ status = "disconnected";
2527
+ console.warn("".concat(LOG, " offline"));
2528
+ });
2529
+ client.on("error", function(err) {
2530
+ status = "error";
2531
+ console.warn("".concat(LOG, " error:"), err.message);
2532
+ });
2533
+ client.on("close", function() {
2534
+ if (status === "connected") {
2535
+ status = "disconnected";
2536
+ }
2537
+ });
2538
+ }
2539
+ function ensureMQTTClient() {
2540
+ if (isMQTTEnabled() && !client) {
2541
+ initMQTTClient();
2542
+ }
2543
+ }
2544
+ function publishMQTT(topic, payload) {
2545
+ if (!isMQTTEnabled()) {
2546
+ return false;
2547
+ }
2548
+ ensureMQTTClient();
2549
+ if (!client) {
2550
+ return false;
2551
+ }
2552
+ try {
2553
+ client.publish(topic, JSON.stringify(payload), {
2554
+ qos: mqttConfig.qos
2555
+ });
2556
+ return true;
2557
+ } catch (err) {
2558
+ console.warn("".concat(LOG, " publish failed on ").concat(topic, ":"), err);
2559
+ return false;
2560
+ }
2561
+ }
2469
2562
  // src/utils/tracking.ts
2470
2563
  var cachedBrowserId = null;
2471
2564
  function getClientInfo() {
@@ -2612,7 +2705,7 @@ function getClientInfo() {
2612
2705
  }
2613
2706
  function getBrowserID(clientInfo) {
2614
2707
  return _async_to_generator(function() {
2615
- var fingerprintString, encodedData, utf8, buffer, i, hashBuffer, hashArray, hashHex, error, hash, i1, char, fallbackHash, timestamp, random;
2708
+ var _crypto_subtle, fingerprintString, encodedData, utf8, buffer, i, hashBuffer, hashHex, unused, hash, i1, char, fallbackHash, timestamp, random;
2616
2709
  return _ts_generator(this, function(_state) {
2617
2710
  switch(_state.label){
2618
2711
  case 0:
@@ -2623,7 +2716,7 @@ function getBrowserID(clientInfo) {
2623
2716
  ];
2624
2717
  }
2625
2718
  fingerprintString = JSON.stringify(clientInfo);
2626
- if (!(typeof crypto !== "undefined" && crypto.subtle && crypto.subtle.digest)) return [
2719
+ if (!(typeof crypto !== "undefined" && ((_crypto_subtle = crypto.subtle) === null || _crypto_subtle === void 0 ? void 0 : _crypto_subtle.digest))) return [
2627
2720
  3,
2628
2721
  5
2629
2722
  ];
@@ -2661,8 +2754,7 @@ function getBrowserID(clientInfo) {
2661
2754
  ];
2662
2755
  case 3:
2663
2756
  hashBuffer = _state.sent();
2664
- hashArray = Array.from(new Uint8Array(hashBuffer));
2665
- hashHex = hashArray.map(function(b) {
2757
+ hashHex = Array.from(new Uint8Array(hashBuffer)).map(function(b) {
2666
2758
  return b.toString(16).padStart(2, "0");
2667
2759
  }).join("");
2668
2760
  cachedBrowserId = hashHex;
@@ -2671,8 +2763,8 @@ function getBrowserID(clientInfo) {
2671
2763
  hashHex
2672
2764
  ];
2673
2765
  case 4:
2674
- error = _state.sent();
2675
- console.warn("[StormcloudVideoPlayer] crypto.subtle.digest not supported, using fallback hash");
2766
+ unused = _state.sent();
2767
+ console.warn("[StormcloudVideoPlayer] crypto.subtle not supported, using fallback hash");
2676
2768
  return [
2677
2769
  3,
2678
2770
  5
@@ -2696,177 +2788,91 @@ function getBrowserID(clientInfo) {
2696
2788
  });
2697
2789
  })();
2698
2790
  }
2699
- var PLAYER_TRACKING_BASE_URL = "https://adstorm.co/api-adstorm-dev/adstorm/player-tracking";
2700
- var TRACK_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/metrics/ingest");
2701
- var HEARTBEAT_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/heartbeat");
2702
- var IMPRESSIONS_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/impressions/ingest");
2703
- function buildHeaders(licenseKey) {
2704
- var headers = {
2705
- "Content-Type": "application/json"
2706
- };
2707
- if (licenseKey) {
2708
- headers["Authorization"] = "Bearer ".concat(licenseKey);
2709
- }
2710
- return headers;
2711
- }
2712
- function sendTrackRequest(licenseKey, body) {
2713
- return _async_to_generator(function() {
2714
- var response;
2715
- return _ts_generator(this, function(_state) {
2716
- switch(_state.label){
2717
- case 0:
2718
- return [
2719
- 4,
2720
- fetch(TRACK_URL, {
2721
- method: "POST",
2722
- headers: buildHeaders(licenseKey),
2723
- body: JSON.stringify(body)
2724
- })
2725
- ];
2726
- case 1:
2727
- response = _state.sent();
2728
- if (!response.ok) {
2729
- throw new Error("HTTP error! status: ".concat(response.status));
2730
- }
2731
- return [
2732
- 4,
2733
- response.json()
2734
- ];
2735
- case 2:
2736
- _state.sent();
2737
- return [
2738
- 2
2739
- ];
2740
- }
2741
- });
2742
- })();
2791
+ function canPublish(licenseKey) {
2792
+ return Boolean(isMQTTEnabled() && licenseKey);
2743
2793
  }
2744
- function postJson(url, licenseKey, body) {
2794
+ function buildPlayerMetricEvent() {
2745
2795
  return _async_to_generator(function() {
2746
- var response;
2747
- return _ts_generator(this, function(_state) {
2748
- switch(_state.label){
2749
- case 0:
2750
- return [
2751
- 4,
2752
- fetch(url, {
2753
- method: "POST",
2754
- headers: buildHeaders(licenseKey),
2755
- body: JSON.stringify(body)
2756
- })
2757
- ];
2758
- case 1:
2759
- response = _state.sent();
2760
- if (!response.ok) {
2761
- throw new Error("HTTP error! status: ".concat(response.status));
2762
- }
2763
- return [
2764
- 4,
2765
- response.json()
2766
- ];
2767
- case 2:
2768
- _state.sent();
2769
- return [
2770
- 2
2771
- ];
2772
- }
2773
- });
2774
- })();
2775
- }
2776
- function buildPlayerMetricEvent(_0) {
2777
- return _async_to_generator(function(licenseKey) {
2778
- var context, flags, _flags_captureAt, clientInfo, browserId, captureAt;
2796
+ var context, flags, _flags_captureAt, _flags_adLoaded, _flags_adDetect, clientInfo, playerId, captureAt;
2779
2797
  var _arguments = arguments;
2780
2798
  return _ts_generator(this, function(_state) {
2781
2799
  switch(_state.label){
2782
2800
  case 0:
2783
- context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2801
+ context = _arguments.length > 0 && _arguments[0] !== void 0 ? _arguments[0] : {}, flags = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
2784
2802
  clientInfo = getClientInfo();
2785
2803
  return [
2786
2804
  4,
2787
2805
  getBrowserID(clientInfo)
2788
2806
  ];
2789
2807
  case 1:
2790
- browserId = _state.sent();
2808
+ playerId = _state.sent();
2791
2809
  captureAt = (_flags_captureAt = flags.captureAt) !== null && _flags_captureAt !== void 0 ? _flags_captureAt : /* @__PURE__ */ new Date().toISOString();
2792
2810
  return [
2793
2811
  2,
2794
- {
2795
- player_id: browserId,
2796
- browserId: browserId,
2812
+ _object_spread({
2813
+ player_id: playerId,
2797
2814
  device_type: clientInfo.deviceType,
2798
- deviceType: clientInfo.deviceType,
2799
- input_stream_type: context.inputStreamType,
2800
- os: clientInfo.os,
2801
- ad_loaded: flags.adLoaded,
2802
- ad_detect: flags.adDetect,
2803
- license_key: licenseKey,
2804
- capture_at: captureAt,
2805
- timestamp: captureAt
2806
- }
2815
+ os: clientInfo.os.toLowerCase(),
2816
+ ad_loaded: (_flags_adLoaded = flags.adLoaded) !== null && _flags_adLoaded !== void 0 ? _flags_adLoaded : false,
2817
+ ad_detect: (_flags_adDetect = flags.adDetect) !== null && _flags_adDetect !== void 0 ? _flags_adDetect : false,
2818
+ capture_at: captureAt
2819
+ }, context.inputStreamType ? {
2820
+ input_stream_type: context.inputStreamType
2821
+ } : {})
2807
2822
  ];
2808
2823
  }
2809
2824
  });
2810
2825
  }).apply(this, arguments);
2811
2826
  }
2827
+ function publishTracking(licenseKey, channel, body) {
2828
+ ensureMQTTClient();
2829
+ publishMQTT(buildPlayerTopic(licenseKey, channel), body);
2830
+ }
2812
2831
  function sendInitialTracking(_0) {
2813
2832
  return _async_to_generator(function(licenseKey) {
2814
- var context, clientInfo, browserId, trackingData, error;
2833
+ var context, metricEvent, error;
2815
2834
  var _arguments = arguments;
2816
2835
  return _ts_generator(this, function(_state) {
2817
2836
  switch(_state.label){
2818
2837
  case 0:
2819
2838
  context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
2839
+ if (!canPublish(licenseKey)) return [
2840
+ 2
2841
+ ];
2820
2842
  _state.label = 1;
2821
2843
  case 1:
2822
2844
  _state.trys.push([
2823
2845
  1,
2824
- 4,
2846
+ 3,
2825
2847
  ,
2826
- 5
2848
+ 4
2827
2849
  ]);
2828
- clientInfo = getClientInfo();
2829
2850
  return [
2830
2851
  4,
2831
- getBrowserID(clientInfo)
2832
- ];
2833
- case 2:
2834
- browserId = _state.sent();
2835
- trackingData = _object_spread({
2836
- browserId: browserId
2837
- }, clientInfo);
2838
- return [
2839
- 4,
2840
- sendTrackRequest(licenseKey, {
2841
- events: [
2842
- {
2843
- player_id: browserId,
2844
- device_type: clientInfo.deviceType,
2845
- input_stream_type: context.inputStreamType,
2846
- os: clientInfo.os,
2847
- ad_loaded: false,
2848
- ad_detect: false,
2849
- license_key: licenseKey,
2850
- capture_at: /* @__PURE__ */ new Date().toISOString()
2851
- }
2852
- ],
2853
- trackingData: trackingData
2852
+ buildPlayerMetricEvent(context, {
2853
+ adLoaded: false,
2854
+ adDetect: false
2854
2855
  })
2855
2856
  ];
2856
- case 3:
2857
- _state.sent();
2857
+ case 2:
2858
+ metricEvent = _state.sent();
2859
+ publishTracking(licenseKey, "metrics", {
2860
+ events: [
2861
+ metricEvent
2862
+ ]
2863
+ });
2858
2864
  return [
2859
2865
  3,
2860
- 5
2866
+ 4
2861
2867
  ];
2862
- case 4:
2868
+ case 3:
2863
2869
  error = _state.sent();
2864
2870
  console.error("[StormcloudVideoPlayer] Error sending initial tracking data:", error);
2865
2871
  return [
2866
2872
  3,
2867
- 5
2873
+ 4
2868
2874
  ];
2869
- case 5:
2875
+ case 4:
2870
2876
  return [
2871
2877
  2
2872
2878
  ];
@@ -2970,53 +2976,48 @@ function sendAdImpressionTracking(_0, _1) {
2970
2976
  switch(_state.label){
2971
2977
  case 0:
2972
2978
  context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2979
+ if (!canPublish(licenseKey)) return [
2980
+ 2
2981
+ ];
2973
2982
  _state.label = 1;
2974
2983
  case 1:
2975
2984
  _state.trys.push([
2976
2985
  1,
2977
- 4,
2986
+ 3,
2978
2987
  ,
2979
- 5
2988
+ 4
2980
2989
  ]);
2981
2990
  return [
2982
2991
  4,
2983
- buildPlayerMetricEvent(licenseKey, context, {
2992
+ buildPlayerMetricEvent(context, {
2984
2993
  captureAt: adImpressionInfo.timestamp
2985
2994
  })
2986
2995
  ];
2987
2996
  case 2:
2988
2997
  metricEvent = _state.sent();
2989
- return [
2990
- 4,
2991
- Promise.all([
2992
- postJson(HEARTBEAT_URL, licenseKey, metricEvent),
2993
- postJson(IMPRESSIONS_URL, licenseKey, {
2994
- events: [
2995
- {
2996
- player_id: metricEvent.player_id,
2997
- ad_played_count: 1,
2998
- ad_url: adImpressionInfo.adUrl,
2999
- license_key: licenseKey,
3000
- capture_at: adImpressionInfo.timestamp
3001
- }
3002
- ]
3003
- })
3004
- ])
3005
- ];
3006
- case 3:
3007
- _state.sent();
2998
+ publishTracking(licenseKey, "heartbeat", metricEvent);
2999
+ publishTracking(licenseKey, "impressions", {
3000
+ events: [
3001
+ {
3002
+ player_id: metricEvent.player_id,
3003
+ ad_played_count: 1,
3004
+ ad_url: adImpressionInfo.adUrl,
3005
+ capture_at: adImpressionInfo.timestamp
3006
+ }
3007
+ ]
3008
+ });
3008
3009
  return [
3009
3010
  3,
3010
- 5
3011
+ 4
3011
3012
  ];
3012
- case 4:
3013
+ case 3:
3013
3014
  error = _state.sent();
3014
3015
  console.error("[StormcloudVideoPlayer] Error sending ad impression tracking:", error);
3015
3016
  return [
3016
3017
  3,
3017
- 5
3018
+ 4
3018
3019
  ];
3019
- case 5:
3020
+ case 4:
3020
3021
  return [
3021
3022
  2
3022
3023
  ];
@@ -3032,38 +3033,36 @@ function sendHeartbeat(_0) {
3032
3033
  switch(_state.label){
3033
3034
  case 0:
3034
3035
  context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
3036
+ if (!canPublish(licenseKey)) return [
3037
+ 2
3038
+ ];
3035
3039
  _state.label = 1;
3036
3040
  case 1:
3037
3041
  _state.trys.push([
3038
3042
  1,
3039
- 4,
3043
+ 3,
3040
3044
  ,
3041
- 5
3045
+ 4
3042
3046
  ]);
3043
3047
  return [
3044
3048
  4,
3045
- buildPlayerMetricEvent(licenseKey, context, flags)
3049
+ buildPlayerMetricEvent(context, flags)
3046
3050
  ];
3047
3051
  case 2:
3048
3052
  heartbeatData = _state.sent();
3049
- return [
3050
- 4,
3051
- postJson(HEARTBEAT_URL, licenseKey, heartbeatData)
3052
- ];
3053
- case 3:
3054
- _state.sent();
3053
+ publishTracking(licenseKey, "heartbeat", heartbeatData);
3055
3054
  return [
3056
3055
  3,
3057
- 5
3056
+ 4
3058
3057
  ];
3059
- case 4:
3058
+ case 3:
3060
3059
  error = _state.sent();
3061
3060
  console.error("[StormcloudVideoPlayer] Error sending heartbeat:", error);
3062
3061
  return [
3063
3062
  3,
3064
- 5
3063
+ 4
3065
3064
  ];
3066
- case 5:
3065
+ case 4:
3067
3066
  return [
3068
3067
  2
3069
3068
  ];