|
@@ -1,9 +1,12 @@
|
1
|
|
-import * as JitsiConferenceEvents from '../../JitsiConferenceEvents';
|
2
|
|
-import * as JitsiTrackEvents from '../../JitsiTrackEvents';
|
3
|
1
|
import EventEmitter from '../util/EventEmitter';
|
4
|
|
-
|
|
2
|
+import { JitsiConferenceEvents } from '../../JitsiConferenceEvents';
|
|
3
|
+import { JitsiTrackEvents } from '../../JitsiTrackEvents';
|
5
|
4
|
import * as DetectionEvents from './DetectionEvents';
|
6
|
5
|
|
|
6
|
+import type JitsiLocalTrack from '../RTC/JitsiLocalTrack';
|
|
7
|
+import type JitsiConference from '../../JitsiConference';
|
|
8
|
+import type TraceablePeerConnection from '../RTC/TraceablePeerConnection';
|
|
9
|
+
|
7
|
10
|
// We wait a certain time interval for constant silence input from the current device to account for
|
8
|
11
|
// potential abnormalities and for a better use experience i.e. don't generate event the instant
|
9
|
12
|
// an audio track is added to the tcr.
|
|
@@ -17,18 +20,26 @@ const SILENCE_PERIOD_MS = 4000;
|
17
|
20
|
* @fires DetectionEvents.NO_AUDIO_INPUT
|
18
|
21
|
*/
|
19
|
22
|
export default class NoAudioSignalDetection extends EventEmitter {
|
|
23
|
+ private _conference: JitsiConference;
|
|
24
|
+ private _timeoutTrigger: Timeout | null;
|
|
25
|
+ private _hasAudioInput: boolean | null;
|
|
26
|
+ private _audioTrack: JitsiLocalTrack | null;
|
|
27
|
+ private _eventFired: boolean;
|
|
28
|
+
|
20
|
29
|
/**
|
21
|
30
|
* Creates new NoAudioSignalDetection.
|
22
|
31
|
*
|
23
|
32
|
* @param conference the JitsiConference instance that created us.
|
24
|
33
|
* @constructor
|
25
|
34
|
*/
|
26
|
|
- constructor(conference) {
|
|
35
|
+ constructor(conference: JitsiConference) {
|
27
|
36
|
super();
|
28
|
37
|
|
29
|
38
|
this._conference = conference;
|
30
|
39
|
this._timeoutTrigger = null;
|
31
|
40
|
this._hasAudioInput = null;
|
|
41
|
+ this._audioTrack = null;
|
|
42
|
+ this._eventFired = false;
|
32
|
43
|
|
33
|
44
|
conference.on(JitsiConferenceEvents.TRACK_ADDED, this._trackAdded.bind(this));
|
34
|
45
|
}
|
|
@@ -36,19 +47,20 @@ export default class NoAudioSignalDetection extends EventEmitter {
|
36
|
47
|
/**
|
37
|
48
|
* Clear the timeout state.
|
38
|
49
|
*/
|
39
|
|
- _clearTriggerTimeout() {
|
40
|
|
- clearTimeout(this._timeoutTrigger);
|
41
|
|
- this._timeoutTrigger = null;
|
|
50
|
+ private _clearTriggerTimeout(): void {
|
|
51
|
+ if (this._timeoutTrigger) {
|
|
52
|
+ clearTimeout(this._timeoutTrigger);
|
|
53
|
+ this._timeoutTrigger = null;
|
|
54
|
+ }
|
42
|
55
|
}
|
43
|
56
|
|
44
|
|
-
|
45
|
57
|
/**
|
46
|
58
|
* Generated event triggered by a change in the current conference audio input state.
|
47
|
59
|
*
|
48
|
|
- * @param {*} audioLevel - The audio level of the ssrc.
|
|
60
|
+ * @param {number} audioLevel - The audio level of the ssrc.
|
49
|
61
|
* @fires DetectionEvents.AUDIO_INPUT_STATE_CHANGE
|
50
|
62
|
*/
|
51
|
|
- _handleAudioInputStateChange(audioLevel) {
|
|
63
|
+ private _handleAudioInputStateChange(audioLevel: number): void {
|
52
|
64
|
// Current audio input state of the active local track in the conference, true for audio input false for no
|
53
|
65
|
// audio input.
|
54
|
66
|
const status = audioLevel !== 0;
|
|
@@ -67,7 +79,7 @@ export default class NoAudioSignalDetection extends EventEmitter {
|
67
|
79
|
* @param {number} audioLevel - The audio level of the ssrc.
|
68
|
80
|
* @fires DetectionEvents.NO_AUDIO_INPUT
|
69
|
81
|
*/
|
70
|
|
- _handleNoAudioInputDetection(audioLevel) {
|
|
82
|
+ private _handleNoAudioInputDetection(audioLevel: number): void {
|
71
|
83
|
if (this._eventFired) {
|
72
|
84
|
return;
|
73
|
85
|
}
|
|
@@ -92,7 +104,7 @@ export default class NoAudioSignalDetection extends EventEmitter {
|
92
|
104
|
* @param {number} audioLevel - The audio level of the ssrc.
|
93
|
105
|
* @param {boolean} isLocal - true for local/send streams or false for remote/receive streams.
|
94
|
106
|
*/
|
95
|
|
- _audioLevel(tpc, ssrc, audioLevel, isLocal) {
|
|
107
|
+ private _audioLevel(tpc: TraceablePeerConnection, ssrc: number, audioLevel: number, isLocal: boolean): void {
|
96
|
108
|
// We are interested in the local audio streams
|
97
|
109
|
if (!isLocal || !this._audioTrack) {
|
98
|
110
|
return;
|
|
@@ -103,7 +115,7 @@ export default class NoAudioSignalDetection extends EventEmitter {
|
103
|
115
|
|
104
|
116
|
// Only target the current active track in the tpc. For some reason audio levels for previous
|
105
|
117
|
// devices are also picked up from the PeerConnection so we filter them out.
|
106
|
|
- if (!localSSRCs || !localSSRCs.ssrcs.includes(ssrc)) {
|
|
118
|
+ if (!localSSRCs?.ssrcs.includes(ssrc)) {
|
107
|
119
|
return;
|
108
|
120
|
}
|
109
|
121
|
|
|
@@ -119,7 +131,7 @@ export default class NoAudioSignalDetection extends EventEmitter {
|
119
|
131
|
*
|
120
|
132
|
* @param {JitsiTrack} track - The added JitsiTrack.
|
121
|
133
|
*/
|
122
|
|
- _trackAdded(track) {
|
|
134
|
+ private _trackAdded(track: JitsiLocalTrack): void {
|
123
|
135
|
if (track.isLocalAudioTrack()) {
|
124
|
136
|
// Reset state for the new track.
|
125
|
137
|
this._audioTrack = track;
|
|
@@ -129,13 +141,13 @@ export default class NoAudioSignalDetection extends EventEmitter {
|
129
|
141
|
// Listen for the audio levels on the newly added audio track
|
130
|
142
|
track.on(
|
131
|
143
|
JitsiTrackEvents.NO_AUDIO_INPUT,
|
132
|
|
- audioLevel => {
|
|
144
|
+ (audioLevel: number) => {
|
133
|
145
|
this._handleNoAudioInputDetection(audioLevel);
|
134
|
146
|
}
|
135
|
147
|
);
|
136
|
148
|
track.on(
|
137
|
149
|
JitsiTrackEvents.TRACK_AUDIO_LEVEL_CHANGED,
|
138
|
|
- audioLevel => {
|
|
150
|
+ (audioLevel: number) => {
|
139
|
151
|
this._handleNoAudioInputDetection(audioLevel);
|
140
|
152
|
this._handleAudioInputStateChange(audioLevel);
|
141
|
153
|
}
|