Browse Source

feat: display noise detection notification (#4952)

* feat: display noise detection notification

* address code review p1

* Address code review p2

* bump lib-jitsi-meet version
master
Andrei Gavrilescu 5 years ago
parent
commit
d2c2919aef

+ 7
- 1
config.js View File

76
     // Enabling this will run the lib-jitsi-meet no audio detection module which
76
     // Enabling this will run the lib-jitsi-meet no audio detection module which
77
     // will notify the user if the current selected microphone has no audio
77
     // will notify the user if the current selected microphone has no audio
78
     // input and will suggest another valid device if one is present.
78
     // input and will suggest another valid device if one is present.
79
-    // enableNoAudioDetection: false
79
+    enableNoAudioDetection: true,
80
+
81
+    // Enabling this will run the lib-jitsi-meet noise detection module which will
82
+    // notify the user if there is noise, other than voice, coming from the current
83
+    // selected microphone. The purpose it to let the user know that the input could
84
+    // be potentially unpleasant for other meeting participants.
85
+    enableNoisyMicDetection: true,
80
 
86
 
81
     // Start the conference in audio only mode (no video is being received nor
87
     // Start the conference in audio only mode (no video is being received nor
82
     // sent).
88
     // sent).

+ 2
- 0
lang/main.json View File

634
         "noAudioSignalTitle": "There is no input coming from your mic!",
634
         "noAudioSignalTitle": "There is no input coming from your mic!",
635
         "noAudioSignalDesc": "If you did not purposely mute it from system settings or hardware, consider changing the device.",
635
         "noAudioSignalDesc": "If you did not purposely mute it from system settings or hardware, consider changing the device.",
636
         "noAudioSignalDescSuggestion": "If you did not purposely mute it from system settings or hardware, consider using the following device:",
636
         "noAudioSignalDescSuggestion": "If you did not purposely mute it from system settings or hardware, consider using the following device:",
637
+        "noisyAudioInputTitle": "Your microphone appears to be noisy!",
638
+        "noisyAudioInputDesc": "Jitsi has detected noise coming from your microphone, please consider muting or changing the device.",
637
         "openChat": "Open chat",
639
         "openChat": "Open chat",
638
         "pip": "Enter Picture-in-Picture mode",
640
         "pip": "Enter Picture-in-Picture mode",
639
         "privateMessage": "Send private message",
641
         "privateMessage": "Send private message",

+ 2
- 2
package-lock.json View File

10869
       }
10869
       }
10870
     },
10870
     },
