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

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.2
8
- * Version: 11/29/2024, 6:55:47 PM
7
+ * Version: 0.9.0-beta.3
8
+ * Version: 12/5/2024, 2:36:50 PM
9
9
  *
10
10
  * LEGAL NOTICE:
11
11
  * This software is subject to the terms and conditions defined in
@@ -1626,6 +1626,13 @@
1626
1626
  this.dispatchVolumeEvent();
1627
1627
  };
1628
1628
  this._videoElement.onpause = () => {};
1629
+ this._videoElement.addEventListener('loadedmetadata', () => {
1630
+ this._main.dispatchEvent("metadata", {
1631
+ ref: this._main,
1632
+ videoWidth: this._videoElement.videoWidth,
1633
+ videoHeight: this._videoElement.videoHeight
1634
+ });
1635
+ });
1629
1636
  this._videoElement.ontimeupdate = function (event) {};
1630
1637
  this._videoElement.onended = event => {
1631
1638
  this._logger.info(this, "VideoElement :: onended");
@@ -1703,7 +1710,9 @@
1703
1710
  this._videoHeight = 0;
1704
1711
  this._scalingMode = ScalingType.FILL;
1705
1712
  this.isInFullScreenMode = false;
1713
+ this._isResizing = false;
1706
1714
  this._autoResizeEnabled = true;
1715
+ this._parentOriginalOverflow = '';
1707
1716
  this.onFullScreenChange = () => {
1708
1717
  if (document.fullscreenElement == null) {
1709
1718
  this.isInFullScreenMode = false;
@@ -1719,35 +1728,6 @@
1719
1728
  });
1720
1729
  }
1721
1730
  };
1722
- this.onResize = () => {
1723
- if (this._parentElement != null) {
1724
- const calcMethod = this._main.getConfigManager().getSettingsData().getVideoData().parentSizeCalculationMethod;
1725
- this._videoContainer.style.display = "none";
1726
- switch (calcMethod) {
1727
- case SizeCalculationType.CLIENT_DIMENSIONS:
1728
- this._tempContainerWidth = this._parentElement.clientWidth;
1729
- this._tempContainerHeight = this._parentElement.clientHeight;
1730
- break;
1731
- case SizeCalculationType.BOUNDING_BOX:
1732
- this._tempContainerWidth = this._parentElement.getBoundingClientRect().width;
1733
- this._tempContainerHeight = this._parentElement.getBoundingClientRect().height;
1734
- break;
1735
- case SizeCalculationType.FULL_BOX:
1736
- this._tempContainerWidth = DomUtilities.calculateDimensionsWithMargins(this._parentElement).width;
1737
- this._tempContainerHeight = DomUtilities.calculateDimensionsWithMargins(this._parentElement).height;
1738
- break;
1739
- }
1740
- this._logger.info(this, "onResize called: " + this._tempContainerWidth + "x" + this._tempContainerHeight + " (" + calcMethod + ")");
1741
- this.resizeVideoContainer();
1742
- this.scaleVideo();
1743
- this._videoContainer.style.display = "block";
1744
- this._main.dispatchEvent("resizeUpdate", {
1745
- ref: this._main,
1746
- width: this._tempContainerWidth,
1747
- height: this._tempContainerHeight
1748
- });
1749
- }
1750
- };
1751
1731
  this._main = main;
1752
1732
  this._logger = main.getLogger();
1753
1733
  this._logger.info(this, "Creating new StageController");
@@ -1767,14 +1747,14 @@
1767
1747
  const debounceValue = this._main.getConfigManager().getSettingsData().getVideoData().resizeDebounce;
1768
1748
  if (debounceValue > 0) {
1769
1749
  this._resizeObserver = new ResizeObserver(debounce$1(() => () => {
1770
- if (this._autoResizeEnabled) this.onResize();
1750
+ if (this._autoResizeEnabled) this.handleResize();
1771
1751
  }, debounceValue, {
1772
1752
  leading: false,
1773
1753
  trailing: true
1774
1754
  }));
1775
1755
  } else {
1776
1756
  this._resizeObserver = new ResizeObserver(() => {
1777
- if (this._autoResizeEnabled) this.onResize();
1757
+ if (this._autoResizeEnabled) this.handleResize();
1778
1758
  });
1779
1759
  }
1780
1760
  document.addEventListener('fullscreenchange', this.onFullScreenChange, false);
@@ -1782,6 +1762,11 @@
1782
1762
  document.addEventListener('mozfullscreenchange', this.onFullScreenChange, false);
1783
1763
  document.addEventListener('webkitendfullscreen', this.onFullScreenChange, false);
1784
1764
  this._screenElement.getVideoElement().addEventListener('webkitendfullscreen', this.onFullScreenChange, false);
1765
+ this._main.addEventListener("metadata", event => {
1766
+ this._videoWidth = event.videoWidth;
1767
+ this._videoHeight = event.videoHeight;
1768
+ this.handleResize();
1769
+ }, false);
1785
1770
  if (containerID) {
1786
1771
  this.attachToParent(containerID);
1787
1772
  } else this._logger.warning(this, `Could not create HTMLObject for the library - "containerID" was not provided`);
