@stormstreaming/stormstreamer 0.9.0-beta.3 → 0.9.0-beta.5

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/dist/amd/index.js CHANGED
@@ -4,8 +4,8 @@
4
4
  * contact@stormstreaming.com
5
5
  * https://stormstreaming.com
6
6
  *
7
- * Version: 0.9.0-beta.3
8
- * Version: 12/5/2024, 2:36:50 PM
7
+ * Version: 0.9.0-beta.5
8
+ * Version: 12/10/2024, 10:26:03 AM
9
9
  *
10
10
  * LEGAL NOTICE:
11
11
  * This software is subject to the terms and conditions defined in
@@ -578,20 +578,22 @@
578
578
  this.startOnDOMReady = false;
579
579
  this.iOSOnDomReadyFix = true;
580
580
  this._restartOnFocus = true;
581
+ this._forceDeviceSelection = false;
581
582
  this.parse(config);
582
583
  }
583
584
  parse(config) {
584
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
585
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
585
586
  this._settingsConfig = config;
586
587
  this._autoConnect = (_a = this._settingsConfig.autoConnect) !== null && _a !== void 0 ? _a : this._autoConnect;
587
588
  this._autoStart = (_b = this._settingsConfig.autoStart) !== null && _b !== void 0 ? _b : this._autoStart;
588
589
  this._restartOnFocus = (_c = this._settingsConfig.restartOnFocus) !== null && _c !== void 0 ? _c : this._restartOnFocus;
589
590
  this._restartOnError = (_d = this._settingsConfig.restartOnError) !== null && _d !== void 0 ? _d : this._restartOnError;
590
591
  this._reconnectTime = (_e = this._settingsConfig.reconnectTime) !== null && _e !== void 0 ? _e : this._reconnectTime;
591
- this._videoData = new VideoData((_f = this._settingsConfig.video) !== null && _f !== void 0 ? _f : null);
592
- this._audioData = new AudioData((_g = this._settingsConfig.audio) !== null && _g !== void 0 ? _g : null);
593
- this._storageData = new StorageData((_h = this._settingsConfig.storage) !== null && _h !== void 0 ? _h : null);
594
- this._debugData = new DebugData((_j = this._settingsConfig.debug) !== null && _j !== void 0 ? _j : null);
592
+ this._forceDeviceSelection = (_f = this._settingsConfig.forceDeviceSelection) !== null && _f !== void 0 ? _f : this._forceDeviceSelection;
593
+ this._videoData = new VideoData((_g = this._settingsConfig.video) !== null && _g !== void 0 ? _g : null);
594
+ this._audioData = new AudioData((_h = this._settingsConfig.audio) !== null && _h !== void 0 ? _h : null);
595
+ this._storageData = new StorageData((_j = this._settingsConfig.storage) !== null && _j !== void 0 ? _j : null);
596
+ this._debugData = new DebugData((_k = this._settingsConfig.debug) !== null && _k !== void 0 ? _k : null);
595
597
  }
596
598
  getAudioData() {
597
599
  return this._audioData;
@@ -623,6 +625,9 @@
623
625
  getDebugData() {
624
626
  return this._debugData;
625
627
  }
628
+ getIfForceSelection() {
629
+ return this._forceDeviceSelection;
630
+ }
626
631
  getIfStartOnDOMReadyEnabled() {
627
632
  return this.startOnDOMReady;
628
633
  }
@@ -1180,6 +1185,12 @@
1180
1185
  localStorage.setItem(this.prefix + name, value);
1181
1186
  }
1182
1187
  }
