diff --git a/app/package.json b/app/package.json
index a67be4d0..bb591e96 100644
--- a/app/package.json
+++ b/app/package.json
@@ -44,7 +44,7 @@
"react-intl-redux": "^2.2.0",
"react-redux": "^7.1.1",
"react-router-dom": "^5.1.2",
- "react-scripts": "^4.0.0",
+ "react-scripts": "^4.0.3",
"react-wakelock-react16": "0.0.7",
"redux": "^4.0.4",
"redux-logger": "^3.0.6",
diff --git a/app/src/RoomClient.js b/app/src/RoomClient.js
index ebff7281..edc1dc5f 100644
--- a/app/src/RoomClient.js
+++ b/app/src/RoomClient.js
@@ -21,6 +21,7 @@ import { permissions } from './permissions';
import * as locales from './translations/locales';
import { createIntl } from 'react-intl';
import { openDB, deleteDB } from 'idb';
+import { RECORDING_START, RECORDING_STOP, RECORDING_PAUSE, RECORDING_RESUME } from './recordingStates';
let createTorrent;
@@ -139,12 +140,6 @@ const VIDEO_SVC_ENCODINGS =
{ scalabilityMode: 'S3T3', dtx: true }
];
-// Recoding STATE
-const RECORDING_STOP='stop';
-const RECORDING_START='start';
-const RECORDING_PAUSE='pause';
-const RECORDING_RESUME='resume';
-
let store;
let intl;
@@ -3706,12 +3701,12 @@ export default class RoomClient
{
const ctx = new AudioContext();
const dest = ctx.createMediaStreamDestination();
- const micms = new MediaStream();
+ const micMS = new MediaStream();
- micms.addTrack(stream1);
+ micMS.addTrack(stream1);
- if (micms.getAudioTracks().length > 0)
- ctx.createMediaStreamSource(micms).connect(dest);
+ if (micMS.getAudioTracks().length > 0)
+ ctx.createMediaStreamSource(micMS).connect(dest);
if (stream2.getAudioTracks().length > 0)
ctx.createMediaStreamSource(stream2).connect(dest);
@@ -3729,6 +3724,14 @@ export default class RoomClient
gumStream = this._micProducer.track;
gdmStream = await navigator.mediaDevices.getDisplayMedia(RECORDING_CONSTRAINTS);
+ gdmStream.getVideoTracks().forEach((track) =>
+ {
+ track.addEventListener('ended', (e) =>
+ {
+ logger.debug(`gdmStream ${track.kind} track ended event: ${JSON.stringify(e)}`);
+ this.stopLocalRecording();
+ });
+ });
recorderStream = gumStream ? mixer(gumStream, gdmStream): gdmStream;
recorder = new MediaRecorder(recorderStream, { mimeType: recordingMimeType });
@@ -3739,7 +3742,7 @@ export default class RoomClient
}
else
{
- idbName=Date.now();
+ idbName = Date.now();
idbDB = await openDB(idbName, 1,
{
upgrade(db)
@@ -3784,11 +3787,25 @@ export default class RoomClient
}
};
- recorder.onerror = (e) =>
+ recorder.onerror = (error) =>
{
- logger.err(e);
- recorder.stop();
- store.dispatch(roomActions.setLocalRecordingInProgress(false));
+ logger.err(`Recorder onerror: ${error}`);
+ switch (error.name)
+ {
+ case 'SecurityError':
+ store.dispatch(requestActions.notify(
+ {
+ type : 'error',
+ text : intl.formatMessage({
+ id : 'room.localRecordingSecurityError',
+ defaultMessage : 'Recording the specified source is not allowed due to security restrictions. Check you client settings!'
+ })
+ }));
+ break;
+ case 'InvalidStateError':
+ default:
+ throw new Error(error);
+ }
};
recorder.onstop = (e) =>
@@ -3835,6 +3852,16 @@ export default class RoomClient
})
}));
logger.error('startLocalRecording() [error:"%o"]', error);
+ if (recorder) recorder.stop();
+ store.dispatch(meActions.setLocalRecordingState(RECORDING_STOP));
+ if (typeof gdmStream !== 'undefined' && gdmStream && typeof gdmStream.getTracks === 'function')
+ {
+ gdmStream.getTracks().forEach((track) => track.stop());
+ }
+
+ gdmStream=null;
+ recorderStream = null;
+ recorder = null;
return -1;
}
@@ -3843,8 +3870,7 @@ export default class RoomClient
{
await this.sendRequest('setLocalRecording', { localRecordingState: RECORDING_START });
- store.dispatch(roomActions.setLocalRecordingInProgress(true));
- store.dispatch(roomActions.setRecordingInProgress(true));
+ store.dispatch(meActions.setLocalRecordingState(RECORDING_START));
store.dispatch(requestActions.notify(
{
@@ -3864,7 +3890,7 @@ export default class RoomClient
defaultMessage : 'Unexpected error ocurred during local recording'
})
}));
- logger.error('startLocalRecord() [error:"%o"]', error);
+ logger.error('startLocalRecording() [error:"%o"]', error);
}
}
async stopLocalRecording()
@@ -3872,7 +3898,7 @@ export default class RoomClient
logger.debug('stopLocalRecording()');
try
{
- await this.sendRequest('setLocalRecording', { localRecordingState: RECORDING_STOP });
+ recorder.stop();
store.dispatch(requestActions.notify(
{
@@ -3882,8 +3908,9 @@ export default class RoomClient
})
}));
- recorder.stop();
- store.dispatch(roomActions.setLocalRecordingInProgress(false));
+ store.dispatch(meActions.setLocalRecordingState(RECORDING_STOP));
+
+ await this.sendRequest('setLocalRecording', { localRecordingState: RECORDING_STOP });
}
catch (error)
@@ -3905,14 +3932,14 @@ export default class RoomClient
async pauseLocalRecording()
{
recorder.pause();
- store.dispatch(roomActions.setLocalRecordingPaused(true));
+ store.dispatch(meActions.setLocalRecordingState(RECORDING_PAUSE));
await this.sendRequest('setLocalRecording', { localRecordingState: RECORDING_PAUSE });
}
async resumeLocalRecording()
{
recorder.resume();
- store.dispatch(roomActions.setLocalRecordingPaused(false));
+ store.dispatch(meActions.setLocalRecordingState(RECORDING_RESUME));
await this.sendRequest('setLocalRecording', { localRecordingState: RECORDING_RESUME });
}
diff --git a/app/src/actions/meActions.js b/app/src/actions/meActions.js
index 14b12136..39795745 100644
--- a/app/src/actions/meActions.js
+++ b/app/src/actions/meActions.js
@@ -116,3 +116,9 @@ export const setAutoMuted = (flag) =>
type : 'SET_AUTO_MUTED',
payload : { flag }
});
+
+export const setLocalRecordingState = (localRecordingState) =>
+ ({
+ type : 'SET_LOCAL_RECORDING_STATE',
+ payload : { localRecordingState }
+ });
\ No newline at end of file
diff --git a/app/src/actions/roomActions.js b/app/src/actions/roomActions.js
index f1ccd1fa..7f3c5441 100644
--- a/app/src/actions/roomActions.js
+++ b/app/src/actions/roomActions.js
@@ -18,24 +18,6 @@ export const setRoomActiveSpeaker = (peerId) =>
payload : { peerId }
});
-export const setRecordingInProgress = (recordingInProgress) =>
- ({
- type : 'SET_RECORDING_IN_PROGRESS',
- payload : { recordingInProgress }
- });
-
-export const setLocalRecordingInProgress = (localRecordingInProgress) =>
- ({
- type : 'SET_LOCAL_RECORDING_IN_PROGRESS',
- payload : { localRecordingInProgress }
- });
-
-export const setLocalRecordingPaused = (localRecordingPaused) =>
- ({
- type : 'SET_LOCAL_RECORDING_PAUSED',
- payload : { localRecordingPaused }
- });
-
export const setRoomLocked = () =>
({
type : 'SET_ROOM_LOCKED'
diff --git a/app/src/components/Controls/TopBar.js b/app/src/components/Controls/TopBar.js
index 2c113180..a63b356e 100644
--- a/app/src/components/Controls/TopBar.js
+++ b/app/src/components/Controls/TopBar.js
@@ -1,4 +1,3 @@
-/* eslint-disable no-console */
import React, { useState, useEffect } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
@@ -6,7 +5,8 @@ import {
lobbyPeersKeySelector,
peersLengthSelector,
raisedHandsSelector,
- makePermissionSelector
+ makePermissionSelector,
+ recordingInProgressSelector
} from '../Selectors';
import { permissions } from '../../permissions';
import * as appPropTypes from '../appPropTypes';
@@ -48,6 +48,7 @@ import PauseCircleOutlineIcon from '@material-ui/icons/PauseCircleOutline';
import PauseCircleFilledIcon from '@material-ui/icons/PauseCircleFilled';
import StopIcon from '@material-ui/icons/Stop';
import randomString from 'random-string';
+import { RECORDING_START, RECORDING_PAUSE, RECORDING_RESUME } from '../../recordingStates';
const styles = (theme) =>
({
@@ -179,7 +180,7 @@ const PulsingBadge = withStyles((theme) =>
}
}))(Badge);
-const RecIcon = withStyles((theme) =>
+const RecIcon = withStyles(() =>
({
root :
{
@@ -267,12 +268,16 @@ const TopBar = (props) =>
canPromote,
classes,
locale,
- localesList
+ localesList,
+ localRecordingState,
+ recordingInProgress
} = props;
useEffect(() =>
{
- if (room.recordingInProgress && !recordingConsentNotificationId)
+ if (
+ recordingInProgress &&
+ !recordingConsentNotificationId)
{
const notificationId = randomString({ length: 6 }).toLowerCase();
@@ -292,14 +297,16 @@ const TopBar = (props) =>
}
);
}
- if (!room.recordingInProgress && recordingConsentNotificationId)
+ if (
+ !recordingInProgress
+ && recordingConsentNotificationId)
{
closeNotification(recordingConsentNotificationId);
setRecordingConsentNotificationId(null);
}
},
[
- room.recordingInProgress, recordingConsentNotificationId,
+ localRecordingState, recordingInProgress, recordingConsentNotificationId,
addNotification, closeNotification, intl
]);
@@ -317,7 +324,8 @@ const TopBar = (props) =>
defaultMessage : 'Lock room'
});
- const recordingTooltip = room.localRecordingInProgress ?
+ const recordingTooltip = (localRecordingState === RECORDING_START ||
+ localRecordingState === RECORDING_RESUME) ?
intl.formatMessage({
id : 'tooltip.stopLocalRecording',
defaultMessage : 'Stop local recording'
@@ -328,7 +336,7 @@ const TopBar = (props) =>
defaultMessage : 'Start local recording'
});
- const recordingPausedTooltip = room.localRecordingPaused ?
+ const recordingPausedTooltip = localRecordingState === RECORDING_PAUSE ?
intl.formatMessage({
id : 'tooltip.resumeLocalRecording',
defaultMessage : 'Resume local recording'
@@ -403,7 +411,7 @@ const TopBar = (props) =>
}
- { room.recordingInProgress &&
+ { recordingInProgress &&
>
{ currentMenu === 'moreActions' &&
- { room.localRecordingInProgress &&
-
}
{
handleMenuClose();
- if (room.localRecordingInProgress)
+ if (localRecordingState === RECORDING_START ||
+ localRecordingState === RECORDING_PAUSE ||
+ localRecordingState === RECORDING_RESUME)
{
roomClient.stopLocalRecording();
}
@@ -713,27 +729,33 @@ const TopBar = (props) =>
- { room.localRecordingInProgress ?
-
- :
-
+ {
+ (localRecordingState === RECORDING_START ||
+ localRecordingState === RECORDING_PAUSE ||
+ localRecordingState === RECORDING_RESUME) ?
+
+ :
+
}
- { room.localRecordingInProgress ?
-
-
-
- :
-
-
-
+ {
+ (localRecordingState === RECORDING_START ||
+ localRecordingState === RECORDING_PAUSE ||
+ localRecordingState === RECORDING_RESUME) ?
+
+
+
+ :
+
+
+
}
@@ -893,57 +915,66 @@ const TopBar = (props) =>
}
}
- { room.localRecordingInProgress &&
-
- {
- handleMenuClose();
- if (room.localRecordingPaused)
+ {
+ (
+ localRecordingState === RECORDING_PAUSE ||
+ localRecordingState === RECORDING_RESUME ||
+ localRecordingState === RECORDING_START
+ )
+ &&
+
{
- roomClient.resumeLocalRecording();
+ handleMenuClose();
+ if (localRecordingState === RECORDING_PAUSE)
+ {
+ roomClient.resumeLocalRecording();
+ }
+ else
+ {
+ roomClient.pauseLocalRecording();
+ }
}
- else
- {
- roomClient.pauseLocalRecording();
}
- }
- }
- >
-
- { room.localRecordingPaused ?
-
+
+ { localRecordingState === RECORDING_PAUSE ?
+
+ :
+
+ }
+
+
+ { localRecordingState === RECORDING_PAUSE ?
+
+
+
:
-
+
+
+
}
-
- { room.localRecordingPaused ?
-
-
-
- :
-
-
-
- }
+
-
}
{
handleMenuClose();
- if (room.localRecordingInProgress)
+ if (localRecordingState === RECORDING_START ||
+ localRecordingState === RECORDING_PAUSE ||
+ localRecordingState === RECORDING_RESUME)
{
roomClient.stopLocalRecording();
}
@@ -957,26 +988,32 @@ const TopBar = (props) =>
- { room.localRecordingInProgress ?
-
- :
-
+ {
+ (localRecordingState === RECORDING_START ||
+ localRecordingState === RECORDING_PAUSE ||
+ localRecordingState === RECORDING_RESUME) ?
+
+ :
+
}
- { room.localRecordingInProgress ?
-
-
-
- :
-
-
-
+ {
+ (localRecordingState === RECORDING_START ||
+ localRecordingState === RECORDING_PAUSE ||
+ localRecordingState === RECORDING_RESUME) ?
+
+
+
+ :
+
+
+
}
@@ -1239,16 +1278,18 @@ const makeMapStateToProps = () =>
const mapStateToProps = (state) =>
({
- room : state.room,
- isMobile : state.me.browser.platform === 'mobile',
- peersLength : peersLengthSelector(state),
- lobbyPeers : lobbyPeersKeySelector(state),
- permanentTopBar : state.settings.permanentTopBar,
- drawerOverlayed : state.settings.drawerOverlayed,
- toolAreaOpen : state.toolarea.toolAreaOpen,
- loggedIn : state.me.loggedIn,
- loginEnabled : state.me.loginEnabled,
- unread : state.toolarea.unreadMessages +
+ room : state.room,
+ isMobile : state.me.browser.platform === 'mobile',
+ peersLength : peersLengthSelector(state),
+ lobbyPeers : lobbyPeersKeySelector(state),
+ permanentTopBar : state.settings.permanentTopBar,
+ drawerOverlayed : state.settings.drawerOverlayed,
+ toolAreaOpen : state.toolarea.toolAreaOpen,
+ loggedIn : state.me.loggedIn,
+ loginEnabled : state.me.loginEnabled,
+ localRecordingState : state.me.localRecordingState,
+ recordingInProgress : recordingInProgressSelector(state),
+ unread : state.toolarea.unreadMessages +
state.toolarea.unreadFiles + raisedHandsSelector(state),
canProduceExtraVideo : hasExtraVideoPermission(state),
canLock : hasLockPermission(state),
@@ -1327,6 +1368,7 @@ export default withRoomContext(connect(
prev.me.loginEnabled === next.me.loginEnabled &&
prev.me.picture === next.me.picture &&
prev.me.roles === next.me.roles &&
+ prev.me.localRecordingState === next.me.localRecordingState &&
prev.toolarea.unreadMessages === next.toolarea.unreadMessages &&
prev.toolarea.unreadFiles === next.toolarea.unreadFiles &&
prev.toolarea.toolAreaOpen === next.toolarea.toolAreaOpen &&
diff --git a/app/src/components/JoinDialog.js b/app/src/components/JoinDialog.js
index 72dc170e..8fd013d8 100644
--- a/app/src/components/JoinDialog.js
+++ b/app/src/components/JoinDialog.js
@@ -205,6 +205,7 @@ const JoinDialog = ({
(location.pathname === '/') && history.push(encodeURIComponent(roomId));
});
+ /* TODO: unused! Should we remove it?
const _askForPerms = () =>
{
if (mediaPerms.video || mediaPerms.audio)
@@ -212,6 +213,7 @@ const JoinDialog = ({
navigator.mediaDevices.getUserMedia(mediaPerms);
}
};
+ */
const handleSetMediaPerms = (event, newMediaPerms) =>
{
diff --git a/app/src/components/Loader/LoadingView.js b/app/src/components/Loader/LoadingView.js
index 3887f67f..62b1f9c2 100644
--- a/app/src/components/Loader/LoadingView.js
+++ b/app/src/components/Loader/LoadingView.js
@@ -1,7 +1,7 @@
import React from 'react';
import { withStyles } from '@material-ui/core/styles';
-const styles = (theme) =>
+const styles = () =>
({
root :
{
diff --git a/app/src/components/Notifications/Notifications.js b/app/src/components/Notifications/Notifications.js
index 38d9cfc9..90176fc3 100644
--- a/app/src/components/Notifications/Notifications.js
+++ b/app/src/components/Notifications/Notifications.js
@@ -29,7 +29,16 @@ class Notifications extends Component
if (notExists) continue;
notExists = notExists ||
- !currentNotifications.filter(({ id }) => newNotifications[i].id === id).length;
+ !currentNotifications.filter(
+ ({ id }) => newNotifications[i].id === id).length ||
+ currentNotifications.filter(
+ ({ id }) =>
+ (
+ newNotifications[i].id === id &&
+ newNotifications[i].toBeClosed === true
+ )
+ ).length;
+
}
return notExists;
diff --git a/app/src/components/Selectors.js b/app/src/components/Selectors.js
index 3b2337ff..728ef04a 100644
--- a/app/src/components/Selectors.js
+++ b/app/src/components/Selectors.js
@@ -1,4 +1,5 @@
import { createSelector } from 'reselect';
+import { RECORDING_INIT, RECORDING_START, RECORDING_STOP, RECORDING_PAUSE, RECORDING_RESUME } from '../recordingStates';
const meRolesSelect = (state) => state.me.roles;
const userRolesSelect = (state) => state.room.userRoles;
@@ -8,6 +9,7 @@ const producersSelect = (state) => state.producers;
const consumersSelect = (state) => state.consumers;
const spotlightsSelector = (state) => state.room.spotlights;
const peersSelector = (state) => state.peers;
+const meSelector = (state) => state.me;
const lobbyPeersSelector = (state) => state.lobbyPeers;
const getPeerConsumers = (state, id) =>
(state.peers[id] ? state.peers[id].consumers : null);
@@ -300,9 +302,32 @@ export const makePermissionSelector = (permission) =>
);
};
-/*
-export const localRecordingSelector = createSelector(
- peersSelector,
- (peers) => peers.reduce((acc, elem) => elem.localRecording, 0)
+export const recordingInProgressSelector = createSelector(
+ peersValueSelector,
+ meSelector,
+ (peers, me) =>
+ {
+ if (
+ me.localRecordingState === RECORDING_START ||
+ me.localRecordingState === RECORDING_RESUME ||
+ peers.findIndex((e) =>
+ e.localRecordingState === RECORDING_START ||
+ e.localRecordingState === RECORDING_RESUME
+ ) !== -1
+ )
+ {
+ return true;
+ }
+ else if (
+ me.localRecordingState === RECORDING_INIT ||
+ me.localRecordingState === RECORDING_STOP ||
+ me.localRecordingState === RECORDING_PAUSE ||
+ peers.findIndex((e) =>
+ e.localRecordingState === RECORDING_START ||
+ e.localRecordingState === RECORDING_RESUME
+ ) === -1
+
+ )
+ return false;
+ }
);
-*/
\ No newline at end of file
diff --git a/app/src/recordingStates.js b/app/src/recordingStates.js
new file mode 100644
index 00000000..c2a5d323
--- /dev/null
+++ b/app/src/recordingStates.js
@@ -0,0 +1,6 @@
+// Recoding STATE
+export const RECORDING_INIT = null;
+export const RECORDING_START = 'start';
+export const RECORDING_STOP = 'stop';
+export const RECORDING_PAUSE = 'pause';
+export const RECORDING_RESUME = 'resume';
diff --git a/app/src/reducers/me.js b/app/src/reducers/me.js
index d0e41495..d9cdef2f 100644
--- a/app/src/reducers/me.js
+++ b/app/src/reducers/me.js
@@ -19,7 +19,8 @@ const initialState =
raisedHandInProgress : false,
loggedIn : false,
isSpeaking : false,
- isAutoMuted : true
+ isAutoMuted : true,
+ localRecordingState : null
};
const me = (state = initialState, action) =>
@@ -167,6 +168,13 @@ const me = (state = initialState, action) =>
return { ...state, isAutoMuted: flag };
}
+ case 'SET_LOCAL_RECORDING_STATE':
+ {
+ const { localRecordingState } = action.payload;
+
+ return { ...state, localRecordingState };
+ }
+
default:
return state;
}
diff --git a/app/src/reducers/room.js b/app/src/reducers/room.js
index af3223dd..1d311477 100644
--- a/app/src/reducers/room.js
+++ b/app/src/reducers/room.js
@@ -4,9 +4,6 @@ const initialState =
// new/connecting/connected/disconnected/closed,
state : 'new',
locked : false,
- recordingInProgress : false,
- localRecordingInProgress : false,
- localRecordingPaused : false,
inLobby : false,
signInRequired : false,
overRoomLimit : false,
@@ -65,27 +62,6 @@ const room = (state = initialState, action) =>
return { ...state, state: roomState, activeSpeakerId: null };
}
- case 'SET_RECORDING_IN_PROGRESS':
- {
- const { recordingInProgress } = action.payload;
-
- return { ...state, recordingInProgress };
- }
-
- case 'SET_LOCAL_RECORDING_IN_PROGRESS':
- {
- const { localRecordingInProgress } = action.payload;
-
- return { ...state, localRecordingInProgress };
- }
-
- case 'SET_LOCAL_RECORDING_PAUSED':
- {
- const { localRecordingPaused } = action.payload;
-
- return { ...state, localRecordingPaused };
- }
-
case 'SET_ROOM_LOCKED':
{
return { ...state, locked: true };
diff --git a/app/src/store.js b/app/src/store.js
index c5a0088b..3b512de9 100644
--- a/app/src/store.js
+++ b/app/src/store.js
@@ -76,11 +76,10 @@ if (process.env.REACT_APP_DEBUG === '*' || process.env.NODE_ENV !== 'production'
{
// filter VOLUME level actions from log
predicate : (getState, action) => !(
- action.type === 'SET_PEER_VOLUME'/* ||
+ action.type === 'SET_PEER_VOLUME' ||
action.type === 'SET_ROOM_ACTIVE_SPEAKER'||
action.type === 'SET_IS_SPEAKING' ||
action.type === 'SET_AUTO_MUTED'
-*/
),
duration : true,
timestamp : false,
diff --git a/app/src/translations/cn.json b/app/src/translations/cn.json
index e0ba227e..3b59dd36 100644
--- a/app/src/translations/cn.json
+++ b/app/src/translations/cn.json
@@ -75,6 +75,7 @@
"room.localRecordingResumed": null,
"room.localRecordingStopped": null,
"room.recordingConsent": null,
+ "room.localRecordingSecurityError": null,
"me.mutedPTT": null,
diff --git a/app/src/translations/cs.json b/app/src/translations/cs.json
index 123ca90a..95b73845 100644
--- a/app/src/translations/cs.json
+++ b/app/src/translations/cs.json
@@ -76,6 +76,7 @@
"room.localRecordingResumed": null,
"room.localRecordingStopped": null,
"room.recordingConsent": null,
+ "room.localRecordingSecurityError": null,
"me.mutedPTT": "Jste ztišen, chcete-li mluvit, podržte mezerník",
diff --git a/app/src/translations/de.json b/app/src/translations/de.json
index da9c45b3..1149754a 100644
--- a/app/src/translations/de.json
+++ b/app/src/translations/de.json
@@ -76,6 +76,7 @@
"room.localRecordingResumed": null,
"room.localRecordingStopped": null,
"room.recordingConsent": null,
+ "room.localRecordingSecurityError": null,
"me.mutedPTT": "Du bist stummgeschaltet. Halte die LEERTASTE um zu sprechen",
diff --git a/app/src/translations/dk.json b/app/src/translations/dk.json
index 84bc79b4..d1407a4f 100644
--- a/app/src/translations/dk.json
+++ b/app/src/translations/dk.json
@@ -76,6 +76,7 @@
"room.localRecordingResumed": null,
"room.localRecordingStopped": null,
"room.recordingConsent": null,
+ "room.localRecordingSecurityError": null,
"me.mutedPTT": null,
diff --git a/app/src/translations/el.json b/app/src/translations/el.json
index c2433842..8807aa9f 100644
--- a/app/src/translations/el.json
+++ b/app/src/translations/el.json
@@ -76,6 +76,7 @@
"room.localRecordingResumed": null,
"room.localRecordingStopped": null,
"room.recordingConsent": null,
+ "room.localRecordingSecurityError": null,
"me.mutedPTT": null,
diff --git a/app/src/translations/en.json b/app/src/translations/en.json
index 70836734..b019d9ee 100644
--- a/app/src/translations/en.json
+++ b/app/src/translations/en.json
@@ -76,6 +76,7 @@
"room.localRecordingResumed": "{displayName} resumed local recording",
"room.localRecordingStopped": "{displayName} stopped local recording",
"room.recordingConsent": "When attending this meeting you agree and give your consent that the meeting will be audio and video recorded and/or live broadcasted through web streaming.",
+ "room.localRecordingSecurityError": "Recording the specified source is not allowed due to security restrictions. Check you client settings!",
"me.mutedPTT": "You are muted, hold down SPACE-BAR to talk",
diff --git a/app/src/translations/es.json b/app/src/translations/es.json
index 855ee6ae..ac68bf04 100644
--- a/app/src/translations/es.json
+++ b/app/src/translations/es.json
@@ -76,6 +76,7 @@
"room.localRecordingResumed": null,
"room.localRecordingStopped": null,
"room.recordingConsent": null,
+ "room.localRecordingSecurityError": null,
"me.mutedPTT": null,
diff --git a/app/src/translations/fr.json b/app/src/translations/fr.json
index 2c177bbd..608204b5 100644
--- a/app/src/translations/fr.json
+++ b/app/src/translations/fr.json
@@ -76,6 +76,7 @@
"room.localRecordingResumed": null,
"room.localRecordingStopped": null,
"room.recordingConsent": null,
+ "room.localRecordingSecurityError": null,
"me.mutedPTT": null,
diff --git a/app/src/translations/hi.json b/app/src/translations/hi.json
index bb9406b2..1190af80 100644
--- a/app/src/translations/hi.json
+++ b/app/src/translations/hi.json
@@ -76,6 +76,7 @@
"room.localRecordingResumed": null,
"room.localRecordingStopped": null,
"room.recordingConsent": null,
+ "room.localRecordingSecurityError": null,
"me.mutedPTT": "आप शांत हैं, बात करने के लिए स्पेस-बार दबाईए",
diff --git a/app/src/translations/hr.json b/app/src/translations/hr.json
index b9fabaf9..a993c266 100644
--- a/app/src/translations/hr.json
+++ b/app/src/translations/hr.json
@@ -76,6 +76,7 @@
"room.localRecordingResumed": null,
"room.localRecordingStopped": null,
"room.recordingConsent": null,
+ "room.localRecordingSecurityError": null,
"me.mutedPTT": "Utišani ste, pritisnite i držite SPACE tipku za razgovor",
diff --git a/app/src/translations/hu.json b/app/src/translations/hu.json
index 016b81b0..4e70e7f0 100644
--- a/app/src/translations/hu.json
+++ b/app/src/translations/hu.json
@@ -39,7 +39,7 @@
"room.audioOnly": "csak Hang",
"room.audioVideo": "Hang és Videó",
"room.youAreReady": "Ok, kész vagy",
- "room.emptyRequireLogin": "A konferencia üres! Be kell lépned a konferencia elkezdéséhez, vagy várnod kell amíg a házigazda becsatlakozik.",
+ "room.emptyRequireLogin": "Be kell jelentkezned a konferencia elkezdéséhez, vagy várnod kell amíg a házigazda megnyitja a szobát.",
"room.locketWait": "Az automatikus belépés tiltva van - Várj amíg valaki beenged ...",
"room.lobbyAdministration": "Előszoba adminisztráció",
"room.peersInLobby": "Résztvevők az előszobában",
@@ -76,6 +76,7 @@
"room.localRecordingResumed": "{displayName} visszaindította a helyi rögzítést",
"room.localRecordingStopped": "{displayName} leállította a helyi rögzítést",
"room.recordingConsent": "A konferencián való részvételeddel beleegyezésed adod hogy a konferenciáról hang és videó felvétel, és/vagy élő közvetítés készüljön!",
+ "room.localRecordingSecurityError": null,
"me.mutedPTT": "Némítva vagy, ha beszélnél nyomd le a SZÓKÖZ billentyűt",
diff --git a/app/src/translations/it.json b/app/src/translations/it.json
index 9eacccbf..440fd8a8 100644
--- a/app/src/translations/it.json
+++ b/app/src/translations/it.json
@@ -76,6 +76,7 @@
"room.localRecordingResumed": null,
"room.localRecordingStopped": null,
"room.recordingConsent": null,
+ "room.localRecordingSecurityError": null,
"me.mutedPTT": "Sei mutato, tieni premuto SPAZIO per parlare",
diff --git a/app/src/translations/kk.json b/app/src/translations/kk.json
index 4c5ff55c..7682442c 100644
--- a/app/src/translations/kk.json
+++ b/app/src/translations/kk.json
@@ -74,6 +74,7 @@
"room.localRecordingResumed": null,
"room.localRecordingStopped": null,
"room.recordingConsent": null,
+ "room.localRecordingSecurityError": null,
"me.mutedPTT": "Сіз дыбыссызсыз, сөйлесу үшін БОС ОРЫН пернесін ұстап тұрыңыз",
diff --git a/app/src/translations/lv.json b/app/src/translations/lv.json
index 142a1400..ec880fb9 100644
--- a/app/src/translations/lv.json
+++ b/app/src/translations/lv.json
@@ -75,6 +75,7 @@
"room.localRecordingResumed": null,
"room.localRecordingStopped": null,
"room.recordingConsent": null,
+ "room.localRecordingSecurityError": null,
"me.mutedPTT": "Jūs esat noklusināts. Turiet taustiņu SPACE-BAR, lai runātu",
diff --git a/app/src/translations/nb.json b/app/src/translations/nb.json
index 8c02e2e6..2e63c529 100644
--- a/app/src/translations/nb.json
+++ b/app/src/translations/nb.json
@@ -76,6 +76,7 @@
"room.localRecordingResumed": null,
"room.localRecordingStopped": null,
"room.recordingConsent": null,
+ "room.localRecordingSecurityError": null,
"me.mutedPTT": "Du er dempet, hold nede SPACE for å snakke",
diff --git a/app/src/translations/pl.json b/app/src/translations/pl.json
index 749be312..324ffdf4 100644
--- a/app/src/translations/pl.json
+++ b/app/src/translations/pl.json
@@ -76,6 +76,7 @@
"room.localRecordingResumed": null,
"room.localRecordingStopped": null,
"room.recordingConsent": null,
+ "room.localRecordingSecurityError": null,
"me.mutedPTT": "Masz wyciszony mikrofon, przytrzymaj SPACJĘ, aby mówić.",
diff --git a/app/src/translations/pt.json b/app/src/translations/pt.json
index 8de4668f..bed3e869 100644
--- a/app/src/translations/pt.json
+++ b/app/src/translations/pt.json
@@ -76,6 +76,7 @@
"room.localRecordingResumed": null,
"room.localRecordingStopped": null,
"room.recordingConsent": null,
+ "room.localRecordingSecurityError": null,
"me.mutedPTT": null,
diff --git a/app/src/translations/ro.json b/app/src/translations/ro.json
index a208a254..3f57158e 100644
--- a/app/src/translations/ro.json
+++ b/app/src/translations/ro.json
@@ -76,6 +76,7 @@
"room.localRecordingResumed": null,
"room.localRecordingStopped": null,
"room.recordingConsent": null,
+ "room.localRecordingSecurityError": null,
"me.mutedPTT": null,
diff --git a/app/src/translations/ru.json b/app/src/translations/ru.json
index 02fba762..b4a3446e 100644
--- a/app/src/translations/ru.json
+++ b/app/src/translations/ru.json
@@ -76,6 +76,7 @@
"room.localRecordingResumed": null,
"room.localRecordingStopped": null,
"room.recordingConsent": null,
+ "room.localRecordingSecurityError": null,
"me.mutedPTT": "Вы отключены, удерживайте ПРОБЕЛ, чтобы говорить",
diff --git a/app/src/translations/tr.json b/app/src/translations/tr.json
index 89793b42..e083d9f0 100644
--- a/app/src/translations/tr.json
+++ b/app/src/translations/tr.json
@@ -76,6 +76,7 @@
"room.localRecordingResumed": null,
"room.localRecordingStopped": null,
"room.recordingConsent": null,
+ "room.localRecordingSecurityError": null,
"me.mutedPTT": "Sesiniz kapalı, konuşmak için SPACE tuşuna basılı tutun",
diff --git a/app/src/translations/tw.json b/app/src/translations/tw.json
index d579e8e9..10678a16 100644
--- a/app/src/translations/tw.json
+++ b/app/src/translations/tw.json
@@ -75,6 +75,7 @@
"room.localRecordingResumed": null,
"room.localRecordingStopped": null,
"room.recordingConsent": null,
+ "room.localRecordingSecurityError": null,
"me.mutedPTT": "您已靜音,請按下 空白鍵 來說話",
diff --git a/app/src/translations/uk.json b/app/src/translations/uk.json
index 327a4b51..f9fb0ff9 100644
--- a/app/src/translations/uk.json
+++ b/app/src/translations/uk.json
@@ -76,6 +76,7 @@
"room.localRecordingResumed": null,
"room.localRecordingStopped": null,
"room.recordingConsent": null,
+ "room.localRecordingSecurityError": null,
"me.mutedPTT": " У вас вимкнено звук, утримуйте клавішу SPACE-BAR (пробіл), щоб говорити",
"roles.gotRole": "Ви отримали роль {role}",
diff --git a/server/lib/Peer.js b/server/lib/Peer.js
index 3f318d6f..ff183dd5 100644
--- a/server/lib/Peer.js
+++ b/server/lib/Peer.js
@@ -4,6 +4,14 @@ const Logger = require('./Logger');
const logger = new Logger('Peer');
+// Recoding STATE
+const RECORDING_STOP='stop';
+const RECORDING_START='start';
+const RECORDING_PAUSE='pause';
+const RECORDING_RESUME='resume';
+
+const RECORDING_TYPE_LOCAL='local';
+
class Peer extends EventEmitter
{
constructor({ id, roomId, socket })
@@ -49,7 +57,7 @@ class Peer extends EventEmitter
this._localRecordingState = null;
- this._localRecordingStateHistory = [];
+ this._recordingStateHistory = [];
this._transports = new Map();
@@ -303,19 +311,24 @@ class Peer extends EventEmitter
return this._localRecordingState;
}
- get localRecordingStateHistory()
+ get recordingStateHistory()
{
- return this._localRecordingStateHistory;
+ return this._recordingStateHistory;
}
- set localRecordingState(localRecordingState)
+ set localRecordingState(recordingState)
{
- this.localRecordingStateHistory.push({
- timestamp : Date.now(),
- localRecordingState
- });
+ this._localRecordingState=recordingState;
+ this.addRecordingStateHistory(recordingState, RECORDING_TYPE_LOCAL);
+ }
- this._localRecordingState=localRecordingState;
+ addRecordingStateHistory(recordingState, recordingType)
+ {
+ this.recordingStateHistory.push({
+ timestamp : Date.now(),
+ recordingState,
+ recordingType
+ });
}
addRole(newRole)
@@ -408,14 +421,14 @@ class Peer extends EventEmitter
{
const peerInfo =
{
- id : this.id,
- displayName : this.displayName,
- picture : this.picture,
- roles : this.roles.map((role) => role.id),
- raisedHand : this.raisedHand,
- raisedHandTimestamp : this.raisedHandTimestamp,
- localRecordingState : this.localRecordingState,
- localRecordingStateHistory : this.localRecordingStateHistory
+ id : this.id,
+ displayName : this.displayName,
+ picture : this.picture,
+ roles : this.roles.map((role) => role.id),
+ raisedHand : this.raisedHand,
+ raisedHandTimestamp : this.raisedHandTimestamp,
+ localRecordingState : this.localRecordingState,
+ recordingStateHistory : this.localRecordingStateHistory
};
return peerInfo;
diff --git a/server/lib/Room.js b/server/lib/Room.js
index b8aa0cbc..c61b846a 100644
--- a/server/lib/Room.js
+++ b/server/lib/Room.js
@@ -838,6 +838,8 @@ class Room extends EventEmitter
roomPermissions[PROMOTE_PEER].some((roomRole) => role.id === roomRole.id)
);
+ delete this._peers[peer.id];
+
// No peers left with PROMOTE_PEER, might need to give
// lobbyPeers to peers that are left.
if (
diff --git a/server/lib/promExporter.js b/server/lib/promExporter.js
index 82bb7a13..3f921abf 100644
--- a/server/lib/promExporter.js
+++ b/server/lib/promExporter.js
@@ -267,7 +267,7 @@ module.exports = async function(rooms, peers, config)
await collect(registry);
res.set('Content-Type', registry.contentType);
- const data = registry.metrics();
+ const data = await registry.metrics();
res.end(data);
});