@@ -1789,7 +1774,6 @@
1789
1774
  attachToParent(container) {
1790
1775
  let result = false;
1791
1776
  let tempParentElement = null;
1792
- console.log("xxxxxxxxx", container);
1793
1777
  if (typeof container === "string") {
1794
1778
  this._logger.info(this, "Attaching container to ID: " + container);
1795
1779
  tempParentElement = document.getElementById(container);
@@ -1807,13 +1791,13 @@
1807
1791
  this._parentElement.appendChild(this._videoContainer);
1808
1792
  this._resizeObserver.observe(this._parentElement);
1809
1793
  this._parentElement.addEventListener("transitionend", () => {
1810
- this.onResize();
1794
+ this.handleResize();
1811
1795
  });
1812
1796
  this._main.dispatchEvent("containerChange", {
1813
1797
  ref: this._main,
1814
1798
  container: this._parentElement
1815
1799
  });
1816
- this.onResize();
1800
+ this.handleResize();
1817
1801
  result = true;
1818
1802
  } else {
1819
1803
  console.log("tempParentElement", tempParentElement);
@@ -1831,7 +1815,7 @@
1831
1815
  this._resizeObserver.unobserve(this._parentElement);
1832
1816
  this._resizeObserver.disconnect();
1833
1817
  }
1834
- if (this._autoResizeEnabled) this._parentElement.removeEventListener("transitionend", this.onResize);
1818
+ if (this._autoResizeEnabled) this._parentElement.removeEventListener("transitionend", this.handleResize);
1835
1819
  this._main.dispatchEvent("containerChange", {
1836
1820
  ref: this._main,
1837
1821
  container: null
@@ -1843,6 +1827,46 @@
1843
1827
  this._parentElement = null;
1844
1828
  return result;
1845
1829
  }
1830
+ handleResize() {
1831
+ if (!this._parentElement || this._isResizing) return;
1832
+ this._isResizing = true;
1833
+ this._parentOriginalOverflow = this._parentElement.style.overflow;
1834
+ this._parentElement.style.overflow = 'hidden';
1835
+ requestAnimationFrame(() => {
1836
+ this.calculateNewDimensions();
1837
+ this._parentElement.style.overflow = this._parentOriginalOverflow;
1838
+ this._isResizing = false;
1839
+ if (this._tempContainerWidth !== this._containerWidth || this._tempContainerHeight !== this._containerHeight) {
1840
+ this._main.dispatchEvent("resizeUpdate", {
1841
+ ref: this._main,
1842
+ width: this._tempContainerWidth,
1843
+ height: this._tempContainerHeight
1844
+ });
1845
+ }
1846
+ });
1847
+ }
1848
+ calculateNewDimensions() {
1849
+ const calcMethod = this._main.getConfigManager().getSettingsData().getVideoData().parentSizeCalculationMethod;
1850
+ switch (calcMethod) {
1851
+ case SizeCalculationType.CLIENT_DIMENSIONS:
1852
+ this._tempContainerWidth = this._parentElement.clientWidth;
1853
+ this._tempContainerHeight = this._parentElement.clientHeight;
1854
+ break;
1855
+ case SizeCalculationType.BOUNDING_BOX:
1856
+ const rect = this._parentElement.getBoundingClientRect();
1857
+ this._tempContainerWidth = rect.width;
1858
+ this._tempContainerHeight = rect.height;
1859
+ break;
1860
+ case SizeCalculationType.FULL_BOX:
1861
+ const dims = DomUtilities.calculateDimensionsWithMargins(this._parentElement);
1862
+ this._tempContainerWidth = dims.width;
1863
+ this._tempContainerHeight = dims.height;
1864
+ break;
1865
+ }
1866
+ this._logger.info(this, `New dimensions calculated: ${this._tempContainerWidth}x${this._tempContainerHeight} (${calcMethod})`);
1867
+ this.resizeVideoContainer();
1868
+ this.scaleVideo();
1869
+ }
1846
1870
  resizeVideoContainer() {
1847
1871
  const isWidthInPX = this._main.getConfigManager().getSettingsData().getVideoData().videoWidthInPixels;
1848
1872
  const isHeightInPX = this._main.getConfigManager().getSettingsData().getVideoData().videoHeightInPixels;
@@ -1877,8 +1901,6 @@
1877
1901
  }
1878
1902
  this._containerWidth = Math.ceil(finalVideoWidth);
1879
1903
  this._containerHeight = Math.ceil(finalVideoHeight);
1880
- this._videoWidth = this._containerWidth;
1881
- this._videoHeight = this._containerHeight;
1882
1904
  if (this._videoContainer !== null) {
1883
1905
  this._videoContainer.style.width = this._containerWidth + "px";
1884
1906
  this._videoContainer.style.height = this._containerHeight + "px";
@@ -2056,6 +2078,38 @@
2056
2078
  }
2057
2079
  StageController.LOG_ACTIVITY = true;
2058
2080
 
2081
+ /******************************************************************************
2082
+ Copyright (c) Microsoft Corporation.
2083
+
2084
+ Permission to use, copy, modify, and/or distribute this software for any
2085
+ purpose with or without fee is hereby granted.
2086
+
2087
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
2088
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
2089
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
2090
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
2091
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
2092
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2093
+ PERFORMANCE OF THIS SOFTWARE.
2094
+ ***************************************************************************** */
2095
+ /* global Reflect, Promise, SuppressedError, Symbol */
2096
+
2097
+
2098
+ function __awaiter(thisArg, _arguments, P, generator) {
2099
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
2100
+ return new (P || (P = Promise))(function (resolve, reject) {
2101
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
2102
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
2103
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
2104
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
2105
+ });
2106
+ }
2107
+
2108
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
2109
+ var e = new Error(message);
2110
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
2111
+ };
2112
+
2059
2113
  class MungeSDP {
2060
2114
  constructor() {}
2061
2115
  addAudio(sdpStr, audioLine) {
@@ -2408,50 +2462,78 @@
2408
2462
 
2409
2463
  class SoundMeter {
2410
2464
  constructor(main) {
2465
+ this._stream = null;
2466
+ this._audioContext = null;
2467
+ this._analyser = null;
2468
+ this._microphone = null;
2469
+ this._lastEventTime = 0;
2470
+ this.THROTTLE_INTERVAL = 100;
2411
2471
  this._instant = 0.0;
2412
2472
  this._slow = 0.0;
2413
- this.clip = 0.0;
2473
+ this._clip = 0.0;
2414
2474
  this._main = main;
2415
2475
  }
2416
2476
  attach(stream) {
2417
2477
  this._stream = stream;
2418
- this.audioContext = new AudioContext();
2419
- this.microphone = this.audioContext.createMediaStreamSource(stream);
2420
- this.processor = this.audioContext.createScriptProcessor(2048, 1, 1);
2421
- this.microphone.connect(this.processor);
2422
- this.processor.connect(this.audioContext.destination);
2423
- this.processor.onaudioprocess = event => {
2424
- this.onAudioProcess(event);
2425
- };
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();
2426
2485
  }
2427
2486
  detach() {
2428
- if (this.microphone !== null) this.microphone.disconnect();
2429
- if (this.processor !== null) this.processor.disconnect();
2487
+ if (this._microphone) {
2488
+ this._microphone.disconnect();
2489
+ this._microphone = null;
2490
+ }
2491
+ if (this._analyser) {
2492
+ this._analyser.disconnect();
2493
+ this._analyser = null;
2494
+ }
2495
+ if (this._audioContext) {
2496
+ this._audioContext.close();
2497
+ this._audioContext = null;
2498
+ }
2499
+ this._stream = null;
2500
+ this.clear();
2430
2501
  }
2431
2502
  clear() {
2432
2503
  this._instant = 0;
2433
2504
  this._slow = 0;
2434
- this.clip = 0;
2435
- }
2436
- onAudioProcess(event) {
2437
- const input = event.inputBuffer.getChannelData(0);
2438
- let i;
2439
- let sum = 0.0;
2440
- let clipcount = 0;
2441
- for (i = 0; i < input.length; ++i) {
2442
- sum += input[i] * input[i];
2443
- if (Math.abs(input[i]) > 0.99) {
2444
- clipcount += 1;
2445
- }
2446
- }
2447
- this._instant = Math.sqrt(sum / input.length);
2448
- this._slow = 0.05 * this._instant + 0.95 * this._slow;
2449
- this.clip = clipcount / input.length;
2450
- this._main.dispatchEvent("soundMeter", {
2451
- ref: this._main,
2452
- high: this._instant,
2453
- low: this._slow
2454
- });
2505
+ this._clip = 0;
2506
+ }
2507
+ startMonitoring() {
2508
+ if (!this._analyser) return;
2509
+ const dataArray = new Float32Array(this._analyser.frequencyBinCount);
2510
+ const analyze = () => {
2511
+ if (!this._analyser) return;
2512
+ 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;
2521
+ }
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
+ });
2533
+ }
2534
+ requestAnimationFrame(analyze);
2535
+ };
2536
+ requestAnimationFrame(analyze);
2455
2537
  }