1188
+ removeField(name) {
1189
+ if (this.isEnabled) {
1190
+ if (this.LOG_ACTIVITY) this.logger.info(this, "Removing data: " + name);
1191
+ localStorage.removeItem(this.prefix + name);
1192
+ }
1193
+ }
1183
1194
  getField(name) {
1184
1195
  if (this.isEnabled == true) {
1185
1196
  const value = localStorage.getItem(this.prefix + name);
@@ -1777,7 +1788,6 @@
1777
1788
  if (typeof container === "string") {
1778
1789
  this._logger.info(this, "Attaching container to ID: " + container);
1779
1790
  tempParentElement = document.getElementById(container);
1780
- console.log(">>", document.getElementById(container));
1781
1791
  } else if (container instanceof HTMLElement) {
1782
1792
  this._logger.info(this, "Attaching container to HTMLElement: " + container);
1783
1793
  tempParentElement = container;
@@ -2462,74 +2472,103 @@
2462
2472
 
2463
2473
  class SoundMeter {
2464
2474
  constructor(main) {
2465
- this._stream = null;
2466
2475
  this._audioContext = null;
2467
2476
  this._analyser = null;
2468
2477
  this._microphone = null;
2469
2478
  this._lastEventTime = 0;
2470
2479
  this.THROTTLE_INTERVAL = 100;
2480
+ this._isMonitoring = false;
2471
2481
  this._instant = 0.0;
2472
2482
  this._slow = 0.0;
2473
- this._clip = 0.0;
2474
2483
  this._main = main;
2475
2484
  }
2476
2485
  attach(stream) {
2477
- this._stream = stream;
2478
- this._audioContext = new AudioContext();
2479
- this._microphone = this._audioContext.createMediaStreamSource(stream);
2480
- this._analyser = this._audioContext.createAnalyser();
2481
- this._analyser.fftSize = 2048;
2482
- this._analyser.smoothingTimeConstant = 0.3;
2483
- this._microphone.connect(this._analyser);
2484
- this.startMonitoring();
2486
+ if (!stream.getAudioTracks().length) {
2487
+ console.warn('SoundMeter: Attempted to attach stream without audio tracks');
2488
+ return;
2489
+ }
2490
+ this.detach();
2491
+ try {
2492
+ this._audioContext = new AudioContext();
2493
+ this._microphone = this._audioContext.createMediaStreamSource(stream);
2494
+ this._analyser = this._audioContext.createAnalyser();
2495
+ this._analyser.fftSize = 2048;
2496
+ this._analyser.smoothingTimeConstant = 0.3;
2497
+ this._microphone.connect(this._analyser);
2498
+ this.startMonitoring();
2499
+ console.log('SoundMeter: Successfully attached to new audio stream');
2500
+ } catch (error) {
2501
+ console.error('SoundMeter: Error during attach:', error);
2502
+ this.detach();
2503
+ }
2485
2504
  }
2486
2505
  detach() {
2506
+ var _a, _b;
2507
+ this._isMonitoring = false;
2487
2508
  if (this._microphone) {
2488
- this._microphone.disconnect();
2509
+ try {
2510
+ this._microphone.disconnect();
2511
+ } catch (e) {
2512
+ console.warn('SoundMeter: Error disconnecting microphone:', e);
2513
+ }
2489
2514
  this._microphone = null;
2490
2515
  }
2491
2516
  if (this._analyser) {
2492
- this._analyser.disconnect();
2517
+ try {
2518
+ this._analyser.disconnect();
2519
+ } catch (e) {
2520
+ console.warn('SoundMeter: Error disconnecting analyser:', e);
2521
+ }
2493
2522
  this._analyser = null;
2494
2523
  }
2495
- if (this._audioContext) {
2496
- this._audioContext.close();
2497
- this._audioContext = null;
2524
+ if (((_a = this._audioContext) === null || _a === void 0 ? void 0 : _a.state) !== 'closed') {
2525
+ try {
2526
+ (_b = this._audioContext) === null || _b === void 0 ? void 0 : _b.close();
2527
+ } catch (e) {
2528
+ console.warn('SoundMeter: Error closing audio context:', e);
2529
+ }
2498
2530
  }
2499
- this._stream = null;
2531
+ this._audioContext = null;
2500
2532
  this.clear();
2533
+ console.log('SoundMeter: Successfully detached');
2501
2534
  }
2502
2535
  clear() {
2503
2536
  this._instant = 0;
2504
2537
  this._slow = 0;
2505
- this._clip = 0;
2538
+ this._lastEventTime = 0;
2506
2539
  }
2507
2540
  startMonitoring() {
2508
- if (!this._analyser) return;
2541
+ if (!this._analyser || this._isMonitoring) return;
2542
+ this._isMonitoring = true;
2509
2543
  const dataArray = new Float32Array(this._analyser.frequencyBinCount);
2510
2544
  const analyze = () => {
2511
- if (!this._analyser) return;
2545
+ if (!this._analyser || !this._isMonitoring) return;
2512
2546
  const now = Date.now();
2513
- this._analyser.getFloatTimeDomainData(dataArray);
2514
- let sum = 0.0;
2515
- let clipcount = 0;
2516
- for (let i = 0; i < dataArray.length; ++i) {
2517
- const amplitude = dataArray[i];
2518
- sum += amplitude * amplitude;
2519
- if (Math.abs(amplitude) > 0.99) {
2520
- clipcount += 1;
2547
+ try {
2548
+ this._analyser.getFloatTimeDomainData(dataArray);
2549
+ let sum = 0.0;
2550
+ let clipcount = 0;
2551
+ for (let i = 0; i < dataArray.length; ++i) {
2552
+ const amplitude = dataArray[i];
2553
+ sum += amplitude * amplitude;
2554
+ if (Math.abs(amplitude) > 0.99) {
2555
+ clipcount += 1;
2556
+ }
2521
2557
  }
2522
- }
2523
- this._instant = Math.sqrt(sum / dataArray.length);
2524
- this._slow = 0.05 * this._instant + 0.95 * this._slow;
2525
- this._clip = clipcount / dataArray.length;
2526
- if (now - this._lastEventTime >= this.THROTTLE_INTERVAL) {
2527
- this._lastEventTime = now;
2528
- this._main.dispatchEvent("soundMeter", {
2529
- ref: this._main,
2530
- high: this._instant,
2531
- low: this._slow
2532
- });
2558
+ this._instant = Math.sqrt(sum / dataArray.length);
2559
+ this._slow = 0.05 * this._instant + 0.95 * this._slow;
2560
+ if (now - this._lastEventTime >= this.THROTTLE_INTERVAL) {
2561
+ this._lastEventTime = now;
2562
+ this._main.dispatchEvent("soundMeter", {
2563
+ ref: this._main,
2564
+ high: this._instant,
2565
+ low: this._slow
2566
+ });
2567
+ }
2568
+ } catch (error) {
2569
+ console.error('SoundMeter: Error during analysis:', error);
2570
+ this._isMonitoring = false;
2571
+ return;
2533
2572
  }
2534
2573
  requestAnimationFrame(analyze);
2535
2574
  };
@@ -2537,6 +2576,16 @@
2537
2576
  }
2538
2577
  }
2539
2578
 
2579
+ var InputDeviceState;
2580
+ (function (InputDeviceState) {
2581
+ InputDeviceState["NOT_INITIALIZED"] = "NOT_INITIALIZED";
2582
+ InputDeviceState["INITIALIZED"] = "INITIALIZED";
2583
+ InputDeviceState["READY"] = "READY";
2584
+ InputDeviceState["UPDATING"] = "UPDATING";
2585
+ InputDeviceState["INVALID"] = "INVALID";
2586
+ InputDeviceState["UNKNOWN"] = "UNKNOWN";
2587
+ })(InputDeviceState || (InputDeviceState = {}));
2588
+
2540
2589
  class PlaybackController {
2541
2590
  constructor(main) {
2542
2591
  this._isWindowActive = true;
@@ -2545,6 +2594,7 @@
2545
2594
  };
2546
2595
  this._isMicrophoneMuted = false;
2547
2596
  this._pendingMicrophoneState = null;
2597
+ this._permissionChecked = false;
2548
2598
  this._constraints = {
2549
2599
  video: {
2550
2600
  width: {
@@ -2566,6 +2616,7 @@
2566
2616
  audio: true
2567
2617
  };
2568
2618
  this._publishState = exports.PublishState.NOT_INITIALIZED;
2619
+ this._inputDeviceState = InputDeviceState.NOT_INITIALIZED;
2569
2620
  this.onServerDisconnect = () => {};
2570
2621
  this.onServerConnect = () => {
2571
2622
  if (this._peerConnection) {
@@ -2641,10 +2692,9 @@
2641
2692
  };
2642
2693
  this._main = main;
2643
2694
  this._logger = main.getLogger();
2644
- this._logger.info(this, "Creating new PlaybackController");
2645
2695
  this._mungeSDP = new MungeSDP();
2646
2696
  this._soundMeter = new SoundMeter(this._main);
2647
- this.initialize();
2697
+ this.initializeDevices();
2648
2698
  }
2649
2699
  initialize() {
2650
2700
  var _a, _b;
@@ -2653,16 +2703,65 @@
2653
2703
  document.addEventListener("visibilitychange", this.visibilityChange);
2654
2704
  window.addEventListener("blur", this.onWindowBlur);
2655
2705
  window.addEventListener("focus", this.onWindowFocus);
2706
+ if (this._selectedCamera || this._selectedMicrophone) {
2707
+ this.startCamera().then(() => {
2708
+ var _a;
2709
+ if (((_a = this._main.getConfigManager()) === null || _a === void 0 ? void 0 : _a.getStreamData().streamKey) != null) {
2710
+ this.initializeWebRTC();
2711
+ }
2712
+ });
2713
+ }
2656
2714
  if ((_a = this._main.getConfigManager()) === null || _a === void 0 ? void 0 : _a.getSettingsData().autoConnect) {
2657
2715
  this._logger.info(this, "Initializing NetworkController (autoConnect is true)");
2658
2716
  (_b = this._main.getNetworkController()) === null || _b === void 0 ? void 0 : _b.initialize();
2659
2717
  } else {
2660
2718
  this._logger.warning(this, "Warning - autoConnect is set to false, switching to standby mode!");
2661
2719
  }
2662
- this.startCamera().then(() => {
2663
- var _a;
2664
- if (((_a = this._main.getConfigManager()) === null || _a === void 0 ? void 0 : _a.getStreamData().streamKey) != null) {
2665
- this.initializeWebRTC();
2720
+ this.setupPermissionListeners();
2721
+ }
2722
+ initializeDevices() {
2723
+ return __awaiter(this, void 0, void 0, function* () {
2724
+ try {
2725
+ yield this.grabDevices();
2726
+ this.setupPermissionListeners();
2727
+ this.initialize();
2728
+ } catch (error) {
2729
+ this._logger.error(this, "Error initializing devices: " + JSON.stringify(error));
2730
+ this.initialize();
2731
+ }
2732
+ });
2733
+ }
2734
+ setupPermissionListeners() {
2735
+ const cameraQuery = {
2736
+ name: 'camera'
2737
+ };
2738
+ const microphoneQuery = {
2739
+ name: 'microphone'
2740
+ };
2741
+ navigator.permissions.query(cameraQuery).then(permissionStatus => {
2742
+ permissionStatus.onchange = () => {
2743
+ this._permissionChecked = false;
2744
+ this.handlePermissionChange('camera', permissionStatus.state);
2745
+ };
2746
+ });
2747
+ navigator.permissions.query(microphoneQuery).then(permissionStatus => {
2748
+ permissionStatus.onchange = () => {
2749
+ this._permissionChecked = false;
2750
+ this.handlePermissionChange('microphone', permissionStatus.state);
2751
+ };
2752
+ });
2753
+ }
2754
+ handlePermissionChange(device, state) {
2755
+ return __awaiter(this, void 0, void 0, function* () {
2756
+ if (state === 'denied') {
2757
+ this.setInputDeviceState(InputDeviceState.INVALID);
2758
+ if (this._publishState == exports.PublishState.PUBLISHED) {
2759
+ this.closeStream();
2760
+ }
2761
+ }
2762
+ yield this.grabDevices();
2763
+ if (state === 'granted') {
2764
+ yield this.startCamera();
2666
2765
  }
2667
2766
  });
2668
2767
  }
@@ -2726,105 +2825,94 @@
2726
2825
  this.closeStream();
2727
2826
  }
2728
2827
  onUserMediaError(error) {
2729
- console.log('%c⏵ 🎥 onUserMediaError: ' + JSON.stringify(error), 'background: green; color: white;');
2730
- const errorName = error.name || '';
2731
- const errorMessage = error.message || '';
2732
- if (error.deviceType) {
2733
- if (error.deviceType === 'video') {
2734
- this._main.dispatchEvent("cameraAccessDenied", {
2735
- ref: this._main
2736
- });
2737
- } else if (error.deviceType === 'audio') {
2738
- this._main.dispatchEvent("microphoneAccessDenied", {
2739
- ref: this._main
2740
- });
2828
+ return __awaiter(this, void 0, void 0, function* () {
2829
+ yield this.grabDevices();
2830
+ if (error.name === "OverconstrainedError") {
2831
+ this._logger.warning(this, "Device constraints not satisfied");
2741
2832
  }
2742
- this.grabDevices();
2743
- return;
2744
- }
2745
- if (errorName === 'NotAllowedError' || errorMessage.includes('Permission denied') || errorMessage.includes('not allowed')) {
2746
- this.checkIndividualDeviceAccess().then(results => {
2747
- if (!results.camera && !results.microphone) {
2748
- this._main.dispatchEvent("cameraAccessDenied", {
2749
- ref: this._main
2750
- });
2751
- this._main.dispatchEvent("microphoneAccessDenied", {
2752
- ref: this._main
2753
- });
2754
- } else {
2755
- if (!results.camera) {
2756
- this._main.dispatchEvent("cameraAccessDenied", {
2757
- ref: this._main
2758
- });
2759
- }
2760
- if (!results.microphone) {
2761
- this._main.dispatchEvent("microphoneAccessDenied", {
2762
- ref: this._main
2763
- });
2764
- }
2765
- }
2766
- this.grabDevices();
2767
- });
2768
- return;
2769
- }
2770
- if (errorName === 'NotFoundError' || errorMessage.includes('Requested device not found')) {
2771
- this.checkDeviceAvailability().then(results => {
2772
- if (!results.camera) {
2773
- this._main.dispatchEvent("noCameraFound", {
2774
- ref: this._main
2775
- });
2776
- }
2777
- if (!results.microphone) {
2778
- this._main.dispatchEvent("noMicrophoneFound", {
2779
- ref: this._main
2780
- });
2781
- }
2782
- this.grabDevices();
2783
- });
2784
- return;
2785
- }
2786
- this._logger.warning(this, "WebRTCStreamer :: Unsupported onUserMediaError: " + errorMessage);
2787
- this._main.dispatchEvent("inputDeviceError", {
2788
- ref: this._main
2789
2833
  });
2790
- this.grabDevices();
2791
2834
  }
2792
2835
  checkIndividualDeviceAccess() {
2793
2836
  return __awaiter(this, void 0, void 0, function* () {
2794
2837
  const results = {
2795
- camera: false,
2796
- microphone: false
2838
+ camera: {
2839
+ allowed: false,
2840
+ available: false
2841
+ },
2842
+ microphone: {
2843
+ allowed: false,
2844
+ available: false
2845
+ }
2797
2846
  };
2847
+ const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
2848
+ const isEdge = /edg/i.test(navigator.userAgent);
2849
+ const isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
2798
2850
  try {
2799
- const videoStream = yield navigator.mediaDevices.getUserMedia({
2800
- video: true
2801
- });
2802
- results.camera = true;
2803
- videoStream.getTracks().forEach(track => track.stop());
2804
- } catch (e) {
2805
- results.camera = false;
2851
+ const devices = yield navigator.mediaDevices.enumerateDevices();
2852
+ results.camera.available = devices.some(device => device.kind === 'videoinput');
2853
+ results.microphone.available = devices.some(device => device.kind === 'audioinput');
2854
+ } catch (error) {
2855
+ console.error("Error checking device availability:", error);
2806
2856
  }
2807
- try {
2808
- const audioStream = yield navigator.mediaDevices.getUserMedia({
2809
- audio: true
2810
- });
2811
- results.microphone = true;
2812
- audioStream.getTracks().forEach(track => track.stop());
2813
- } catch (e) {
2814
- results.microphone = false;
2857
+ if (isFirefox) {
2858
+ console.log("Firefox detected, using direct getUserMedia check...");
2859
+ if (results.camera.available) {
2860
+ try {
2861
+ const stream = yield navigator.mediaDevices.getUserMedia({
2862
+ video: true
2863
+ });
2864
+ results.camera.allowed = true;
2865
+ stream.getTracks().forEach(track => track.stop());
2866
+ } catch (e) {
2867
+ console.log("Camera permission check failed:", e);
2868
+ results.camera.allowed = false;
2869
+ }
2870
+ }
2871
+ if (results.microphone.available) {
2872
+ try {
2873
+ const stream = yield navigator.mediaDevices.getUserMedia({
2874
+ audio: true
2875
+ });
2876
+ results.microphone.allowed = true;
2877
+ stream.getTracks().forEach(track => track.stop());
2878
+ } catch (e) {
2879
+ console.log("Microphone permission check failed:", e);
2880
+ results.microphone.allowed = false;
2881
+ }
2882
+ }
2883
+ } else {
2884
+ try {
2885
+ const [cameraPermission, microphonePermission] = yield Promise.all([navigator.permissions.query({
2886
+ name: 'camera'
2887
+ }), navigator.permissions.query({
2888
+ name: 'microphone'
2889
+ })]);
2890
+ results.camera.allowed = cameraPermission.state === "granted";
2891
+ results.microphone.allowed = microphonePermission.state === "granted";
2892
+ if ((isSafari || isEdge) && (!results.camera.allowed || !results.microphone.allowed)) {
2893
+ try {
2894
+ const stream = yield navigator.mediaDevices.getUserMedia({
2895
+ video: results.camera.available && !results.camera.allowed,
2896
+ audio: results.microphone.available && !results.microphone.allowed
2897
+ });
2898
+ if (stream.getVideoTracks().length > 0) {
2899
+ results.camera.allowed = true;
2900
+ }
2901
+ if (stream.getAudioTracks().length > 0) {
2902
+ results.microphone.allowed = true;
2903
+ }
2904
+ stream.getTracks().forEach(track => track.stop());
2905
+ } catch (error) {
2906
+ console.log("Additional permission check failed:", error);
2907
+ }
2908
+ }
2909
+ } catch (error) {
2910
+ console.error("Error checking permissions:", error);
2911
+ }
2815
2912
  }
2816
2913
  return results;
2817
2914
  });
2818
2915
  }
2819
- checkDeviceAvailability() {
2820
- return __awaiter(this, void 0, void 0, function* () {
2821
- const devices = yield navigator.mediaDevices.enumerateDevices();
2822
- return {
2823
- camera: devices.some(device => device.kind === 'videoinput'),
2824
- microphone: devices.some(device => device.kind === 'audioinput')
2825
- };
2826
- });
2827
- }
2828
2916
  onSocketMessage(data) {
2829
2917
  let msgJSON = JSON.parse(data);
2830
2918
  let msgStatus = Number(msgJSON["status"]);
@@ -2882,60 +2970,67 @@
2882
2970
  grabDevices() {
2883
2971
  return __awaiter(this, void 0, void 0, function* () {
2884
2972
  try {
2885
- try {
2886
- yield navigator.mediaDevices.getUserMedia({
2887
- audio: true,
2888
- video: true
2889
- });
2890
- } catch (e) {}
2891
- const devices = yield navigator.mediaDevices.enumerateDevices();
2973
+ const deviceAccess = yield this.checkIndividualDeviceAccess();
2892
2974
  this._cameraList = new InputDeviceList();
2893
2975
  this._microphoneList = new InputDeviceList();
2894
- for (let device of devices) {
2895
- try {
2896
- if (device.deviceId && device.label) {
2897
- if (device.kind === 'videoinput') {
2898
- let inputDevice = new InputDevice(device, this._cameraList.getSize());
2899
- this._cameraList.push(inputDevice);
2900
- } else if (device.kind === 'audioinput') {
2901
- let inputDevice = new InputDevice(device, this._microphoneList.getSize());
2902
- this._microphoneList.push(inputDevice);
2903
- }
2904
- }
2905
- } catch (error) {
2906
- this._logger.error(this, "WebRTCStreamer :: Input Device Error: " + error);
2976
+ if (!this._permissionChecked) {
2977
+ if (!deviceAccess.camera.allowed) {
2978
+ this._main.dispatchEvent("cameraAccessDenied", {
2979
+ ref: this._main
2980
+ });
2981
+ } else if (!deviceAccess.camera.available) {
2982
+ this._main.dispatchEvent("noCameraFound", {
2983
+ ref: this._main
2984
+ });
2985
+ }
2986
+ if (!deviceAccess.microphone.allowed) {
2987
+ this._main.dispatchEvent("microphoneAccessDenied", {
2988
+ ref: this._main
2989
+ });
2990
+ } else if (!deviceAccess.microphone.available) {
2991
+ this._main.dispatchEvent("noMicrophoneFound", {
2992
+ ref: this._main
2993
+ });
2907
2994
  }
2908
2995
  }
2909
- this._logger.info(this, "Camera list:");
2910
- for (let i = 0; i < this._cameraList.getSize(); i++) {
2911
- this._logger.info(this, "=> [" + i + "] InputDevice: " + this._cameraList.get(i).getLabel());
2912
- }
2913
- this._logger.info(this, "Microphone list:");
2914
- for (let k = 0; k < this._microphoneList.getSize(); k++) {
2915
- this._logger.info(this, "=> [" + k + "] InputDevice: " + this._microphoneList.get(k).getLabel());
2916
- }
2917
- if (this._cameraList.getSize() == 0) {
2918
- this._main.dispatchEvent("noCameraFound", {
2919
- ref: this._main
2920
- });
2921
- } else {
2922
- this._selectedCamera = this.pickCamera();
2996
+ const devices = yield navigator.mediaDevices.enumerateDevices();
2997
+ for (const device of devices) {
2998
+ if (device.deviceId && device.label) {
2999
+ if (device.kind === 'videoinput' && deviceAccess.camera.allowed) {
3000
+ const inputDevice = new InputDevice(device, this._cameraList.getSize());
3001
+ this._cameraList.push(inputDevice);
3002
+ } else if (device.kind === 'audioinput' && deviceAccess.microphone.allowed) {
3003
+ const inputDevice = new InputDevice(device, this._microphoneList.getSize());
3004
+ this._microphoneList.push(inputDevice);
3005
+ }
3006
+ }
2923
3007
  }
2924
- if (this._microphoneList.getSize() == 0) {
2925
- this._main.dispatchEvent("noMicrophoneFound", {
2926
- ref: this._main
2927
- });
2928
- } else {
2929
- this._selectedMicrophone = this.pickMicrophone();
3008
+ try {
3009
+ if (deviceAccess.camera.allowed) {
3010
+ this._selectedCamera = this.pickCamera();
3011
+ }
3012
+ if (deviceAccess.microphone.allowed) {
3013
+ this._selectedMicrophone = this.pickMicrophone();
3014
+ }
3015
+ if (this._selectedCamera != null && this._selectedMicrophone != null) {
3016
+ this.setInputDeviceState(InputDeviceState.READY);
3017
+ } else {
3018
+ this.setInputDeviceState(InputDeviceState.INVALID);
3019
+ }
3020
+ } catch (error) {
3021
+ this.setInputDeviceState(InputDeviceState.INVALID);
3022
+ this._logger.error(this, "Errror on grab devices: " + JSON.stringify(error));
2930
3023
  }
2931
3024
  this._main.dispatchEvent("deviceListUpdate", {
2932
3025
  ref: this._main,
2933
3026
  cameraList: this._cameraList.getArray(),
2934
3027
  microphoneList: this._microphoneList.getArray()
2935
3028
  });
3029
+ this._permissionChecked = true;
2936
3030
  } catch (error) {
2937
- if (!this._cameraList) this._cameraList = new InputDeviceList();
2938
- if (!this._microphoneList) this._microphoneList = new InputDeviceList();
3031
+ console.error("Error in grabDevices:", error);
3032
+ this._cameraList = new InputDeviceList();
3033
+ this._microphoneList = new InputDeviceList();
2939
3034
  this._main.dispatchEvent("deviceListUpdate", {
2940
3035
  ref: this._main,
2941
3036
  cameraList: this._cameraList.getArray(),
@@ -2948,109 +3043,138 @@
2948
3043
  });
2949
3044
  }
2950
3045
  selectCamera(cameraID) {
2951
- var _a;
3046
+ var _a, _b;
3047
+ this._selectedCamera = null;
3048
+ this.setInputDeviceState(InputDeviceState.UPDATING);
3049
+ const streamKey = (_a = this._main.getConfigManager()) === null || _a === void 0 ? void 0 : _a.getStreamData().streamKey;
3050
+ const wasPublished = this._publishState === exports.PublishState.PUBLISHED;
2952
3051
  for (let i = 0; i < this._cameraList.getSize(); i++) {
2953
3052
  if (this._cameraList.get(i).getID() == cameraID) {
2954
3053
  this._selectedCamera = this._cameraList.get(i);
2955
- (_a = this._main.getStorageManager()) === null || _a === void 0 ? void 0 : _a.saveField("cameraID", this._selectedCamera.getID());
3054
+ console.log("kamera znaleziona i zapisana " + this._cameraList.get(i).getLabel() + " " + this._cameraList.get(i).getID());
3055
+ (_b = this._main.getStorageManager()) === null || _b === void 0 ? void 0 : _b.saveField("cameraID", this._selectedCamera.getID());
2956
3056
  break;
2957
3057
  }
2958
3058
  }
2959
- const wasPublishing = this._publishState === exports.PublishState.PUBLISHED;
2960
3059
  this.stopCameraStream();
2961
- this._constraints.video.deviceId = this._selectedCamera.getID();
2962
- this.startCamera().then(() => {
2963
- var _a;
2964
- if (wasPublishing && ((_a = this._main.getConfigManager()) === null || _a === void 0 ? void 0 : _a.getStreamData().streamKey)) {
2965
- this.updateWebRTCStream();
3060
+ if (this._selectedCamera != null) {
3061
+ this._constraints.video.deviceId = this._selectedCamera.getID();
3062
+ if (this._selectedCamera != null && this._selectedMicrophone != null) {
3063
+ this.setInputDeviceState(InputDeviceState.READY);
3064
+ } else {
3065
+ this.setInputDeviceState(InputDeviceState.INVALID);
2966
3066
  }
2967
- });
3067
+ this.startCamera().then(() => {
3068
+ if (wasPublished && streamKey) {
3069
+ this.publish(streamKey);
3070
+ }
3071
+ });
3072
+ } else {
3073
+ this.setInputDeviceState(InputDeviceState.INVALID);
3074
+ }
2968
3075
  }
2969
3076
  selectMicrophone(micID) {
2970
- var _a;
2971
- for (let i = 0; i < this._microphoneList.getSize(); i++) {
2972
- if (this._microphoneList.get(i).getID() == micID) {
2973
- this._selectedMicrophone = this._microphoneList.get(i);
2974
- (_a = this._main.getStorageManager()) === null || _a === void 0 ? void 0 : _a.saveField("microphoneID", this._selectedMicrophone.getID());
2975
- break;
3077
+ var _a, _b, _c, _d;
3078
+ return __awaiter(this, void 0, void 0, function* () {
3079
+ this._selectedMicrophone = null;
3080
+ this.setInputDeviceState(InputDeviceState.UPDATING);
3081
+ console.log("🎤 Selecting microphone:", micID);
3082
+ const streamKey = (_a = this._main.getConfigManager()) === null || _a === void 0 ? void 0 : _a.getStreamData().streamKey;
3083
+ const wasPublished = this._publishState === exports.PublishState.PUBLISHED;
3084
+ for (let i = 0; i < this._microphoneList.getSize(); i++) {
3085
+ if (this._microphoneList.get(i).getID() == micID) {
3086
+ this._selectedMicrophone = this._microphoneList.get(i);
3087
+ (_b = this._main.getStorageManager()) === null || _b === void 0 ? void 0 : _b.saveField("microphoneID", this._selectedMicrophone.getID());
3088
+ break;
3089
+ }
2976
3090
  }
2977
- }
2978
- const wasPublishing = this._publishState === exports.PublishState.PUBLISHED;
2979
- this.stopCameraStream();
2980
- this._constraints.audio = {
2981
- deviceId: this._selectedMicrophone.getID()
2982
- };
2983
- this.startCamera().then(() => {
2984
- var _a;
2985
- if (wasPublishing && ((_a = this._main.getConfigManager()) === null || _a === void 0 ? void 0 : _a.getStreamData().streamKey)) {
2986
- this.updateWebRTCStream();
3091
+ this._soundMeter.detach();
3092
+ try {
3093
+ const audioStream = yield navigator.mediaDevices.getUserMedia({
3094
+ audio: {
3095
+ deviceId: {
3096
+ exact: (_c = this._selectedMicrophone) === null || _c === void 0 ? void 0 : _c.getID()
3097
+ }
3098
+ }
3099
+ });
3100
+ const oldAudioTracks = ((_d = this._stream) === null || _d === void 0 ? void 0 : _d.getAudioTracks()) || [];
3101
+ oldAudioTracks.forEach(track => {
3102
+ var _a;
3103
+ (_a = this._stream) === null || _a === void 0 ? void 0 : _a.removeTrack(track);
3104
+ track.stop();
3105
+ });
3106
+ const newAudioTrack = audioStream.getAudioTracks()[0];
3107
+ if (this._stream) {
3108
+ this._stream.addTrack(newAudioTrack);
3109
+ if (newAudioTrack.readyState === 'live') {
3110
+ this._soundMeter.attach(this._stream);
3111
+ }
3112
+ }
3113
+ if (this._selectedCamera != null && this._selectedMicrophone != null) {
3114
+ this.setInputDeviceState(InputDeviceState.READY);
3115
+ } else {
3116
+ this.setInputDeviceState(InputDeviceState.INVALID);
3117
+ }
3118
+ if (wasPublished && streamKey) {
3119
+ this.publish(streamKey);
3120
+ }
3121
+ } catch (error) {
3122
+ console.error("Error changing microphone:", error);
3123
+ this.setInputDeviceState(InputDeviceState.INVALID);
3124
+ this._main.dispatchEvent("inputDeviceError", {
3125
+ ref: this._main
3126
+ });
2987
3127
  }
2988
3128
  });
2989
3129
  }
2990
3130
  startCamera() {
2991
3131
  return __awaiter(this, void 0, void 0, function* () {
3132
+ if (this._stream) {
3133
+ console.log("Stopping existing stream before starting new one");
3134
+ this._stream.getTracks().forEach(track => {
3135
+ track.stop();
3136
+ });
3137
+ this._stream = null;
3138
+ }
2992
3139
  try {
2993
- const devices = yield navigator.mediaDevices.enumerateDevices();
2994
- const hasVideo = devices.some(device => device.kind === 'videoinput');
2995
- const hasAudio = devices.some(device => device.kind === 'audioinput');
2996
- let tracks = [];
2997
- let hadError = false;
2998
- if (hasVideo) {
2999
- try {
3000
- const videoStream = yield navigator.mediaDevices.getUserMedia({
3001
- video: this._constraints.video
3002
- });
3003
- tracks.push(...videoStream.getTracks());
3004
- } catch (error) {
3005
- hadError = true;
3140
+ const constraints = {
3141
+ video: this._selectedCamera ? Object.assign(Object.assign({}, this._constraints.video), {
3142
+ deviceId: {
3143
+ exact: this._selectedCamera.getID()
3144
+ }
3145
+ }) : false,
3146
+ audio: this._selectedMicrophone ? {
3147
+ deviceId: {
3148
+ exact: this._selectedMicrophone.getID()
3149
+ }
3150
+ } : false
3151
+ };
3152
+ try {
3153
+ const stream = yield navigator.mediaDevices.getUserMedia(constraints);
3154
+ this._stream = stream;
3155
+ this.onCameraStreamSuccess(this._stream);
3156
+ } catch (error) {
3157
+ if (constraints.video) {
3006
3158
  this.onUserMediaError({
3007
- name: error instanceof Error ? error.name : 'UnknownError',
3008
- message: error instanceof Error ? error.message : 'Unknown error',
3159
+ name: error.name || 'Error',
3160
+ message: error.message || 'Unknown error',
3009
3161
  deviceType: 'video'
3010
3162
  });
3011
3163
  }
3012
- }
3013
- if (hasAudio) {
3014
- try {
3015
- const audioStream = yield navigator.mediaDevices.getUserMedia({
3016
- audio: this._constraints.audio
3017
- });
3018
- tracks.push(...audioStream.getTracks());
3019
- } catch (error) {
3020
- hadError = true;
3164
+ if (constraints.audio) {
3021
3165
  this.onUserMediaError({
3022
- name: error instanceof Error ? error.name : 'UnknownError',
3023
- message: error instanceof Error ? error.message : 'Unknown error',
3166
+ name: error.name || 'Error',
3167
+ message: error.message || 'Unknown error',
3024
3168
  deviceType: 'audio'
3025
3169
  });
3026
3170
  }
3027
3171
  }
3028
- if (tracks.length > 0) {
3029
- this._stream = new MediaStream(tracks);
3030
- this.onCameraStreamSuccess(this._stream);
3031
- } else if (hadError) {
3032
- yield this.grabDevices();
3033
- }
3034
3172
  } catch (error) {
3035
- if (error instanceof Error && !('deviceType' in error)) {
3036
- this.onUserMediaError({
3037
- name: error.name,
3038
- message: error.message
3039
- });
3040
- }
3173
+ console.error("Error in startCamera:", error);
3041
3174
  yield this.grabDevices();
3042
3175
  }
3043
3176
  });
3044
3177
  }
3045
- stopCameraStream() {
3046
- if (this._stream) {
3047
- this._stream.getTracks().forEach(track => track.stop());
3048
- const videoElement = this._main.getStageController().getScreenElement().getVideoElement();
3049
- videoElement.srcObject = null;
3050
- this._soundMeter.detach();
3051
- this._stream = null;
3052
- }
3053
- }
3054
3178
  updateWebRTCStream() {
3055
3179
  if (!this._peerConnection || !this._stream) {
3056
3180
  return;
@@ -3072,28 +3196,44 @@
3072
3196
  this.setPublishState(exports.PublishState.UNPUBLISHED);
3073
3197
  }
3074
3198
  pickCamera() {
3075
- var _a, _b;
3199
+ var _a, _b, _c;
3076
3200
  for (let i = 0; i < this._cameraList.getSize(); i++) {
3077
3201
  this._cameraList.get(i).setSelected(false);
3078
3202
  }
3079
3203
  let savedCameraID = (_b = (_a = this._main.getStorageManager()) === null || _a === void 0 ? void 0 : _a.getField("cameraID")) !== null && _b !== void 0 ? _b : null;
3080
- if (this._selectedCamera == null || savedCameraID == null) {
3081
- if (this._cameraList.getSize() > 0) {
3082
- this._selectedCamera = this._cameraList.get(0);
3083
- this._selectedCamera.setSelected(true);
3204
+ if (this._cameraList.getSize() > 0) {
3205
+ if (savedCameraID) {
3206
+ let found = false;
3207
+ for (let i = 0; i < this._cameraList.getSize(); i++) {
3208
+ if (this._cameraList.get(i).getID() === savedCameraID) {
3209
+ this._selectedCamera = this._cameraList.get(i);
3210
+ this._selectedCamera.setSelected(true);
3211
+ found = true;
3212
+ this._constraints.video.deviceId = this._selectedCamera.getID();
3213
+ break;
3214
+ }
3215
+ }
3216
+ if (!found) {
3217
+ this._main.dispatchEvent("savedCameraNotFound", {
3218
+ ref: this._main,
3219
+ savedDeviceID: savedCameraID
3220
+ });
3221
+ return null;
3222
+ }
3084
3223
  }
3085
- } else {
3086
- for (let i = 0; i < this._cameraList.getSize(); i++) {
3087
- if (this._cameraList.get(i).getID() == savedCameraID) {
3088
- this._selectedCamera = this._cameraList.get(i);
3224
+ if (!this._selectedCamera) {
3225
+ this._main.dispatchEvent("savedCameraNotFound", {
3226
+ ref: this._main,
3227
+ savedDeviceID: null
3228
+ });
3229
+ if (!((_c = this._main.getConfigManager()) === null || _c === void 0 ? void 0 : _c.getSettingsData().getIfForceSelection())) {
3230
+ this._selectedCamera = this._cameraList.get(0);
3089
3231
  this._selectedCamera.setSelected(true);
3090
- break;
3232
+ this._constraints.video.deviceId = this._selectedCamera.getID();
3233
+ } else {
3234
+ return null;
3091
3235
  }
3092
3236
  }
3093
- if (!this._selectedCamera && this._cameraList.getSize() > 0) {
3094
- this._selectedCamera = this._cameraList.get(0);
3095
- this._selectedCamera.setSelected(true);
3096
- }
3097
3237
  }
3098
3238
  this._main.dispatchEvent("deviceListUpdate", {
3099
3239
  ref: this._main,
@@ -3103,36 +3243,57 @@
3103
3243
  return this._selectedCamera;
3104
3244
  }
3105
3245
  pickMicrophone() {
3106
- var _a, _b;
3246
+ var _a, _b, _c;
3107
3247
  for (let i = 0; i < this._microphoneList.getSize(); i++) {
3108
3248
  this._microphoneList.get(i).setSelected(false);
3109
3249
  }
3110
3250
  let savedMicID = (_b = (_a = this._main.getStorageManager()) === null || _a === void 0 ? void 0 : _a.getField("microphoneID")) !== null && _b !== void 0 ? _b : null;
3111
- if (this._selectedMicrophone == null || savedMicID == null) {
3112
- if (this._microphoneList.getSize() > 0) {
3113
- this._selectedMicrophone = this._microphoneList.get(0);
3114
- this._selectedMicrophone.setSelected(true);
3115
- }
3116
- } else {
3117
- for (let i = 0; i < this._microphoneList.getSize(); i++) {
3118
- if (this._microphoneList.get(i).getID() == savedMicID) {
3119
- this._selectedMicrophone = this._microphoneList.get(i);
3120
- this._selectedMicrophone.setSelected(true);
3121
- break;
3251
+ if (this._microphoneList.getSize() > 0) {
3252
+ if (savedMicID) {
3253
+ let found = false;
3254
+ for (let i = 0; i < this._microphoneList.getSize(); i++) {
3255
+ if (this._microphoneList.get(i).getID() === savedMicID) {
3256
+ this._selectedMicrophone = this._microphoneList.get(i);
3257
+ found = true;
3258
+ break;
3259
+ }
3260
+ }
3261
+ if (!found) {
3262
+ this._main.dispatchEvent("savedMicrophoneNotFound", {
3263
+ ref: this._main,
3264
+ savedDeviceID: savedMicID
3265
+ });
3266
+ return null;
3122
3267
  }
3123
3268
  }
3124
- if (!this._selectedMicrophone && this._microphoneList.getSize() > 0) {
3125
- this._selectedMicrophone = this._microphoneList.get(0);
3126
- this._selectedMicrophone.setSelected(true);
3269
+ if (!this._selectedMicrophone) {
3270
+ this._main.dispatchEvent("savedMicrophoneNotFound", {
3271
+ ref: this._main,
3272
+ savedDeviceID: null
3273
+ });
3274
+ if (!((_c = this._main.getConfigManager()) === null || _c === void 0 ? void 0 : _c.getSettingsData().getIfForceSelection())) {
3275
+ this._selectedMicrophone = this._microphoneList.get(0);
3276
+ } else {
3277
+ return null;
3278
+ }
3127
3279
  }
3280
+ this._selectedMicrophone.setSelected(true);
3281
+ this._constraints.audio = {
3282
+ deviceId: this._selectedMicrophone.getID()
3283
+ };
3128
3284
  }
3129
- this._main.dispatchEvent("deviceListUpdate", {
3130
- ref: this._main,
3131
- cameraList: this._cameraList.getArray(),
3132
- microphoneList: this._microphoneList.getArray()
3133
- });
3134
3285
  return this._selectedMicrophone;
3135
3286
  }
3287
+ clearSavedDevices() {
3288
+ var _a, _b;
3289
+ (_a = this._main.getStorageManager()) === null || _a === void 0 ? void 0 : _a.removeField("cameraID");
3290
+ (_b = this._main.getStorageManager()) === null || _b === void 0 ? void 0 : _b.removeField("microphoneID");
3291
+ }
3292
+ messSavedDevices() {
3293
+ var _a, _b;
3294
+ (_a = this._main.getStorageManager()) === null || _a === void 0 ? void 0 : _a.saveField("cameraID", "a");
3295
+ (_b = this._main.getStorageManager()) === null || _b === void 0 ? void 0 : _b.saveField("microphoneID", "b");
3296
+ }
3136
3297
  muteMicrophone(shouldMute) {
3137
3298
  if (this._isMicrophoneMuted === shouldMute) {
3138
3299
  return;
@@ -3200,6 +3361,15 @@
3200
3361
  state: this._publishState
3201
3362
  });
3202
3363
  }
3364
+ setInputDeviceState(newState) {
3365
+ this._inputDeviceState = newState;
3366
+ this._main.dispatchEvent("deviceStateChange", {
3367
+ ref: this._main,
3368
+ state: this._inputDeviceState,
3369
+ selectedCamera: this._selectedCamera,
3370
+ selectedMicrophone: this._selectedMicrophone
3371
+ });
3372
+ }
3203
3373
  getCameraList() {
3204
3374
  return this._cameraList != null ? this._cameraList.getArray() : [];
3205
3375
  }
@@ -3209,19 +3379,111 @@
3209
3379
  getPublishState() {
3210
3380
  return this._publishState;
3211
3381
  }
3382
+ getInputDeviceState() {
3383
+ return this._inputDeviceState;
3384
+ }
3212
3385
  getPlayer() {
3213
3386
  return this._selectedPlayer;
3214
3387
  }
3388
+ stopCameraStream() {
3389
+ var _a, _b;
3390
+ if (this._stream) {
3391
+ this._stream.getTracks().forEach(track => track.stop());
3392
+ const videoElement = (_b = (_a = this._main.getStageController()) === null || _a === void 0 ? void 0 : _a.getScreenElement()) === null || _b === void 0 ? void 0 : _b.getVideoElement();
3393
+ if (videoElement) {
3394
+ videoElement.srcObject = null;
3395
+ }
3396
+ this._soundMeter.detach();
3397
+ this._stream = null;
3398
+ }
3399
+ }
3400
+ forceStopAllStreams() {
3401
+ var _a, _b;
3402
+ console.log("Force stopping all streams...");
3403
+ if (this._peerConnection) {
3404
+ try {
3405
+ const senders = this._peerConnection.getSenders();
3406
+ senders.forEach(sender => {
3407
+ var _a;
3408
+ try {
3409
+ if (sender.track) {
3410
+ sender.track.enabled = false;
3411
+ sender.track.stop();
3412
+ (_a = this._peerConnection) === null || _a === void 0 ? void 0 : _a.removeTrack(sender);
3413
+ }
3414
+ } catch (e) {
3415
+ console.error('Error stopping sender track:', e);
3416
+ }
3417
+ });
3418
+ this._peerConnection.close();
3419
+ this._peerConnection = null;
3420
+ } catch (e) {
3421
+ console.error('Error closing peer connection:', e);
3422
+ }
3423
+ }
3424
+ try {
3425
+ const videoElement = (_b = (_a = this._main.getStageController()) === null || _a === void 0 ? void 0 : _a.getScreenElement()) === null || _b === void 0 ? void 0 : _b.getVideoElement();
3426
+ if (videoElement && videoElement.srcObject instanceof MediaStream) {
3427
+ const videoTracks = videoElement.srcObject.getTracks();
3428
+ videoTracks.forEach(track => {
3429
+ try {
3430
+ track.enabled = false;
3431
+ track.stop();
3432
+ } catch (e) {
3433
+ console.error('Error stopping video element track:', e);
3434
+ }
3435
+ });
3436
+ videoElement.srcObject = null;
3437
+ videoElement.removeAttribute('src');
3438
+ videoElement.load();
3439
+ }
3440
+ } catch (e) {
3441
+ console.error('Error cleaning video element:', e);
3442
+ }
3443
+ if (this._stream) {
3444
+ try {
3445
+ const tracks = this._stream.getTracks();
3446
+ console.log(`Stopping ${tracks.length} tracks from main stream`);
3447
+ tracks.forEach(track => {
3448
+ try {
3449
+ console.log(`Stopping ${track.kind} track, enabled: ${track.enabled}, state: ${track.readyState}`);
3450
+ track.enabled = false;
3451
+ track.stop();
3452
+ console.log(`Track after stop - state: ${track.readyState}`);
3453
+ } catch (e) {
3454
+ console.error(`Error stopping ${track.kind} track:`, e);
3455
+ }
3456
+ });
3457
+ this._stream = null;
3458
+ } catch (e) {
3459
+ console.error('Error stopping main stream:', e);
3460
+ }
3461
+ }
3462
+ console.log("All streams should be stopped now");
3463
+ }
3215
3464
  destroy() {
3216
- var _a;
3465
+ console.log("Starting destroy process...");
3466
+ this.forceStopAllStreams();
3467
+ if (this._soundMeter) {
3468
+ this._soundMeter.detach();
3469
+ }
3217
3470
  this._pendingMicrophoneState = null;
3218
- this.closeStream();
3219
- (_a = this._selectedPlayer) === null || _a === void 0 ? void 0 : _a.clear();
3220
- this._selectedPlayer = null;
3221
- this._main.removeEventListener("serverConnect", this.onServerConnect);
3222
- document.removeEventListener("visibilitychange", this.visibilityChange);
3223
- window.removeEventListener("blur", this.onWindowBlur);
3224
- window.removeEventListener("focus", this.onWindowFocus);
3471
+ this._cameraList = new InputDeviceList();
3472
+ this._microphoneList = new InputDeviceList();
3473
+ this._permissionChecked = false;
3474
+ this._isWindowActive = false;
3475
+ this._isMicrophoneMuted = false;
3476
+ try {
3477
+ this._main.removeEventListener("serverConnect", this.onServerConnect);
3478
+ this._main.removeEventListener("serverDisconnect", this.onServerDisconnect);
3479
+ document.removeEventListener("visibilitychange", this.visibilityChange);
3480
+ window.removeEventListener("blur", this.onWindowBlur);
3481
+ window.removeEventListener("focus", this.onWindowFocus);
3482
+ } catch (e) {
3483
+ console.error('Error removing event listeners:', e);
3484
+ }
3485
+ this._publishState = exports.PublishState.NOT_INITIALIZED;
3486
+ console.log("Destroy process completed");
3225
3487
  }
3226
3488
  }
3227
3489
 
@@ -3523,8 +3785,8 @@
3523
3785
  constructor(streamConfig, autoInitialize = false) {
3524
3786
  super();
3525
3787
  this.DEV_MODE = true;
3526
- this.STREAMER_VERSION = "0.9.0-beta.3";
3527
- this.COMPILE_DATE = "12/5/2024, 2:36:49 PM";
3788
+ this.STREAMER_VERSION = "0.9.0-beta.5";
3789
+ this.COMPILE_DATE = "12/10/2024, 10:26:02 AM";
3528
3790
  this.STREAMER_BRANCH = "Experimental";
3529
3791
  this.STREAMER_PROTOCOL_VERSION = 1;
3530
3792
  this._initialized = false;
@@ -3680,6 +3942,18 @@
3680
3942
  var _a, _b;
3681
3943
  return (_b = (_a = this._playbackController) === null || _a === void 0 ? void 0 : _a.publish(streamKey)) !== null && _b !== void 0 ? _b : false;
3682
3944
  }
3945
+ getDeviceState() {
3946
+ var _a, _b;
3947
+ return (_b = (_a = this._playbackController) === null || _a === void 0 ? void 0 : _a.getInputDeviceState()) !== null && _b !== void 0 ? _b : InputDeviceState.NOT_INITIALIZED;
3948
+ }
3949
+ clearSavedDevices() {
3950
+ var _a;
3951
+ return (_a = this._playbackController) === null || _a === void 0 ? void 0 : _a.clearSavedDevices();
3952
+ }
3953
+ messSavedDevices() {
3954
+ var _a;
3955
+ return (_a = this._playbackController) === null || _a === void 0 ? void 0 : _a.messSavedDevices();
3956
+ }
3683
3957
  isStreamReady() {
3684
3958
  var _a, _b;
3685
3959
  return (_b = (_a = this._playbackController) === null || _a === void 0 ? void 0 : _a.isStreamReady()) !== null && _b !== void 0 ? _b : false;
@@ -3818,8 +4092,8 @@
3818
4092
  this._initialized = false;
3819
4093
  this._isRemoved = true;
3820
4094
  (_b = (_a = this._networkController) === null || _a === void 0 ? void 0 : _a.getConnection()) === null || _b === void 0 ? void 0 : _b.destroy();
3821
- (_c = this._stageController) === null || _c === void 0 ? void 0 : _c.destroy();
3822
- (_d = this._playbackController) === null || _d === void 0 ? void 0 : _d.destroy();
4095
+ (_c = this._playbackController) === null || _c === void 0 ? void 0 : _c.destroy();
4096
+ (_d = this._stageController) === null || _d === void 0 ? void 0 : _d.destroy();
3823
4097
  this.removeAllEventListeners();
3824
4098
  }
3825
4099
  }