stormcloud-video-player 0.3.60 → 0.3.62

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.
@@ -2646,40 +2646,66 @@ function getBrowserID(clientInfo) {
2646
2646
  });
2647
2647
  })();
2648
2648
  }
2649
- function sendInitialTracking(licenseKey) {
2649
+ var PLAYER_TRACKING_BASE_URL = "https://adstorm.co/api-adstorm-dev/adstorm/player-tracking";
2650
+ var TRACK_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/metrics/ingest");
2651
+ var HEARTBEAT_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/heartbeat");
2652
+ var IMPRESSIONS_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/impressions/ingest");
2653
+ function buildHeaders(licenseKey) {
2654
+ var headers = {
2655
+ "Content-Type": "application/json"
2656
+ };
2657
+ if (licenseKey) {
2658
+ headers["Authorization"] = "Bearer ".concat(licenseKey);
2659
+ }
2660
+ return headers;
2661
+ }
2662
+ function sendTrackRequest(licenseKey, body) {
2650
2663
  return _async_to_generator(function() {
2651
- var clientInfo, browserId, trackingData, headers, response, error;
2664
+ var response;
2652
2665
  return _ts_generator(this, function(_state) {
2653
2666
  switch(_state.label){
2654
2667
  case 0:
2655
- _state.trys.push([
2656
- 0,
2657
- 4,
2658
- ,
2659
- 5
2660
- ]);
2661
- clientInfo = getClientInfo();
2662
2668
  return [
2663
2669
  4,
2664
- getBrowserID(clientInfo)
2670
+ fetch(TRACK_URL, {
2671
+ method: "POST",
2672
+ headers: buildHeaders(licenseKey),
2673
+ body: JSON.stringify(body)
2674
+ })
2665
2675
  ];
2666
2676
  case 1:
2667
- browserId = _state.sent();
2668
- trackingData = _object_spread({
2669
- browserId: browserId
2670
- }, clientInfo);
2671
- headers = {
2672
- "Content-Type": "application/json"
2673
- };
2677
+ response = _state.sent();
2678
+ if (!response.ok) {
2679
+ throw new Error("HTTP error! status: ".concat(response.status));
2680
+ }
2681
+ return [
2682
+ 4,
2683
+ response.json()
2684
+ ];
2685
+ case 2:
2686
+ _state.sent();
2687
+ return [
2688
+ 2
2689
+ ];
2690
+ }
2691
+ });
2692
+ })();
2693
+ }
2694
+ function postJson(url, licenseKey, body) {
2695
+ return _async_to_generator(function() {
2696
+ var response;
2697
+ return _ts_generator(this, function(_state) {
2698
+ switch(_state.label){
2699
+ case 0:
2674
2700
  return [
2675
2701
  4,
2676
- fetch("https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track", {
2702
+ fetch(url, {
2677
2703
  method: "POST",
2678
- headers: headers,
2679
- body: JSON.stringify(trackingData)
2704
+ headers: buildHeaders(licenseKey),
2705
+ body: JSON.stringify(body)
2680
2706
  })
2681
2707
  ];
2682
- case 2:
2708
+ case 1:
2683
2709
  response = _state.sent();
2684
2710
  if (!response.ok) {
2685
2711
  throw new Error("HTTP error! status: ".concat(response.status));
@@ -2688,35 +2714,63 @@ function sendInitialTracking(licenseKey) {
2688
2714
  4,
2689
2715
  response.json()
2690
2716
  ];
2691
- case 3:
2717
+ case 2:
2692
2718
  _state.sent();
2693
2719
  return [
2694
- 3,
2695
- 5
2720
+ 2
2696
2721
  ];
2697
- case 4:
2698
- error = _state.sent();
2699
- console.error("[StormcloudVideoPlayer] Error sending initial tracking data:", error);
2722
+ }
2723
+ });
2724
+ })();
2725
+ }
2726
+ function buildPlayerMetricEvent(_0) {
2727
+ return _async_to_generator(function(licenseKey) {
2728
+ var context, flags, _flags_captureAt, clientInfo, browserId, captureAt;
2729
+ var _arguments = arguments;
2730
+ return _ts_generator(this, function(_state) {
2731
+ switch(_state.label){
2732
+ case 0:
2733
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2734
+ clientInfo = getClientInfo();
2700
2735
  return [
2701
- 3,
2702
- 5
2736
+ 4,
2737
+ getBrowserID(clientInfo)
2703
2738
  ];
2704
- case 5:
2739
+ case 1:
2740
+ browserId = _state.sent();
2741
+ captureAt = (_flags_captureAt = flags.captureAt) !== null && _flags_captureAt !== void 0 ? _flags_captureAt : /* @__PURE__ */ new Date().toISOString();
2705
2742
  return [
2706
- 2
2743
+ 2,
2744
+ {
2745
+ player_id: browserId,
2746
+ browserId: browserId,
2747
+ device_type: clientInfo.deviceType,
2748
+ deviceType: clientInfo.deviceType,
2749
+ input_stream_type: context.inputStreamType,
2750
+ os: clientInfo.os,
2751
+ ad_loaded: flags.adLoaded,
2752
+ ad_detect: flags.adDetect,
2753
+ license_key: licenseKey,
2754
+ capture_at: captureAt,
2755
+ timestamp: captureAt
2756
+ }
2707
2757
  ];
2708
2758
  }
2709
2759
  });
2710
- })();
2760
+ }).apply(this, arguments);
2711
2761
  }
2712
- function sendHeartbeat(licenseKey) {
2713
- return _async_to_generator(function() {
2714
- var clientInfo, browserId, heartbeatData, headers, response, error;
2762
+ function sendInitialTracking(_0) {
2763
+ return _async_to_generator(function(licenseKey) {
2764
+ var context, clientInfo, browserId, trackingData, error;
2765
+ var _arguments = arguments;
2715
2766
  return _ts_generator(this, function(_state) {
2716
2767
  switch(_state.label){
2717
2768
  case 0:
2769
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
2770
+ _state.label = 1;
2771
+ case 1:
2718
2772
  _state.trys.push([
2719
- 0,
2773
+ 1,
2720
2774
  4,
2721
2775
  ,
2722
2776
  5
@@ -2726,35 +2780,29 @@ function sendHeartbeat(licenseKey) {
2726
2780
  4,
2727
2781
  getBrowserID(clientInfo)
2728
2782
  ];
2729
- case 1:
2783
+ case 2:
2730
2784
  browserId = _state.sent();
2731
- heartbeatData = {
2732
- browserId: browserId,
2733
- timestamp: /* @__PURE__ */ new Date().toISOString()
2734
- };
2735
- headers = {
2736
- "Content-Type": "application/json"
2737
- };
2738
- if (licenseKey) {
2739
- headers["Authorization"] = "Bearer ".concat(licenseKey);
2740
- }
2785
+ trackingData = _object_spread({
2786
+ browserId: browserId
2787
+ }, clientInfo);
2741
2788
  return [
2742
2789
  4,
2743
- fetch("https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat", {
2744
- method: "POST",
2745
- headers: headers,
2746
- body: JSON.stringify(heartbeatData)
2790
+ sendTrackRequest(licenseKey, {
2791
+ events: [
2792
+ {
2793
+ player_id: browserId,
2794
+ device_type: clientInfo.deviceType,
2795
+ input_stream_type: context.inputStreamType,
2796
+ os: clientInfo.os,
2797
+ ad_loaded: false,
2798
+ ad_detect: false,
2799
+ license_key: licenseKey,
2800
+ capture_at: /* @__PURE__ */ new Date().toISOString()
2801
+ }
2802
+ ],
2803
+ trackingData: trackingData
2747
2804
  })
2748
2805
  ];
2749
- case 2:
2750
- response = _state.sent();
2751
- if (!response.ok) {
2752
- throw new Error("HTTP error! status: ".concat(response.status));
2753
- }
2754
- return [
2755
- 4,
2756
- response.json()
2757
- ];
2758
2806
  case 3:
2759
2807
  _state.sent();
2760
2808
  return [
@@ -2763,7 +2811,7 @@ function sendHeartbeat(licenseKey) {
2763
2811
  ];
2764
2812
  case 4:
2765
2813
  error = _state.sent();
2766
- console.error("[StormcloudVideoPlayer] Error sending heartbeat:", error);
2814
+ console.error("[StormcloudVideoPlayer] Error sending initial tracking data:", error);
2767
2815
  return [
2768
2816
  3,
2769
2817
  5
@@ -2774,95 +2822,74 @@ function sendHeartbeat(licenseKey) {
2774
2822
  ];
2775
2823
  }
2776
2824
  });
2777
- })();
2825
+ }).apply(this, arguments);
2778
2826
  }
2779
- var TRACK_API_URL = "https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track";
2780
- function mapToAdTrackingSource(source, adPlayerType) {
2781
- if (source === "prebid" || source === "ima" || source === "hls") {
2782
- return source;
2783
- }
2784
- if (source === "preload" || source === "ssp") {
2785
- return source === "ssp" ? "prebid" : "ima";
2786
- }
2787
- return adPlayerType === "hls" ? "hls" : "ima";
2788
- }
2789
- function postAdTracking(licenseKey, body) {
2790
- return _async_to_generator(function() {
2791
- var headers, response;
2827
+ function sendAdDetectTracking(_0, _1) {
2828
+ return _async_to_generator(function(licenseKey, adDetectInfo) {
2829
+ var context, error;
2830
+ var _arguments = arguments;
2792
2831
  return _ts_generator(this, function(_state) {
2793
2832
  switch(_state.label){
2794
2833
  case 0:
2795
- headers = {
2796
- "Content-Type": "application/json"
2797
- };
2798
- if (licenseKey) {
2799
- headers["Authorization"] = "Bearer ".concat(licenseKey);
2800
- }
2801
- return [
2802
- 4,
2803
- fetch(TRACK_API_URL, {
2804
- method: "POST",
2805
- headers: headers,
2806
- body: JSON.stringify(body)
2807
- })
2808
- ];
2834
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2835
+ _state.label = 1;
2809
2836
  case 1:
2810
- response = _state.sent();
2811
- if (!response.ok) {
2812
- throw new Error("HTTP error! status: ".concat(response.status));
2813
- }
2837
+ _state.trys.push([
2838
+ 1,
2839
+ 3,
2840
+ ,
2841
+ 4
2842
+ ]);
2814
2843
  return [
2815
2844
  4,
2816
- response.json()
2845
+ sendHeartbeat(licenseKey, context, {
2846
+ adDetect: true,
2847
+ captureAt: adDetectInfo.timestamp
2848
+ })
2817
2849
  ];
2818
2850
  case 2:
2819
2851
  _state.sent();
2852
+ return [
2853
+ 3,
2854
+ 4
2855
+ ];
2856
+ case 3:
2857
+ error = _state.sent();
2858
+ console.error("[StormcloudVideoPlayer] Error sending ad detect tracking:", error);
2859
+ return [
2860
+ 3,
2861
+ 4
2862
+ ];
2863
+ case 4:
2820
2864
  return [
2821
2865
  2
2822
2866
  ];
2823
2867
  }
2824
2868
  });
2825
- })();
2869
+ }).apply(this, arguments);
2826
2870
  }
2827
- function sendAdDetectTracking(licenseKey, payload) {
2828
- return _async_to_generator(function() {
2829
- var _payload_source, _payload_timestamp, clientInfo, browserId, adDetectInfo, body, error;
2871
+ function sendAdLoadedTracking(_0, _1) {
2872
+ return _async_to_generator(function(licenseKey, adLoadedInfo) {
2873
+ var context, error;
2874
+ var _arguments = arguments;
2830
2875
  return _ts_generator(this, function(_state) {
2831
2876
  switch(_state.label){
2832
2877
  case 0:
2878
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2879
+ _state.label = 1;
2880
+ case 1:
2833
2881
  _state.trys.push([
2834
- 0,
2882
+ 1,
2835
2883
  3,
2836
2884
  ,
2837
2885
  4
2838
2886
  ]);
2839
- clientInfo = getClientInfo();
2840
2887
  return [
2841
2888
  4,
2842
- getBrowserID(clientInfo)
2843
- ];
2844
- case 1:
2845
- browserId = _state.sent();
2846
- adDetectInfo = _object_spread({
2847
- source: (_payload_source = payload.source) !== null && _payload_source !== void 0 ? _payload_source : "scte35",
2848
- timestamp: (_payload_timestamp = payload.timestamp) !== null && _payload_timestamp !== void 0 ? _payload_timestamp : /* @__PURE__ */ new Date().toISOString()
2849
- }, payload.durationSeconds != null && {
2850
- durationSeconds: payload.durationSeconds
2851
- }, payload.ptsSeconds != null && {
2852
- ptsSeconds: payload.ptsSeconds
2853
- }, payload.detectedAtFragmentSn != null && {
2854
- detectedAtFragmentSn: payload.detectedAtFragmentSn
2855
- });
2856
- body = _object_spread_props(_object_spread({
2857
- browserId: browserId
2858
- }, clientInfo, licenseKey && {
2859
- licenseKey: licenseKey
2860
- }), {
2861
- adDetectInfo: adDetectInfo
2862
- });
2863
- return [
2864
- 4,
2865
- postAdTracking(licenseKey, body)
2889
+ sendHeartbeat(licenseKey, context, {
2890
+ adLoaded: true,
2891
+ captureAt: adLoadedInfo.timestamp
2892
+ })
2866
2893
  ];
2867
2894
  case 2:
2868
2895
  _state.sent();
@@ -2872,7 +2899,7 @@ function sendAdDetectTracking(licenseKey, payload) {
2872
2899
  ];
2873
2900
  case 3:
2874
2901
  error = _state.sent();
2875
- console.error("[StormcloudVideoPlayer] Error sending ad-detect tracking:", error);
2902
+ console.error("[StormcloudVideoPlayer] Error sending ad loaded tracking:", error);
2876
2903
  return [
2877
2904
  3,
2878
2905
  4
@@ -2883,126 +2910,116 @@ function sendAdDetectTracking(licenseKey, payload) {
2883
2910
  ];
2884
2911
  }
2885
2912
  });
2886
- })();
2913
+ }).apply(this, arguments);
2887
2914
  }
2888
- function sendAdLoadedTracking(licenseKey, payload, adPlayerType) {
2889
- return _async_to_generator(function() {
2890
- var clientInfo, browserId, source, adLoadedInfo, body, error;
2915
+ function sendAdImpressionTracking(_0, _1) {
2916
+ return _async_to_generator(function(licenseKey, adImpressionInfo) {
2917
+ var context, metricEvent, error;
2918
+ var _arguments = arguments;
2891
2919
  return _ts_generator(this, function(_state) {
2892
2920
  switch(_state.label){
2893
2921
  case 0:
2922
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2923
+ _state.label = 1;
2924
+ case 1:
2894
2925
  _state.trys.push([
2895
- 0,
2896
- 3,
2926
+ 1,
2927
+ 4,
2897
2928
  ,
2898
- 4
2929
+ 5
2899
2930
  ]);
2900
- clientInfo = getClientInfo();
2901
2931
  return [
2902
2932
  4,
2903
- getBrowserID(clientInfo)
2933
+ buildPlayerMetricEvent(licenseKey, context, {
2934
+ captureAt: adImpressionInfo.timestamp
2935
+ })
2904
2936
  ];
2905
- case 1:
2906
- browserId = _state.sent();
2907
- source = mapToAdTrackingSource(payload.source, adPlayerType);
2908
- adLoadedInfo = _object_spread({
2909
- source: source,
2910
- timestamp: /* @__PURE__ */ new Date().toISOString()
2911
- }, payload.vastUrl != null && {
2912
- vastUrl: payload.vastUrl
2913
- }, payload.durationSeconds != null && {
2914
- durationSeconds: payload.durationSeconds
2915
- });
2916
- body = _object_spread_props(_object_spread({
2917
- browserId: browserId
2918
- }, clientInfo, licenseKey && {
2919
- licenseKey: licenseKey
2920
- }), {
2921
- adLoadedInfo: adLoadedInfo
2922
- });
2937
+ case 2:
2938
+ metricEvent = _state.sent();
2923
2939
  return [
2924
2940
  4,
2925
- postAdTracking(licenseKey, body)
2941
+ Promise.all([
2942
+ postJson(HEARTBEAT_URL, licenseKey, metricEvent),
2943
+ postJson(IMPRESSIONS_URL, licenseKey, {
2944
+ events: [
2945
+ {
2946
+ player_id: metricEvent.player_id,
2947
+ ad_played_count: 1,
2948
+ ad_url: adImpressionInfo.adUrl,
2949
+ license_key: licenseKey,
2950
+ capture_at: adImpressionInfo.timestamp
2951
+ }
2952
+ ]
2953
+ })
2954
+ ])
2926
2955
  ];
2927
- case 2:
2956
+ case 3:
2928
2957
  _state.sent();
2929
2958
  return [
2930
2959
  3,
2931
- 4
2960
+ 5
2932
2961
  ];
2933
- case 3:
2962
+ case 4:
2934
2963
  error = _state.sent();
2935
- console.error("[StormcloudVideoPlayer] Error sending ad-loaded tracking:", error);
2964
+ console.error("[StormcloudVideoPlayer] Error sending ad impression tracking:", error);
2936
2965
  return [
2937
2966
  3,
2938
- 4
2967
+ 5
2939
2968
  ];
2940
- case 4:
2969
+ case 5:
2941
2970
  return [
2942
2971
  2
2943
2972
  ];
2944
2973
  }
2945
2974
  });
2946
- })();
2975
+ }).apply(this, arguments);
2947
2976
  }
2948
- function sendAdImpressionTracking(licenseKey, payload, adPlayerType) {
2949
- return _async_to_generator(function() {
2950
- var clientInfo, browserId, source, adImpressionInfo, body, error;
2977
+ function sendHeartbeat(_0) {
2978
+ return _async_to_generator(function(licenseKey) {
2979
+ var context, flags, heartbeatData, error;
2980
+ var _arguments = arguments;
2951
2981
  return _ts_generator(this, function(_state) {
2952
2982
  switch(_state.label){
2953
2983
  case 0:
2984
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2985
+ _state.label = 1;
2986
+ case 1:
2954
2987
  _state.trys.push([
2955
- 0,
2956
- 3,
2988
+ 1,
2989
+ 4,
2957
2990
  ,
2958
- 4
2991
+ 5
2959
2992
  ]);
2960
- clientInfo = getClientInfo();
2961
2993
  return [
2962
2994
  4,
2963
- getBrowserID(clientInfo)
2995
+ buildPlayerMetricEvent(licenseKey, context, flags)
2964
2996
  ];
2965
- case 1:
2966
- browserId = _state.sent();
2967
- source = mapToAdTrackingSource(payload.source, adPlayerType);
2968
- adImpressionInfo = _object_spread({
2969
- source: source,
2970
- adIndex: payload.adIndex,
2971
- timestamp: /* @__PURE__ */ new Date().toISOString()
2972
- }, payload.durationSeconds != null && {
2973
- durationSeconds: payload.durationSeconds
2974
- });
2975
- body = _object_spread_props(_object_spread({
2976
- browserId: browserId
2977
- }, clientInfo, licenseKey && {
2978
- licenseKey: licenseKey
2979
- }), {
2980
- adImpressionInfo: adImpressionInfo
2981
- });
2997
+ case 2:
2998
+ heartbeatData = _state.sent();
2982
2999
  return [
2983
3000
  4,
2984
- postAdTracking(licenseKey, body)
3001
+ postJson(HEARTBEAT_URL, licenseKey, heartbeatData)
2985
3002
  ];
2986
- case 2:
3003
+ case 3:
2987
3004
  _state.sent();
2988
3005
  return [
2989
3006
  3,
2990
- 4
3007
+ 5
2991
3008
  ];
2992
- case 3:
3009
+ case 4:
2993
3010
  error = _state.sent();
2994
- console.error("[StormcloudVideoPlayer] Error sending ad-impression tracking:", error);
3011
+ console.error("[StormcloudVideoPlayer] Error sending heartbeat:", error);
2995
3012
  return [
2996
3013
  3,
2997
- 4
3014
+ 5
2998
3015
  ];
2999
- case 4:
3016
+ case 5:
3000
3017
  return [
3001
3018
  2
3002
3019
  ];
3003
3020
  }
3004
3021
  });
3005
- })();
3022
+ }).apply(this, arguments);
3006
3023
  }
3007
3024
  // src/utils/polyfills.ts
3008
3025
  function polyfillURLSearchParams() {
@@ -3358,7 +3375,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3358
3375
  key: "load",
3359
3376
  value: function load() {
3360
3377
  return _async_to_generator(function() {
3361
- var _this, error, _this_config_lowLatencyMode, _this_video_play;
3378
+ var _this, error, _this_config_isLiveStream, _this_config_lowLatencyMode, _this_video_play;
3362
3379
  return _ts_generator(this, function(_state) {
3363
3380
  switch(_state.label){
3364
3381
  case 0:
@@ -3402,7 +3419,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3402
3419
  this.nativeHlsMode = true;
3403
3420
  this.videoSrcProtection = this.config.src;
3404
3421
  this.video.src = this.config.src;
3405
- this.isLiveStream = (_this_config_lowLatencyMode = this.config.lowLatencyMode) !== null && _this_config_lowLatencyMode !== void 0 ? _this_config_lowLatencyMode : false;
3422
+ this.isLiveStream = (_this_config_isLiveStream = this.config.isLiveStream) !== null && _this_config_isLiveStream !== void 0 ? _this_config_isLiveStream : (_this_config_lowLatencyMode = this.config.lowLatencyMode) !== null && _this_config_lowLatencyMode !== void 0 ? _this_config_lowLatencyMode : false;
3406
3423
  if (this.config.debugAdTiming) {
3407
3424
  console.log("[StormcloudVideoPlayer] Using native HLS playback - VOD mode:", {
3408
3425
  isLive: this.isLiveStream,
@@ -3453,19 +3470,28 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3453
3470
  });
3454
3471
  this.hls.on(import_hls2.default.Events.MANIFEST_PARSED, function(_, data) {
3455
3472
  return _async_to_generator(function() {
3456
- var _this_config_minSegmentsBeforePlay, _ref, _this_hls_levels, _this_hls, adBehavior, minSegments, _this_video_play;
3473
+ var _this_config_isLiveStream, _ref, _this_config_minSegmentsBeforePlay, _this_hls_levels, _this_hls, prerollKey, adBehavior, minSegments, _this_video_play;
3457
3474
  return _ts_generator(this, function(_state) {
3458
3475
  switch(_state.label){
3459
3476
  case 0:
3460
- if (this.config.allowNativeHls === false) {
3461
- this.isLiveStream = true;
3462
- } else {
3463
- ;
3464
- ;
3465
- this.isLiveStream = (_ref = (_this_hls = this.hls) === null || _this_hls === void 0 ? void 0 : (_this_hls_levels = _this_hls.levels) === null || _this_hls_levels === void 0 ? void 0 : _this_hls_levels.some(function(level) {
3466
- var _level_details, _level_details1;
3467
- return (level === null || level === void 0 ? void 0 : (_level_details = level.details) === null || _level_details === void 0 ? void 0 : _level_details.live) === true || (level === null || level === void 0 ? void 0 : (_level_details1 = level.details) === null || _level_details1 === void 0 ? void 0 : _level_details1.type) === "LIVE";
3468
- })) !== null && _ref !== void 0 ? _ref : false;
3477
+ this.isLiveStream = (_this_config_isLiveStream = this.config.isLiveStream) !== null && _this_config_isLiveStream !== void 0 ? _this_config_isLiveStream : (_ref = (_this_hls = this.hls) === null || _this_hls === void 0 ? void 0 : (_this_hls_levels = _this_hls.levels) === null || _this_hls_levels === void 0 ? void 0 : _this_hls_levels.some(function(level) {
3478
+ var _level_details, _level_details1;
3479
+ return (level === null || level === void 0 ? void 0 : (_level_details = level.details) === null || _level_details === void 0 ? void 0 : _level_details.live) === true || (level === null || level === void 0 ? void 0 : (_level_details1 = level.details) === null || _level_details1 === void 0 ? void 0 : _level_details1.type) === "LIVE";
3480
+ })) !== null && _ref !== void 0 ? _ref : false;
3481
+ if (!this.isLiveStream && this.vmapBreaks.length === 0 && this.apiVastTagUrl) {
3482
+ prerollKey = "synthetic-vod-preroll";
3483
+ if (!this.consumedVmapBreakIds.has(prerollKey)) {
3484
+ this.vmapBreaks = [
3485
+ {
3486
+ id: prerollKey,
3487
+ startTimeMs: 0,
3488
+ vastTagUrl: this.apiVastTagUrl
3489
+ }
3490
+ ];
3491
+ if (this.config.debugAdTiming) {
3492
+ console.log("[StormcloudVideoPlayer] Injected synthetic VOD preroll from apiVastTagUrl");
3493
+ }
3494
+ }
3469
3495
  }
3470
3496
  if (this.config.debugAdTiming) {
3471
3497
  adBehavior = this.shouldContinueLiveStreamDuringAds() ? "live (main video continues muted during ads)" : "vod (main video pauses during ads)";
@@ -3795,8 +3821,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3795
3821
  var _this = this;
3796
3822
  this.ima.on("all_ads_completed", function() {
3797
3823
  sendAdImpressionTracking(_this.config.licenseKey, {
3798
- adIndex: _this.currentAdIndex
3799
- }, _this.config.adPlayerType).catch(function() {});
3824
+ source: "ima",
3825
+ adIndex: _this.currentAdIndex,
3826
+ timestamp: /* @__PURE__ */ new Date().toISOString()
3827
+ }).catch(function() {});
3800
3828
  var remaining = _this.getRemainingAdMs();
3801
3829
  _this.consecutiveFailures = 0;
3802
3830
  if (_this.config.debugAdTiming) {
@@ -3857,8 +3885,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3857
3885
  });
3858
3886
  this.ima.on("content_resume", function() {
3859
3887
  sendAdImpressionTracking(_this.config.licenseKey, {
3860
- adIndex: _this.currentAdIndex
3861
- }, _this.config.adPlayerType).catch(function() {});
3888
+ source: "ima",
3889
+ adIndex: _this.currentAdIndex,
3890
+ timestamp: /* @__PURE__ */ new Date().toISOString()
3891
+ }).catch(function() {});
3862
3892
  if (!_this.video.muted) {
3863
3893
  _this.video.muted = true;
3864
3894
  _this.video.volume = 0;
@@ -4492,7 +4522,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4492
4522
  var detectPayload = {};
4493
4523
  if (marker.durationSeconds != null) detectPayload.durationSeconds = marker.durationSeconds;
4494
4524
  if (marker.ptsSeconds != null) detectPayload.ptsSeconds = marker.ptsSeconds;
4495
- sendAdDetectTracking(this.config.licenseKey, detectPayload).catch(function() {});
4525
+ sendAdDetectTracking(this.config.licenseKey, _object_spread({
4526
+ source: "scte35",
4527
+ timestamp: /* @__PURE__ */ new Date().toISOString()
4528
+ }, detectPayload)).catch(function() {});
4496
4529
  }
4497
4530
  var hasPrefetchedAds = this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0;
4498
4531
  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;
@@ -5734,7 +5767,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5734
5767
  if (marker.durationSeconds != null) detectPayload.durationSeconds = marker.durationSeconds;
5735
5768
  if (marker.ptsSeconds != null) detectPayload.ptsSeconds = marker.ptsSeconds;
5736
5769
  if (fragmentSn !== void 0) detectPayload.detectedAtFragmentSn = fragmentSn;
5737
- sendAdDetectTracking(this.config.licenseKey, detectPayload).catch(function() {});
5770
+ sendAdDetectTracking(this.config.licenseKey, _object_spread({
5771
+ source: "scte35",
5772
+ timestamp: /* @__PURE__ */ new Date().toISOString()
5773
+ }, detectPayload)).catch(function() {});
5738
5774
  if (this.config.debugAdTiming) {
5739
5775
  console.log("[PREFETCH] \uD83D\uDD04 Starting ad prefetch for upcoming ad break");
5740
5776
  console.log("[PREFETCH] \uD83D\uDCCB Pre-generated ".concat(generatedUrls.length, " VAST URLs"));
@@ -6215,9 +6251,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6215
6251
  preloadedController = preloaded.imaController;
6216
6252
  usePreloadedAd = true;
6217
6253
  sendAdLoadedTracking(this.config.licenseKey, {
6218
- source: "preload",
6219
- vastUrl: firstAdUrl
6220
- }, this.config.adPlayerType).catch(function() {});
6254
+ source: "ima",
6255
+ vastUrl: firstAdUrl,
6256
+ timestamp: /* @__PURE__ */ new Date().toISOString()
6257
+ }).catch(function() {});
6221
6258
  if (this.config.debugAdTiming) {
6222
6259
  console.log("[CONTINUOUS-FETCH] \uD83D\uDE80 Using preloaded ad from pool (preloaded in advance, ready immediately!)");
6223
6260
  console.log("[CONTINUOUS-FETCH] Pool still has ".concat(this.preloadPool.length, " preloaded ads ready"));
@@ -6307,9 +6344,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6307
6344
  case 5:
6308
6345
  _state.sent();
6309
6346
  sendAdLoadedTracking(this.config.licenseKey, {
6310
- source: "ssp",
6311
- vastUrl: firstAdUrl
6312
- }, this.config.adPlayerType).catch(function() {});
6347
+ source: "ima",
6348
+ vastUrl: firstAdUrl,
6349
+ timestamp: /* @__PURE__ */ new Date().toISOString()
6350
+ }).catch(function() {});
6313
6351
  if (this.config.debugAdTiming) {
6314
6352
  console.log("[CONTINUOUS-FETCH] \u2705 First ad request successful, starting playback");
6315
6353
  }
@@ -6705,9 +6743,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6705
6743
  console.log("[CONTINUOUS-FETCH] \uD83C\uDFAF Using preloaded ad from pool (".concat(this.preloadPool.length, " remaining in pool)"));
6706
6744
  }
6707
6745
  sendAdLoadedTracking(this.config.licenseKey, {
6708
- source: "preload",
6709
- vastUrl: preloaded.vastUrl
6710
- }, this.config.adPlayerType).catch(function() {});
6746
+ source: "ima",
6747
+ vastUrl: preloaded.vastUrl,
6748
+ timestamp: /* @__PURE__ */ new Date().toISOString()
6749
+ }).catch(function() {});
6711
6750
  _state.label = 1;
6712
6751
  case 1:
6713
6752
  _state.trys.push([
@@ -7459,9 +7498,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7459
7498
  case 3:
7460
7499
  _state.sent();
7461
7500
  sendAdLoadedTracking(this.config.licenseKey, {
7462
- source: "ssp",
7463
- vastUrl: vastTagUrl
7464
- }, this.config.adPlayerType).catch(function() {});
7501
+ source: "ima",
7502
+ vastUrl: vastTagUrl,
7503
+ timestamp: /* @__PURE__ */ new Date().toISOString()
7504
+ }).catch(function() {});
7465
7505
  this.clearAdRequestWatchdog();
7466
7506
  if (this.activeAdRequestToken !== requestToken) {
7467
7507
  return [
@@ -7889,7 +7929,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7889
7929
  continue;
7890
7930
  }
7891
7931
  var end = breakStartMs + (b.durationMs || 0);
7892
- if (nowMs >= breakStartMs && (b.durationMs ? nowMs < end : nowMs <= breakStartMs + tol)) {
7932
+ var effectiveTol = breakStartMs === 0 ? Math.max(tol, 3e4) : tol;
7933
+ if (nowMs >= breakStartMs && (b.durationMs ? nowMs < end : nowMs <= breakStartMs + effectiveTol)) {
7893
7934
  return b;
7894
7935
  }
7895
7936
  }
@@ -8120,6 +8161,7 @@ var import_jsx_runtime = require("react/jsx-runtime");
8120
8161
  var CRITICAL_PROPS = [
8121
8162
  "src",
8122
8163
  "allowNativeHls",
8164
+ "isLiveStream",
8123
8165
  "licenseKey",
8124
8166
  "vmapUrl",
8125
8167
  "lowLatencyMode",
@@ -8129,12 +8171,13 @@ var CRITICAL_PROPS = [
8129
8171
  var CONTROLS_HIDE_DELAY = 3e3;
8130
8172
  var DEFAULT_PLAYER_ASPECT_RATIO = 16 / 9;
8131
8173
  var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
8132
- 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, vastMode = props.vastMode, vastTagUrl = props.vastTagUrl, vmapUrl = props.vmapUrl, adPlayerType = props.adPlayerType, minSegmentsBeforePlay = props.minSegmentsBeforePlay, restVideoAttrs = _object_without_properties(props, [
8174
+ var src = props.src, autoplay = props.autoplay, muted = props.muted, lowLatencyMode = props.lowLatencyMode, allowNativeHls = props.allowNativeHls, isLiveStream = props.isLiveStream, 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, vastMode = props.vastMode, vastTagUrl = props.vastTagUrl, vmapUrl = props.vmapUrl, adPlayerType = props.adPlayerType, minSegmentsBeforePlay = props.minSegmentsBeforePlay, restVideoAttrs = _object_without_properties(props, [
8133
8175
  "src",
8134
8176
  "autoplay",
8135
8177
  "muted",
8136
8178
  "lowLatencyMode",
8137
8179
  "allowNativeHls",
8180
+ "isLiveStream",
8138
8181
  "driftToleranceMs",
8139
8182
  "immediateManifestAds",
8140
8183
  "debugAdTiming",
@@ -8289,7 +8332,7 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
8289
8332
  setShowSpeedMenu(false);
8290
8333
  };
8291
8334
  var isHlsStream = (src === null || src === void 0 ? void 0 : src.toLowerCase().includes(".m3u8")) || (src === null || src === void 0 ? void 0 : src.toLowerCase().includes("/hls/"));
8292
- var shouldShowEnhancedControls = showCustomControls && (isHlsStream ? allowNativeHls : true);
8335
+ var shouldShowEnhancedControls = showCustomControls && (isHlsStream ? allowNativeHls || isLiveStream === false : true);
8293
8336
  var criticalPropsKey = (0, import_react.useMemo)(function() {
8294
8337
  return CRITICAL_PROPS.map(function(prop) {
8295
8338
  return "".concat(prop, ":").concat(props[prop]);
@@ -8297,6 +8340,7 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
8297
8340
  }, [
8298
8341
  src,
8299
8342
  allowNativeHls,
8343
+ isLiveStream,
8300
8344
  licenseKey,
8301
8345
  vmapUrl,
8302
8346
  lowLatencyMode,
@@ -8331,6 +8375,7 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
8331
8375
  if (muted !== void 0) cfg.muted = muted;
8332
8376
  if (lowLatencyMode !== void 0) cfg.lowLatencyMode = lowLatencyMode;
8333
8377
  if (allowNativeHls !== void 0) cfg.allowNativeHls = allowNativeHls;
8378
+ if (isLiveStream !== void 0) cfg.isLiveStream = isLiveStream;
8334
8379
  if (driftToleranceMs !== void 0) cfg.driftToleranceMs = driftToleranceMs;
8335
8380
  if (immediateManifestAds !== void 0) cfg.immediateManifestAds = immediateManifestAds;
8336
8381
  if (debugAdTiming !== void 0) cfg.debugAdTiming = debugAdTiming;
@@ -9170,161 +9215,202 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
9170
9215
  ]
9171
9216
  })
9172
9217
  ]
9173
- }) : showCustomControls && !showLicenseWarning && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
9174
- className: "sc-controls-bar",
9175
- style: {
9176
- position: "absolute",
9177
- bottom: "".concat(10 * responsiveScale, "px"),
9178
- right: "".concat(10 * responsiveScale, "px"),
9179
- display: "flex",
9180
- flexDirection: isPortrait ? "column" : "row",
9181
- gap: "".concat(8 * responsiveScale, "px"),
9182
- zIndex: 10,
9183
- opacity: controlsVisible ? 1 : 0,
9184
- transform: controlsVisible ? "translateY(0)" : "translateY(4px)",
9185
- pointerEvents: controlsVisible ? "auto" : "none"
9186
- },
9218
+ }) : showCustomControls && !showLicenseWarning && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, {
9187
9219
  children: [
9188
9220
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
9189
9221
  style: {
9222
+ position: "absolute",
9223
+ top: "".concat(10 * responsiveScale, "px"),
9224
+ left: "".concat(10 * responsiveScale, "px"),
9190
9225
  display: "flex",
9191
9226
  alignItems: "center",
9192
- background: "rgba(0, 0, 0, 0.6)",
9193
- borderRadius: "".concat(18 * responsiveScale, "px"),
9194
- padding: "2px",
9195
- paddingRight: "".concat(8 * responsiveScale, "px")
9227
+ gap: "6px",
9228
+ zIndex: 10,
9229
+ opacity: controlsVisible ? 1 : 0,
9230
+ transition: "opacity 0.35s ease"
9196
9231
  },
9197
- onMouseEnter: function onMouseEnter() {
9198
- return setShowVolumeSlider(true);
9199
- },
9200
- onMouseLeave: function onMouseLeave() {
9201
- return setShowVolumeSlider(false);
9232
+ children: [
9233
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
9234
+ style: {
9235
+ width: "8px",
9236
+ height: "8px",
9237
+ borderRadius: "50%",
9238
+ background: "#ff3b30",
9239
+ animation: "sc-pulse 1.5s ease-in-out infinite",
9240
+ flexShrink: 0
9241
+ }
9242
+ }),
9243
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
9244
+ style: {
9245
+ fontSize: "".concat(12 * responsiveScale, "px"),
9246
+ fontFamily: "'SF Pro Display', 'Segoe UI', Arial, sans-serif",
9247
+ fontWeight: 700,
9248
+ letterSpacing: "0.08em",
9249
+ color: "#fff",
9250
+ textShadow: "0 1px 3px rgba(0,0,0,0.6)",
9251
+ userSelect: "none"
9252
+ },
9253
+ children: "LIVE"
9254
+ })
9255
+ ]
9256
+ }),
9257
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
9258
+ className: "sc-controls-bar",
9259
+ style: {
9260
+ position: "absolute",
9261
+ bottom: "".concat(10 * responsiveScale, "px"),
9262
+ right: "".concat(10 * responsiveScale, "px"),
9263
+ display: "flex",
9264
+ flexDirection: isPortrait ? "column" : "row",
9265
+ gap: "".concat(8 * responsiveScale, "px"),
9266
+ zIndex: 10,
9267
+ opacity: controlsVisible ? 1 : 0,
9268
+ transform: controlsVisible ? "translateY(0)" : "translateY(4px)",
9269
+ pointerEvents: controlsVisible ? "auto" : "none"
9202
9270
  },
9203
9271
  children: [
9272
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
9273
+ style: {
9274
+ display: "flex",
9275
+ alignItems: "center",
9276
+ background: "rgba(0, 0, 0, 0.6)",
9277
+ borderRadius: "".concat(18 * responsiveScale, "px"),
9278
+ padding: "2px",
9279
+ paddingRight: "".concat(8 * responsiveScale, "px")
9280
+ },
9281
+ onMouseEnter: function onMouseEnter() {
9282
+ return setShowVolumeSlider(true);
9283
+ },
9284
+ onMouseLeave: function onMouseLeave() {
9285
+ return setShowVolumeSlider(false);
9286
+ },
9287
+ children: [
9288
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
9289
+ className: "sc-ctrl-btn",
9290
+ onClick: function onClick() {
9291
+ if (playerRef.current) playerRef.current.toggleMute();
9292
+ onVolumeToggle === null || onVolumeToggle === void 0 ? void 0 : onVolumeToggle();
9293
+ resetControlsTimer();
9294
+ },
9295
+ style: {
9296
+ padding: "".concat(8 * responsiveScale, "px"),
9297
+ borderRadius: "50%",
9298
+ minWidth: "".concat(36 * responsiveScale, "px"),
9299
+ minHeight: "".concat(36 * responsiveScale, "px")
9300
+ },
9301
+ title: isMuted ? "Unmute" : "Mute",
9302
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(VolumeIcon, {
9303
+ size: Math.max(14, 18 * responsiveScale)
9304
+ })
9305
+ }),
9306
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
9307
+ style: {
9308
+ width: showVolumeSlider ? "".concat(68 * responsiveScale, "px") : "0px",
9309
+ overflow: "hidden",
9310
+ transition: "width 0.2s cubic-bezier(0.4, 0, 0.2, 1)",
9311
+ display: "flex",
9312
+ alignItems: "center",
9313
+ paddingLeft: showVolumeSlider ? "".concat(3 * responsiveScale, "px") : "0",
9314
+ paddingRight: showVolumeSlider ? "".concat(10 * responsiveScale, "px") : "0"
9315
+ },
9316
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
9317
+ style: {
9318
+ position: "relative",
9319
+ width: "".concat(56 * responsiveScale, "px"),
9320
+ height: "3px",
9321
+ cursor: "pointer",
9322
+ borderRadius: "1.5px"
9323
+ },
9324
+ onMouseDown: function onMouseDown(e) {
9325
+ e.preventDefault();
9326
+ var el = e.currentTarget;
9327
+ var move = function move(ev) {
9328
+ var r2 = el.getBoundingClientRect();
9329
+ handleVolumeChange(Math.max(0, Math.min(1, (ev.clientX - r2.left) / r2.width)));
9330
+ };
9331
+ var up = function up1() {
9332
+ document.removeEventListener("mousemove", move);
9333
+ document.removeEventListener("mouseup", up);
9334
+ };
9335
+ document.addEventListener("mousemove", move);
9336
+ document.addEventListener("mouseup", up);
9337
+ var r = el.getBoundingClientRect();
9338
+ handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));
9339
+ },
9340
+ onClick: function onClick(e) {
9341
+ e.stopPropagation();
9342
+ var r = e.currentTarget.getBoundingClientRect();
9343
+ handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));
9344
+ },
9345
+ children: [
9346
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
9347
+ style: {
9348
+ position: "absolute",
9349
+ inset: 0,
9350
+ background: "rgba(255, 255, 255, 0.2)",
9351
+ borderRadius: "1.5px"
9352
+ }
9353
+ }),
9354
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
9355
+ style: {
9356
+ position: "absolute",
9357
+ top: 0,
9358
+ left: 0,
9359
+ bottom: 0,
9360
+ width: "".concat((isMuted ? 0 : volume) * 100, "%"),
9361
+ background: "#fff",
9362
+ borderRadius: "1.5px",
9363
+ transition: "width 0.1s ease-out"
9364
+ }
9365
+ }),
9366
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
9367
+ style: {
9368
+ position: "absolute",
9369
+ top: "50%",
9370
+ left: "".concat((isMuted ? 0 : volume) * 100, "%"),
9371
+ transform: "translate(-50%, -50%)",
9372
+ width: "12px",
9373
+ height: "12px",
9374
+ background: "#fff",
9375
+ borderRadius: "50%",
9376
+ boxShadow: "0 0 3px rgba(0, 0, 0, 0.3)",
9377
+ transition: "left 0.1s ease-out"
9378
+ }
9379
+ })
9380
+ ]
9381
+ })
9382
+ })
9383
+ ]
9384
+ }),
9204
9385
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
9205
9386
  className: "sc-ctrl-btn",
9206
9387
  onClick: function onClick() {
9207
- if (playerRef.current) playerRef.current.toggleMute();
9208
- onVolumeToggle === null || onVolumeToggle === void 0 ? void 0 : onVolumeToggle();
9388
+ if (onFullscreenToggle) {
9389
+ onFullscreenToggle();
9390
+ } else if (wrapperRef.current) {
9391
+ if (!document.fullscreenElement) {
9392
+ wrapperRef.current.requestFullscreen().catch(function() {});
9393
+ } else {
9394
+ document.exitFullscreen().catch(function() {});
9395
+ }
9396
+ }
9209
9397
  resetControlsTimer();
9210
9398
  },
9211
9399
  style: {
9212
9400
  padding: "".concat(8 * responsiveScale, "px"),
9213
9401
  borderRadius: "50%",
9214
9402
  minWidth: "".concat(36 * responsiveScale, "px"),
9215
- minHeight: "".concat(36 * responsiveScale, "px")
9403
+ minHeight: "".concat(36 * responsiveScale, "px"),
9404
+ background: "rgba(0, 0, 0, 0.6)"
9216
9405
  },
9217
- title: isMuted ? "Unmute" : "Mute",
9218
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(VolumeIcon, {
9406
+ title: isFullscreen ? "Exit Fullscreen" : "Enter Fullscreen",
9407
+ children: isFullscreen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaCompress, {
9408
+ size: Math.max(14, 18 * responsiveScale)
9409
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaExpand, {
9219
9410
  size: Math.max(14, 18 * responsiveScale)
9220
- })
9221
- }),
9222
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
9223
- style: {
9224
- width: showVolumeSlider ? "".concat(68 * responsiveScale, "px") : "0px",
9225
- overflow: "hidden",
9226
- transition: "width 0.2s cubic-bezier(0.4, 0, 0.2, 1)",
9227
- display: "flex",
9228
- alignItems: "center",
9229
- paddingLeft: showVolumeSlider ? "".concat(3 * responsiveScale, "px") : "0",
9230
- paddingRight: showVolumeSlider ? "".concat(10 * responsiveScale, "px") : "0"
9231
- },
9232
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
9233
- style: {
9234
- position: "relative",
9235
- width: "".concat(56 * responsiveScale, "px"),
9236
- height: "3px",
9237
- cursor: "pointer",
9238
- borderRadius: "1.5px"
9239
- },
9240
- onMouseDown: function onMouseDown(e) {
9241
- e.preventDefault();
9242
- var el = e.currentTarget;
9243
- var move = function move(ev) {
9244
- var r2 = el.getBoundingClientRect();
9245
- handleVolumeChange(Math.max(0, Math.min(1, (ev.clientX - r2.left) / r2.width)));
9246
- };
9247
- var up = function up1() {
9248
- document.removeEventListener("mousemove", move);
9249
- document.removeEventListener("mouseup", up);
9250
- };
9251
- document.addEventListener("mousemove", move);
9252
- document.addEventListener("mouseup", up);
9253
- var r = el.getBoundingClientRect();
9254
- handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));
9255
- },
9256
- onClick: function onClick(e) {
9257
- e.stopPropagation();
9258
- var r = e.currentTarget.getBoundingClientRect();
9259
- handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));
9260
- },
9261
- children: [
9262
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
9263
- style: {
9264
- position: "absolute",
9265
- inset: 0,
9266
- background: "rgba(255, 255, 255, 0.2)",
9267
- borderRadius: "1.5px"
9268
- }
9269
- }),
9270
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
9271
- style: {
9272
- position: "absolute",
9273
- top: 0,
9274
- left: 0,
9275
- bottom: 0,
9276
- width: "".concat((isMuted ? 0 : volume) * 100, "%"),
9277
- background: "#fff",
9278
- borderRadius: "1.5px",
9279
- transition: "width 0.1s ease-out"
9280
- }
9281
- }),
9282
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
9283
- style: {
9284
- position: "absolute",
9285
- top: "50%",
9286
- left: "".concat((isMuted ? 0 : volume) * 100, "%"),
9287
- transform: "translate(-50%, -50%)",
9288
- width: "12px",
9289
- height: "12px",
9290
- background: "#fff",
9291
- borderRadius: "50%",
9292
- boxShadow: "0 0 3px rgba(0, 0, 0, 0.3)",
9293
- transition: "left 0.1s ease-out"
9294
- }
9295
- })
9296
- ]
9297
9411
  })