2456
2538
  }
2457
2539
 
@@ -2462,6 +2544,7 @@
2462
2544
  'iceServers': []
2463
2545
  };
2464
2546
  this._isMicrophoneMuted = false;
2547
+ this._pendingMicrophoneState = null;
2465
2548
  this._constraints = {
2466
2549
  video: {
2467
2550
  width: {
@@ -2485,6 +2568,9 @@
2485
2568
  this._publishState = exports.PublishState.NOT_INITIALIZED;
2486
2569
  this.onServerDisconnect = () => {};
2487
2570
  this.onServerConnect = () => {
2571
+ if (this._peerConnection) {
2572
+ this.closeWebRTCConnection();
2573
+ }
2488
2574
  this._peerConnection = new RTCPeerConnection(this._peerConnectionConfig);
2489
2575
  this._peerConnection.onicecandidate = event => {
2490
2576
  this.onIceCandidate(event);
@@ -2493,17 +2579,21 @@
2493
2579
  this.onConnectionStateChange(event);
2494
2580
  };
2495
2581
  this._peerConnection.onnegotiationneeded = event => {
2496
- this._peerConnection.createOffer(description => {
2497
- this.onDescriptionSuccess(description);
2498
- }, error => {
2499
- this.onDescriptionError(error);
2500
- }).catch(reason => {
2501
- console.log(reason);
2502
- });
2582
+ if (this._peerConnection) {
2583
+ this._peerConnection.createOffer(description => {
2584
+ this.onDescriptionSuccess(description);
2585
+ }, error => {
2586
+ this.onDescriptionError(error);
2587
+ }).catch(reason => {
2588
+ console.log(reason);
2589
+ });
2590
+ }
2503
2591
  };
2504
- let localTracks = this._stream.getTracks();
2505
- for (let localTrack in localTracks) {
2506
- this._peerConnection.addTrack(localTracks[localTrack], this._stream);
2592
+ if (this._stream) {
2593
+ let localTracks = this._stream.getTracks();
2594
+ for (let localTrack in localTracks) {
2595
+ this._peerConnection.addTrack(localTracks[localTrack], this._stream);
2596
+ }
2507
2597
  }
2508
2598
  };
2509
2599
  this.onDescriptionSuccess = description => {
@@ -2521,12 +2611,14 @@
2521
2611
  videoCodec: "42e01f",
2522
2612
  audioCodec: "opus"
2523
2613
  });
2524
- this._peerConnection.setLocalDescription(description).then(() => {
2525
- var _a;
2526
- (_a = this._main.getNetworkController()) === null || _a === void 0 ? void 0 : _a.sendMessage('{"direction":"publish", "command":"sendOffer", "streamInfo":' + JSON.stringify(streamInfo) + ', "sdp":' + JSON.stringify(description) + '}');
2527
- }).catch(error => {
2528
- console.log(error);
2529
- });
2614
+ if (this._peerConnection) {
2615
+ this._peerConnection.setLocalDescription(description).then(() => {
2616
+ var _a;
2617
+ (_a = this._main.getNetworkController()) === null || _a === void 0 ? void 0 : _a.sendMessage('{"direction":"publish", "command":"sendOffer", "streamInfo":' + JSON.stringify(streamInfo) + ', "sdp":' + JSON.stringify(description) + '}');
2618
+ }).catch(error => {
2619
+ console.log(error);
2620
+ });
2621
+ }
2530
2622
  };
2531
2623
  this.visibilityChange = () => {
2532
2624
  if (document.visibilityState === 'hidden') {
@@ -2555,7 +2647,7 @@
2555
2647
  this.initialize();
2556
2648
  }
2557
2649
  initialize() {
2558
- var _a, _b, _c;
2650
+ var _a, _b;
2559
2651
  this._main.addEventListener("serverConnect", this.onServerConnect, false);
2560
2652
  this._main.addEventListener("serverDisconnect", this.onServerDisconnect, false);
2561
2653
  document.addEventListener("visibilitychange", this.visibilityChange);
@@ -2564,89 +2656,174 @@
2564
2656
  if ((_a = this._main.getConfigManager()) === null || _a === void 0 ? void 0 : _a.getSettingsData().autoConnect) {
2565
2657
  this._logger.info(this, "Initializing NetworkController (autoConnect is true)");
2566
2658
  (_b = this._main.getNetworkController()) === null || _b === void 0 ? void 0 : _b.initialize();
2567
- } else this._logger.warning(this, "Warning - autoConnect is set to false, switching to standby mode!");
2568
- if (((_c = this._main.getConfigManager()) === null || _c === void 0 ? void 0 : _c.getStreamData().streamKey) != null) this.startWebRTC();
2569
- }
2570
- startWebRTC() {
2571
- try {
2572
- if (navigator.mediaDevices.getUserMedia) {
2573
- navigator.mediaDevices.getUserMedia(this._constraints).then(stream => {
2574
- this.onUserMediaSuccess(stream);
2575
- }).catch(error => {
2576
- this.onUserMediaError(error);
2577
- });
2578
- } else {
2579
- this._logger.error(this, "WebRTCStreamer :: Browser does not support WebRTC");
2580
- this._main.dispatchEvent("compatibilityError", {
2581
- ref: this._main,
2582
- message: "WebRTC is not supported"
2583
- });
2584
- }
2585
- } catch (error) {
2586
- this.onUserMediaError(error);
2659
+ } else {
2660
+ this._logger.warning(this, "Warning - autoConnect is set to false, switching to standby mode!");
2587
2661
  }
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();
2666
+ }
2667
+ });
2588
2668
  }
