From 4aba07c76d7344865e705d20fd5f2ae3881684fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Thu, 25 Mar 2021 21:12:41 +0100 Subject: [PATCH] recording state moved to peer and other fixes --- app/package.json | 2 +- app/src/RoomClient.js | 73 +++-- app/src/actions/meActions.js | 6 + app/src/actions/roomActions.js | 18 -- app/src/components/Controls/TopBar.js | 304 ++++++++++-------- app/src/components/JoinDialog.js | 2 + app/src/components/Loader/LoadingView.js | 2 +- .../components/Notifications/Notifications.js | 11 +- app/src/components/Selectors.js | 35 +- app/src/recordingStates.js | 6 + app/src/reducers/me.js | 10 +- app/src/reducers/room.js | 24 -- app/src/store.js | 3 +- app/src/translations/cn.json | 1 + app/src/translations/cs.json | 1 + app/src/translations/de.json | 1 + app/src/translations/dk.json | 1 + app/src/translations/el.json | 1 + app/src/translations/en.json | 1 + app/src/translations/es.json | 1 + app/src/translations/fr.json | 1 + app/src/translations/hi.json | 1 + app/src/translations/hr.json | 1 + app/src/translations/hu.json | 3 +- app/src/translations/it.json | 1 + app/src/translations/kk.json | 1 + app/src/translations/lv.json | 1 + app/src/translations/nb.json | 1 + app/src/translations/pl.json | 1 + app/src/translations/pt.json | 1 + app/src/translations/ro.json | 1 + app/src/translations/ru.json | 1 + app/src/translations/tr.json | 1 + app/src/translations/tw.json | 1 + app/src/translations/uk.json | 1 + server/lib/Peer.js | 47 ++- server/lib/Room.js | 2 + server/lib/promExporter.js | 2 +- 38 files changed, 345 insertions(+), 226 deletions(-) create mode 100644 app/src/recordingStates.js 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.localRecordingPaused) + { + ( + localRecordingState === RECORDING_START || + localRecordingState === RECORDING_RESUME || + localRecordingState === RECORDING_PAUSE + ) + && + { - 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(); } @@ -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); });