9298
9412
  })
9299
9413
  ]
9300
- }),
9301
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
9302
- className: "sc-ctrl-btn",
9303
- onClick: function onClick() {
9304
- if (onFullscreenToggle) {
9305
- onFullscreenToggle();
9306
- } else if (wrapperRef.current) {
9307
- if (!document.fullscreenElement) {
9308
- wrapperRef.current.requestFullscreen().catch(function() {});
9309
- } else {
9310
- document.exitFullscreen().catch(function() {});
9311
- }
9312
- }
9313
- resetControlsTimer();
9314
- },
9315
- style: {
9316
- padding: "".concat(8 * responsiveScale, "px"),
9317
- borderRadius: "50%",
9318
- minWidth: "".concat(36 * responsiveScale, "px"),
9319
- minHeight: "".concat(36 * responsiveScale, "px"),
9320
- background: "rgba(0, 0, 0, 0.6)"
9321
- },
9322
- title: isFullscreen ? "Exit Fullscreen" : "Enter Fullscreen",
9323
- children: isFullscreen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaCompress, {
9324
- size: Math.max(14, 18 * responsiveScale)
9325
- }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaExpand, {
9326
- size: Math.max(14, 18 * responsiveScale)
9327
- })
9328
9414
  })
9329
9415
  ]
9330
9416
  }),