2589
- publish(streamKey) {
2590
- if (this._publishState == exports.PublishState.PUBLISHED) this.closeStream();
2591
- this._main.getConfigManager().getStreamData().streamKey = streamKey;
2592
- this.startWebRTC();
2593
- }
2594
- unpublish() {
2595
- this.closeStream();
2596
- }
2597
- onUserMediaSuccess(stream) {
2598
- var _a;
2599
- console.log('%c⏵ 🎥 onUserMediaSuccess', 'background: green; color: white;');
2600
- this._logger.success(this, "WebRTCStreamer :: WebRTC UserMedia successfully retrieved");
2669
+ onCameraStreamSuccess(stream) {
2670
+ this._logger.success(this, "Camera stream successfully retrieved");
2601
2671
  this._stream = stream;
2602
- this._soundMeter.attach(this._stream);
2603
- this.setPublishState(exports.PublishState.INITIALIZED);
2604
- if (this._cameraList == null || this._microphoneList == null) this.grabDevices();
2672
+ if (this._pendingMicrophoneState !== null) {
2673
+ this.applyMicrophoneState(this._pendingMicrophoneState);
2674
+ this._pendingMicrophoneState = null;
2675
+ } else {
2676
+ this.applyMicrophoneState(!this._isMicrophoneMuted);
2677
+ }
2678
+ if (this._stream.getAudioTracks().length > 0) {
2679
+ this._soundMeter.attach(this._stream);
2680
+ }
2681
+ if (this._cameraList == null || this._microphoneList == null) {
2682
+ this.grabDevices();
2683
+ }
2605
2684
  const videoElement = this._main.getStageController().getScreenElement().getVideoElement();
2606
2685
  videoElement.srcObject = stream;
2607
2686
  videoElement.autoplay = true;
2608
2687
  videoElement.playsInline = true;
2609
2688
  videoElement.disableRemotePlayback = true;
2610
2689
  videoElement.controls = false;
2611
- (_a = this._main.getNetworkController()) === null || _a === void 0 ? void 0 : _a.start();
2690
+ videoElement.muted = true;
2691
+ this.setPublishState(exports.PublishState.INITIALIZED);
2692
+ }
2693
+ initializeWebRTC() {
2694
+ var _a;
2695
+ if (!this._stream) {
2696
+ this._logger.error(this, "Cannot initialize WebRTC - no camera stream available");
2697
+ return;
2698
+ }
2699
+ if (this._peerConnection) {
2700
+ this._logger.info(this, "WebRTC connection already exists, updating stream");
2701
+ this.updateWebRTCStream();
2702
+ } else {
2703
+ this._logger.info(this, "Initializing new WebRTC connection");
2704
+ (_a = this._main.getNetworkController()) === null || _a === void 0 ? void 0 : _a.start();
2705
+ }
2706
+ }
2707
+ publish(streamKey) {
2708
+ if (!this.isStreamReady(true, true)) {
2709
+ this._logger.warning(this, "Cannot publish - stream not ready (missing video or audio track)");
2710
+ return false;
2711
+ }
2712
+ this.closeWebRTCConnection();
2713
+ this._main.getConfigManager().getStreamData().streamKey = streamKey;
2714
+ this._main.dispatchEvent("publish", {
2715
+ ref: this._main,
2716
+ streamKey: streamKey
2717
+ });
2718
+ this.initializeWebRTC();
2719
+ return true;
2720
+ }
2721
+ unpublish() {
2722
+ this._main.getConfigManager().getStreamData().streamKey = null;
2723
+ this._main.dispatchEvent("unpublish", {
2724
+ ref: this._main
2725
+ });
2726
+ this.closeStream();
2612
2727
  }
2613
2728
  onUserMediaError(error) {
2614
2729
  console.log('%c⏵ 🎥 onUserMediaError: ' + JSON.stringify(error), 'background: green; color: white;');
2615
- switch (error.message) {
2616
- case "Permission denied":
2617
- this._logger.warning(this, "WebRTCStreamer :: No permission to access camera & microphone");
2618
- this._main.dispatchEvent("inputDeviceDenied", {
2730
+ const errorName = error.name || '';
2731
+ const errorMessage = error.message || '';
2732
+ if (error.deviceType) {
2733
+ if (error.deviceType === 'video') {
2734
+ this._main.dispatchEvent("cameraAccessDenied", {
2619
2735
  ref: this._main
2620
2736
  });
2621
- break;
2622
- case "The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.":
2623
- this._logger.warning(this, "WebRTCStreamer :: No permission to access camera & microphone");
2624
- this._main.dispatchEvent("inputDeviceDenied", {
2737
+ } else if (error.deviceType === 'audio') {
2738
+ this._main.dispatchEvent("microphoneAccessDenied", {
2625
2739
  ref: this._main
2626
2740
  });
2627
- break;
2628
- case "The request is not allowed by the user agent or the platform in the current context.":
2629
- this._logger.warning(this, "WebRTCStreamer :: No permission to access camera & microphone");
2630
- this._main.dispatchEvent("inputDeviceDenied", {
2631
- ref: this._main
2632
- });
2633
- break;
2634
- case "The object can not be found here.":
2635
- this._logger.warning(this, "WebRTCStreamer :: Could not access camera or microphone");
2636
- this._main.dispatchEvent("inputDeviceError", {
2637
- ref: this._main
2741
+ }
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
+ });
2790
+ this.grabDevices();
2791
+ }
2792
+ checkIndividualDeviceAccess() {
2793
+ return __awaiter(this, void 0, void 0, function* () {
2794
+ const results = {
2795
+ camera: false,
2796
+ microphone: false
2797
+ };
2798
+ try {
2799
+ const videoStream = yield navigator.mediaDevices.getUserMedia({
2800
+ video: true
2638
2801
  });
2639
- break;
2640
- case "Requested device not found":
2641
- this._logger.warning(this, "WebRTCStreamer :: Could not access camera or microphone");
2642
- this._main.dispatchEvent("inputDeviceError", {
2643
- ref: this._main
2802
+ results.camera = true;
2803
+ videoStream.getTracks().forEach(track => track.stop());
2804
+ } catch (e) {
2805
+ results.camera = false;
2806
+ }
2807
+ try {
2808
+ const audioStream = yield navigator.mediaDevices.getUserMedia({
2809
+ audio: true
2644
2810
  });
2645
- break;
2646
- default:
2647
- this._logger.warning(this, "WebRTCStreamer :: Unsupported onUserMediaError: " + error.message);
2648
- break;
2649
- }
2811
+ results.microphone = true;
2812
+ audioStream.getTracks().forEach(track => track.stop());
2813
+ } catch (e) {
2814
+ results.microphone = false;
2815
+ }
2816
+ return results;
2817
+ });
2818
+ }
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
+ });
2650
2827
  }
2651
2828
  onSocketMessage(data) {
2652
2829
  let msgJSON = JSON.parse(data);
@@ -2661,7 +2838,7 @@
2661
2838
  let iceCandidates = msgJSON['iceCandidates'];
2662
2839
  if (iceCandidates !== undefined) {
2663
2840
  for (let index in iceCandidates) {
2664
- this._peerConnection.addIceCandidate(new RTCIceCandidate(iceCandidates[index]));
2841
+ if (this._peerConnection) this._peerConnection.addIceCandidate(new RTCIceCandidate(iceCandidates[index]));
2665
2842
  }
2666
2843
  }
2667
2844
  break;
@@ -2703,42 +2880,71 @@
2703
2880
  }
2704
2881
  }
2705
2882
  grabDevices() {
2706
- navigator.mediaDevices.enumerateDevices().then(devices => {
2707
- this._cameraList = new InputDeviceList();
2708
- this._microphoneList = new InputDeviceList();
2709
- for (let i = 0; i < devices.length; i++) {
2883
+ return __awaiter(this, void 0, void 0, function* () {
2884
+ try {
2710
2885
  try {
2711
- if (devices[i].kind === 'videoinput') {
2712
- let device = new InputDevice(devices[i], i);
2713
- this._cameraList.push(device);
2714
- } else if (devices[i].kind === 'audioinput') {
2715
- let device = new InputDevice(devices[i], i);
2716
- this._microphoneList.push(device);
2886
+ yield navigator.mediaDevices.getUserMedia({
2887
+ audio: true,
2888
+ video: true
2889
+ });
2890
+ } catch (e) {}
2891
+ const devices = yield navigator.mediaDevices.enumerateDevices();
2892
+ this._cameraList = new InputDeviceList();
2893
+ 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);
2717
2907
  }
2718
- } catch (error) {
2719
- this._logger.error(this, "WebRTCStreamer :: Input Device Error: " + error);
2720
2908
  }
2721
- }
2722
- if (this._cameraList.getSize() == 0) {
2723
- this._main.dispatchEvent("noCameraFound", {
2724
- ref: this._main
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();
2923
+ }
2924
+ if (this._microphoneList.getSize() == 0) {
2925
+ this._main.dispatchEvent("noMicrophoneFound", {
2926
+ ref: this._main
2927
+ });
2928
+ } else {
2929
+ this._selectedMicrophone = this.pickMicrophone();
2930
+ }
2931
+ this._main.dispatchEvent("deviceListUpdate", {
2932
+ ref: this._main,
2933
+ cameraList: this._cameraList.getArray(),
2934
+ microphoneList: this._microphoneList.getArray()
2935
+ });
2936
+ } catch (error) {
2937
+ if (!this._cameraList) this._cameraList = new InputDeviceList();
2938
+ if (!this._microphoneList) this._microphoneList = new InputDeviceList();
2939
+ this._main.dispatchEvent("deviceListUpdate", {
2940
+ ref: this._main,
2941
+ cameraList: this._cameraList.getArray(),
2942
+ microphoneList: this._microphoneList.getArray()
2725
2943
  });
2726
- } else if (this._microphoneList.getSize() == 0) {
2727
- this._main.dispatchEvent("noMicrophoneFound", {
2944
+ this._main.dispatchEvent("inputDeviceError", {
2728
2945
  ref: this._main
2729
2946
  });
2730
- } else {
2731
- this._logger.info(this, "Camera list:");
2732
- for (let i = 0; i < this._cameraList.getSize(); i++) this._logger.info(this, "=> [" + i + "] InputDevice: " + this._cameraList.get(i).getLabel());
2733
- this._logger.info(this, "Microphone list:");
2734
- for (let k = 0; k < this._microphoneList.getSize(); k++) this._logger.info(this, "=> [" + k + "] InputDevice: " + this._microphoneList.get(k).getLabel());
2735
- this._selectedCamera = this.pickCamera();
2736
- this._selectedMicrophone = this.pickMicrophone();
2737
2947
  }
2738
- }).catch(() => {
2739
- this._main.dispatchEvent("inputDeviceError", {
2740
- ref: this._main
2741
- });
2742
2948
  });
2743
2949
  }
2744
2950
  selectCamera(cameraID) {
@@ -2750,9 +2956,15 @@
2750
2956
  break;
2751
2957
  }
2752
2958
  }
2753
- this.closeStream();
2959
+ const wasPublishing = this._publishState === exports.PublishState.PUBLISHED;
2960
+ this.stopCameraStream();
2754
2961
  this._constraints.video.deviceId = this._selectedCamera.getID();
2755
- this.startWebRTC();
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();
2966
+ }
2967
+ });
2756
2968
  }
2757
2969
  selectMicrophone(micID) {
2758
2970
  var _a;
@@ -2763,18 +2975,126 @@
2763
2975
  break;
2764
2976
  }
2765
2977
  }
2766
- this.closeStream();
2978
+ const wasPublishing = this._publishState === exports.PublishState.PUBLISHED;
2979
+ this.stopCameraStream();
2767
2980
  this._constraints.audio = {
2768
2981
  deviceId: this._selectedMicrophone.getID()
2769
2982
  };
2770
- this.startWebRTC();
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();
2987
+ }
2988
+ });
2989
+ }
2990
+ startCamera() {
2991
+ return __awaiter(this, void 0, void 0, function* () {
2992
+ 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;
3006
+ this.onUserMediaError({
3007
+ name: error instanceof Error ? error.name : 'UnknownError',
3008
+ message: error instanceof Error ? error.message : 'Unknown error',
3009
+ deviceType: 'video'
3010
+ });
3011
+ }
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;
3021
+ this.onUserMediaError({
3022
+ name: error instanceof Error ? error.name : 'UnknownError',
3023
+ message: error instanceof Error ? error.message : 'Unknown error',
3024
+ deviceType: 'audio'
3025
+ });
3026
+ }
3027
+ }
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
+ } catch (error) {
3035
+ if (error instanceof Error && !('deviceType' in error)) {
3036
+ this.onUserMediaError({
3037
+ name: error.name,
3038
+ message: error.message
3039
+ });
3040
+ }
3041
+ yield this.grabDevices();
3042
+ }
3043
+ });
3044
+ }
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
+ updateWebRTCStream() {
3055
+ if (!this._peerConnection || !this._stream) {
3056
+ return;
3057
+ }
3058
+ const senders = this._peerConnection.getSenders();
3059
+ senders.forEach(sender => {
3060
+ if (this._peerConnection) this._peerConnection.removeTrack(sender);
3061
+ });
3062
+ this._stream.getTracks().forEach(track => {
3063
+ if (this._stream != null && this._peerConnection) {
3064
+ this._peerConnection.addTrack(track, this._stream);
3065
+ }
3066
+ });
3067
+ }
3068
+ closeStream() {
3069
+ if (this._peerConnection !== undefined && this._peerConnection !== null) {
3070
+ this._peerConnection.close();
3071
+ }
3072
+ this.setPublishState(exports.PublishState.UNPUBLISHED);
2771
3073
  }