10871
     "lib-jitsi-meet": {
10871
     "lib-jitsi-meet": {
10872
-      "version": "github:jitsi/lib-jitsi-meet#8deeaf6bd2b233ab163303e42febfee87201b2d9",
10873
-      "from": "github:jitsi/lib-jitsi-meet#8deeaf6bd2b233ab163303e42febfee87201b2d9",
10872
+      "version": "github:jitsi/lib-jitsi-meet#e4b523d0fab83a1cf1408abbf41f5d0ca1169900",
10873
+      "from": "github:jitsi/lib-jitsi-meet#e4b523d0fab83a1cf1408abbf41f5d0ca1169900",
10874
       "requires": {
10874
       "requires": {
10875
         "@jitsi/sdp-interop": "0.1.14",
10875
         "@jitsi/sdp-interop": "0.1.14",
10876
         "@jitsi/sdp-simulcast": "0.2.2",
10876
         "@jitsi/sdp-simulcast": "0.2.2",

+ 1
- 1
package.json View File

56
     "js-utils": "github:jitsi/js-utils#400ce825d3565019946ee75d86ed773c6f21e117",
56
     "js-utils": "github:jitsi/js-utils#400ce825d3565019946ee75d86ed773c6f21e117",
57
     "jsrsasign": "8.0.12",
57
     "jsrsasign": "8.0.12",
58
     "jwt-decode": "2.2.0",
58
     "jwt-decode": "2.2.0",
59
-    "lib-jitsi-meet": "github:jitsi/lib-jitsi-meet#8deeaf6bd2b233ab163303e42febfee87201b2d9",
59
+    "lib-jitsi-meet": "github:jitsi/lib-jitsi-meet#e4b523d0fab83a1cf1408abbf41f5d0ca1169900",
60
     "libflacjs": "github:mmig/libflac.js#93d37e7f811f01cf7d8b6a603e38bd3c3810907d",
60
     "libflacjs": "github:mmig/libflac.js#93d37e7f811f01cf7d8b6a603e38bd3c3810907d",
61
     "lodash": "4.17.13",
61
     "lodash": "4.17.13",
62
     "moment": "2.19.4",
62
     "moment": "2.19.4",

+ 1
- 0
react/features/app/components/App.web.js View File

8
 import '../../chat';
8
 import '../../chat';
9
 import '../../external-api';
9
 import '../../external-api';
10
 import '../../no-audio-signal';
10
 import '../../no-audio-signal';
11
+import '../../noise-detection';
11
 import '../../power-monitor';
12
 import '../../power-monitor';
12
 import '../../room-lock';
13
 import '../../room-lock';
13
 import '../../talk-while-muted';
14
 import '../../talk-while-muted';

+ 0
- 12
react/features/no-audio-signal/middleware.js View File

48
 async function _handleNoAudioSignalNotification({ dispatch, getState }, action) {
48
 async function _handleNoAudioSignalNotification({ dispatch, getState }, action) {
49
 
49
 
50
     const { conference } = action;
50
     const { conference } = action;
51
-    let confAudioInputState;
52
 
51
 
53
     conference.on(JitsiConferenceEvents.AUDIO_INPUT_STATE_CHANGE, hasAudioInput => {
52
     conference.on(JitsiConferenceEvents.AUDIO_INPUT_STATE_CHANGE, hasAudioInput => {
54
         const { noAudioSignalNotificationUid } = getState()['features/no-audio-signal'];
53
         const { noAudioSignalNotificationUid } = getState()['features/no-audio-signal'];
55
 
54
 
56
-        confAudioInputState = hasAudioInput;
57
-
58
         // In case the notification is displayed but the conference detected audio input signal we hide it.
55
         // In case the notification is displayed but the conference detected audio input signal we hide it.
59
         if (noAudioSignalNotificationUid && hasAudioInput) {
56
         if (noAudioSignalNotificationUid && hasAudioInput) {
60
             dispatch(hideNotification(noAudioSignalNotificationUid));
57
             dispatch(hideNotification(noAudioSignalNotificationUid));
71
             return;
68
             return;
72
         }
69
         }
73
 
70
 
74
-        // Force the flag to false in case AUDIO_INPUT_STATE_CHANGE is received after the notification is displayed,
75
-        // possibly preventing the notification from displaying because of an outdated state.
76
-        confAudioInputState = false;
77
-
78
-
79
         const activeDevice = await JitsiMeetJS.getActiveAudioDevice();
71
         const activeDevice = await JitsiMeetJS.getActiveAudioDevice();
80
 
72
 
81
-        if (confAudioInputState) {
82
-            return;
83
-        }
84
-
85
         // In case there is a previous notification displayed just hide it.
73
         // In case there is a previous notification displayed just hide it.
86
         const { noAudioSignalNotificationUid } = getState()['features/no-audio-signal'];
74
         const { noAudioSignalNotificationUid } = getState()['features/no-audio-signal'];
87
 
75
 

+ 11
- 0
react/features/noise-detection/actionTypes.js View File

1
+/**
2
+ * The type of Redux action which sets the pending notification UID
3
+ * to use it when hiding the notification is necessary, or unset it when
4
+ * undefined (or no param) is passed.
5
+ *
6
+ * {
7
+ *     type: SET_NOISY_AUDIO_INPUT_NOTIFICATION_UID
8
+ *     uid: ?number
9
+ * }
10
+ */
11
+export const SET_NOISY_AUDIO_INPUT_NOTIFICATION_UID = 'SET_NOISY_AUDIO_INPUT_NOTIFICATION_UID';

+ 21
- 0
react/features/noise-detection/actions.js View File

1
+// @flow
2
+
3
+import { SET_NOISY_AUDIO_INPUT_NOTIFICATION_UID } from './actionTypes';
4
+
5
+/**
6
+ * Sets UID of the the pending notification to use it when hiding
7
+ * the notification is necessary, or unset it when undefined (or no param) is
8
+ * passed.
9
+ *
10
+ * @param {?number} uid - The UID of the notification.
11
+ * @returns {{
12
+ *     type: SET_NOISY_AUDIO_INPUT_NOTIFICATION_UID,
13
+ *     uid: number
14
+ * }}
15
+ */
16
+export function setNoisyAudioInputNotificationUid(uid: ?number) {
17
+    return {
18
+        type: SET_NOISY_AUDIO_INPUT_NOTIFICATION_UID,
19
+        uid
20
+    };
21
+}

+ 6
- 0
react/features/noise-detection/constants.js View File

1
+/**
2
+ * The identifier of the sound to be played when we display a you are noisy notification.
3
+ *
4
+ * @type {string}
5
+ */
6
+export const NOISY_AUDIO_INPUT_SOUND_ID = 'NOISY_AUDIO_INPUT_SOUND_ID';

+ 4
- 0
react/features/noise-detection/index.js View File

1
+// @flow
2
+
3
+import './middleware';
4
+import './reducer';

+ 57
- 0
react/features/noise-detection/middleware.js View File

1
+// @flow
2
+
3
+import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../base/app';
4
+import { CONFERENCE_JOINED } from '../base/conference';
5
+import { JitsiConferenceEvents } from '../base/lib-jitsi-meet';
6
+import { MiddlewareRegistry } from '../base/redux';
7
+import { playSound, registerSound, unregisterSound } from '../base/sounds';
8
+import { hideNotification, showNotification } from '../notifications';
9
+
10
+import { setNoisyAudioInputNotificationUid } from './actions';
11
+import { NOISY_AUDIO_INPUT_SOUND_ID } from './constants';
12
+import { NOISY_AUDIO_INPUT_SOUND_FILE } from './sounds';
13
+
14
+MiddlewareRegistry.register(store => next => action => {
15
+    const result = next(action);
16
+
17
+    switch (action.type) {
18
+    case APP_WILL_MOUNT:
19
+        store.dispatch(registerSound(NOISY_AUDIO_INPUT_SOUND_ID, NOISY_AUDIO_INPUT_SOUND_FILE));
20
+        break;
21
+    case APP_WILL_UNMOUNT:
22
+        store.dispatch(unregisterSound(NOISY_AUDIO_INPUT_SOUND_ID));
23
+        break;
24
+    case CONFERENCE_JOINED: {
25
+        const { dispatch, getState } = store;
26
+        const { conference } = action;
27
+
28
+        conference.on(
29
+            JitsiConferenceEvents.TRACK_MUTE_CHANGED,
30
+            track => {
31
+                const { noisyAudioInputNotificationUid } = getState()['features/noise-detection'];
32
+
33
+                // Hide the notification in case the user mutes the microphone
34
+                if (noisyAudioInputNotificationUid && track.isAudioTrack() && track.isLocal() && track.isMuted()) {
35
+                    dispatch(hideNotification(noisyAudioInputNotificationUid));
36
+                    dispatch(setNoisyAudioInputNotificationUid());
37
+                }
38
+            });
39
+        conference.on(
40
+            JitsiConferenceEvents.NOISY_MIC, () => {
41
+                const notification = showNotification({
42
+                    titleKey: 'toolbar.noisyAudioInputTitle',
43
+                    descriptionKey: 'toolbar.noisyAudioInputDesc'
44
+                });
45
+
46
+                dispatch(notification);
47
+                dispatch(playSound(NOISY_AUDIO_INPUT_SOUND_ID));
48
+
49
+                // we store the last notification id so we can hide it if the mic is muted
50
+                dispatch(setNoisyAudioInputNotificationUid(notification.uid));
51
+            });
52
+        break;
53
+    }
54
+    }
55
+
56
+    return result;
57
+});

+ 17
- 0
react/features/noise-detection/reducer.js View File

1
+// @flow
2
+
3
+import { ReducerRegistry, set } from '../base/redux';
4
+
5
+import { SET_NOISY_AUDIO_INPUT_NOTIFICATION_UID } from './actionTypes';
6
+
7
+/**
8
+ * Reduces the redux actions of noise detection feature
9
+ */
10
+ReducerRegistry.register('features/noise-detection', (state = {}, action) => {
11
+    switch (action.type) {
12
+    case SET_NOISY_AUDIO_INPUT_NOTIFICATION_UID:
13
+        return set(state, 'noisyAudioInputNotificationUid', action.uid);
14
+    }
15
+
16
+    return state;
17
+});

+ 6
- 0
react/features/noise-detection/sounds.js View File

1
+/**
2
+ * The file used for the noisy audio input notification.
3
+ *
4
+ * @type {string}
5
+ */
6
+export const NOISY_AUDIO_INPUT_SOUND_FILE = 'noisyAudioInput.mp3';

BIN
sounds/noisyAudioInput.mp3 View File


Loading…
Cancel
Save