Browse Source

feat(audio-recording): Handles conference properties sent from jicofo and play notification.

When audio-recording is enabled server-side play the recording audio and visual notification.
factor2
damencho 7 months ago
parent
commit
04bee97682

+ 5
- 0
conference.js View File

@@ -27,6 +27,7 @@ import {
27 27
     conferenceJoinInProgress,
28 28
     conferenceJoined,
29 29
     conferenceLeft,
30
+    conferencePropertiesChanged,
30 31
     conferenceSubjectChanged,
31 32
     conferenceTimestampChanged,
32 33
     conferenceUniqueIdSet,
@@ -1759,6 +1760,10 @@ export default {
1759 1760
             JitsiConferenceEvents.LOCK_STATE_CHANGED,
1760 1761
             (...args) => APP.store.dispatch(lockStateChanged(room, ...args)));
1761 1762
 
1763
+        room.on(
1764
+            JitsiConferenceEvents.PROPERTIES_CHANGED,
1765
+            properties => APP.store.dispatch(conferencePropertiesChanged(properties)));
1766
+
1762 1767
         room.on(JitsiConferenceEvents.KICKED, (participant, reason, isReplaced) => {
1763 1768
             if (isReplaced) {
1764 1769
                 // this event triggers when the local participant is kicked, `participant`

+ 13
- 0
react/features/base/conference/actionTypes.ts View File

@@ -82,6 +82,19 @@ export const CONFERENCE_FOCUSED = 'CONFERENCE_FOCUSED';
82 82
  */
83 83
  export const CONFERENCE_LOCAL_SUBJECT_CHANGED = 'CONFERENCE_LOCAL_SUBJECT_CHANGED';
84 84
 
85
+/**
86
+ * The type of (redux) action, which indicates conference properties change.
87
+ *
88
+ * {
89
+ *     type: CONFERENCE_PROPERTIES_CHANGED
90
+ *     properties: {
91
+*           audio-recording-enabled: boolean,
92
+ *          visitor-count: number
93
+ *     }
94
+ * }
95
+ */
96
+ export const CONFERENCE_PROPERTIES_CHANGED = 'CONFERENCE_PROPERTIES_CHANGED';
97
+
85 98
  /**
86 99
  * The type of (redux) action, which indicates conference subject changes.
87 100
  *

+ 22
- 0
react/features/base/conference/actions.any.ts View File

@@ -45,6 +45,7 @@ import {
45 45
     CONFERENCE_JOIN_IN_PROGRESS,
46 46
     CONFERENCE_LEFT,
47 47
     CONFERENCE_LOCAL_SUBJECT_CHANGED,
48
+    CONFERENCE_PROPERTIES_CHANGED,
48 49
     CONFERENCE_SUBJECT_CHANGED,
49 50
     CONFERENCE_TIMESTAMP_CHANGED,
50 51
     CONFERENCE_UNIQUE_ID_SET,
@@ -156,6 +157,10 @@ function _addConferenceListeners(conference: IJitsiConference, dispatch: IStore[
156 157
         JitsiConferenceEvents.LOCK_STATE_CHANGED,
157 158
         (locked: boolean) => dispatch(lockStateChanged(conference, locked)));
158 159
 
160
+    conference.on(
161
+        JitsiConferenceEvents.PROPERTIES_CHANGED,
162
+        (properties: Object) => dispatch(conferencePropertiesChanged(properties)));
163
+
159 164
     // Dispatches into features/base/media follow:
160 165
 
161 166
     conference.on(
@@ -449,6 +454,23 @@ export function conferenceLeft(conference?: IJitsiConference) {
449 454
     };
450 455
 }
451 456
 
457
+/**
458
+ * Signals that the conference properties have been changed.
459
+ *
460
+ * @param {Object} properties - The new properties set.
461
+ * @returns {{
462
+ *     type: CONFERENCE_PROPERTIES_CHANGED,
463
+ *     properties: Object
464
+ * }}
465
+ */
466
+export function conferencePropertiesChanged(properties: object) {
467
+    return {
468
+        type: CONFERENCE_PROPERTIES_CHANGED,
469
+        properties
470
+    };
471
+}
472
+
473
+
452 474
 /**
453 475
  * Signals that the conference subject has been changed.
454 476
  *

+ 13
- 0
react/features/base/conference/functions.ts View File

@@ -393,6 +393,19 @@ export function isP2pActive(stateful: IStateful): boolean | null {
393 393
     return conference.isP2PActive();
394 394
 }
395 395
 
396
+/**
397
+ * Returns whether the current conference has audio recording property which is on.
398
+ *
399
+ * @param {IStateful} stateful - The redux store, state, or {@code getState} function.
400
+ * @returns {boolean|null}
401
+ */
402
+export function isConferenceAudioRecordingOn(stateful: IStateful): boolean | null {
403
+    const state = getConferenceState(toState(stateful));
404
+
405
+    // @ts-ignore
406
+    return state.properties?.['audio-recording-enabled'] === 'true';
407
+}
408
+
396 409
 /**
397 410
  * Returns the stored room name.
398 411
  *

+ 28
- 2
react/features/base/conference/reducer.ts View File

@@ -8,7 +8,7 @@ import { IConfig } from '../config/configType';
8 8
 import { CONNECTION_WILL_CONNECT, SET_LOCATION_URL } from '../connection/actionTypes';
9 9
 import { JitsiConferenceErrors } from '../lib-jitsi-meet';
10 10
 import ReducerRegistry from '../redux/ReducerRegistry';
11
-import { assign, set } from '../redux/functions';
11
+import { assign, equals, set } from '../redux/functions';
12 12
 
13 13
 import {
14 14
     AUTH_STATUS_CHANGED,
@@ -16,6 +16,7 @@ import {
16 16
     CONFERENCE_JOINED,
17 17
     CONFERENCE_LEFT,
18 18
     CONFERENCE_LOCAL_SUBJECT_CHANGED,
19
+    CONFERENCE_PROPERTIES_CHANGED,
19 20
     CONFERENCE_SUBJECT_CHANGED,
20 21
     CONFERENCE_TIMESTAMP_CHANGED,
21 22
     CONFERENCE_WILL_JOIN,
@@ -48,7 +49,8 @@ const DEFAULT_STATE = {
48 49
     membersOnly: undefined,
49 50
     metadata: undefined,
50 51
     password: undefined,
51
-    passwordRequired: undefined
52
+    passwordRequired: undefined,
53
+    properties: undefined
52 54
 };
53 55
 
54 56
 export interface IConferenceMetadata {
@@ -176,6 +178,7 @@ export interface IConferenceState {
176 178
     password?: string;
177 179
     passwordRequired?: IJitsiConference;
178 180
     pendingSubjectChange?: string;
181
+    properties?: object;
179 182
     room?: string;
180 183
     startAudioMutedPolicy?: boolean;
181 184
     startReactionsMuted?: boolean;
@@ -220,6 +223,9 @@ ReducerRegistry.register<IConferenceState>('features/base/conference',
220 223
         case CONFERENCE_LOCAL_SUBJECT_CHANGED:
221 224
             return set(state, 'localSubject', action.localSubject);
222 225
 
226
+        case CONFERENCE_PROPERTIES_CHANGED:
227
+            return _conferencePropertiesChanged(state, action);
228
+
223 229
         case CONFERENCE_TIMESTAMP_CHANGED:
224 230
             return set(state, 'conferenceTimestamp', action.conferenceTimestamp);
225 231
 
@@ -518,6 +524,26 @@ function _conferenceLeftOrWillLeave(state: IConferenceState, { conference, type
518 524
     return nextState;
519 525
 }
520 526
 
527
+/**
528
+ * Reduces a specific Redux action CONFERENCE_PROPERTIES_CHANGED of the feature
529
+ * base/conference.
530
+ *
531
+ * @param {Object} state - The Redux state of the feature base/conference.
532
+ * @param {Action} action - The Redux action CONFERENCE_PROPERTIES_CHANGED to reduce.
533
+ * @private
534
+ * @returns {Object} The new state of the feature base/conference after the
535
+ * reduction of the specified action.
536
+ */
537
+function _conferencePropertiesChanged(state: IConferenceState, { properties }: { properties: Object; }) {
538
+    if (!equals(state.properties, properties)) {
539
+        return assign(state, {
540
+            properties
541
+        });
542
+    }
543
+
544
+    return state;
545
+}
546
+
521 547
 /**
522 548
  * Reduces a specific Redux action CONFERENCE_WILL_JOIN of the feature
523 549
  * base/conference.

+ 11
- 0
react/features/transcribing/subscriber.ts View File

@@ -1,6 +1,7 @@
1 1
 import { batch } from 'react-redux';
2 2
 
3 3
 import { IStore } from '../app/types';
4
+import { isConferenceAudioRecordingOn } from '../base/conference/functions';
4 5
 import { JitsiRecordingConstants } from '../base/lib-jitsi-meet';
5 6
 import StateListenerRegistry from '../base/redux/StateListenerRegistry';
6 7
 import { playSound } from '../base/sounds/actions';
@@ -27,6 +28,16 @@ StateListenerRegistry.register(
27 28
     }
28 29
 );
29 30
 
31
+/**
32
+ * Listens for audio-recording-enabled conference property change.
33
+ */
34
+StateListenerRegistry.register(
35
+    /* selector */ isConferenceAudioRecordingOn,
36
+    /* listener */ (audioRecordingOn, { getState, dispatch }) => {
37
+        maybeEmitRecordingNotification(dispatch, getState, audioRecordingOn);
38
+    }
39
+);
40
+
30 41
 /**
31 42
  * Emit a recording started / stopped notification if the transcription started / stopped. Only
32 43
  * if there is no recording in progress.

+ 0
- 10
react/features/visitors/actionTypes.ts View File

@@ -1,13 +1,3 @@
1
-/**
2
- * The type of (redux) action to update visitors count.
3
- *
4
- * {
5
- *     type: UPDATE_VISITORS_COUNT,
6
- *     count: number
7
- * }
8
- */
9
-export const UPDATE_VISITORS_COUNT = 'UPDATE_VISITORS_COUNT';
10
-
11 1
 /**
12 2
  * The type of (redux) action to update visitors in queue count.
13 3
  *

+ 0
- 16
react/features/visitors/actions.ts View File

@@ -11,7 +11,6 @@ import {
11 11
     SET_IN_VISITORS_QUEUE,
12 12
     SET_VISITORS_SUPPORTED,
13 13
     SET_VISITOR_DEMOTE_ACTOR,
14
-    UPDATE_VISITORS_COUNT,
15 14
     UPDATE_VISITORS_IN_QUEUE_COUNT,
16 15
     VISITOR_PROMOTION_REQUEST
17 16
 } from './actionTypes';
@@ -202,21 +201,6 @@ export function setVisitorsSupported(value: boolean) {
202 201
     };
203 202
 }
204 203
 
205
-/**
206
- * Visitors count has been updated.
207
- *
208
- * @param {number} count - The new visitors count.
209
- * @returns {{
210
- *     type: UPDATE_VISITORS_COUNT,
211
- * }}
212
- */
213
-export function updateVisitorsCount(count: number) {
214
-    return {
215
-        type: UPDATE_VISITORS_COUNT,
216
-        count
217
-    };
218
-}
219
-
220 204
 /**
221 205
  * Visitors in queue count has been updated.
222 206
  *

+ 1
- 15
react/features/visitors/middleware.ts View File

@@ -5,7 +5,6 @@ import { IStore } from '../app/types';
5 5
 import { IStateful } from '../base/app/types';
6 6
 import {
7 7
     CONFERENCE_JOINED,
8
-    CONFERENCE_JOIN_IN_PROGRESS,
9 8
     ENDPOINT_MESSAGE_RECEIVED,
10 9
     UPDATE_CONFERENCE_METADATA
11 10
 } from '../base/conference/actionTypes';
@@ -46,28 +45,15 @@ import {
46 45
     setInVisitorsQueue,
47 46
     setVisitorDemoteActor,
48 47
     setVisitorsSupported,
49
-    updateVisitorsCount,
50 48
     updateVisitorsInQueueCount
51 49
 } from './actions';
52 50
 import { JoinMeetingDialog } from './components';
53
-import { getPromotionRequests, getVisitorsCount, getVisitorsInQueueCount } from './functions';
51
+import { getPromotionRequests, getVisitorsInQueueCount } from './functions';
54 52
 import logger from './logger';
55 53
 import { WebsocketClient } from './websocket-client';
56 54
 
57 55
 MiddlewareRegistry.register(({ dispatch, getState }) => next => action => {
58 56
     switch (action.type) {
59
-    case CONFERENCE_JOIN_IN_PROGRESS: {
60
-        const { conference } = action;
61
-
62
-        conference.on(JitsiConferenceEvents.PROPERTIES_CHANGED, (properties: { 'visitor-count': number; }) => {
63
-            const visitorCount = Number(properties?.['visitor-count']);
64
-
65
-            if (!isNaN(visitorCount) && getVisitorsCount(getState) !== visitorCount) {
66
-                dispatch(updateVisitorsCount(visitorCount));
67
-            }
68
-        });
69
-        break;
70
-    }
71 57
     case CONFERENCE_JOINED: {
72 58
         const { conference } = action;
73 59
 

+ 13
- 12
react/features/visitors/reducer.ts View File

@@ -1,4 +1,4 @@
1
-import { CONFERENCE_WILL_LEAVE } from '../base/conference/actionTypes';
1
+import { CONFERENCE_PROPERTIES_CHANGED, CONFERENCE_WILL_LEAVE } from '../base/conference/actionTypes';
2 2
 import ReducerRegistry from '../base/redux/ReducerRegistry';
3 3
 
4 4
 import {
@@ -7,7 +7,6 @@ import {
7 7
     SET_IN_VISITORS_QUEUE,
8 8
     SET_VISITORS_SUPPORTED,
9 9
     SET_VISITOR_DEMOTE_ACTOR,
10
-    UPDATE_VISITORS_COUNT,
11 10
     UPDATE_VISITORS_IN_QUEUE_COUNT,
12 11
     VISITOR_PROMOTION_REQUEST
13 12
 } from './actionTypes';
@@ -34,6 +33,18 @@ export interface IVisitorsState {
34 33
 }
35 34
 ReducerRegistry.register<IVisitorsState>('features/visitors', (state = DEFAULT_STATE, action): IVisitorsState => {
36 35
     switch (action.type) {
36
+    case CONFERENCE_PROPERTIES_CHANGED: {
37
+        const visitorCount = Number(action.properties?.['visitor-count']);
38
+
39
+        if (!isNaN(visitorCount) && state.count !== visitorCount) {
40
+            return {
41
+                ...state,
42
+                count: visitorCount
43
+            };
44
+        }
45
+
46
+        break;
47
+    }
37 48
     case CONFERENCE_WILL_LEAVE: {
38 49
         return {
39 50
             ...state,
@@ -45,16 +56,6 @@ ReducerRegistry.register<IVisitorsState>('features/visitors', (state = DEFAULT_S
45 56
             iAmVisitor: action.isRedirect ? state.iAmVisitor : DEFAULT_STATE.iAmVisitor
46 57
         };
47 58
     }
48
-    case UPDATE_VISITORS_COUNT: {
49
-        if (state.count === action.count) {
50
-            return state;
51
-        }
52
-
53
-        return {
54
-            ...state,
55
-            count: action.count
56
-        };
57
-    }
58 59
     case UPDATE_VISITORS_IN_QUEUE_COUNT: {
59 60
         if (state.count === action.count) {
60 61
             return state;

Loading…
Cancel
Save