2772
3074
  pickCamera() {
2773
3075
  var _a, _b;
2774
- for (let i = 0; i < this._cameraList.getSize(); i++) this._cameraList.get(i).setSelected(false);
3076
+ for (let i = 0; i < this._cameraList.getSize(); i++) {
3077
+ this._cameraList.get(i).setSelected(false);
3078
+ }
2775
3079
  let savedCameraID = (_b = (_a = this._main.getStorageManager()) === null || _a === void 0 ? void 0 : _a.getField("cameraID")) !== null && _b !== void 0 ? _b : null;
2776
- if (this._selectedCamera == null || savedCameraID == null) this._selectedCamera = this._cameraList.get(0);else this.selectCamera(savedCameraID);
2777
- this._selectedCamera.setSelected(true);
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);
3084
+ }
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);
3089
+ this._selectedCamera.setSelected(true);
3090
+ break;
3091
+ }
3092
+ }
3093
+ if (!this._selectedCamera && this._cameraList.getSize() > 0) {
3094
+ this._selectedCamera = this._cameraList.get(0);
3095
+ this._selectedCamera.setSelected(true);
3096
+ }
3097
+ }
2778
3098
  this._main.dispatchEvent("deviceListUpdate", {
2779
3099
  ref: this._main,
2780
3100
  cameraList: this._cameraList.getArray(),
@@ -2784,10 +3104,28 @@
2784
3104
  }
2785
3105
  pickMicrophone() {
2786
3106
  var _a, _b;
2787
- for (let i = 0; i < this._microphoneList.getSize(); i++) this._microphoneList.get(i).setSelected(false);
3107
+ for (let i = 0; i < this._microphoneList.getSize(); i++) {
3108
+ this._microphoneList.get(i).setSelected(false);
3109
+ }
2788
3110
  let savedMicID = (_b = (_a = this._main.getStorageManager()) === null || _a === void 0 ? void 0 : _a.getField("microphoneID")) !== null && _b !== void 0 ? _b : null;
2789
- if (this._selectedMicrophone == null || savedMicID == null) this._selectedMicrophone = this._microphoneList.get(0);else this.selectMicrophone(savedMicID);
2790
- this._selectedMicrophone.setSelected(true);
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;
3122
+ }
3123
+ }
3124
+ if (!this._selectedMicrophone && this._microphoneList.getSize() > 0) {
3125
+ this._selectedMicrophone = this._microphoneList.get(0);
3126
+ this._selectedMicrophone.setSelected(true);
3127
+ }
3128
+ }
2791
3129
  this._main.dispatchEvent("deviceListUpdate", {
2792
3130
  ref: this._main,
2793
3131
  cameraList: this._cameraList.getArray(),
@@ -2795,45 +3133,60 @@
2795
3133
  });
