mirror of
https://github.com/edumeet/edumeet.git
synced 2026-07-28 13:33:53 +00:00
recording state moved to peer and other fixes
This commit is contained in:
parent
d4da1cde0e
commit
4aba07c76d
38 changed files with 345 additions and 226 deletions
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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 });
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
});
|
||||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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) =>
|
|||
}
|
||||
<div className={classes.grow} />
|
||||
<div className={classes.sectionDesktop}>
|
||||
{ room.recordingInProgress &&
|
||||
{ recordingInProgress &&
|
||||
<IconButton
|
||||
disabled
|
||||
color='inherit'
|
||||
|
|
@ -650,56 +658,64 @@ const TopBar = (props) =>
|
|||
>
|
||||
{ currentMenu === 'moreActions' &&
|
||||
<Paper>
|
||||
{ room.localRecordingInProgress &&
|
||||
<MenuItem
|
||||
aria-label={recordingPausedTooltip}
|
||||
onClick={() =>
|
||||
{
|
||||
handleMenuClose();
|
||||
if (room.localRecordingPaused)
|
||||
{
|
||||
(
|
||||
localRecordingState === RECORDING_START ||
|
||||
localRecordingState === RECORDING_RESUME ||
|
||||
localRecordingState === RECORDING_PAUSE
|
||||
)
|
||||
&&
|
||||
<MenuItem
|
||||
aria-label={recordingPausedTooltip}
|
||||
onClick={() =>
|
||||
{
|
||||
roomClient.resumeLocalRecording();
|
||||
handleMenuClose();
|
||||
if (localRecordingState === RECORDING_PAUSE)
|
||||
{
|
||||
roomClient.resumeLocalRecording();
|
||||
}
|
||||
else
|
||||
{
|
||||
roomClient.pauseLocalRecording();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
roomClient.pauseLocalRecording();
|
||||
}
|
||||
}
|
||||
}
|
||||
>
|
||||
<Badge
|
||||
color='primary'
|
||||
>
|
||||
{ room.localRecordingPaused ?
|
||||
<PauseCircleFilledIcon />
|
||||
<Badge
|
||||
color='primary'
|
||||
>
|
||||
{ localRecordingState === RECORDING_PAUSE ?
|
||||
<PauseCircleFilledIcon />
|
||||
:
|
||||
<PauseCircleOutlineIcon />
|
||||
}
|
||||
</Badge>
|
||||
{ localRecordingState === RECORDING_PAUSE ?
|
||||
<p className={classes.moreAction}>
|
||||
<FormattedMessage
|
||||
id='tooltip.resumeLocalRecording'
|
||||
defaultMessage='Resume local recording'
|
||||
/>
|
||||
</p>
|
||||
:
|
||||
<PauseCircleOutlineIcon />
|
||||
<p className={classes.moreAction}>
|
||||
<FormattedMessage
|
||||
id='tooltip.pauseLocalRecording'
|
||||
defaultMessage='Pause local recording'
|
||||
/>
|
||||
</p>
|
||||
}
|
||||
</Badge>
|
||||
{ room.localRecordingPaused ?
|
||||
<p className={classes.moreAction}>
|
||||
<FormattedMessage
|
||||
id='tooltip.resumeLocalRecording'
|
||||
defaultMessage='Resume local recording'
|
||||
/>
|
||||
</p>
|
||||
:
|
||||
<p className={classes.moreAction}>
|
||||
<FormattedMessage
|
||||
id='tooltip.pauseLocalRecording'
|
||||
defaultMessage='Pause local recording'
|
||||
/>
|
||||
</p>
|
||||
}
|
||||
|
||||
</MenuItem>
|
||||
</MenuItem>
|
||||
}
|
||||
<MenuItem
|
||||
aria-label={recordingTooltip}
|
||||
onClick={() =>
|
||||
{
|
||||
handleMenuClose();
|
||||
if (room.localRecordingInProgress)
|
||||
if (localRecordingState === RECORDING_START ||
|
||||
localRecordingState === RECORDING_PAUSE ||
|
||||
localRecordingState === RECORDING_RESUME)
|
||||
{
|
||||
roomClient.stopLocalRecording();
|
||||
}
|
||||
|
|
@ -713,27 +729,33 @@ const TopBar = (props) =>
|
|||
<Badge
|
||||
color='primary'
|
||||
>
|
||||
{ room.localRecordingInProgress ?
|
||||
<StopIcon />
|
||||
:
|
||||
<FiberManualRecordIcon />
|
||||
{
|
||||
(localRecordingState === RECORDING_START ||
|
||||
localRecordingState === RECORDING_PAUSE ||
|
||||
localRecordingState === RECORDING_RESUME) ?
|
||||
<StopIcon />
|
||||
:
|
||||
<FiberManualRecordIcon />
|
||||
}
|
||||
</Badge>
|
||||
|
||||
{ room.localRecordingInProgress ?
|
||||
<p className={classes.moreAction}>
|
||||
<FormattedMessage
|
||||
id='tooltip.stopLocalRecording'
|
||||
defaultMessage='Stop local recording'
|
||||
/>
|
||||
</p>
|
||||
:
|
||||
<p className={classes.moreAction}>
|
||||
<FormattedMessage
|
||||
id='tooltip.startLocalRecording'
|
||||
defaultMessage='Start local recording'
|
||||
/>
|
||||
</p>
|
||||
{
|
||||
(localRecordingState === RECORDING_START ||
|
||||
localRecordingState === RECORDING_PAUSE ||
|
||||
localRecordingState === RECORDING_RESUME) ?
|
||||
<p className={classes.moreAction}>
|
||||
<FormattedMessage
|
||||
id='tooltip.stopLocalRecording'
|
||||
defaultMessage='Stop local recording'
|
||||
/>
|
||||
</p>
|
||||
:
|
||||
<p className={classes.moreAction}>
|
||||
<FormattedMessage
|
||||
id='tooltip.startLocalRecording'
|
||||
defaultMessage='Start local recording'
|
||||
/>
|
||||
</p>
|
||||
}
|
||||
|
||||
</MenuItem>
|
||||
|
|
@ -893,57 +915,66 @@ const TopBar = (props) =>
|
|||
}
|
||||
</MenuItem>
|
||||
}
|
||||
{ room.localRecordingInProgress &&
|
||||
<MenuItem
|
||||
aria-label={recordingPausedTooltip}
|
||||
onClick={() =>
|
||||
{
|
||||
handleMenuClose();
|
||||
if (room.localRecordingPaused)
|
||||
{
|
||||
(
|
||||
localRecordingState === RECORDING_PAUSE ||
|
||||
localRecordingState === RECORDING_RESUME ||
|
||||
localRecordingState === RECORDING_START
|
||||
)
|
||||
&&
|
||||
<MenuItem
|
||||
aria-label={recordingPausedTooltip}
|
||||
onClick={() =>
|
||||
{
|
||||
roomClient.resumeLocalRecording();
|
||||
handleMenuClose();
|
||||
if (localRecordingState === RECORDING_PAUSE)
|
||||
{
|
||||
roomClient.resumeLocalRecording();
|
||||
}
|
||||
else
|
||||
{
|
||||
roomClient.pauseLocalRecording();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
roomClient.pauseLocalRecording();
|
||||
}
|
||||
}
|
||||
}
|
||||
>
|
||||
<Badge
|
||||
color='primary'
|
||||
>
|
||||
{ room.localRecordingPaused ?
|
||||
<PauseCircleFilledIcon />
|
||||
<Badge
|
||||
color='primary'
|
||||
>
|
||||
{ localRecordingState === RECORDING_PAUSE ?
|
||||
<PauseCircleFilledIcon />
|
||||
:
|
||||
<PauseCircleOutlineIcon />
|
||||
}
|
||||
</Badge>
|
||||
|
||||
{ localRecordingState === RECORDING_PAUSE ?
|
||||
<p className={classes.moreAction}>
|
||||
<FormattedMessage
|
||||
id='tooltip.resumeLocalRecording'
|
||||
defaultMessage='Resume local recording'
|
||||
/>
|
||||
</p>
|
||||
:
|
||||
<PauseCircleOutlineIcon />
|
||||
<p className={classes.moreAction}>
|
||||
<FormattedMessage
|
||||
id='tooltip.pauseLocalRecording'
|
||||
defaultMessage='Pause local recording'
|
||||
/>
|
||||
</p>
|
||||
}
|
||||
</Badge>
|
||||
|
||||
{ room.localRecordingPaused ?
|
||||
<p className={classes.moreAction}>
|
||||
<FormattedMessage
|
||||
id='tooltip.resumeLocalRecording'
|
||||
defaultMessage='Resume local recording'
|
||||
/>
|
||||
</p>
|
||||
:
|
||||
<p className={classes.moreAction}>
|
||||
<FormattedMessage
|
||||
id='tooltip.pauseLocalRecording'
|
||||
defaultMessage='Pause local recording'
|
||||
/>
|
||||
</p>
|
||||
}
|
||||
</MenuItem>
|
||||
|
||||
</MenuItem>
|
||||
}
|
||||
<MenuItem
|
||||
aria-label={recordingTooltip}
|
||||
onClick={() =>
|
||||
{
|
||||
handleMenuClose();
|
||||
if (room.localRecordingInProgress)
|
||||
if (localRecordingState === RECORDING_START ||
|
||||
localRecordingState === RECORDING_PAUSE ||
|
||||
localRecordingState === RECORDING_RESUME)
|
||||
{
|
||||
roomClient.stopLocalRecording();
|
||||
}
|
||||
|
|
@ -957,26 +988,32 @@ const TopBar = (props) =>
|
|||
<Badge
|
||||
color='primary'
|
||||
>
|
||||
{ room.localRecordingInProgress ?
|
||||
<StopIcon />
|
||||
:
|
||||
<FiberManualRecordIcon />
|
||||
{
|
||||
(localRecordingState === RECORDING_START ||
|
||||
localRecordingState === RECORDING_PAUSE ||
|
||||
localRecordingState === RECORDING_RESUME) ?
|
||||
<StopIcon />
|
||||
:
|
||||
<FiberManualRecordIcon />
|
||||
}
|
||||
</Badge>
|
||||
{ room.localRecordingInProgress ?
|
||||
<p className={classes.moreAction}>
|
||||
<FormattedMessage
|
||||
id='tooltip.stopLocalRecording'
|
||||
defaultMessage='Stop local recording'
|
||||
/>
|
||||
</p>
|
||||
:
|
||||
<p className={classes.moreAction}>
|
||||
<FormattedMessage
|
||||
id='tooltip.startLocalRecording'
|
||||
defaultMessage='Start local recording'
|
||||
/>
|
||||
</p>
|
||||
{
|
||||
(localRecordingState === RECORDING_START ||
|
||||
localRecordingState === RECORDING_PAUSE ||
|
||||
localRecordingState === RECORDING_RESUME) ?
|
||||
<p className={classes.moreAction}>
|
||||
<FormattedMessage
|
||||
id='tooltip.stopLocalRecording'
|
||||
defaultMessage='Stop local recording'
|
||||
/>
|
||||
</p>
|
||||
:
|
||||
<p className={classes.moreAction}>
|
||||
<FormattedMessage
|
||||
id='tooltip.startLocalRecording'
|
||||
defaultMessage='Start local recording'
|
||||
/>
|
||||
</p>
|
||||
}
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
|
|
@ -1223,7 +1260,9 @@ TopBar.propTypes =
|
|||
theme : PropTypes.object.isRequired,
|
||||
intl : PropTypes.object,
|
||||
locale : PropTypes.string,
|
||||
localesList : PropTypes.array
|
||||
localesList : PropTypes.array,
|
||||
localRecordingState : PropTypes.string,
|
||||
recordingInProgress : PropTypes.bool
|
||||
};
|
||||
|
||||
const makeMapStateToProps = () =>
|
||||
|
|
@ -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 &&
|
||||
|
|
|
|||
|
|
@ -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) =>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react';
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
|
||||
const styles = (theme) =>
|
||||
const styles = () =>
|
||||
({
|
||||
root :
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
);
|
||||
*/
|
||||
6
app/src/recordingStates.js
Normal file
6
app/src/recordingStates.js
Normal file
|
|
@ -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';
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 };
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@
|
|||
"room.localRecordingResumed": null,
|
||||
"room.localRecordingStopped": null,
|
||||
"room.recordingConsent": null,
|
||||
"room.localRecordingSecurityError": null,
|
||||
|
||||
"me.mutedPTT": null,
|
||||
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@
|
|||
"room.localRecordingResumed": null,
|
||||
"room.localRecordingStopped": null,
|
||||
"room.recordingConsent": null,
|
||||
"room.localRecordingSecurityError": null,
|
||||
|
||||
"me.mutedPTT": null,
|
||||
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@
|
|||
"room.localRecordingResumed": null,
|
||||
"room.localRecordingStopped": null,
|
||||
"room.recordingConsent": null,
|
||||
"room.localRecordingSecurityError": null,
|
||||
|
||||
"me.mutedPTT": null,
|
||||
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@
|
|||
"room.localRecordingResumed": null,
|
||||
"room.localRecordingStopped": null,
|
||||
"room.recordingConsent": null,
|
||||
"room.localRecordingSecurityError": null,
|
||||
|
||||
"me.mutedPTT": null,
|
||||
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@
|
|||
"room.localRecordingResumed": null,
|
||||
"room.localRecordingStopped": null,
|
||||
"room.recordingConsent": null,
|
||||
"room.localRecordingSecurityError": null,
|
||||
|
||||
"me.mutedPTT": null,
|
||||
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@
|
|||
"room.localRecordingResumed": null,
|
||||
"room.localRecordingStopped": null,
|
||||
"room.recordingConsent": null,
|
||||
"room.localRecordingSecurityError": null,
|
||||
|
||||
"me.mutedPTT": "आप शांत हैं, बात करने के लिए स्पेस-बार दबाईए",
|
||||
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@
|
|||
"room.localRecordingResumed": null,
|
||||
"room.localRecordingStopped": null,
|
||||
"room.recordingConsent": null,
|
||||
"room.localRecordingSecurityError": null,
|
||||
|
||||
"me.mutedPTT": "Сіз дыбыссызсыз, сөйлесу үшін БОС ОРЫН пернесін ұстап тұрыңыз",
|
||||
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
||||
|
|
|
|||
|
|
@ -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ć.",
|
||||
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@
|
|||
"room.localRecordingResumed": null,
|
||||
"room.localRecordingStopped": null,
|
||||
"room.recordingConsent": null,
|
||||
"room.localRecordingSecurityError": null,
|
||||
|
||||
"me.mutedPTT": null,
|
||||
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@
|
|||
"room.localRecordingResumed": null,
|
||||
"room.localRecordingStopped": null,
|
||||
"room.recordingConsent": null,
|
||||
"room.localRecordingSecurityError": null,
|
||||
|
||||
"me.mutedPTT": null,
|
||||
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@
|
|||
"room.localRecordingResumed": null,
|
||||
"room.localRecordingStopped": null,
|
||||
"room.recordingConsent": null,
|
||||
"room.localRecordingSecurityError": null,
|
||||
|
||||
"me.mutedPTT": "Вы отключены, удерживайте ПРОБЕЛ, чтобы говорить",
|
||||
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@
|
|||
"room.localRecordingResumed": null,
|
||||
"room.localRecordingStopped": null,
|
||||
"room.recordingConsent": null,
|
||||
"room.localRecordingSecurityError": null,
|
||||
|
||||
"me.mutedPTT": "您已靜音,請按下 空白鍵 來說話",
|
||||
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@
|
|||
"room.localRecordingResumed": null,
|
||||
"room.localRecordingStopped": null,
|
||||
"room.recordingConsent": null,
|
||||
"room.localRecordingSecurityError": null,
|
||||
|
||||
"me.mutedPTT": " У вас вимкнено звук, утримуйте клавішу SPACE-BAR (пробіл), щоб говорити",
|
||||
"roles.gotRole": "Ви отримали роль {role}",
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue