@stormstreaming/stormstreamer 0.9.3-beta.0 → 1.0.0-rc.1
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/CHANGELOG.md +6 -0
- package/LICENSE +133 -0
- package/README.md +211 -63
- package/dist/amd/index.js +669 -279
- package/dist/cjs/index.js +9 -9
- package/dist/esm/index.js +9 -9
- package/dist/iife/index.js +5 -5
- package/dist/types/events/StormStreamerEvent.d.ts +141 -0
- package/dist/types/playback/SoundMeter.d.ts +2 -0
- package/dist/types/playback/StreamerController.d.ts +27 -12
- package/dist/types/stage/ScreenElement.d.ts +6 -0
- package/dist/types/stage/StageController.d.ts +4 -0
- package/dist/umd/index.js +5 -5
- package/package.json +6 -2
- package/samples/embed/index_amd.html +50 -0
- package/samples/embed/index_esm.html +46 -0
- package/samples/embed/index_iife.html +45 -0
- package/samples/embed/index_umd.html +45 -0
- package/samples/index.html +492 -0
package/dist/amd/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* StormStreaming JavaScript Streamer
|
|
3
|
-
* Copyright © 2021-
|
|
3
|
+
* Copyright © 2021-2025 Web-Anatomy s.c. All rights reserved.
|
|
4
4
|
* contact@stormstreaming.com
|
|
5
5
|
* https://stormstreaming.com
|
|
6
6
|
*
|
|
7
|
-
* Version: 0.
|
|
8
|
-
* Version:
|
|
7
|
+
* Version: 1.0.0-rc.1
|
|
8
|
+
* Version: 11/17/2025, 10:30:25 AM
|
|
9
9
|
*
|
|
10
10
|
* LEGAL NOTICE:
|
|
11
11
|
* This software is subject to the terms and conditions defined in
|
|
@@ -2500,6 +2500,9 @@
|
|
|
2500
2500
|
* @private
|
|
2501
2501
|
*/
|
|
2502
2502
|
this._isMutedByBrowser = false;
|
|
2503
|
+
// POPRAWKA: Dodane pola do przechowywania referencji do handlerów
|
|
2504
|
+
this._loadedMetadataHandler = null;
|
|
2505
|
+
this._volumeChangeHandler = null;
|
|
2503
2506
|
/**
|
|
2504
2507
|
* Called whenever browser stops playback
|
|
2505
2508
|
*/
|
|
@@ -2555,20 +2558,24 @@
|
|
|
2555
2558
|
* Fires whenever something changes video object volume
|
|
2556
2559
|
* @param event
|
|
2557
2560
|
*/
|
|
2558
|
-
//
|
|
2559
|
-
this.
|
|
2561
|
+
// POPRAWKA: Zapisanie referencji do handlera
|
|
2562
|
+
this._volumeChangeHandler = () => {
|
|
2560
2563
|
this.dispatchVolumeEvent();
|
|
2561
2564
|
};
|
|
2565
|
+
// @ts-ignore
|
|
2566
|
+
this._videoElement.onvolumechange = this._volumeChangeHandler;
|
|
2562
2567
|
this._videoElement.onpause = () => {
|
|
2563
2568
|
// nothing
|
|
2564
2569
|
};
|
|
2565
|
-
|
|
2570
|
+
// POPRAWKA: Zapisanie referencji do handlera
|
|
2571
|
+
this._loadedMetadataHandler = () => {
|
|
2566
2572
|
this._main.dispatchEvent("metadata", {
|
|
2567
2573
|
ref: this._main,
|
|
2568
2574
|
videoWidth: this._videoElement.videoWidth,
|
|
2569
2575
|
videoHeight: this._videoElement.videoHeight
|
|
2570
2576
|
});
|
|
2571
|
-
}
|
|
2577
|
+
};
|
|
2578
|
+
this._videoElement.addEventListener('loadedmetadata', this._loadedMetadataHandler);
|
|
2572
2579
|
/**
|
|
2573
2580
|
* Updates every second,
|
|
2574
2581
|
* @param event
|
|
@@ -2590,7 +2597,9 @@
|
|
|
2590
2597
|
this._videoElement.onended = event => {
|
|
2591
2598
|
this._logger.info(this, "VideoElement :: onended");
|
|
2592
2599
|
};
|
|
2593
|
-
this._videoElement.onplay = () => {
|
|
2600
|
+
this._videoElement.onplay = () => {
|
|
2601
|
+
// nothing
|
|
2602
|
+
};
|
|
2594
2603
|
}
|
|
2595
2604
|
/**
|
|
2596
2605
|
* Sets new volume for playback. It'll also try to store value in a browser memory
|
|
@@ -2647,6 +2656,65 @@
|
|
|
2647
2656
|
getVideoElement() {
|
|
2648
2657
|
return this._videoElement;
|
|
2649
2658
|
}
|
|
2659
|
+
// POPRAWKA: Dodana metoda destroy
|
|
2660
|
+
/**
|
|
2661
|
+
* Destroys the ScreenElement and cleans up all resources
|
|
2662
|
+
*/
|
|
2663
|
+
destroy() {
|
|
2664
|
+
this._logger.info(this, "Destroying ScreenElement...");
|
|
2665
|
+
try {
|
|
2666
|
+
// 1. Usuń event listener z głównej klasy
|
|
2667
|
+
this._main.removeEventListener("playbackForceMute", this.onForceMute);
|
|
2668
|
+
// 2. Zatrzymaj wszelkie aktywne strumienie w elemencie video
|
|
2669
|
+
if (this._videoElement.srcObject instanceof MediaStream) {
|
|
2670
|
+
const stream = this._videoElement.srcObject;
|
|
2671
|
+
stream.getTracks().forEach(track => {
|
|
2672
|
+
track.enabled = false;
|
|
2673
|
+
track.stop();
|
|
2674
|
+
});
|
|
2675
|
+
}
|
|
2676
|
+
this._videoElement.pause();
|
|
2677
|
+
this._videoElement.onload = null;
|
|
2678
|
+
this._videoElement.onstalled = null;
|
|
2679
|
+
this._videoElement.onerror = null;
|
|
2680
|
+
this._videoElement.onvolumechange = null;
|
|
2681
|
+
this._videoElement.onpause = null;
|
|
2682
|
+
this._videoElement.ontimeupdate = null;
|
|
2683
|
+
this._videoElement.onended = null;
|
|
2684
|
+
this._videoElement.onplay = null;
|
|
2685
|
+
this._videoElement.onloadstart = null;
|
|
2686
|
+
this._videoElement.onloadeddata = null;
|
|
2687
|
+
this._videoElement.onloadedmetadata = null;
|
|
2688
|
+
this._videoElement.oncanplay = null;
|
|
2689
|
+
this._videoElement.oncanplaythrough = null;
|
|
2690
|
+
this._videoElement.onprogress = null;
|
|
2691
|
+
this._videoElement.onseeking = null;
|
|
2692
|
+
this._videoElement.onseeked = null;
|
|
2693
|
+
this._videoElement.onwaiting = null;
|
|
2694
|
+
this._videoElement.ondurationchange = null;
|
|
2695
|
+
this._videoElement.onratechange = null;
|
|
2696
|
+
this._videoElement.onsuspend = null;
|
|
2697
|
+
this._videoElement.onemptied = null;
|
|
2698
|
+
if (this._loadedMetadataHandler) {
|
|
2699
|
+
this._videoElement.removeEventListener('loadedmetadata', this._loadedMetadataHandler);
|
|
2700
|
+
this._loadedMetadataHandler = null;
|
|
2701
|
+
}
|
|
2702
|
+
this._videoElement.removeAttribute('src');
|
|
2703
|
+
this._videoElement.srcObject = null;
|
|
2704
|
+
try {
|
|
2705
|
+
this._videoElement.load();
|
|
2706
|
+
} catch (e) {
|
|
2707
|
+
// Ignoruj błędy podczas load()
|
|
2708
|
+
}
|
|
2709
|
+
this._videoElement.removeAttribute('playsinline');
|
|
2710
|
+
this._videoElement.removeAttribute('webkit-playsinline');
|
|
2711
|
+
if (this._videoElement.parentNode) this._videoElement.parentNode.removeChild(this._videoElement);
|
|
2712
|
+
this._volumeChangeHandler = null;
|
|
2713
|
+
this._logger.success(this, "ScreenElement successfully destroyed");
|
|
2714
|
+
} catch (error) {
|
|
2715
|
+
this._logger.error(this, "Error during ScreenElement destroy: " + error);
|
|
2716
|
+
}
|
|
2717
|
+
}
|
|
2650
2718
|
}
|
|
2651
2719
|
|
|
2652
2720
|
/**
|
|
@@ -2741,6 +2809,10 @@
|
|
|
2741
2809
|
*/
|
|
2742
2810
|
this._parentOriginalOverflow = '';
|
|
2743
2811
|
this._debug = false;
|
|
2812
|
+
this._animationFrameId = null;
|
|
2813
|
+
this._isDestroying = false;
|
|
2814
|
+
this._fullscreenChangeHandler = null;
|
|
2815
|
+
this._transitionEndHandler = null;
|
|
2744
2816
|
//------------------------------------------------------------------------//
|
|
2745
2817
|
// FULLSCREEN
|
|
2746
2818
|
//------------------------------------------------------------------------//
|
|
@@ -2795,11 +2867,15 @@
|
|
|
2795
2867
|
if (this._autoResizeEnabled) this.handleResize();
|
|
2796
2868
|
});
|
|
2797
2869
|
}
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2870
|
+
this._fullscreenChangeHandler = this.onFullScreenChange;
|
|
2871
|
+
this._transitionEndHandler = () => {
|
|
2872
|
+
this.handleResize();
|
|
2873
|
+
};
|
|
2874
|
+
document.addEventListener('fullscreenchange', this._fullscreenChangeHandler, false);
|
|
2875
|
+
document.addEventListener('webkitfullscreenchange', this._fullscreenChangeHandler, false);
|
|
2876
|
+
document.addEventListener('mozfullscreenchange', this._fullscreenChangeHandler, false);
|
|
2877
|
+
document.addEventListener('webkitendfullscreen', this._fullscreenChangeHandler, false);
|
|
2878
|
+
this._screenElement.getVideoElement().addEventListener('webkitendfullscreen', this._fullscreenChangeHandler, false);
|
|
2803
2879
|
this._main.addEventListener("metadata", event => {
|
|
2804
2880
|
this._videoWidth = event.videoWidth;
|
|
2805
2881
|
this._videoHeight = event.videoHeight;
|
|
@@ -2861,12 +2937,14 @@
|
|
|
2861
2937
|
let result = false;
|
|
2862
2938
|
if (this._parentElement != null && this._videoContainer != null) {
|
|
2863
2939
|
this._logger.info(this, "Detaching from parent: " + this._videoContainer);
|
|
2940
|
+
// POPRAWKA: Usuń event listener z zapisanym handlerem
|
|
2941
|
+
if (this._transitionEndHandler) {
|
|
2942
|
+
this._parentElement.removeEventListener("transitionend", this._transitionEndHandler);
|
|
2943
|
+
}
|
|
2864
2944
|
this._parentElement.removeChild(this._videoContainer);
|
|
2865
2945
|
if (this._resizeObserver) {
|
|
2866
2946
|
this._resizeObserver.unobserve(this._parentElement);
|
|
2867
|
-
this._resizeObserver.disconnect();
|
|
2868
2947
|
}
|
|
2869
|
-
if (this._autoResizeEnabled) this._parentElement.removeEventListener("transitionend", this.handleResize);
|
|
2870
2948
|
this._main.dispatchEvent("containerChange", {
|
|
2871
2949
|
ref: this._main,
|
|
2872
2950
|
container: null
|
|
@@ -2879,16 +2957,22 @@
|
|
|
2879
2957
|
return result;
|
|
2880
2958
|
}
|
|
2881
2959
|
handleResize() {
|
|
2882
|
-
if (!this._parentElement || this._isResizing) return;
|
|
2960
|
+
if (!this._parentElement || this._isResizing || this._isDestroying) return;
|
|
2961
|
+
// POPRAWKA: Anulowanie poprzedniego requestAnimationFrame
|
|
2962
|
+
if (this._animationFrameId !== null) {
|
|
2963
|
+
cancelAnimationFrame(this._animationFrameId);
|
|
2964
|
+
}
|
|
2883
2965
|
this._isResizing = true;
|
|
2884
2966
|
this._parentOriginalOverflow = this._parentElement.style.overflow;
|
|
2885
2967
|
this._parentElement.style.overflow = 'hidden';
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
// Obliczamy nowe wymiary
|
|
2968
|
+
this._animationFrameId = requestAnimationFrame(() => {
|
|
2969
|
+
if (this._isDestroying) return;
|
|
2889
2970
|
this.calculateNewDimensions();
|
|
2890
|
-
this._parentElement
|
|
2971
|
+
if (this._parentElement) {
|
|
2972
|
+
this._parentElement.style.overflow = this._parentOriginalOverflow;
|
|
2973
|
+
}
|
|
2891
2974
|
this._isResizing = false;
|
|
2975
|
+
this._animationFrameId = null;
|
|
2892
2976
|
if (this._tempContainerWidth !== this._containerWidth || this._tempContainerHeight !== this._containerHeight) {
|
|
2893
2977
|
this._main.dispatchEvent("resizeUpdate", {
|
|
2894
2978
|
ref: this._main,
|
|
@@ -3145,7 +3229,83 @@
|
|
|
3145
3229
|
// CLEANUP
|
|
3146
3230
|
//------------------------------------------------------------------------//
|
|
3147
3231
|
destroy() {
|
|
3148
|
-
|
|
3232
|
+
var _a;
|
|
3233
|
+
this._logger.info(this, "Starting StageController destroy...");
|
|
3234
|
+
this._isDestroying = true;
|
|
3235
|
+
try {
|
|
3236
|
+
// 1. Anuluj animacje
|
|
3237
|
+
if (this._animationFrameId !== null) {
|
|
3238
|
+
cancelAnimationFrame(this._animationFrameId);
|
|
3239
|
+
this._animationFrameId = null;
|
|
3240
|
+
}
|
|
3241
|
+
// 2. Odłącz od rodzica
|
|
3242
|
+
this.detachFromParent();
|
|
3243
|
+
// 3. Zatrzymaj i rozłącz ResizeObserver
|
|
3244
|
+
if (this._resizeObserver) {
|
|
3245
|
+
this._resizeObserver.disconnect();
|
|
3246
|
+
}
|
|
3247
|
+
// 4. Usuń event listenery fullscreen
|
|
3248
|
+
if (this._fullscreenChangeHandler) {
|
|
3249
|
+
document.removeEventListener('fullscreenchange', this._fullscreenChangeHandler);
|
|
3250
|
+
document.removeEventListener('webkitfullscreenchange', this._fullscreenChangeHandler);
|
|
3251
|
+
document.removeEventListener('mozfullscreenchange', this._fullscreenChangeHandler);
|
|
3252
|
+
document.removeEventListener('webkitendfullscreen', this._fullscreenChangeHandler);
|
|
3253
|
+
if ((_a = this._screenElement) === null || _a === void 0 ? void 0 : _a.getVideoElement()) {
|
|
3254
|
+
this._screenElement.getVideoElement().removeEventListener('webkitendfullscreen', this._fullscreenChangeHandler);
|
|
3255
|
+
}
|
|
3256
|
+
this._fullscreenChangeHandler = null;
|
|
3257
|
+
}
|
|
3258
|
+
// 6. Zniszcz ScreenElement
|
|
3259
|
+
if (this._screenElement) {
|
|
3260
|
+
// Wyczyść video element
|
|
3261
|
+
const videoElement = this._screenElement.getVideoElement();
|
|
3262
|
+
if (videoElement) {
|
|
3263
|
+
// Zatrzymaj wszelkie strumienie
|
|
3264
|
+
if (videoElement.srcObject instanceof MediaStream) {
|
|
3265
|
+
videoElement.srcObject.getTracks().forEach(track => {
|
|
3266
|
+
track.enabled = false;
|
|
3267
|
+
track.stop();
|
|
3268
|
+
});
|
|
3269
|
+
}
|
|
3270
|
+
// Wyczyść element
|
|
3271
|
+
videoElement.pause();
|
|
3272
|
+
videoElement.removeAttribute('src');
|
|
3273
|
+
videoElement.srcObject = null;
|
|
3274
|
+
videoElement.load();
|
|
3275
|
+
// Usuń z DOM jeśli jest podłączony
|
|
3276
|
+
if (videoElement.parentNode) {
|
|
3277
|
+
videoElement.parentNode.removeChild(videoElement);
|
|
3278
|
+
}
|
|
3279
|
+
}
|
|
3280
|
+
// Jeśli ScreenElement ma własną metodę destroy, wywołaj ją
|
|
3281
|
+
if (typeof this._screenElement.destroy === 'function') {
|
|
3282
|
+
this._screenElement.destroy();
|
|
3283
|
+
}
|
|
3284
|
+
this._screenElement = null;
|
|
3285
|
+
}
|
|
3286
|
+
// 7. Usuń kontener video z DOM
|
|
3287
|
+
if (this._videoContainer) {
|
|
3288
|
+
if (this._videoContainer.parentNode) {
|
|
3289
|
+
this._videoContainer.parentNode.removeChild(this._videoContainer);
|
|
3290
|
+
}
|
|
3291
|
+
this._videoContainer = null;
|
|
3292
|
+
}
|
|
3293
|
+
// 8. Resetuj zmienne
|
|
3294
|
+
this._containerWidth = 0;
|
|
3295
|
+
this._containerHeight = 0;
|
|
3296
|
+
this._tempContainerWidth = 0;
|
|
3297
|
+
this._tempContainerHeight = 0;
|
|
3298
|
+
this._videoWidth = 0;
|
|
3299
|
+
this._videoHeight = 0;
|
|
3300
|
+
this.isInFullScreenMode = false;
|
|
3301
|
+
this._isResizing = false;
|
|
3302
|
+
this._autoResizeEnabled = false;
|
|
3303
|
+
this._logger.success(this, "StageController successfully destroyed");
|
|
3304
|
+
} catch (error) {
|
|
3305
|
+
this._logger.error(this, "Error during destroy: " + error);
|
|
3306
|
+
} finally {
|
|
3307
|
+
this._isDestroying = false;
|
|
3308
|
+
}
|
|
3149
3309
|
}
|
|
3150
3310
|
}
|
|
3151
3311
|
/**
|
|
@@ -3512,10 +3672,13 @@
|
|
|
3512
3672
|
this._lastEventTime = 0;
|
|
3513
3673
|
this.THROTTLE_INTERVAL = 100; // ms between updates
|
|
3514
3674
|
this._isMonitoring = false;
|
|
3675
|
+
// POPRAWKA: Dodane pole do przechowywania ID animacji
|
|
3676
|
+
this._animationFrameId = null;
|
|
3515
3677
|
// Moving average variables for smoothing
|
|
3516
3678
|
this._instant = 0.0;
|
|
3517
3679
|
this._slow = 0.0;
|
|
3518
3680
|
this._main = main;
|
|
3681
|
+
console.log('SoundMeter: Created new instance');
|
|
3519
3682
|
}
|
|
3520
3683
|
attach(stream) {
|
|
3521
3684
|
if (!stream.getAudioTracks().length) {
|
|
@@ -3542,9 +3705,17 @@
|
|
|
3542
3705
|
}
|
|
3543
3706
|
|
|
3544
3707
|
detach() {
|
|
3545
|
-
|
|
3708
|
+
// POPRAWKA: Zabezpieczenie przed wielokrotnym wywołaniem
|
|
3709
|
+
if (!this._audioContext && !this._analyser && !this._microphone) {
|
|
3710
|
+
return; // Już wyczyszczone
|
|
3711
|
+
}
|
|
3546
3712
|
// Stop monitoring first
|
|
3547
3713
|
this._isMonitoring = false;
|
|
3714
|
+
// POPRAWKA: Anulowanie requestAnimationFrame
|
|
3715
|
+
if (this._animationFrameId !== null) {
|
|
3716
|
+
cancelAnimationFrame(this._animationFrameId);
|
|
3717
|
+
this._animationFrameId = null;
|
|
3718
|
+
}
|
|
3548
3719
|
// Disconnect and cleanup nodes in reverse order
|
|
3549
3720
|
if (this._microphone) {
|
|
3550
3721
|
try {
|
|
@@ -3562,14 +3733,26 @@
|
|
|
3562
3733
|
}
|
|
3563
3734
|
this._analyser = null;
|
|
3564
3735
|
}
|
|
3565
|
-
if (
|
|
3736
|
+
if (this._audioContext) {
|
|
3566
3737
|
try {
|
|
3567
|
-
|
|
3738
|
+
// POPRAWKA: Sprawdzenie przed użyciem w Promise
|
|
3739
|
+
if (this._audioContext.state !== 'closed') {
|
|
3740
|
+
// Zapisz referencję przed asynchroniczną operacją
|
|
3741
|
+
const audioContextRef = this._audioContext;
|
|
3742
|
+
// Najpierw ustaw na null, żeby uniknąć podwójnego wywołania
|
|
3743
|
+
this._audioContext = null;
|
|
3744
|
+
// Teraz bezpiecznie zamknij
|
|
3745
|
+
audioContextRef.suspend().then(() => audioContextRef.close()).catch(e => {
|
|
3746
|
+
console.warn('SoundMeter: Error closing audio context:', e);
|
|
3747
|
+
});
|
|
3748
|
+
} else {
|
|
3749
|
+
this._audioContext = null;
|
|
3750
|
+
}
|
|
3568
3751
|
} catch (e) {
|
|
3569
|
-
console.warn('SoundMeter: Error
|
|
3752
|
+
console.warn('SoundMeter: Error handling audio context:', e);
|
|
3753
|
+
this._audioContext = null;
|
|
3570
3754
|
}
|
|
3571
3755
|
}
|
|
3572
|
-
this._audioContext = null;
|
|
3573
3756
|
this.clear();
|
|
3574
3757
|
}
|
|
3575
3758
|
clear() {
|
|
@@ -3582,7 +3765,11 @@
|
|
|
3582
3765
|
this._isMonitoring = true;
|
|
3583
3766
|
const dataArray = new Float32Array(this._analyser.frequencyBinCount);
|
|
3584
3767
|
const analyze = () => {
|
|
3585
|
-
|
|
3768
|
+
// POPRAWKA: Dodatkowe sprawdzenie przed kontynuacją
|
|
3769
|
+
if (!this._analyser || !this._isMonitoring || !this._audioContext) {
|
|
3770
|
+
this._animationFrameId = null;
|
|
3771
|
+
return;
|
|
3772
|
+
}
|
|
3586
3773
|
const now = Date.now();
|
|
3587
3774
|
try {
|
|
3588
3775
|
// Read time-domain data
|
|
@@ -3612,13 +3799,21 @@
|
|
|
3612
3799
|
} catch (error) {
|
|
3613
3800
|
console.error('SoundMeter: Error during analysis:', error);
|
|
3614
3801
|
this._isMonitoring = false;
|
|
3802
|
+
this._animationFrameId = null;
|
|
3615
3803
|
return;
|
|
3616
3804
|
}
|
|
3617
|
-
// Schedule next analysis
|
|
3618
|
-
|
|
3805
|
+
// Schedule next analysis only if still monitoring
|
|
3806
|
+
if (this._isMonitoring) {
|
|
3807
|
+
this._animationFrameId = requestAnimationFrame(analyze);
|
|
3808
|
+
}
|
|
3619
3809
|
};
|
|
3620
3810
|
// Start analysis loop
|
|
3621
|
-
requestAnimationFrame(analyze);
|
|
3811
|
+
this._animationFrameId = requestAnimationFrame(analyze);
|
|
3812
|
+
}
|
|
3813
|
+
// POPRAWKA: Dodana metoda destroy
|
|
3814
|
+
destroy() {
|
|
3815
|
+
console.log('SoundMeter: Destroying instance');
|
|
3816
|
+
this.detach();
|
|
3622
3817
|
}
|
|
3623
3818
|
}
|
|
3624
3819
|
|
|
@@ -4018,7 +4213,6 @@
|
|
|
4018
4213
|
streamStatusInfo.videoWidth = msgJSON.videoWidth;
|
|
4019
4214
|
streamStatusInfo.videoHeight = msgJSON.videoHeight;
|
|
4020
4215
|
streamStatusInfo.currentBitrate = msgJSON.realBitrate;
|
|
4021
|
-
console.log(streamStatusInfo);
|
|
4022
4216
|
this._main.dispatchEvent("streamStatusUpdate", {
|
|
4023
4217
|
ref: this._main,
|
|
4024
4218
|
streamStatus: streamStatusInfo
|
|
@@ -4224,6 +4418,16 @@
|
|
|
4224
4418
|
this._currentOrientation = ((_a = window.screen.orientation) === null || _a === void 0 ? void 0 : _a.type) || '';
|
|
4225
4419
|
this._statusTimer = null;
|
|
4226
4420
|
this._debug = false;
|
|
4421
|
+
// NOWE POLA DLA ANULOWANIA OPERACJI
|
|
4422
|
+
this._deviceChangeHandler = null;
|
|
4423
|
+
this._orientationChangeHandler = null;
|
|
4424
|
+
this._isDestroying = false;
|
|
4425
|
+
this._cameraAbortController = null;
|
|
4426
|
+
this._microphoneAbortController = null;
|
|
4427
|
+
this._startCameraAbortController = null;
|
|
4428
|
+
this._switchingCamera = false;
|
|
4429
|
+
this._switchingMicrophone = false;
|
|
4430
|
+
this._firstPublish = true;
|
|
4227
4431
|
/**
|
|
4228
4432
|
* Handles device state changes and initiates publishing if appropriate
|
|
4229
4433
|
* @private
|
|
@@ -4240,6 +4444,7 @@
|
|
|
4240
4444
|
*/
|
|
4241
4445
|
this.handleOrientationChange = () => __awaiter(this, void 0, void 0, function* () {
|
|
4242
4446
|
var _d, _e;
|
|
4447
|
+
if (this._isDestroying) return;
|
|
4243
4448
|
// Dajemy chwilę na ustabilizowanie się orientacji
|
|
4244
4449
|
yield new Promise(resolve => setTimeout(resolve, 500));
|
|
4245
4450
|
const newOrientation = ((_d = window.screen.orientation) === null || _d === void 0 ? void 0 : _d.type) || '';
|
|
@@ -4261,7 +4466,7 @@
|
|
|
4261
4466
|
try {
|
|
4262
4467
|
yield this.startCamera();
|
|
4263
4468
|
// Jeśli stream był opublikowany, publikujemy ponownie
|
|
4264
|
-
if (streamKey) {
|
|
4469
|
+
if (streamKey && !this._isDestroying) {
|
|
4265
4470
|
this.publish(streamKey);
|
|
4266
4471
|
}
|
|
4267
4472
|
} catch (error) {
|
|
@@ -4270,7 +4475,9 @@
|
|
|
4270
4475
|
}
|
|
4271
4476
|
}
|
|
4272
4477
|
});
|
|
4273
|
-
this.onServerDisconnect = () => {
|
|
4478
|
+
this.onServerDisconnect = () => {
|
|
4479
|
+
// Implementation
|
|
4480
|
+
};
|
|
4274
4481
|
/**
|
|
4275
4482
|
* Method for handling a situation when a given streamKey is already in use.
|
|
4276
4483
|
*/
|
|
@@ -4463,6 +4670,7 @@
|
|
|
4463
4670
|
this.initializeStream();
|
|
4464
4671
|
this.setupOrientationListener();
|
|
4465
4672
|
this.setupPermissionListeners();
|
|
4673
|
+
this.setupDeviceChangeListener();
|
|
4466
4674
|
if ((_a = this._main.getConfigManager()) === null || _a === void 0 ? void 0 : _a.getSettingsData().autoConnect) {
|
|
4467
4675
|
this._logger.info(this, "Initializing NetworkController (autoConnect is true)");
|
|
4468
4676
|
(_b = this._main.getNetworkController()) === null || _b === void 0 ? void 0 : _b.initialize();
|
|
@@ -4508,6 +4716,7 @@
|
|
|
4508
4716
|
// Initialize device lists
|
|
4509
4717
|
yield this.grabDevices();
|
|
4510
4718
|
} catch (error) {
|
|
4719
|
+
console.log(error);
|
|
4511
4720
|
this._logger.error(this, "Error initializing devices: " + JSON.stringify(error));
|
|
4512
4721
|
yield this.grabDevices();
|
|
4513
4722
|
}
|
|
@@ -4542,6 +4751,46 @@
|
|
|
4542
4751
|
};
|
|
4543
4752
|
});
|
|
4544
4753
|
}
|
|
4754
|
+
/**
|
|
4755
|
+
* Sets up event listener for device changes and handles them appropriately
|
|
4756
|
+
* @private
|
|
4757
|
+
*/
|
|
4758
|
+
setupDeviceChangeListener() {
|
|
4759
|
+
this._deviceChangeHandler = () => __awaiter(this, void 0, void 0, function* () {
|
|
4760
|
+
var _a;
|
|
4761
|
+
if (this._isDestroying) return;
|
|
4762
|
+
if (this._publishState === exports.PublishState.PUBLISHED) {
|
|
4763
|
+
this._logger.info(this, "Device change detected, but already publish - no restarting streamer");
|
|
4764
|
+
return;
|
|
4765
|
+
}
|
|
4766
|
+
this._logger.info(this, "Device change detected, restarting streamer");
|
|
4767
|
+
const streamKey = (_a = this._main.getConfigManager()) === null || _a === void 0 ? void 0 : _a.getStreamData().streamKey;
|
|
4768
|
+
const wasPublishing = this._publishState === exports.PublishState.CONNECTED;
|
|
4769
|
+
try {
|
|
4770
|
+
this.stop();
|
|
4771
|
+
yield new Promise(resolve => setTimeout(resolve, 500));
|
|
4772
|
+
if (!this._isDestroying) {
|
|
4773
|
+
yield this.start();
|
|
4774
|
+
if (wasPublishing && streamKey && !this._isDestroying) {
|
|
4775
|
+
this._logger.info(this, "Resuming publishing after device change");
|
|
4776
|
+
if (this.isStreamReady(true, true)) {
|
|
4777
|
+
this.publish(streamKey);
|
|
4778
|
+
} else {
|
|
4779
|
+
this._logger.warning(this, "Cannot resume publishing - stream not ready after device change");
|
|
4780
|
+
this._main.dispatchEvent("inputDeviceError", {
|
|
4781
|
+
ref: this._main
|
|
4782
|
+
});
|
|
4783
|
+
}
|
|
4784
|
+
}
|
|
4785
|
+
}
|
|
4786
|
+
this._logger.success(this, "Successfully handled device change");
|
|
4787
|
+
} catch (error) {
|
|
4788
|
+
this._logger.error(this, "Error handling device change: " + JSON.stringify(error));
|
|
4789
|
+
this.setInputDeviceState(exports.InputDevicesState.INVALID);
|
|
4790
|
+
}
|
|
4791
|
+
});
|
|
4792
|
+
navigator.mediaDevices.addEventListener('devicechange', this._deviceChangeHandler);
|
|
4793
|
+
}
|
|
4545
4794
|
handlePermissionChange(device, state) {
|
|
4546
4795
|
return __awaiter(this, void 0, void 0, function* () {
|
|
4547
4796
|
if (state === 'denied') {
|
|
@@ -4617,12 +4866,14 @@
|
|
|
4617
4866
|
this.grabDevices();
|
|
4618
4867
|
}
|
|
4619
4868
|
const videoElement = this._main.getStageController().getScreenElement().getVideoElement();
|
|
4620
|
-
videoElement
|
|
4621
|
-
|
|
4622
|
-
|
|
4623
|
-
|
|
4624
|
-
|
|
4625
|
-
|
|
4869
|
+
if (videoElement) {
|
|
4870
|
+
videoElement.srcObject = stream;
|
|
4871
|
+
videoElement.autoplay = true;
|
|
4872
|
+
videoElement.playsInline = true;
|
|
4873
|
+
videoElement.disableRemotePlayback = true;
|
|
4874
|
+
videoElement.controls = false;
|
|
4875
|
+
videoElement.muted = true;
|
|
4876
|
+
}
|
|
4626
4877
|
this.setPublishState(exports.PublishState.INITIALIZED);
|
|
4627
4878
|
}
|
|
4628
4879
|
/**
|
|
@@ -4649,25 +4900,24 @@
|
|
|
4649
4900
|
* @returns {boolean} - true jeśli udało się rozpocząć publikowanie
|
|
4650
4901
|
*/
|
|
4651
4902
|
publish(streamKey) {
|
|
4903
|
+
if (this._debug) this._logger.decoratedLog("Publishing: " + streamKey, "dark-red");
|
|
4904
|
+
this._logger.info(this, "Publish: " + streamKey);
|
|
4652
4905
|
if (this._statusTimer != null) clearInterval(this._statusTimer);
|
|
4653
|
-
if (this._main.getConfigManager().getStreamData().streamKey
|
|
4654
|
-
this.
|
|
4655
|
-
return false;
|
|
4906
|
+
if (this._main.getConfigManager().getStreamData().streamKey != null && !this._firstPublish) {
|
|
4907
|
+
this.unpublish();
|
|
4656
4908
|
}
|
|
4657
|
-
if (this._main.getConfigManager().getStreamData().streamKey != null) this.unpublish();
|
|
4658
4909
|
this._main.getConfigManager().getStreamData().streamKey = streamKey;
|
|
4659
4910
|
if (!this.isStreamReady(true, true)) {
|
|
4660
4911
|
this._logger.warning(this, "Cannot publish - stream not ready (missing video or audio track)");
|
|
4661
4912
|
return false;
|
|
4662
4913
|
}
|
|
4663
|
-
if (this._debug) this._logger.decoratedLog("Publishing: " + streamKey, "dark-red");
|
|
4664
|
-
this._logger.info(this, "Publish: " + streamKey);
|
|
4665
4914
|
this.closeWebRTCConnection();
|
|
4666
4915
|
this._main.dispatchEvent("publish", {
|
|
4667
4916
|
ref: this._main,
|
|
4668
4917
|
streamKey: streamKey
|
|
4669
4918
|
});
|
|
4670
4919
|
this.initializeWebRTC();
|
|
4920
|
+
this._firstPublish = false;
|
|
4671
4921
|
return true;
|
|
4672
4922
|
}
|
|
4673
4923
|
unpublish() {
|
|
@@ -4692,12 +4942,11 @@
|
|
|
4692
4942
|
* @private
|
|
4693
4943
|
*/
|
|
4694
4944
|
setupOrientationListener() {
|
|
4695
|
-
|
|
4945
|
+
this._orientationChangeHandler = this.handleOrientationChange;
|
|
4696
4946
|
if (window.screen && window.screen.orientation) {
|
|
4697
|
-
window.screen.orientation.addEventListener('change', this.
|
|
4947
|
+
window.screen.orientation.addEventListener('change', this._orientationChangeHandler);
|
|
4698
4948
|
} else {
|
|
4699
|
-
|
|
4700
|
-
window.addEventListener('orientationchange', this.handleOrientationChange);
|
|
4949
|
+
window.addEventListener('orientationchange', this._orientationChangeHandler);
|
|
4701
4950
|
}
|
|
4702
4951
|
}
|
|
4703
4952
|
//------------------------------------------------------------------------//
|
|
@@ -4916,6 +5165,7 @@
|
|
|
4916
5165
|
this._selectedMicrophone = this.pickMicrophone();
|
|
4917
5166
|
}
|
|
4918
5167
|
} catch (error) {
|
|
5168
|
+
console.log(error);
|
|
4919
5169
|
this.setInputDeviceState(exports.InputDevicesState.INVALID);
|
|
4920
5170
|
this._logger.error(this, "Errror on grab devices: " + JSON.stringify(error));
|
|
4921
5171
|
}
|
|
@@ -4942,94 +5192,145 @@
|
|
|
4942
5192
|
});
|
|
4943
5193
|
}
|
|
4944
5194
|
/**
|
|
4945
|
-
* Selects camera based on camera device ID
|
|
5195
|
+
* Selects camera based on camera device ID with abort support
|
|
4946
5196
|
* @param cameraID
|
|
4947
5197
|
*/
|
|
4948
5198
|
selectCamera(cameraID) {
|
|
4949
|
-
var _a, _b;
|
|
4950
|
-
|
|
4951
|
-
|
|
4952
|
-
|
|
4953
|
-
|
|
4954
|
-
this.setInputDeviceState(exports.InputDevicesState.UPDATING);
|
|
4955
|
-
this.setCameraState(exports.DeviceState.NOT_INITIALIZED);
|
|
4956
|
-
// Zapamiętaj aktualny stream key i stan publikacji
|
|
4957
|
-
const streamKey = (_a = this._main.getConfigManager()) === null || _a === void 0 ? void 0 : _a.getStreamData().streamKey;
|
|
4958
|
-
const wasPublished = this._publishState === exports.PublishState.CONNECTED;
|
|
4959
|
-
for (let i = 0; i < this._cameraList.getSize(); i++) {
|
|
4960
|
-
if (this._cameraList.get(i).id == cameraID) {
|
|
4961
|
-
this._selectedCamera = this._cameraList.get(i);
|
|
4962
|
-
this._selectedCamera.isSelected = true;
|
|
4963
|
-
(_b = this._main.getStorageManager()) === null || _b === void 0 ? void 0 : _b.saveField("cameraID", this._selectedCamera.id);
|
|
4964
|
-
break;
|
|
5199
|
+
var _a, _b, _c;
|
|
5200
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
5201
|
+
// Anuluj poprzednie przełączanie kamery
|
|
5202
|
+
if (this._cameraAbortController) {
|
|
5203
|
+
this._cameraAbortController.abort();
|
|
4965
5204
|
}
|
|
4966
|
-
|
|
4967
|
-
|
|
4968
|
-
|
|
4969
|
-
|
|
4970
|
-
|
|
4971
|
-
|
|
4972
|
-
this.stopCameraStream();
|
|
4973
|
-
if (this._selectedCamera != null) {
|
|
4974
|
-
// Update constraints with new device
|
|
4975
|
-
this._constraints.video.deviceId = this._selectedCamera.id;
|
|
4976
|
-
// Restart camera stream
|
|
4977
|
-
this.startCamera().then(() => {
|
|
4978
|
-
// Jeśli stream był opublikowany, publikujemy ponownie
|
|
4979
|
-
this.setCameraState(exports.DeviceState.ENABLED);
|
|
4980
|
-
if (this._cameraState == exports.DeviceState.ENABLED && this._microphoneState == exports.DeviceState.ENABLED) this.setInputDeviceState(exports.InputDevicesState.READY);else this.setInputDeviceState(exports.InputDevicesState.INVALID);
|
|
4981
|
-
if (wasPublished && streamKey) {
|
|
4982
|
-
this.publish(streamKey);
|
|
5205
|
+
this._cameraAbortController = new AbortController();
|
|
5206
|
+
const signal = this._cameraAbortController.signal;
|
|
5207
|
+
try {
|
|
5208
|
+
this._switchingCamera = true;
|
|
5209
|
+
for (let i = 0; i < this._cameraList.getSize(); i++) {
|
|
5210
|
+
this._cameraList.get(i).isSelected = false;
|
|
4983
5211
|
}
|
|
4984
|
-
|
|
4985
|
-
|
|
4986
|
-
|
|
4987
|
-
|
|
5212
|
+
this._selectedCamera = null;
|
|
5213
|
+
this.setInputDeviceState(exports.InputDevicesState.UPDATING);
|
|
5214
|
+
this.setCameraState(exports.DeviceState.NOT_INITIALIZED);
|
|
5215
|
+
// Zapamiętaj aktualny stream key i stan publikacji
|
|
5216
|
+
const streamKey = (_a = this._main.getConfigManager()) === null || _a === void 0 ? void 0 : _a.getStreamData().streamKey;
|
|
5217
|
+
const wasPublished = this._publishState === exports.PublishState.CONNECTED;
|
|
5218
|
+
let found = false;
|
|
5219
|
+
for (let i = 0; i < this._cameraList.getSize(); i++) {
|
|
5220
|
+
if (this._cameraList.get(i).id == cameraID) {
|
|
5221
|
+
this._selectedCamera = this._cameraList.get(i);
|
|
5222
|
+
this._selectedCamera.isSelected = true;
|
|
5223
|
+
(_b = this._main.getStorageManager()) === null || _b === void 0 ? void 0 : _b.saveField("cameraID", this._selectedCamera.id);
|
|
5224
|
+
found = true;
|
|
5225
|
+
break;
|
|
5226
|
+
}
|
|
5227
|
+
}
|
|
5228
|
+
this._main.dispatchEvent("deviceListUpdate", {
|
|
5229
|
+
ref: this._main,
|
|
5230
|
+
cameraList: this._cameraList.getArray(),
|
|
5231
|
+
microphoneList: this._microphoneList.getArray()
|
|
5232
|
+
});
|
|
5233
|
+
if (signal.aborted) return;
|
|
5234
|
+
this.stopCameraStream();
|
|
5235
|
+
if (this._selectedCamera != null) {
|
|
5236
|
+
// Update constraints with new device
|
|
5237
|
+
this._constraints.video.deviceId = this._selectedCamera.id;
|
|
5238
|
+
// Sprawdź czy nie anulowano
|
|
5239
|
+
if (signal.aborted) return;
|
|
5240
|
+
// Poczekaj z możliwością anulowania
|
|
5241
|
+
yield new Promise((resolve, reject) => {
|
|
5242
|
+
const timeout = setTimeout(resolve, 500);
|
|
5243
|
+
signal.addEventListener('abort', () => {
|
|
5244
|
+
clearTimeout(timeout);
|
|
5245
|
+
reject(new Error('Aborted'));
|
|
5246
|
+
});
|
|
5247
|
+
});
|
|
5248
|
+
if (signal.aborted) return;
|
|
5249
|
+
// Restart camera stream
|
|
5250
|
+
yield this.startCamera();
|
|
5251
|
+
this.setCameraState(exports.DeviceState.ENABLED);
|
|
5252
|
+
if (this._cameraState == exports.DeviceState.ENABLED && this._microphoneState == exports.DeviceState.ENABLED) this.setInputDeviceState(exports.InputDevicesState.READY);else this.setInputDeviceState(exports.InputDevicesState.INVALID);
|
|
5253
|
+
if (wasPublished && streamKey && !signal.aborted) {
|
|
5254
|
+
this.publish(streamKey);
|
|
5255
|
+
}
|
|
5256
|
+
} else {
|
|
5257
|
+
this.setInputDeviceState(exports.InputDevicesState.INVALID);
|
|
5258
|
+
}
|
|
5259
|
+
} catch (error) {
|
|
5260
|
+
if (error.message !== 'Aborted') {
|
|
5261
|
+
this._logger.error(this, 'Error switching camera: ' + error);
|
|
5262
|
+
this.setInputDeviceState(exports.InputDevicesState.INVALID);
|
|
5263
|
+
}
|
|
5264
|
+
} finally {
|
|
5265
|
+
this._switchingCamera = false;
|
|
5266
|
+
if (((_c = this._cameraAbortController) === null || _c === void 0 ? void 0 : _c.signal) === signal) {
|
|
5267
|
+
this._cameraAbortController = null;
|
|
5268
|
+
}
|
|
5269
|
+
}
|
|
5270
|
+
});
|
|
4988
5271
|
}
|
|
4989
5272
|
/**
|
|
4990
|
-
* Method tries to select (change) microphone based on its system ID
|
|
5273
|
+
* Method tries to select (change) microphone based on its system ID with abort support
|
|
4991
5274
|
* @param micID
|
|
4992
5275
|
*/
|
|
4993
5276
|
selectMicrophone(micID) {
|
|
4994
|
-
var _a, _b;
|
|
5277
|
+
var _a, _b, _c;
|
|
4995
5278
|
return __awaiter(this, void 0, void 0, function* () {
|
|
4996
|
-
|
|
4997
|
-
|
|
5279
|
+
// Anuluj poprzednie przełączanie mikrofonu
|
|
5280
|
+
if (this._microphoneAbortController) {
|
|
5281
|
+
this._microphoneAbortController.abort();
|
|
4998
5282
|
}
|
|
4999
|
-
this.
|
|
5000
|
-
this.
|
|
5001
|
-
|
|
5002
|
-
|
|
5003
|
-
|
|
5004
|
-
|
|
5005
|
-
const wasPublished = this._publishState === exports.PublishState.CONNECTED;
|
|
5006
|
-
// Znajdź i zapisz wybrany mikrofon
|
|
5007
|
-
for (let i = 0; i < this._microphoneList.getSize(); i++) {
|
|
5008
|
-
if (this._microphoneList.get(i).id == micID) {
|
|
5009
|
-
this._selectedMicrophone = this._microphoneList.get(i);
|
|
5010
|
-
this._selectedMicrophone.isSelected = true;
|
|
5011
|
-
(_b = this._main.getStorageManager()) === null || _b === void 0 ? void 0 : _b.saveField("microphoneID", this._selectedMicrophone.id);
|
|
5012
|
-
break;
|
|
5283
|
+
this._microphoneAbortController = new AbortController();
|
|
5284
|
+
const signal = this._microphoneAbortController.signal;
|
|
5285
|
+
try {
|
|
5286
|
+
this._switchingMicrophone = true;
|
|
5287
|
+
for (let i = 0; i < this._microphoneList.getSize(); i++) {
|
|
5288
|
+
this._microphoneList.get(i).isSelected = false;
|
|
5013
5289
|
}
|
|
5014
|
-
|
|
5015
|
-
|
|
5016
|
-
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
|
|
5021
|
-
|
|
5022
|
-
|
|
5023
|
-
|
|
5024
|
-
|
|
5025
|
-
|
|
5026
|
-
|
|
5027
|
-
|
|
5028
|
-
|
|
5290
|
+
this._selectedMicrophone = null;
|
|
5291
|
+
this.setInputDeviceState(exports.InputDevicesState.UPDATING);
|
|
5292
|
+
this.setMicrophoneState(exports.DeviceState.NOT_INITIALIZED);
|
|
5293
|
+
this._logger.info(this, "Selecting microphone: " + micID);
|
|
5294
|
+
// Zapamiętaj aktualny stream key i stan publikacji
|
|
5295
|
+
const streamKey = (_a = this._main.getConfigManager()) === null || _a === void 0 ? void 0 : _a.getStreamData().streamKey;
|
|
5296
|
+
const wasPublished = this._publishState === exports.PublishState.CONNECTED;
|
|
5297
|
+
// Znajdź i zapisz wybrany mikrofon
|
|
5298
|
+
for (let i = 0; i < this._microphoneList.getSize(); i++) {
|
|
5299
|
+
if (this._microphoneList.get(i).id == micID) {
|
|
5300
|
+
this._selectedMicrophone = this._microphoneList.get(i);
|
|
5301
|
+
this._selectedMicrophone.isSelected = true;
|
|
5302
|
+
(_b = this._main.getStorageManager()) === null || _b === void 0 ? void 0 : _b.saveField("microphoneID", this._selectedMicrophone.id);
|
|
5303
|
+
break;
|
|
5304
|
+
}
|
|
5305
|
+
}
|
|
5306
|
+
// Zawsze wysyłamy aktualizację list urządzeń
|
|
5307
|
+
this._main.dispatchEvent("deviceListUpdate", {
|
|
5308
|
+
ref: this._main,
|
|
5309
|
+
cameraList: this._cameraList.getArray(),
|
|
5310
|
+
microphoneList: this._microphoneList.getArray()
|
|
5029
5311
|
});
|
|
5030
|
-
|
|
5031
|
-
|
|
5032
|
-
|
|
5312
|
+
if (signal.aborted) return;
|
|
5313
|
+
// Odłącz SoundMeter przed zmianą strumienia
|
|
5314
|
+
this._soundMeter.detach();
|
|
5315
|
+
// Zamknij istniejące połączenie WebRTC
|
|
5316
|
+
this.closeWebRTCConnection();
|
|
5317
|
+
// Zatrzymaj obecny strumień
|
|
5318
|
+
if (this._stream) {
|
|
5319
|
+
this._stream.getTracks().forEach(track => {
|
|
5320
|
+
track.stop();
|
|
5321
|
+
});
|
|
5322
|
+
this._stream = null;
|
|
5323
|
+
}
|
|
5324
|
+
if (signal.aborted) return;
|
|
5325
|
+
// Poczekaj z możliwością anulowania
|
|
5326
|
+
yield new Promise((resolve, reject) => {
|
|
5327
|
+
const timeout = setTimeout(resolve, 500);
|
|
5328
|
+
signal.addEventListener('abort', () => {
|
|
5329
|
+
clearTimeout(timeout);
|
|
5330
|
+
reject(new Error('Aborted'));
|
|
5331
|
+
});
|
|
5332
|
+
});
|
|
5333
|
+
if (signal.aborted) return;
|
|
5033
5334
|
// Rozpocznij wszystko od nowa
|
|
5034
5335
|
yield this.startCamera();
|
|
5035
5336
|
this.setMicrophoneState(exports.DeviceState.ENABLED);
|
|
@@ -5039,25 +5340,38 @@
|
|
|
5039
5340
|
this.setInputDeviceState(exports.InputDevicesState.INVALID);
|
|
5040
5341
|
}
|
|
5041
5342
|
// Jeśli stream był opublikowany, publikujemy ponownie
|
|
5042
|
-
if (wasPublished && streamKey) {
|
|
5343
|
+
if (wasPublished && streamKey && !signal.aborted) {
|
|
5043
5344
|
this.publish(streamKey);
|
|
5044
5345
|
}
|
|
5045
5346
|
} catch (error) {
|
|
5046
|
-
|
|
5047
|
-
|
|
5048
|
-
|
|
5049
|
-
|
|
5050
|
-
|
|
5347
|
+
if (error.message !== 'Aborted') {
|
|
5348
|
+
console.error("Error changing microphone:", error);
|
|
5349
|
+
this._main.dispatchEvent("inputDeviceError", {
|
|
5350
|
+
ref: this._main
|
|
5351
|
+
});
|
|
5352
|
+
this.setInputDeviceState(exports.InputDevicesState.INVALID);
|
|
5353
|
+
}
|
|
5354
|
+
} finally {
|
|
5355
|
+
this._switchingMicrophone = false;
|
|
5356
|
+
if (((_c = this._microphoneAbortController) === null || _c === void 0 ? void 0 : _c.signal) === signal) {
|
|
5357
|
+
this._microphoneAbortController = null;
|
|
5358
|
+
}
|
|
5051
5359
|
}
|
|
5052
5360
|
});
|
|
5053
5361
|
}
|
|
5054
5362
|
/**
|
|
5055
|
-
* This method tries to start a camera
|
|
5056
|
-
*
|
|
5363
|
+
* This method tries to start a camera with abort support
|
|
5057
5364
|
* @private
|
|
5058
5365
|
*/
|
|
5059
5366
|
startCamera() {
|
|
5367
|
+
var _a;
|
|
5060
5368
|
return __awaiter(this, void 0, void 0, function* () {
|
|
5369
|
+
// Anuluj poprzednie uruchamianie kamery
|
|
5370
|
+
if (this._startCameraAbortController) {
|
|
5371
|
+
this._startCameraAbortController.abort();
|
|
5372
|
+
}
|
|
5373
|
+
this._startCameraAbortController = new AbortController();
|
|
5374
|
+
const signal = this._startCameraAbortController.signal;
|
|
5061
5375
|
if (this._stream) {
|
|
5062
5376
|
this._stream.getTracks().forEach(track => {
|
|
5063
5377
|
track.stop();
|
|
@@ -5077,11 +5391,18 @@
|
|
|
5077
5391
|
}
|
|
5078
5392
|
} : false
|
|
5079
5393
|
};
|
|
5394
|
+
if (signal.aborted) return;
|
|
5080
5395
|
try {
|
|
5081
5396
|
const stream = yield navigator.mediaDevices.getUserMedia(constraints);
|
|
5397
|
+
if (signal.aborted) {
|
|
5398
|
+
// Jeśli anulowano, zatrzymaj nowo utworzony strumień
|
|
5399
|
+
stream.getTracks().forEach(track => track.stop());
|
|
5400
|
+
return;
|
|
5401
|
+
}
|
|
5082
5402
|
this._stream = stream;
|
|
5083
5403
|
this.onCameraStreamSuccess(this._stream);
|
|
5084
5404
|
} catch (error) {
|
|
5405
|
+
if (signal.aborted) return;
|
|
5085
5406
|
if (constraints.video) {
|
|
5086
5407
|
this.onUserMediaError({
|
|
5087
5408
|
name: error.name || 'Error',
|
|
@@ -5101,6 +5422,10 @@
|
|
|
5101
5422
|
} catch (error) {
|
|
5102
5423
|
console.error("Error in startCamera:", error);
|
|
5103
5424
|
yield this.grabDevices();
|
|
5425
|
+
} finally {
|
|
5426
|
+
if (((_a = this._startCameraAbortController) === null || _a === void 0 ? void 0 : _a.signal) === signal) {
|
|
5427
|
+
this._startCameraAbortController = null;
|
|
5428
|
+
}
|
|
5104
5429
|
}
|
|
5105
5430
|
});
|
|
5106
5431
|
}
|
|
@@ -5132,7 +5457,6 @@
|
|
|
5132
5457
|
}
|
|
5133
5458
|
/**
|
|
5134
5459
|
* This method selects a camera based on previous uses or saved IDs
|
|
5135
|
-
*
|
|
5136
5460
|
* @private
|
|
5137
5461
|
*/
|
|
5138
5462
|
pickCamera() {
|
|
@@ -5202,7 +5526,6 @@
|
|
|
5202
5526
|
}
|
|
5203
5527
|
/**
|
|
5204
5528
|
* This method selects a microphone based on previous uses or saved IDs
|
|
5205
|
-
*
|
|
5206
5529
|
* @private
|
|
5207
5530
|
*/
|
|
5208
5531
|
pickMicrophone() {
|
|
@@ -5303,7 +5626,6 @@
|
|
|
5303
5626
|
}
|
|
5304
5627
|
/**
|
|
5305
5628
|
* Applies the microphone state to the actual stream tracks
|
|
5306
|
-
*
|
|
5307
5629
|
* @param enabled true to enable tracks, false to disable
|
|
5308
5630
|
* @private
|
|
5309
5631
|
*/
|
|
@@ -5322,7 +5644,6 @@
|
|
|
5322
5644
|
}
|
|
5323
5645
|
/**
|
|
5324
5646
|
* This methods is a final check whenever we're ready to publish a stream
|
|
5325
|
-
*
|
|
5326
5647
|
* @param requireVideo - whenever video track is required
|
|
5327
5648
|
* @param requireAudio - whenever audio track is required
|
|
5328
5649
|
* @returns {boolean} true if stream is ready for publishing
|
|
@@ -5343,6 +5664,47 @@
|
|
|
5343
5664
|
this._peerConnection = null;
|
|
5344
5665
|
}
|
|
5345
5666
|
}
|
|
5667
|
+
// Asynchroniczna wersja do użycia w destroy
|
|
5668
|
+
closeWebRTCConnectionAsync() {
|
|
5669
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
5670
|
+
if (this._peerConnection) {
|
|
5671
|
+
try {
|
|
5672
|
+
// Usuń event handlery
|
|
5673
|
+
this._peerConnection.onicecandidate = null;
|
|
5674
|
+
this._peerConnection.onconnectionstatechange = null;
|
|
5675
|
+
this._peerConnection.onnegotiationneeded = null;
|
|
5676
|
+
this._peerConnection.oniceconnectionstatechange = null;
|
|
5677
|
+
this._peerConnection.onicegatheringstatechange = null;
|
|
5678
|
+
this._peerConnection.onsignalingstatechange = null;
|
|
5679
|
+
this._peerConnection.ontrack = null;
|
|
5680
|
+
// Zatrzymaj wszystkie transceivery
|
|
5681
|
+
const transceivers = this._peerConnection.getTransceivers();
|
|
5682
|
+
for (const transceiver of transceivers) {
|
|
5683
|
+
if (transceiver.stop) {
|
|
5684
|
+
transceiver.stop();
|
|
5685
|
+
}
|
|
5686
|
+
}
|
|
5687
|
+
// Usuń wszystkie tracks
|
|
5688
|
+
const senders = this._peerConnection.getSenders();
|
|
5689
|
+
for (const sender of senders) {
|
|
5690
|
+
if (sender.track) {
|
|
5691
|
+
sender.track.enabled = false;
|
|
5692
|
+
sender.track.stop();
|
|
5693
|
+
}
|
|
5694
|
+
this._peerConnection.removeTrack(sender);
|
|
5695
|
+
}
|
|
5696
|
+
// Zamknij połączenie
|
|
5697
|
+
this._peerConnection.close();
|
|
5698
|
+
// Poczekaj na zamknięcie
|
|
5699
|
+
yield new Promise(resolve => setTimeout(resolve, 100));
|
|
5700
|
+
} catch (e) {
|
|
5701
|
+
this._logger.error(this, 'Error closing peer connection: ' + e);
|
|
5702
|
+
} finally {
|
|
5703
|
+
this._peerConnection = null;
|
|
5704
|
+
}
|
|
5705
|
+
}
|
|
5706
|
+
});
|
|
5707
|
+
}
|
|
5346
5708
|
onDescriptionError(error) {
|
|
5347
5709
|
this._logger.info(this, "WebRTCStreamer :: onDescriptionError: " + JSON.stringify(error));
|
|
5348
5710
|
}
|
|
@@ -5455,110 +5817,101 @@
|
|
|
5455
5817
|
}
|
|
5456
5818
|
}
|
|
5457
5819
|
/**
|
|
5458
|
-
*
|
|
5820
|
+
* Ulepszona metoda czyszczenia strumienia
|
|
5821
|
+
* @private
|
|
5822
|
+
*/
|
|
5823
|
+
cleanupMediaStream(stream) {
|
|
5824
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
5825
|
+
if (!stream) return;
|
|
5826
|
+
const tracks = stream.getTracks();
|
|
5827
|
+
for (const track of tracks) {
|
|
5828
|
+
try {
|
|
5829
|
+
// Usuń wszystkie event listenery
|
|
5830
|
+
track.onended = null;
|
|
5831
|
+
track.onmute = null;
|
|
5832
|
+
track.onunmute = null;
|
|
5833
|
+
// Wyłącz track
|
|
5834
|
+
track.enabled = false;
|
|
5835
|
+
// Zatrzymaj track
|
|
5836
|
+
track.stop();
|
|
5837
|
+
this._logger.info(this, `Track ${track.kind} stopped. ReadyState: ${track.readyState}`);
|
|
5838
|
+
} catch (e) {
|
|
5839
|
+
this._logger.error(this, `Error stopping track: ${e}`);
|
|
5840
|
+
}
|
|
5841
|
+
}
|
|
5842
|
+
// Poczekaj na cleanup
|
|
5843
|
+
yield new Promise(resolve => setTimeout(resolve, 50));
|
|
5844
|
+
});
|
|
5845
|
+
}
|
|
5846
|
+
/**
|
|
5847
|
+
* Method stops streaming for all streams with proper cleanup
|
|
5459
5848
|
* @private
|
|
5460
5849
|
*/
|
|
5461
5850
|
forceStopAllStreams() {
|
|
5462
5851
|
var _a, _b;
|
|
5463
|
-
|
|
5464
|
-
|
|
5465
|
-
|
|
5466
|
-
|
|
5467
|
-
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
this._logger.info(this, `Stopping ${tracks.length} tracks from main stream`);
|
|
5472
|
-
tracks.forEach(track => {
|
|
5473
|
-
try {
|
|
5474
|
-
track.enabled = false;
|
|
5475
|
-
track.stop();
|
|
5476
|
-
this._logger.info(this, `Stopped ${track.kind} track: ${track.id}`);
|
|
5477
|
-
} catch (e) {
|
|
5478
|
-
this._logger.error(this, `Error stopping ${track.kind} track: ${e}`);
|
|
5479
|
-
}
|
|
5480
|
-
});
|
|
5481
|
-
this._stream = null;
|
|
5482
|
-
} catch (e) {
|
|
5483
|
-
this._logger.error(this, 'Error stopping main stream');
|
|
5484
|
-
}
|
|
5485
|
-
}
|
|
5486
|
-
// 3. Clean up video element
|
|
5487
|
-
try {
|
|
5488
|
-
const videoElement = (_b = (_a = this._main.getStageController()) === null || _a === void 0 ? void 0 : _a.getScreenElement()) === null || _b === void 0 ? void 0 : _b.getVideoElement();
|
|
5489
|
-
if (videoElement && videoElement.srcObject instanceof MediaStream) {
|
|
5490
|
-
const videoTracks = videoElement.srcObject.getTracks();
|
|
5491
|
-
if (videoTracks.length > 0) {
|
|
5492
|
-
this._logger.info(this, `Stopping ${videoTracks.length} tracks from video element`);
|
|
5493
|
-
videoTracks.forEach(track => {
|
|
5494
|
-
try {
|
|
5495
|
-
track.enabled = false;
|
|
5496
|
-
track.stop();
|
|
5497
|
-
} catch (e) {
|
|
5498
|
-
this._logger.error(this, `Error stopping video element track: ${e}`);
|
|
5499
|
-
}
|
|
5500
|
-
});
|
|
5852
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
5853
|
+
this._logger.info(this, "Force stopping all streams...");
|
|
5854
|
+
// 1. Odłączenie i zniszczenie SoundMeter
|
|
5855
|
+
if (this._soundMeter) {
|
|
5856
|
+
try {
|
|
5857
|
+
this._soundMeter.destroy();
|
|
5858
|
+
} catch (e) {
|
|
5859
|
+
this._logger.error(this, 'Error destroying SoundMeter: ' + e);
|
|
5501
5860
|
}
|
|
5502
|
-
videoElement.srcObject = null;
|
|
5503
|
-
videoElement.removeAttribute('src');
|
|
5504
|
-
videoElement.load();
|
|
5505
5861
|
}
|
|
5506
|
-
|
|
5507
|
-
this.
|
|
5508
|
-
|
|
5509
|
-
|
|
5510
|
-
|
|
5862
|
+
// 2. Zatrzymanie głównego strumienia
|
|
5863
|
+
if (this._stream) {
|
|
5864
|
+
yield this.cleanupMediaStream(this._stream);
|
|
5865
|
+
this._stream = null;
|
|
5866
|
+
}
|
|
5867
|
+
// 3. Czyszczenie elementu video
|
|
5511
5868
|
try {
|
|
5512
|
-
|
|
5513
|
-
if (
|
|
5514
|
-
|
|
5515
|
-
|
|
5516
|
-
|
|
5517
|
-
|
|
5518
|
-
|
|
5519
|
-
|
|
5520
|
-
|
|
5521
|
-
|
|
5522
|
-
|
|
5523
|
-
|
|
5524
|
-
|
|
5525
|
-
|
|
5526
|
-
|
|
5527
|
-
|
|
5528
|
-
}
|
|
5529
|
-
});
|
|
5869
|
+
const videoElement = (_b = (_a = this._main.getStageController()) === null || _a === void 0 ? void 0 : _a.getScreenElement()) === null || _b === void 0 ? void 0 : _b.getVideoElement();
|
|
5870
|
+
if (videoElement) {
|
|
5871
|
+
// Zatrzymaj strumień w elemencie video
|
|
5872
|
+
if (videoElement.srcObject instanceof MediaStream) {
|
|
5873
|
+
yield this.cleanupMediaStream(videoElement.srcObject);
|
|
5874
|
+
}
|
|
5875
|
+
// Wyczyść element video
|
|
5876
|
+
videoElement.pause();
|
|
5877
|
+
videoElement.removeAttribute('src');
|
|
5878
|
+
videoElement.srcObject = null;
|
|
5879
|
+
videoElement.load();
|
|
5880
|
+
// Usuń event listenery
|
|
5881
|
+
videoElement.onloadedmetadata = null;
|
|
5882
|
+
videoElement.onloadeddata = null;
|
|
5883
|
+
videoElement.oncanplay = null;
|
|
5884
|
+
videoElement.onerror = null;
|
|
5530
5885
|
}
|
|
5531
|
-
// Now close the peer connection
|
|
5532
|
-
this._peerConnection.close();
|
|
5533
|
-
this._peerConnection = null;
|
|
5534
5886
|
} catch (e) {
|
|
5535
|
-
this._logger.error(this, 'Error
|
|
5887
|
+
this._logger.error(this, 'Error cleaning video element: ' + e);
|
|
5536
5888
|
}
|
|
5537
|
-
|
|
5538
|
-
|
|
5539
|
-
|
|
5540
|
-
|
|
5541
|
-
|
|
5542
|
-
|
|
5543
|
-
|
|
5544
|
-
|
|
5545
|
-
navigator.mediaDevices.getUserMedia({
|
|
5546
|
-
audio: false,
|
|
5547
|
-
video: false
|
|
5548
|
-
}).then(() => {
|
|
5549
|
-
// This is just to trigger a device check
|
|
5550
|
-
this._logger.info(this, "Performed final device check");
|
|
5551
|
-
}).catch(() => {
|
|
5552
|
-
// Ignore errors from this check
|
|
5553
|
-
});
|
|
5554
|
-
} catch (e) {
|
|
5555
|
-
// Ignore errors from final check
|
|
5556
|
-
}
|
|
5889
|
+
// 4. Zamknięcie WebRTC
|
|
5890
|
+
yield this.closeWebRTCConnectionAsync();
|
|
5891
|
+
// 5. Resetuj zmienne
|
|
5892
|
+
this._selectedCamera = null;
|
|
5893
|
+
this._selectedMicrophone = null;
|
|
5894
|
+
this._pendingMicrophoneState = null;
|
|
5895
|
+
this._logger.info(this, "Force stop all streams completed");
|
|
5896
|
+
});
|
|
5557
5897
|
}
|
|
5558
5898
|
/**
|
|
5559
5899
|
* Stops all streaming operations and cleans up resources
|
|
5560
5900
|
*/
|
|
5561
5901
|
stop() {
|
|
5902
|
+
// Anuluj wszystkie aktywne operacje
|
|
5903
|
+
if (this._cameraAbortController) {
|
|
5904
|
+
this._cameraAbortController.abort();
|
|
5905
|
+
this._cameraAbortController = null;
|
|
5906
|
+
}
|
|
5907
|
+
if (this._microphoneAbortController) {
|
|
5908
|
+
this._microphoneAbortController.abort();
|
|
5909
|
+
this._microphoneAbortController = null;
|
|
5910
|
+
}
|
|
5911
|
+
if (this._startCameraAbortController) {
|
|
5912
|
+
this._startCameraAbortController.abort();
|
|
5913
|
+
this._startCameraAbortController = null;
|
|
5914
|
+
}
|
|
5562
5915
|
// Stop status connection and clear timer
|
|
5563
5916
|
if (this._statusConnection) {
|
|
5564
5917
|
this._statusConnection.destroy();
|
|
@@ -5617,60 +5970,96 @@
|
|
|
5617
5970
|
});
|
|
5618
5971
|
}
|
|
5619
5972
|
/**
|
|
5620
|
-
* Method used for destroying everything (one-time use)
|
|
5973
|
+
* Method used for destroying everything (one-time use) with proper cleanup
|
|
5621
5974
|
*/
|
|
5622
5975
|
destroy() {
|
|
5623
|
-
|
|
5624
|
-
|
|
5625
|
-
|
|
5626
|
-
|
|
5627
|
-
|
|
5628
|
-
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
|
|
5632
|
-
|
|
5633
|
-
|
|
5634
|
-
|
|
5635
|
-
|
|
5636
|
-
|
|
5637
|
-
|
|
5638
|
-
|
|
5639
|
-
|
|
5640
|
-
|
|
5641
|
-
|
|
5642
|
-
|
|
5643
|
-
|
|
5644
|
-
|
|
5645
|
-
|
|
5646
|
-
|
|
5647
|
-
|
|
5648
|
-
|
|
5649
|
-
|
|
5650
|
-
|
|
5651
|
-
|
|
5652
|
-
|
|
5653
|
-
|
|
5654
|
-
|
|
5655
|
-
|
|
5656
|
-
|
|
5657
|
-
|
|
5658
|
-
|
|
5659
|
-
|
|
5660
|
-
|
|
5661
|
-
|
|
5662
|
-
|
|
5663
|
-
|
|
5664
|
-
|
|
5665
|
-
|
|
5666
|
-
|
|
5667
|
-
|
|
5668
|
-
|
|
5669
|
-
|
|
5670
|
-
|
|
5671
|
-
|
|
5672
|
-
|
|
5673
|
-
|
|
5976
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
5977
|
+
this._logger.info(this, "Starting StreamerController destroy...");
|
|
5978
|
+
this._isDestroying = true;
|
|
5979
|
+
try {
|
|
5980
|
+
// 1. Anuluj wszystkie aktywne operacje
|
|
5981
|
+
if (this._cameraAbortController) {
|
|
5982
|
+
this._cameraAbortController.abort();
|
|
5983
|
+
this._cameraAbortController = null;
|
|
5984
|
+
}
|
|
5985
|
+
if (this._microphoneAbortController) {
|
|
5986
|
+
this._microphoneAbortController.abort();
|
|
5987
|
+
this._microphoneAbortController = null;
|
|
5988
|
+
}
|
|
5989
|
+
if (this._startCameraAbortController) {
|
|
5990
|
+
this._startCameraAbortController.abort();
|
|
5991
|
+
this._startCameraAbortController = null;
|
|
5992
|
+
}
|
|
5993
|
+
// 2. Zatrzymaj timery
|
|
5994
|
+
if (this._statusTimer != null) {
|
|
5995
|
+
clearInterval(this._statusTimer);
|
|
5996
|
+
this._statusTimer = null;
|
|
5997
|
+
}
|
|
5998
|
+
if (this._restartTimer != null) {
|
|
5999
|
+
clearInterval(this._restartTimer);
|
|
6000
|
+
this._restartTimer = null;
|
|
6001
|
+
}
|
|
6002
|
+
clearTimeout(this._publishTimer);
|
|
6003
|
+
// 3. Usuń event listenery urządzeń
|
|
6004
|
+
if (this._deviceChangeHandler) {
|
|
6005
|
+
navigator.mediaDevices.removeEventListener('devicechange', this._deviceChangeHandler);
|
|
6006
|
+
this._deviceChangeHandler = null;
|
|
6007
|
+
}
|
|
6008
|
+
// 4. Usuń event listenery orientacji
|
|
6009
|
+
if (this._orientationChangeHandler) {
|
|
6010
|
+
if (window.screen && window.screen.orientation) {
|
|
6011
|
+
window.screen.orientation.removeEventListener('change', this._orientationChangeHandler);
|
|
6012
|
+
} else {
|
|
6013
|
+
window.removeEventListener('orientationchange', this._orientationChangeHandler);
|
|
6014
|
+
}
|
|
6015
|
+
this._orientationChangeHandler = null;
|
|
6016
|
+
}
|
|
6017
|
+
// 5. Usuń pozostałe event listenery
|
|
6018
|
+
try {
|
|
6019
|
+
this._main.removeEventListener("serverConnect", this.onServerConnect);
|
|
6020
|
+
this._main.removeEventListener("serverDisconnect", this.onServerDisconnect);
|
|
6021
|
+
this._main.removeEventListener("streamKeyInUse", this.onStreamKeyTaken);
|
|
6022
|
+
this._main.removeEventListener("statusServerConnect", this.onStatusServerConnect);
|
|
6023
|
+
this._main.removeEventListener("statusServerDisconnect", this.onStatusServerDisconnect);
|
|
6024
|
+
this._main.removeEventListener("streamStatusUpdate", this.onStreamStatsUpdate);
|
|
6025
|
+
this._main.removeEventListener("deviceStateChange", this.onDeviceStateChange);
|
|
6026
|
+
document.removeEventListener("visibilitychange", this.visibilityChange);
|
|
6027
|
+
window.removeEventListener("blur", this.onWindowBlur);
|
|
6028
|
+
window.removeEventListener("focus", this.onWindowFocus);
|
|
6029
|
+
} catch (e) {
|
|
6030
|
+
this._logger.error(this, 'Error removing event listeners: ' + e);
|
|
6031
|
+
}
|
|
6032
|
+
// 6. Zniszcz status connection
|
|
6033
|
+
if (this._statusConnection) {
|
|
6034
|
+
this._statusConnection.destroy();
|
|
6035
|
+
this._statusConnection = null;
|
|
6036
|
+
}
|
|
6037
|
+
// 7. Zatrzymaj wszystkie strumienie
|
|
6038
|
+
yield this.forceStopAllStreams();
|
|
6039
|
+
// 8. Resetuj stany
|
|
6040
|
+
this._permissionChecked = false;
|
|
6041
|
+
this._isWindowActive = false;
|
|
6042
|
+
this._isMicrophoneMuted = false;
|
|
6043
|
+
this._publishState = exports.PublishState.NOT_INITIALIZED;
|
|
6044
|
+
this._inputDeviceState = exports.InputDevicesState.NOT_INITIALIZED;
|
|
6045
|
+
this._cameraState = exports.DeviceState.NOT_INITIALIZED;
|
|
6046
|
+
this._microphoneState = exports.DeviceState.NOT_INITIALIZED;
|
|
6047
|
+
this._switchingCamera = false;
|
|
6048
|
+
this._switchingMicrophone = false;
|
|
6049
|
+
// 9. Wyczyść listy urządzeń
|
|
6050
|
+
if (this._cameraList) {
|
|
6051
|
+
this._cameraList = new InputDeviceList();
|
|
6052
|
+
}
|
|
6053
|
+
if (this._microphoneList) {
|
|
6054
|
+
this._microphoneList = new InputDeviceList();
|
|
6055
|
+
}
|
|
6056
|
+
this._logger.success(this, "StreamerController successfully destroyed");
|
|
6057
|
+
} catch (error) {
|
|
6058
|
+
this._logger.error(this, "Error during destroy: " + error);
|
|
6059
|
+
} finally {
|
|
6060
|
+
this._isDestroying = false;
|
|
6061
|
+
}
|
|
6062
|
+
});
|
|
5674
6063
|
}
|
|
5675
6064
|
}
|
|
5676
6065
|
|
|
@@ -6255,7 +6644,6 @@
|
|
|
6255
6644
|
this.onStreamStatsUpdate = event => {
|
|
6256
6645
|
var _a;
|
|
6257
6646
|
(_a = this._graph) === null || _a === void 0 ? void 0 : _a.addEntry(event.high * 500);
|
|
6258
|
-
console.log(event.high * 200);
|
|
6259
6647
|
};
|
|
6260
6648
|
this._main = main;
|
|
6261
6649
|
this._object = container;
|
|
@@ -6303,12 +6691,12 @@
|
|
|
6303
6691
|
* Version of this streamer in SemVer format (Major.Minor.Patch).
|
|
6304
6692
|
* @private
|
|
6305
6693
|
*/
|
|
6306
|
-
this.STREAMER_VERSION = "0.
|
|
6694
|
+
this.STREAMER_VERSION = "1.0.0-rc.1";
|
|
6307
6695
|
/**
|
|
6308
6696
|
* Compile date for this streamer
|
|
6309
6697
|
* @private
|
|
6310
6698
|
*/
|
|
6311
|
-
this.COMPILE_DATE = "
|
|
6699
|
+
this.COMPILE_DATE = "11/17/2025, 10:30:23 AM";
|
|
6312
6700
|
/**
|
|
6313
6701
|
* Defines from which branch this streamer comes from e.g. "Main", "Experimental"
|
|
6314
6702
|
* @private
|
|
@@ -6370,6 +6758,7 @@
|
|
|
6370
6758
|
if (this._configManager == null) {
|
|
6371
6759
|
this._configManager = new ConfigManager(copiedStreamConfig);
|
|
6372
6760
|
this._logger = new Logger(this._configManager.getSettingsData().getDebugData(), this);
|
|
6761
|
+
this._logger.info(this, "Storm Streamer :: Storm Streaming Suite");
|
|
6373
6762
|
this._logger.info(this, "StreamerID: " + this._streamerID);
|
|
6374
6763
|
this._logger.info(this, "Version: " + this.STREAMER_VERSION + " | Compile Date: " + this.COMPILE_DATE + " | Branch: " + this.STREAMER_BRANCH);
|
|
6375
6764
|
this._logger.info(this, "UserCapabilities :: Browser: " + UserCapabilities.getBrowserName() + " " + UserCapabilities.getBrowserVersion());
|
|
@@ -6573,6 +6962,7 @@
|
|
|
6573
6962
|
*/
|
|
6574
6963
|
unpublish() {
|
|
6575
6964
|
var _a;
|
|
6965
|
+
console.log("kutas 1");
|
|
6576
6966
|
(_a = this._streamerController) === null || _a === void 0 ? void 0 : _a.unpublish();
|
|
6577
6967
|
}
|
|
6578
6968
|
/**
|