2796
3134
  return this._selectedMicrophone;
2797
3135
  }
2798
- muteMicrophone(microphoneState) {
2799
- this._isMicrophoneMuted = microphoneState;
2800
- if (this._stream != null) {
2801
- if (microphoneState) {
2802
- this._logger.success(this, "WebRTCStreamer1 :: Unmuting microphone");
2803
- } else {
2804
- this._logger.success(this, "WebRTCStreamer1 :: Muting microphone");
2805
- }
2806
- if (this._stream.getAudioTracks() != null) {
2807
- for (let i = 0; i < this._stream.getAudioTracks().length; i++) this._stream.getAudioTracks()[i].enabled = microphoneState;
2808
- }
2809
- this._isMicrophoneMuted = !microphoneState;
3136
+ muteMicrophone(shouldMute) {
3137
+ if (this._isMicrophoneMuted === shouldMute) {
3138
+ return;
3139
+ }
3140
+ this._isMicrophoneMuted = shouldMute;
3141
+ if (this._stream) {
3142
+ this.applyMicrophoneState(!shouldMute);
2810
3143
  } else {
2811
- this._logger.warning(this, "WebRTCStreamer :: Stream object not present!");
3144
+ this._pendingMicrophoneState = !shouldMute;
3145
+ this._logger.info(this, `WebRTCStreamer :: Stream not yet available, storing microphone state (muted: ${shouldMute})`);
2812
3146
  }
2813
3147
  this._main.dispatchEvent("microphoneStateChange", {
2814
3148
  ref: this._main,
2815
3149
  isMuted: this._isMicrophoneMuted
2816
3150
  });
2817
3151
  }
3152
+ applyMicrophoneState(enabled) {
3153
+ if (!this._stream) {
3154
+ this._logger.warning(this, "WebRTCStreamer :: Cannot apply microphone state - stream not available");
3155
+ return;
3156
+ }
3157
+ const audioTracks = this._stream.getAudioTracks();
3158
+ if (audioTracks && audioTracks.length > 0) {
3159
+ this._logger.success(this, `WebRTCStreamer :: ${enabled ? 'Unmuting' : 'Muting'} microphone`);
3160
+ audioTracks.forEach(track => track.enabled = enabled);
3161
+ } else {
3162
+ this._logger.warning(this, "WebRTCStreamer :: No audio tracks found in stream");
3163
+ }
3164
+ }
2818
3165
  isMicrophoneMuted() {
2819
3166
  return this._isMicrophoneMuted;
2820
3167
  }
3168
+ isStreamReady(requireVideo = true, requireAudio = true) {
3169
+ if (!this._stream) {
3170
+ return false;
3171
+ }
3172
+ const videoTracks = this._stream.getVideoTracks();
3173
+ const audioTracks = this._stream.getAudioTracks();
3174
+ const videoReady = !requireVideo || videoTracks.length > 0 && videoTracks[0].readyState === 'live';
3175
+ const audioReady = !requireAudio || audioTracks.length > 0 && audioTracks[0].readyState === 'live';
3176
+ return videoReady && audioReady;
3177
+ }
3178
+ closeWebRTCConnection() {
3179
+ if (this._peerConnection) {
3180
+ this._peerConnection.close();
3181
+ this._peerConnection = null;
3182
+ }
3183
+ }
2821
3184
  onDescriptionError(error) {
2822
3185
  this._logger.info(this, "WebRTCStreamer :: onDescriptionError: " + JSON.stringify(error));
2823
3186
  }
2824
3187
  onIceCandidate(event) {
2825
3188
  if (event.candidate !== null) ;
2826
3189
  }
2827
- closeStream() {
2828
- if (this._stream) {
2829
- this._stream.getTracks().forEach(function (track) {
2830
- track.stop();
2831
- });
2832
- }
2833
- this._soundMeter.detach();
2834
- if (this._peerConnection !== undefined && this._peerConnection !== null) this._peerConnection.close();
2835
- this.setPublishState(exports.PublishState.UNPUBLISHED);
2836
- }
2837
3190
  getCurrentCamera() {
2838
3191
  return this._selectedCamera;
2839
3192
  }
@@ -2861,6 +3214,7 @@
2861
3214
  }
2862
3215
  destroy() {
2863
3216
  var _a;
3217
+ this._pendingMicrophoneState = null;
2864
3218
  this.closeStream();
2865
3219
  (_a = this._selectedPlayer) === null || _a === void 0 ? void 0 : _a.clear();
2866
3220
  this._selectedPlayer = null;
@@ -3169,8 +3523,8 @@
3169
3523
  constructor(streamConfig, autoInitialize = false) {
3170
3524
  super();
3171
3525
  this.DEV_MODE = true;
3172
- this.STREAMER_VERSION = "0.9.0-beta.2";
3173
- this.COMPILE_DATE = "11/29/2024, 6:55:45 PM";
3526
+ this.STREAMER_VERSION = "0.9.0-beta.3";
3527
+ this.COMPILE_DATE = "12/5/2024, 2:36:49 PM";
3174
3528
  this.STREAMER_BRANCH = "Experimental";
3175
3529
  this.STREAMER_PROTOCOL_VERSION = 1;
3176
3530
  this._initialized = false;
@@ -3323,8 +3677,12 @@
3323
3677
  return (_b = (_a = this._playbackController) === null || _a === void 0 ? void 0 : _a.getPublishState()) !== null && _b !== void 0 ? _b : exports.PublishState.NOT_INITIALIZED;
3324
3678
  }
3325
3679
  publish(streamKey) {
3326
- var _a;
3327
- (_a = this._playbackController) === null || _a === void 0 ? void 0 : _a.publish(streamKey);
3680
+ var _a, _b;
3681
+ return (_b = (_a = this._playbackController) === null || _a === void 0 ? void 0 : _a.publish(streamKey)) !== null && _b !== void 0 ? _b : false;
3682
+ }
3683
+ isStreamReady() {
3684
+ var _a, _b;
3685
+ return (_b = (_a = this._playbackController) === null || _a === void 0 ? void 0 : _a.isStreamReady()) !== null && _b !== void 0 ? _b : false;
3328
3686
  }
3329
3687
  unpublish() {
3330
3688
  var _a;
@@ -3382,7 +3740,7 @@
3382
3740
  }
3383
3741
  updateToSize() {
3384
3742
  if (this._initialized) {
3385
- this._stageController.onResize();
3743
+ this._stageController.handleResize();
3386
3744
  }
3387
3745
  }
3388
3746
  makeScreenshot() {
@@ -3454,14 +3812,14 @@
3454
3812
  super.dispatchEvent(eventName, event);
3455
3813
  }
3456
3814
  destroy() {
3457
- var _a, _b, _c;
3815
+ var _a, _b, _c, _d;
3458
3816
  this._logger.warning(this, "Destroying library instance, bye, bye!");
3459
3817
  if (this.DEV_MODE && 'StormStreamerArray' in window) window.StormStreamerArray[this._streamerID] = null;
3460
3818
  this._initialized = false;
3461
3819
  this._isRemoved = true;
3462
- (_a = this._networkController) === null || _a === void 0 ? void 0 : _a.getConnection().destroy();
3463
- (_b = this._stageController) === null || _b === void 0 ? void 0 : _b.destroy();
3464
- (_c = this._playbackController) === null || _c === void 0 ? void 0 : _c.destroy();
3820
+ (_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();
3465
3823
  this.removeAllEventListeners();
3466
3824
  }
3467
3825
  }