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.
pull/15282/head jitsi-meet_9816
damencho 4 weeks ago committed by Дамян Минков
parent aa506a7607
commit 04bee97682
  1. 5
      conference.js
  2. 13
      react/features/base/conference/actionTypes.ts
  3. 22
      react/features/base/conference/actions.any.ts
  4. 13
      react/features/base/conference/functions.ts
  5. 30
      react/features/base/conference/reducer.ts
  6. 11
      react/features/transcribing/subscriber.ts
  7. 10
      react/features/visitors/actionTypes.ts
  8. 16
      react/features/visitors/actions.ts
  9. 16
      react/features/visitors/middleware.ts
  10. 25
      react/features/visitors/reducer.ts

@ -27,6 +27,7 @@ import {
conferenceJoinInProgress,
conferenceJoined,
conferenceLeft,
conferencePropertiesChanged,
conferenceSubjectChanged,
conferenceTimestampChanged,
conferenceUniqueIdSet,
@ -1759,6 +1760,10 @@ export default {
JitsiConferenceEvents.LOCK_STATE_CHANGED,
(...args) => APP.store.dispatch(lockStateChanged(room, ...args)));
room.on(
JitsiConferenceEvents.PROPERTIES_CHANGED,
properties => APP.store.dispatch(conferencePropertiesChanged(properties)));
room.on(JitsiConferenceEvents.KICKED, (participant, reason, isReplaced) => {
if (isReplaced) {
// this event triggers when the local participant is kicked, `participant`

@ -82,6 +82,19 @@ export const CONFERENCE_FOCUSED = 'CONFERENCE_FOCUSED';
*/
export const CONFERENCE_LOCAL_SUBJECT_CHANGED = 'CONFERENCE_LOCAL_SUBJECT_CHANGED';
/**
* The type of (redux) action, which indicates conference properties change.
*
* {
* type: CONFERENCE_PROPERTIES_CHANGED
* properties: {
* audio-recording-enabled: boolean,
* visitor-count: number
* }
* }
*/
export const CONFERENCE_PROPERTIES_CHANGED = 'CONFERENCE_PROPERTIES_CHANGED';
/**
* The type of (redux) action, which indicates conference subject changes.
*

@ -45,6 +45,7 @@ import {
CONFERENCE_JOIN_IN_PROGRESS,
CONFERENCE_LEFT,
CONFERENCE_LOCAL_SUBJECT_CHANGED,
CONFERENCE_PROPERTIES_CHANGED,
CONFERENCE_SUBJECT_CHANGED,
CONFERENCE_TIMESTAMP_CHANGED,
CONFERENCE_UNIQUE_ID_SET,
@ -156,6 +157,10 @@ function _addConferenceListeners(conference: IJitsiConference, dispatch: IStore[
JitsiConferenceEvents.LOCK_STATE_CHANGED,
(locked: boolean) => dispatch(lockStateChanged(conference, locked)));
conference.on(
JitsiConferenceEvents.PROPERTIES_CHANGED,
(properties: Object) => dispatch(conferencePropertiesChanged(properties)));
// Dispatches into features/base/media follow:
conference.on(
@ -449,6 +454,23 @@ export function conferenceLeft(conference?: IJitsiConference) {
};
}
/**
* Signals that the conference properties have been changed.
*
* @param {Object} properties - The new properties set.
* @returns {{
* type: CONFERENCE_PROPERTIES_CHANGED,
* properties: Object
* }}
*/
export function conferencePropertiesChanged(properties: object) {
return {
type: CONFERENCE_PROPERTIES_CHANGED,
properties
};
}
/**
* Signals that the conference subject has been changed.
*

@ -393,6 +393,19 @@ export function isP2pActive(stateful: IStateful): boolean | null {
return conference.isP2PActive();
}
/**
* Returns whether the current conference has audio recording property which is on.
*
* @param {IStateful} stateful - The redux store, state, or {@code getState} function.
* @returns {boolean|null}
*/
export function isConferenceAudioRecordingOn(stateful: IStateful): boolean | null {
const state = getConferenceState(toState(stateful));
// @ts-ignore
return state.properties?.['audio-recording-enabled'] === 'true';
}
/**
* Returns the stored room name.
*

@ -8,7 +8,7 @@ import { IConfig } from '../config/configType';
import { CONNECTION_WILL_CONNECT, SET_LOCATION_URL } from '../connection/actionTypes';
import { JitsiConferenceErrors } from '../lib-jitsi-meet';
import ReducerRegistry from '../redux/ReducerRegistry';
import { assign, set } from '../redux/functions';
import { assign, equals, set } from '../redux/functions';
import {
AUTH_STATUS_CHANGED,
@ -16,6 +16,7 @@ import {
CONFERENCE_JOINED,
CONFERENCE_LEFT,
CONFERENCE_LOCAL_SUBJECT_CHANGED,
CONFERENCE_PROPERTIES_CHANGED,
CONFERENCE_SUBJECT_CHANGED,
CONFERENCE_TIMESTAMP_CHANGED,
CONFERENCE_WILL_JOIN,
@ -48,7 +49,8 @@ const DEFAULT_STATE = {
membersOnly: undefined,
metadata: undefined,
password: undefined,
passwordRequired: undefined
passwordRequired: undefined,
properties: undefined
};
export interface IConferenceMetadata {
@ -176,6 +178,7 @@ export interface IConferenceState {
password?: string;
passwordRequired?: IJitsiConference;
pendingSubjectChange?: string;
properties?: object;
room?: string;
startAudioMutedPolicy?: boolean;
startReactionsMuted?: boolean;
@ -220,6 +223,9 @@ ReducerRegistry.register<IConferenceState>('features/base/conference',
case CONFERENCE_LOCAL_SUBJECT_CHANGED:
return set(state, 'localSubject', action.localSubject);
case CONFERENCE_PROPERTIES_CHANGED:
return _conferencePropertiesChanged(state, action);
case CONFERENCE_TIMESTAMP_CHANGED:
return set(state, 'conferenceTimestamp', action.conferenceTimestamp);
@ -518,6 +524,26 @@ function _conferenceLeftOrWillLeave(state: IConferenceState, { conference, type
return nextState;
}
/**
* Reduces a specific Redux action CONFERENCE_PROPERTIES_CHANGED of the feature
* base/conference.
*
* @param {Object} state - The Redux state of the feature base/conference.
* @param {Action} action - The Redux action CONFERENCE_PROPERTIES_CHANGED to reduce.
* @private
* @returns {Object} The new state of the feature base/conference after the
* reduction of the specified action.
*/
function _conferencePropertiesChanged(state: IConferenceState, { properties }: { properties: Object; }) {
if (!equals(state.properties, properties)) {
return assign(state, {
properties
});
}
return state;
}
/**
* Reduces a specific Redux action CONFERENCE_WILL_JOIN of the feature
* base/conference.

@ -1,6 +1,7 @@
import { batch } from 'react-redux';
import { IStore } from '../app/types';
import { isConferenceAudioRecordingOn } from '../base/conference/functions';
import { JitsiRecordingConstants } from '../base/lib-jitsi-meet';
import StateListenerRegistry from '../base/redux/StateListenerRegistry';
import { playSound } from '../base/sounds/actions';
@ -27,6 +28,16 @@ StateListenerRegistry.register(
}
);
/**
* Listens for audio-recording-enabled conference property change.
*/
StateListenerRegistry.register(
/* selector */ isConferenceAudioRecordingOn,
/* listener */ (audioRecordingOn, { getState, dispatch }) => {
maybeEmitRecordingNotification(dispatch, getState, audioRecordingOn);
}
);
/**
* Emit a recording started / stopped notification if the transcription started / stopped. Only
* if there is no recording in progress.

@ -1,13 +1,3 @@
/**
* The type of (redux) action to update visitors count.
*
* {
* type: UPDATE_VISITORS_COUNT,
* count: number
* }
*/
export const UPDATE_VISITORS_COUNT = 'UPDATE_VISITORS_COUNT';
/**
* The type of (redux) action to update visitors in queue count.
*

@ -11,7 +11,6 @@ import {
SET_IN_VISITORS_QUEUE,
SET_VISITORS_SUPPORTED,
SET_VISITOR_DEMOTE_ACTOR,
UPDATE_VISITORS_COUNT,
UPDATE_VISITORS_IN_QUEUE_COUNT,
VISITOR_PROMOTION_REQUEST
} from './actionTypes';
@ -202,21 +201,6 @@ export function setVisitorsSupported(value: boolean) {
};
}
/**
* Visitors count has been updated.
*
* @param {number} count - The new visitors count.
* @returns {{
* type: UPDATE_VISITORS_COUNT,
* }}
*/
export function updateVisitorsCount(count: number) {
return {
type: UPDATE_VISITORS_COUNT,
count
};
}
/**
* Visitors in queue count has been updated.
*

@ -5,7 +5,6 @@ import { IStore } from '../app/types';
import { IStateful } from '../base/app/types';
import {
CONFERENCE_JOINED,
CONFERENCE_JOIN_IN_PROGRESS,
ENDPOINT_MESSAGE_RECEIVED,
UPDATE_CONFERENCE_METADATA
} from '../base/conference/actionTypes';
@ -46,28 +45,15 @@ import {
setInVisitorsQueue,
setVisitorDemoteActor,
setVisitorsSupported,
updateVisitorsCount,
updateVisitorsInQueueCount
} from './actions';
import { JoinMeetingDialog } from './components';
import { getPromotionRequests, getVisitorsCount, getVisitorsInQueueCount } from './functions';
import { getPromotionRequests, getVisitorsInQueueCount } from './functions';
import logger from './logger';
import { WebsocketClient } from './websocket-client';
MiddlewareRegistry.register(({ dispatch, getState }) => next => action => {
switch (action.type) {
case CONFERENCE_JOIN_IN_PROGRESS: {
const { conference } = action;
conference.on(JitsiConferenceEvents.PROPERTIES_CHANGED, (properties: { 'visitor-count': number; }) => {
const visitorCount = Number(properties?.['visitor-count']);
if (!isNaN(visitorCount) && getVisitorsCount(getState) !== visitorCount) {
dispatch(updateVisitorsCount(visitorCount));
}
});
break;
}
case CONFERENCE_JOINED: {
const { conference } = action;

@ -1,4 +1,4 @@
import { CONFERENCE_WILL_LEAVE } from '../base/conference/actionTypes';
import { CONFERENCE_PROPERTIES_CHANGED, CONFERENCE_WILL_LEAVE } from '../base/conference/actionTypes';
import ReducerRegistry from '../base/redux/ReducerRegistry';
import {
@ -7,7 +7,6 @@ import {
SET_IN_VISITORS_QUEUE,
SET_VISITORS_SUPPORTED,
SET_VISITOR_DEMOTE_ACTOR,
UPDATE_VISITORS_COUNT,
UPDATE_VISITORS_IN_QUEUE_COUNT,
VISITOR_PROMOTION_REQUEST
} from './actionTypes';
@ -34,6 +33,18 @@ export interface IVisitorsState {
}
ReducerRegistry.register<IVisitorsState>('features/visitors', (state = DEFAULT_STATE, action): IVisitorsState => {
switch (action.type) {
case CONFERENCE_PROPERTIES_CHANGED: {
const visitorCount = Number(action.properties?.['visitor-count']);
if (!isNaN(visitorCount) && state.count !== visitorCount) {
return {
...state,
count: visitorCount
};
}
break;
}
case CONFERENCE_WILL_LEAVE: {
return {
...state,
@ -45,16 +56,6 @@ ReducerRegistry.register<IVisitorsState>('features/visitors', (state = DEFAULT_S
iAmVisitor: action.isRedirect ? state.iAmVisitor : DEFAULT_STATE.iAmVisitor
};
}
case UPDATE_VISITORS_COUNT: {
if (state.count === action.count) {
return state;
}
return {
...state,
count: action.count
};
}
case UPDATE_VISITORS_IN_QUEUE_COUNT: {
if (state.count === action.count) {
return state;

Loading…
Cancel
Save