Merge branch 'develop' into feat-unsupportedbrowser
commit
ee1a691642
|
|
@ -0,0 +1,2 @@
|
||||||
|
REACT_APP_VERSION=$npm_package_version
|
||||||
|
REACT_APP_NAME=$npm_package_name
|
||||||
|
|
@ -37,7 +37,8 @@ var config =
|
||||||
'opera'
|
'opera'
|
||||||
],
|
],
|
||||||
// Socket.io request timeout
|
// Socket.io request timeout
|
||||||
requestTimeout : 10000,
|
requestTimeout : 20000,
|
||||||
|
requestRetries : 3,
|
||||||
transportOptions :
|
transportOptions :
|
||||||
{
|
{
|
||||||
tcp : true
|
tcp : true
|
||||||
|
|
@ -50,6 +51,7 @@ var config =
|
||||||
autoGainControl : true,
|
autoGainControl : true,
|
||||||
echoCancellation : true,
|
echoCancellation : true,
|
||||||
noiseSuppression : true,
|
noiseSuppression : true,
|
||||||
|
voiceActivityMute : false,
|
||||||
sampleSize : 16
|
sampleSize : 16
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import Logger from './Logger';
|
import Logger from './Logger';
|
||||||
import hark from 'hark';
|
import hark from 'hark';
|
||||||
import { getSignalingUrl } from './urlFactory';
|
import { getSignalingUrl } from './urlFactory';
|
||||||
|
import { SocketTimeoutError } from './utils';
|
||||||
import * as requestActions from './actions/requestActions';
|
import * as requestActions from './actions/requestActions';
|
||||||
import * as meActions from './actions/meActions';
|
import * as meActions from './actions/meActions';
|
||||||
import * as roomActions from './actions/roomActions';
|
import * as roomActions from './actions/roomActions';
|
||||||
|
|
@ -574,7 +575,7 @@ export default class RoomClient
|
||||||
if (called)
|
if (called)
|
||||||
return;
|
return;
|
||||||
called = true;
|
called = true;
|
||||||
callback(new Error('Request timeout.'));
|
callback(new SocketTimeoutError('Request timed out'));
|
||||||
},
|
},
|
||||||
ROOM_OPTIONS.requestTimeout
|
ROOM_OPTIONS.requestTimeout
|
||||||
);
|
);
|
||||||
|
|
@ -590,13 +591,13 @@ export default class RoomClient
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
sendRequest(method, data)
|
_sendRequest(method, data)
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) =>
|
return new Promise((resolve, reject) =>
|
||||||
{
|
{
|
||||||
if (!this._signalingSocket)
|
if (!this._signalingSocket)
|
||||||
{
|
{
|
||||||
reject('No socket connection.');
|
reject('No socket connection');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -606,19 +607,42 @@ export default class RoomClient
|
||||||
this.timeoutCallback((err, response) =>
|
this.timeoutCallback((err, response) =>
|
||||||
{
|
{
|
||||||
if (err)
|
if (err)
|
||||||
{
|
|
||||||
reject(err);
|
reject(err);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
resolve(response);
|
resolve(response);
|
||||||
}
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async sendRequest(method, data)
|
||||||
|
{
|
||||||
|
logger.debug('sendRequest() [method:"%s", data:"%o"]', method, data);
|
||||||
|
|
||||||
|
const {
|
||||||
|
requestRetries = 3
|
||||||
|
} = window.config;
|
||||||
|
|
||||||
|
for (let tries = 0; tries < requestRetries; tries++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return await this._sendRequest(method, data);
|
||||||
|
}
|
||||||
|
catch (error)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
error instanceof SocketTimeoutError &&
|
||||||
|
tries < requestRetries
|
||||||
|
)
|
||||||
|
logger.warn('sendRequest() | timeout, retrying [attempt:"%s"]', tries);
|
||||||
|
else
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async changeDisplayName(displayName)
|
async changeDisplayName(displayName)
|
||||||
{
|
{
|
||||||
logger.debug('changeDisplayName() [displayName:"%s"]', displayName);
|
logger.debug('changeDisplayName() [displayName:"%s"]', displayName);
|
||||||
|
|
@ -1003,37 +1027,50 @@ export default class RoomClient
|
||||||
if (!this._harkStream.getAudioTracks()[0])
|
if (!this._harkStream.getAudioTracks()[0])
|
||||||
throw new Error('getMicStream():something went wrong with hark');
|
throw new Error('getMicStream():something went wrong with hark');
|
||||||
|
|
||||||
this._hark = hark(this._harkStream, { play: false });
|
this._hark = hark(this._harkStream,
|
||||||
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
this._hark.on('volume_change', (dBs, threshold) =>
|
|
||||||
{
|
{
|
||||||
// The exact formula to convert from dBs (-100..0) to linear (0..1) is:
|
play : false,
|
||||||
// Math.pow(10, dBs / 20)
|
interval : 5,
|
||||||
// However it does not produce a visually useful output, so let exagerate
|
threshold : store.getState().settings.noiseThreshold,
|
||||||
// it a bit. Also, let convert it from 0..1 to 0..10 and avoid value 1 to
|
history : 300
|
||||||
// minimize component renderings.
|
});
|
||||||
let volume = Math.round(Math.pow(10, dBs / 85) * 10);
|
this._hark.lastVolume = -100;
|
||||||
|
|
||||||
if (volume === 1)
|
|
||||||
volume = 0;
|
|
||||||
|
|
||||||
|
this._hark.on('volume_change', (volume) =>
|
||||||
|
{
|
||||||
volume = Math.round(volume);
|
volume = Math.round(volume);
|
||||||
|
if (this._micProducer && volume !== Math.round(this._hark.lastVolume))
|
||||||
if (this._micProducer && volume !== this._micProducer.volume)
|
|
||||||
{
|
{
|
||||||
this._micProducer.volume = volume;
|
if (volume < this._hark.lastVolume * 1.02)
|
||||||
|
{
|
||||||
|
volume = this._hark.lastVolume * 1.02;
|
||||||
|
}
|
||||||
|
this._hark.lastVolume = volume;
|
||||||
store.dispatch(peerVolumeActions.setPeerVolume(this._peerId, volume));
|
store.dispatch(peerVolumeActions.setPeerVolume(this._peerId, volume));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this._hark.on('speaking', function()
|
this._hark.on('speaking', () =>
|
||||||
{
|
{
|
||||||
store.dispatch(meActions.setIsSpeaking(true));
|
store.dispatch(meActions.setIsSpeaking(true));
|
||||||
|
if ((store.getState().settings.voiceActivatedUnmute ||
|
||||||
|
store.getState().me.isAutoMuted) &&
|
||||||
|
this._micProducer &&
|
||||||
|
this._micProducer.paused)
|
||||||
|
{
|
||||||
|
this._micProducer.resume();
|
||||||
|
}
|
||||||
|
store.dispatch(meActions.setAutoMuted(false)); // sanity action
|
||||||
});
|
});
|
||||||
this._hark.on('stopped_speaking', function()
|
this._hark.on('stopped_speaking', () =>
|
||||||
{
|
{
|
||||||
store.dispatch(meActions.setIsSpeaking(false));
|
store.dispatch(meActions.setIsSpeaking(false));
|
||||||
|
if (store.getState().settings.voiceActivatedUnmute &&
|
||||||
|
this._micProducer &&
|
||||||
|
!this._micProducer.paused)
|
||||||
|
{
|
||||||
|
this._micProducer.pause();
|
||||||
|
store.dispatch(meActions.setAutoMuted(true));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1962,23 +1999,12 @@ export default class RoomClient
|
||||||
producerPaused
|
producerPaused
|
||||||
} = request.data;
|
} = request.data;
|
||||||
|
|
||||||
let codecOptions;
|
|
||||||
|
|
||||||
if (kind === 'audio')
|
|
||||||
{
|
|
||||||
codecOptions =
|
|
||||||
{
|
|
||||||
opusStereo : 1
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const consumer = await this._recvTransport.consume(
|
const consumer = await this._recvTransport.consume(
|
||||||
{
|
{
|
||||||
id,
|
id,
|
||||||
producerId,
|
producerId,
|
||||||
kind,
|
kind,
|
||||||
rtpParameters,
|
rtpParameters,
|
||||||
codecOptions,
|
|
||||||
appData : { ...appData, peerId } // Trick.
|
appData : { ...appData, peerId } // Trick.
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -2031,19 +2057,8 @@ export default class RoomClient
|
||||||
|
|
||||||
consumer.hark = hark(stream, { play: false });
|
consumer.hark = hark(stream, { play: false });
|
||||||
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
consumer.hark.on('volume_change', (volume) =>
|
||||||
consumer.hark.on('volume_change', (dBs, threshold) =>
|
|
||||||
{
|
{
|
||||||
// The exact formula to convert from dBs (-100..0) to linear (0..1) is:
|
|
||||||
// Math.pow(10, dBs / 20)
|
|
||||||
// However it does not produce a visually useful output, so let exaggerate
|
|
||||||
// it a bit. Also, let convert it from 0..1 to 0..10 and avoid value 1 to
|
|
||||||
// minimize component renderings.
|
|
||||||
let volume = Math.round(Math.pow(10, dBs / 85) * 10);
|
|
||||||
|
|
||||||
if (volume === 1)
|
|
||||||
volume = 0;
|
|
||||||
|
|
||||||
volume = Math.round(volume);
|
volume = Math.round(volume);
|
||||||
|
|
||||||
if (consumer && volume !== consumer.volume)
|
if (consumer && volume !== consumer.volume)
|
||||||
|
|
@ -2667,7 +2682,7 @@ export default class RoomClient
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : intl.formatMessage({
|
text : intl.formatMessage({
|
||||||
id : 'moderator.muteScreenSharingModerator',
|
id : 'moderator.stopScreenSharing',
|
||||||
defaultMessage : 'Moderator stopped your screen sharing'
|
defaultMessage : 'Moderator stopped your screen sharing'
|
||||||
})
|
})
|
||||||
}));
|
}));
|
||||||
|
|
@ -3888,6 +3903,14 @@ export default class RoomClient
|
||||||
store.dispatch(meActions.setWebcamInProgress(false));
|
store.dispatch(meActions.setWebcamInProgress(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _setNoiseThreshold(threshold)
|
||||||
|
{
|
||||||
|
logger.debug('_setNoiseThreshold:%s', threshold);
|
||||||
|
this._hark.setThreshold(threshold);
|
||||||
|
store.dispatch(
|
||||||
|
settingsActions.setNoiseThreshold(threshold));
|
||||||
|
}
|
||||||
|
|
||||||
async _updateAudioDevices()
|
async _updateAudioDevices()
|
||||||
{
|
{
|
||||||
logger.debug('_updateAudioDevices()');
|
logger.debug('_updateAudioDevices()');
|
||||||
|
|
|
||||||
|
|
@ -110,3 +110,9 @@ export const setIsSpeaking = (flag) =>
|
||||||
type : 'SET_IS_SPEAKING',
|
type : 'SET_IS_SPEAKING',
|
||||||
payload : { flag }
|
payload : { flag }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const setAutoMuted = (flag) =>
|
||||||
|
({
|
||||||
|
type : 'SET_AUTO_MUTED',
|
||||||
|
payload : { flag }
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,18 @@ export const setNoiseSuppression = (noiseSuppression) =>
|
||||||
payload : { noiseSuppression }
|
payload : { noiseSuppression }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const setVoiceActivatedUnmute = (voiceActivatedUnmute) =>
|
||||||
|
({
|
||||||
|
type: 'SET_VOICE_ACTIVATED_UNMUTE',
|
||||||
|
payload: { voiceActivatedUnmute }
|
||||||
|
});
|
||||||
|
|
||||||
|
export const setNoiseThreshold = (noiseThreshold) =>
|
||||||
|
({
|
||||||
|
type: 'SET_NOISE_THRESHOLD',
|
||||||
|
payload: { noiseThreshold }
|
||||||
|
});
|
||||||
|
|
||||||
export const setDefaultAudio = (audio) =>
|
export const setDefaultAudio = (audio) =>
|
||||||
({
|
({
|
||||||
type : 'SET_DEFAULT_AUDIO',
|
type : 'SET_DEFAULT_AUDIO',
|
||||||
|
|
|
||||||
|
|
@ -137,10 +137,10 @@ const styles = (theme) =>
|
||||||
transform : 'translate(-50%, 0%)',
|
transform : 'translate(-50%, 0%)',
|
||||||
color : 'rgba(255, 255, 255, 0.7)',
|
color : 'rgba(255, 255, 255, 0.7)',
|
||||||
fontSize : '1.3em',
|
fontSize : '1.3em',
|
||||||
backgroundColor : 'rgba(255, 0, 0, 0.9)',
|
backgroundColor : 'rgba(245, 0, 87, 0.70)',
|
||||||
margin : '4px',
|
margin : '4px',
|
||||||
padding : theme.spacing(2),
|
padding : theme.spacing(2),
|
||||||
zIndex : 31,
|
zIndex : 1200,
|
||||||
borderRadius : '20px',
|
borderRadius : '20px',
|
||||||
textAlign : 'center',
|
textAlign : 'center',
|
||||||
opacity : 0,
|
opacity : 0,
|
||||||
|
|
@ -176,6 +176,7 @@ const Me = (props) =>
|
||||||
screenProducer,
|
screenProducer,
|
||||||
extraVideoProducers,
|
extraVideoProducers,
|
||||||
canShareScreen,
|
canShareScreen,
|
||||||
|
noiseVolume,
|
||||||
classes
|
classes
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
|
@ -440,7 +441,12 @@ const Me = (props) =>
|
||||||
})}
|
})}
|
||||||
className={classes.smallContainer}
|
className={classes.smallContainer}
|
||||||
disabled={!me.canSendMic || me.audioInProgress}
|
disabled={!me.canSendMic || me.audioInProgress}
|
||||||
color={micState === 'on' ? 'primary' : 'secondary'}
|
color={
|
||||||
|
micState === 'on' ?
|
||||||
|
settings.voiceActivatedUnmute && !me.isAutoMuted ?
|
||||||
|
'primary'
|
||||||
|
: 'default'
|
||||||
|
: 'secondary'}
|
||||||
size='small'
|
size='small'
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
{
|
{
|
||||||
|
|
@ -453,7 +459,10 @@ const Me = (props) =>
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{ micState === 'on' ?
|
{ micState === 'on' ?
|
||||||
<MicIcon />
|
<MicIcon
|
||||||
|
color={me.isAutoMuted ? 'secondary' : 'primary'}
|
||||||
|
style={{ opacity: noiseVolume }}
|
||||||
|
/>
|
||||||
:
|
:
|
||||||
<MicOffIcon />
|
<MicOffIcon />
|
||||||
}
|
}
|
||||||
|
|
@ -468,7 +477,10 @@ const Me = (props) =>
|
||||||
})}
|
})}
|
||||||
className={classes.fab}
|
className={classes.fab}
|
||||||
disabled={!me.canSendMic || me.audioInProgress}
|
disabled={!me.canSendMic || me.audioInProgress}
|
||||||
color={micState === 'on' ? 'default' : 'secondary'}
|
color={micState === 'on' ?
|
||||||
|
settings.voiceActivatedUnmute && !me.isAutoMuted? 'primary'
|
||||||
|
: 'default'
|
||||||
|
: 'secondary'}
|
||||||
size='large'
|
size='large'
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
{
|
{
|
||||||
|
|
@ -481,7 +493,11 @@ const Me = (props) =>
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{ micState === 'on' ?
|
{ micState === 'on' ?
|
||||||
<MicIcon />
|
<MicIcon
|
||||||
|
color={me.isAutoMuted && settings.voiceActivatedUnmute ? 'secondary' : 'primary'}
|
||||||
|
style={me.isAutoMuted && settings.voiceActivatedUnmute ? { opacity: noiseVolume }
|
||||||
|
: { opacity: 1 }}
|
||||||
|
/>
|
||||||
:
|
:
|
||||||
<MicOffIcon />
|
<MicOffIcon />
|
||||||
}
|
}
|
||||||
|
|
@ -868,6 +884,7 @@ Me.propTypes =
|
||||||
style : PropTypes.object,
|
style : PropTypes.object,
|
||||||
smallContainer : PropTypes.bool,
|
smallContainer : PropTypes.bool,
|
||||||
canShareScreen : PropTypes.bool.isRequired,
|
canShareScreen : PropTypes.bool.isRequired,
|
||||||
|
noiseVolume : PropTypes.number,
|
||||||
classes : PropTypes.object.isRequired,
|
classes : PropTypes.object.isRequired,
|
||||||
theme : PropTypes.object.isRequired
|
theme : PropTypes.object.isRequired
|
||||||
};
|
};
|
||||||
|
|
@ -878,12 +895,26 @@ const makeMapStateToProps = () =>
|
||||||
|
|
||||||
const mapStateToProps = (state) =>
|
const mapStateToProps = (state) =>
|
||||||
{
|
{
|
||||||
|
let volume;
|
||||||
|
|
||||||
|
// noiseVolume under threshold
|
||||||
|
if (state.peerVolumes[state.me.id] < state.settings.noiseThreshold)
|
||||||
|
{
|
||||||
|
// noiseVolume mapped to range 0.5 ... 1 (threshold switch)
|
||||||
|
volume = 1 + ((Math.abs(state.peerVolumes[state.me.id] -
|
||||||
|
state.settings.noiseThreshold) / (-120 -
|
||||||
|
state.settings.noiseThreshold)));
|
||||||
|
}
|
||||||
|
// noiseVolume over threshold: no noise but voice
|
||||||
|
else { volume = 0; }
|
||||||
|
|
||||||
return {
|
return {
|
||||||
me : state.me,
|
me : state.me,
|
||||||
...meProducersSelector(state),
|
...meProducersSelector(state),
|
||||||
settings : state.settings,
|
settings : state.settings,
|
||||||
activeSpeaker : state.me.id === state.room.activeSpeakerId,
|
activeSpeaker : state.me.id === state.room.activeSpeakerId,
|
||||||
canShareScreen : hasPermission(state)
|
canShareScreen : hasPermission(state),
|
||||||
|
noiseVolume : volume
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -900,6 +931,8 @@ export default withRoomContext(connect(
|
||||||
return (
|
return (
|
||||||
prev.room === next.room &&
|
prev.room === next.room &&
|
||||||
prev.me === next.me &&
|
prev.me === next.me &&
|
||||||
|
Math.round(prev.peerVolumes[prev.me.id]) ===
|
||||||
|
Math.round(next.peerVolumes[next.me.id]) &&
|
||||||
prev.peers === next.peers &&
|
prev.peers === next.peers &&
|
||||||
prev.producers === next.producers &&
|
prev.producers === next.producers &&
|
||||||
prev.settings === next.settings
|
prev.settings === next.settings
|
||||||
|
|
|
||||||
|
|
@ -94,17 +94,17 @@ const styles = () =>
|
||||||
smallBar :
|
smallBar :
|
||||||
{
|
{
|
||||||
flex : '0 0 auto',
|
flex : '0 0 auto',
|
||||||
margin : '0.3rem',
|
|
||||||
backgroundSize : '75%',
|
backgroundSize : '75%',
|
||||||
backgroundRepeat : 'no-repeat',
|
backgroundRepeat : 'no-repeat',
|
||||||
backgroundColor : 'rgba(0, 0, 0, 1)',
|
backgroundColor : 'rgba(0, 0, 0, 1)',
|
||||||
cursor : 'pointer',
|
cursor : 'pointer',
|
||||||
transitionProperty : 'opacity, background-color',
|
transitionProperty : 'opacity, background-color',
|
||||||
width : 3,
|
width : 3,
|
||||||
borderRadius : 6,
|
borderRadius : 2,
|
||||||
transitionDuration : '0.25s',
|
transitionDuration : '0.25s',
|
||||||
position : 'absolute',
|
position : 'absolute',
|
||||||
bottom : 0,
|
top : '50%',
|
||||||
|
transform : 'translateY(-50%)',
|
||||||
'&.level0' : { height: 0 },
|
'&.level0' : { height: 0 },
|
||||||
'&.level1' : { height: '0.2vh' },
|
'&.level1' : { height: '0.2vh' },
|
||||||
'&.level2' : { height: '0.4vh' },
|
'&.level2' : { height: '0.4vh' },
|
||||||
|
|
@ -148,10 +148,17 @@ Volume.propTypes =
|
||||||
const makeMapStateToProps = (initialState, props) =>
|
const makeMapStateToProps = (initialState, props) =>
|
||||||
{
|
{
|
||||||
const mapStateToProps = (state) =>
|
const mapStateToProps = (state) =>
|
||||||
|
{
|
||||||
|
if (state.peerVolumes[props.id]>state.settings.noiseThreshold)
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
volume : state.peerVolumes[props.id]
|
volume : Math.round((state.peerVolumes[props.id]+100) / 10)
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return { volume: 0 };
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return mapStateToProps;
|
return mapStateToProps;
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,8 @@ const styles = (theme) =>
|
||||||
link :
|
link :
|
||||||
{
|
{
|
||||||
display : 'block',
|
display : 'block',
|
||||||
textAlign : 'center'
|
textAlign : 'center',
|
||||||
|
marginBottom : theme.spacing(1)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -68,15 +69,16 @@ const About = ({
|
||||||
/>
|
/>
|
||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
<DialogContent dividers='true'>
|
<DialogContent dividers='true'>
|
||||||
<DialogContentText>
|
<DialogContentText paragraph>
|
||||||
Contributions to this work were made on behalf of the GÉANT
|
Contributions to this work were made on behalf of the GÉANT
|
||||||
project, a project that has received funding from the
|
project, a project that has received funding from the
|
||||||
European Union’s Horizon 2020 research and innovation
|
European Union’s Horizon 2020 research and innovation
|
||||||
programme under Grant Agreement No. 731122 (GN4-2).
|
programme under Grant Agreement No. 731122 (GN4-2).
|
||||||
On behalf of GÉANT project, GÉANT Association is the sole
|
On behalf of GÉANT project, GÉANT Association is the sole
|
||||||
owner of the copyright in all material which was developed
|
owner of the copyright in all material which was developed
|
||||||
by a member of the GÉANT project.<br />
|
by a member of the GÉANT project.
|
||||||
<br />
|
</DialogContentText>
|
||||||
|
<DialogContentText paragraph>
|
||||||
GÉANT Vereniging (Association) is registered with the
|
GÉANT Vereniging (Association) is registered with the
|
||||||
Chamber of Commerce in Amsterdam with registration number
|
Chamber of Commerce in Amsterdam with registration number
|
||||||
40535155 and operates in the UK as a branch of GÉANT
|
40535155 and operates in the UK as a branch of GÉANT
|
||||||
|
|
@ -87,6 +89,13 @@ const About = ({
|
||||||
<Link href='https://edumeet.org' target='_blank' rel='noreferrer' color='secondary' variant='h6' className={classes.link}>
|
<Link href='https://edumeet.org' target='_blank' rel='noreferrer' color='secondary' variant='h6' className={classes.link}>
|
||||||
https://edumeet.org
|
https://edumeet.org
|
||||||
</Link>
|
</Link>
|
||||||
|
<DialogContentText align='center' variant='h7'>
|
||||||
|
<FormattedMessage
|
||||||
|
id='label.version'
|
||||||
|
defaultMessage='Version'
|
||||||
|
/>
|
||||||
|
:{` ${process.env.REACT_APP_VERSION}`}
|
||||||
|
</DialogContentText>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
{ window.config.logo && <img alt='Logo' className={classes.logo} src={window.config.logo} /> }
|
{ window.config.logo && <img alt='Logo' className={classes.logo} src={window.config.logo} /> }
|
||||||
|
|
|
||||||
|
|
@ -472,14 +472,6 @@ const TopBar = (props) =>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div className={classes.sectionMobile}>
|
<div className={classes.sectionMobile}>
|
||||||
<IconButton
|
|
||||||
aria-haspopup='true'
|
|
||||||
onClick={handleMobileMenuOpen}
|
|
||||||
color='inherit'
|
|
||||||
>
|
|
||||||
<MoreIcon />
|
|
||||||
</IconButton>
|
|
||||||
</div>
|
|
||||||
{ lobbyPeers.length > 0 &&
|
{ lobbyPeers.length > 0 &&
|
||||||
<Tooltip
|
<Tooltip
|
||||||
title={intl.formatMessage({
|
title={intl.formatMessage({
|
||||||
|
|
@ -508,6 +500,14 @@ const TopBar = (props) =>
|
||||||
</span>
|
</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
}
|
}
|
||||||
|
<IconButton
|
||||||
|
aria-haspopup='true'
|
||||||
|
onClick={handleMobileMenuOpen}
|
||||||
|
color='inherit'
|
||||||
|
>
|
||||||
|
<MoreIcon />
|
||||||
|
</IconButton>
|
||||||
|
</div>
|
||||||
<div className={classes.divider} />
|
<div className={classes.divider} />
|
||||||
<Button
|
<Button
|
||||||
aria-label={intl.formatMessage({
|
aria-label={intl.formatMessage({
|
||||||
|
|
@ -697,33 +697,6 @@ const TopBar = (props) =>
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
{ lobbyPeers.length > 0 &&
|
|
||||||
<MenuItem
|
|
||||||
aria-label={intl.formatMessage({
|
|
||||||
id : 'tooltip.lobby',
|
|
||||||
defaultMessage : 'Show lobby'
|
|
||||||
})}
|
|
||||||
disabled={!canPromote}
|
|
||||||
onClick={() =>
|
|
||||||
{
|
|
||||||
handleMenuClose();
|
|
||||||
setLockDialogOpen(!room.lockDialogOpen);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<PulsingBadge
|
|
||||||
color='secondary'
|
|
||||||
badgeContent={lobbyPeers.length}
|
|
||||||
>
|
|
||||||
<SecurityIcon />
|
|
||||||
</PulsingBadge>
|
|
||||||
<p className={classes.moreAction}>
|
|
||||||
<FormattedMessage
|
|
||||||
id='tooltip.lobby'
|
|
||||||
defaultMessage='Show lobby'
|
|
||||||
/>
|
|
||||||
</p>
|
|
||||||
</MenuItem>
|
|
||||||
}
|
|
||||||
<MenuItem
|
<MenuItem
|
||||||
aria-label={intl.formatMessage({
|
aria-label={intl.formatMessage({
|
||||||
id : 'tooltip.participants',
|
id : 'tooltip.participants',
|
||||||
|
|
|
||||||
|
|
@ -6,19 +6,52 @@ import { withRoomContext } from '../../RoomContext';
|
||||||
import * as settingsActions from '../../actions/settingsActions';
|
import * as settingsActions from '../../actions/settingsActions';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { useIntl, FormattedMessage } from 'react-intl';
|
import { useIntl, FormattedMessage } from 'react-intl';
|
||||||
|
import classnames from 'classnames';
|
||||||
import MenuItem from '@material-ui/core/MenuItem';
|
import MenuItem from '@material-ui/core/MenuItem';
|
||||||
import FormHelperText from '@material-ui/core/FormHelperText';
|
import FormHelperText from '@material-ui/core/FormHelperText';
|
||||||
import FormControl from '@material-ui/core/FormControl';
|
import FormControl from '@material-ui/core/FormControl';
|
||||||
import FormControlLabel from '@material-ui/core/FormControlLabel';
|
import FormControlLabel from '@material-ui/core/FormControlLabel';
|
||||||
import Select from '@material-ui/core/Select';
|
import Select from '@material-ui/core/Select';
|
||||||
import Checkbox from '@material-ui/core/Checkbox';
|
import Checkbox from '@material-ui/core/Checkbox';
|
||||||
|
import Slider from '@material-ui/core/Slider';
|
||||||
|
import Typography from '@material-ui/core/Typography';
|
||||||
|
|
||||||
const styles = (theme) =>
|
const NoiseSlider = withStyles(
|
||||||
({
|
{
|
||||||
|
root :
|
||||||
|
{
|
||||||
|
color : '#3880ff',
|
||||||
|
height : 2,
|
||||||
|
padding : '15px 0'
|
||||||
|
},
|
||||||
|
track : {
|
||||||
|
height : 2
|
||||||
|
},
|
||||||
|
rail : {
|
||||||
|
height : 2,
|
||||||
|
opacity : 0.2
|
||||||
|
},
|
||||||
|
mark : {
|
||||||
|
backgroundColor : '#bfbfbf',
|
||||||
|
height : 10,
|
||||||
|
width : 3,
|
||||||
|
marginTop : -3
|
||||||
|
},
|
||||||
|
markActive : {
|
||||||
|
opacity : 1,
|
||||||
|
backgroundColor : 'currentColor'
|
||||||
|
}
|
||||||
|
})(Slider);
|
||||||
|
|
||||||
|
const styles = (theme) => ({
|
||||||
setting :
|
setting :
|
||||||
{
|
{
|
||||||
padding : theme.spacing(2)
|
padding : theme.spacing(2)
|
||||||
},
|
},
|
||||||
|
margin :
|
||||||
|
{
|
||||||
|
height : theme.spacing(3)
|
||||||
|
},
|
||||||
formControl :
|
formControl :
|
||||||
{
|
{
|
||||||
display : 'flex'
|
display : 'flex'
|
||||||
|
|
@ -29,8 +62,10 @@ const MediaSettings = ({
|
||||||
setEchoCancellation,
|
setEchoCancellation,
|
||||||
setAutoGainControl,
|
setAutoGainControl,
|
||||||
setNoiseSuppression,
|
setNoiseSuppression,
|
||||||
|
setVoiceActivatedUnmute,
|
||||||
roomClient,
|
roomClient,
|
||||||
me,
|
me,
|
||||||
|
volume,
|
||||||
settings,
|
settings,
|
||||||
classes
|
classes
|
||||||
}) =>
|
}) =>
|
||||||
|
|
@ -135,6 +170,34 @@ const MediaSettings = ({
|
||||||
}
|
}
|
||||||
</FormHelperText>
|
</FormHelperText>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
<FormControl className={classes.formControl}>
|
||||||
|
<Select
|
||||||
|
value={settings.resolution || ''}
|
||||||
|
onChange={(event) =>
|
||||||
|
{
|
||||||
|
if (event.target.value)
|
||||||
|
roomClient.changeVideoResolution(event.target.value);
|
||||||
|
}}
|
||||||
|
name='Video resolution'
|
||||||
|
autoWidth
|
||||||
|
className={classes.selectEmpty}
|
||||||
|
>
|
||||||
|
{resolutions.map((resolution, index) =>
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
<MenuItem key={index} value={resolution.value}>
|
||||||
|
{resolution.label}
|
||||||
|
</MenuItem>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Select>
|
||||||
|
<FormHelperText>
|
||||||
|
<FormattedMessage
|
||||||
|
id='settings.resolution'
|
||||||
|
defaultMessage='Select your video resolution'
|
||||||
|
/>
|
||||||
|
</FormHelperText>
|
||||||
|
</FormControl>
|
||||||
</form>
|
</form>
|
||||||
<form className={classes.setting} autoComplete='off'>
|
<form className={classes.setting} autoComplete='off'>
|
||||||
<FormControl className={classes.formControl}>
|
<FormControl className={classes.formControl}>
|
||||||
|
|
@ -148,7 +211,7 @@ const MediaSettings = ({
|
||||||
displayEmpty
|
displayEmpty
|
||||||
name={intl.formatMessage({
|
name={intl.formatMessage({
|
||||||
id : 'settings.audio',
|
id : 'settings.audio',
|
||||||
defaultMessage : 'Audio device'
|
defaultMessage : 'Audio input device'
|
||||||
})}
|
})}
|
||||||
autoWidth
|
autoWidth
|
||||||
className={classes.selectEmpty}
|
className={classes.selectEmpty}
|
||||||
|
|
@ -165,12 +228,12 @@ const MediaSettings = ({
|
||||||
{ audioDevices.length > 0 ?
|
{ audioDevices.length > 0 ?
|
||||||
intl.formatMessage({
|
intl.formatMessage({
|
||||||
id : 'settings.selectAudio',
|
id : 'settings.selectAudio',
|
||||||
defaultMessage : 'Select audio device'
|
defaultMessage : 'Select audio input device'
|
||||||
})
|
})
|
||||||
:
|
:
|
||||||
intl.formatMessage({
|
intl.formatMessage({
|
||||||
id : 'settings.cantSelectAudio',
|
id : 'settings.cantSelectAudio',
|
||||||
defaultMessage : 'Unable to select audio device'
|
defaultMessage : 'Unable to select audio input device'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</FormHelperText>
|
</FormHelperText>
|
||||||
|
|
@ -225,34 +288,6 @@ const MediaSettings = ({
|
||||||
</form>
|
</form>
|
||||||
}
|
}
|
||||||
<form className={classes.setting} autoComplete='off'>
|
<form className={classes.setting} autoComplete='off'>
|
||||||
<FormControl className={classes.formControl}>
|
|
||||||
<Select
|
|
||||||
value={settings.resolution || ''}
|
|
||||||
onChange={(event) =>
|
|
||||||
{
|
|
||||||
if (event.target.value)
|
|
||||||
roomClient.changeVideoResolution(event.target.value);
|
|
||||||
}}
|
|
||||||
name='Video resolution'
|
|
||||||
autoWidth
|
|
||||||
className={classes.selectEmpty}
|
|
||||||
>
|
|
||||||
{ resolutions.map((resolution, index) =>
|
|
||||||
{
|
|
||||||
return (
|
|
||||||
<MenuItem key={index} value={resolution.value}>
|
|
||||||
{resolution.label}
|
|
||||||
</MenuItem>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Select>
|
|
||||||
<FormHelperText>
|
|
||||||
<FormattedMessage
|
|
||||||
id='settings.resolution'
|
|
||||||
defaultMessage='Select your video resolution'
|
|
||||||
/>
|
|
||||||
</FormHelperText>
|
|
||||||
</FormControl>
|
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
className={classes.setting}
|
className={classes.setting}
|
||||||
control={
|
control={
|
||||||
|
|
@ -298,6 +333,43 @@ const MediaSettings = ({
|
||||||
defaultMessage : 'Noise suppression'
|
defaultMessage : 'Noise suppression'
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
|
<FormControlLabel
|
||||||
|
className={classes.setting}
|
||||||
|
control={
|
||||||
|
<Checkbox checked={settings.voiceActivatedUnmute} onChange={
|
||||||
|
(event) =>
|
||||||
|
{
|
||||||
|
setVoiceActivatedUnmute(event.target.checked);
|
||||||
|
}}
|
||||||
|
/>}
|
||||||
|
label={intl.formatMessage({
|
||||||
|
id : 'settings.voiceActivatedUnmute',
|
||||||
|
defaultMessage : 'Voice activated unmute'
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
<div className={classes.margin} />
|
||||||
|
<Typography gutterBottom>
|
||||||
|
{
|
||||||
|
intl.formatMessage({
|
||||||
|
id : 'settings.noiseThreshold',
|
||||||
|
defaultMessage : 'Noise threshold:'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</Typography>
|
||||||
|
<NoiseSlider className={classnames(classes.slider, classnames.setting)}
|
||||||
|
key={'noise-threshold-slider'}
|
||||||
|
min={-100}
|
||||||
|
value={settings.noiseThreshold}
|
||||||
|
max={0}
|
||||||
|
valueLabelDisplay={'off'}
|
||||||
|
onChange={
|
||||||
|
(event, value) =>
|
||||||
|
{
|
||||||
|
roomClient._setNoiseThreshold(value);
|
||||||
|
}}
|
||||||
|
marks={[ { value: volume, label: 'level' } ]}
|
||||||
|
/>
|
||||||
|
<div className={classes.margin} />
|
||||||
</form>
|
</form>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
|
|
@ -309,7 +381,9 @@ MediaSettings.propTypes =
|
||||||
setEchoCancellation : PropTypes.func.isRequired,
|
setEchoCancellation : PropTypes.func.isRequired,
|
||||||
setAutoGainControl : PropTypes.func.isRequired,
|
setAutoGainControl : PropTypes.func.isRequired,
|
||||||
setNoiseSuppression : PropTypes.func.isRequired,
|
setNoiseSuppression : PropTypes.func.isRequired,
|
||||||
|
setVoiceActivatedUnmute : PropTypes.func.isRequired,
|
||||||
me : appPropTypes.Me.isRequired,
|
me : appPropTypes.Me.isRequired,
|
||||||
|
volume : PropTypes.number,
|
||||||
settings : PropTypes.object.isRequired,
|
settings : PropTypes.object.isRequired,
|
||||||
classes : PropTypes.object.isRequired
|
classes : PropTypes.object.isRequired
|
||||||
};
|
};
|
||||||
|
|
@ -318,6 +392,7 @@ const mapStateToProps = (state) =>
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
me : state.me,
|
me : state.me,
|
||||||
|
volume : state.peerVolumes[state.me.id],
|
||||||
settings : state.settings
|
settings : state.settings
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -325,7 +400,8 @@ const mapStateToProps = (state) =>
|
||||||
const mapDispatchToProps = {
|
const mapDispatchToProps = {
|
||||||
setEchoCancellation : settingsActions.setEchoCancellation,
|
setEchoCancellation : settingsActions.setEchoCancellation,
|
||||||
setAutoGainControl : settingsActions.toggleAutoGainControl,
|
setAutoGainControl : settingsActions.toggleAutoGainControl,
|
||||||
setNoiseSuppression : settingsActions.toggleNoiseSuppression
|
setNoiseSuppression : settingsActions.toggleNoiseSuppression,
|
||||||
|
setVoiceActivatedUnmute : settingsActions.setVoiceActivatedUnmute
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withRoomContext(connect(
|
export default withRoomContext(connect(
|
||||||
|
|
@ -337,7 +413,8 @@ export default withRoomContext(connect(
|
||||||
{
|
{
|
||||||
return (
|
return (
|
||||||
prev.me === next.me &&
|
prev.me === next.me &&
|
||||||
prev.settings === next.settings
|
prev.settings === next.settings &&
|
||||||
|
prev.peerVolumes[prev.me.id] === next[next.me.id]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,8 @@ const initialState =
|
||||||
raisedHand : false,
|
raisedHand : false,
|
||||||
raisedHandInProgress : false,
|
raisedHandInProgress : false,
|
||||||
loggedIn : false,
|
loggedIn : false,
|
||||||
isSpeaking : false
|
isSpeaking : false,
|
||||||
|
isAutoMuted : true
|
||||||
};
|
};
|
||||||
|
|
||||||
const me = (state = initialState, action) =>
|
const me = (state = initialState, action) =>
|
||||||
|
|
@ -162,6 +163,13 @@ const me = (state = initialState, action) =>
|
||||||
return { ...state, isSpeaking: flag };
|
return { ...state, isSpeaking: flag };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'SET_AUTO_MUTED':
|
||||||
|
{
|
||||||
|
const { flag } = action.payload;
|
||||||
|
|
||||||
|
return { ...state, isAutoMuted: flag };
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,10 @@ const peerVolumes = (state = initialState, action) =>
|
||||||
|
|
||||||
case 'SET_PEER_VOLUME':
|
case 'SET_PEER_VOLUME':
|
||||||
{
|
{
|
||||||
const { peerId, volume } = action.payload;
|
const { peerId } = action.payload;
|
||||||
|
const dBs = action.payload.volume < -100 ? -100 : action.payload.volume;
|
||||||
|
|
||||||
return { ...state, [peerId]: volume };
|
return { ...state, [peerId]: Math.round(dBs) };
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,11 @@ const initialState =
|
||||||
sampleRate : 48000,
|
sampleRate : 48000,
|
||||||
channelCount : 1,
|
channelCount : 1,
|
||||||
volume : 1.0,
|
volume : 1.0,
|
||||||
autoGainControl : true,
|
autoGainControl : false,
|
||||||
echoCancellation : true,
|
echoCancellation : true,
|
||||||
noiseSuppression : true,
|
noiseSuppression : true,
|
||||||
|
voiceActivatedUnmute : false,
|
||||||
|
noiseThreshold : -50,
|
||||||
sampleSize : 16,
|
sampleSize : 16,
|
||||||
// low, medium, high, veryhigh, ultra
|
// low, medium, high, veryhigh, ultra
|
||||||
resolution : window.config.defaultResolution || 'medium',
|
resolution : window.config.defaultResolution || 'medium',
|
||||||
|
|
@ -99,6 +101,20 @@ const settings = (state = initialState, action) =>
|
||||||
return { ...state, noiseSuppression };
|
return { ...state, noiseSuppression };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'SET_VOICE_ACTIVATED_UNMUTE':
|
||||||
|
{
|
||||||
|
const { voiceActivatedUnmute } = action.payload;
|
||||||
|
|
||||||
|
return { ...state, voiceActivatedUnmute };
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'SET_NOISE_THRESHOLD':
|
||||||
|
{
|
||||||
|
const { noiseThreshold } = action.payload;
|
||||||
|
|
||||||
|
return { ...state, noiseThreshold };
|
||||||
|
}
|
||||||
|
|
||||||
case 'SET_DEFAULT_AUDIO':
|
case 'SET_DEFAULT_AUDIO':
|
||||||
{
|
{
|
||||||
const { audio } = action.payload;
|
const { audio } = action.payload;
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": null,
|
"label.addVideo": null,
|
||||||
"label.promoteAllPeers": null,
|
"label.promoteAllPeers": null,
|
||||||
"label.moreActions": null,
|
"label.moreActions": null,
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "设置",
|
"settings.settings": "设置",
|
||||||
"settings.camera": "视频设备",
|
"settings.camera": "视频设备",
|
||||||
|
|
@ -190,6 +191,7 @@
|
||||||
"moderator.muteAudio": null,
|
"moderator.muteAudio": null,
|
||||||
"moderator.muteVideo": null,
|
"moderator.muteVideo": null,
|
||||||
"moderator.muteScreenSharing": null,
|
"moderator.muteScreenSharing": null,
|
||||||
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
|
|
||||||
|
|
@ -118,6 +118,7 @@
|
||||||
"label.addVideo": null,
|
"label.addVideo": null,
|
||||||
"label.promoteAllPeers": null,
|
"label.promoteAllPeers": null,
|
||||||
"label.moreActions": null,
|
"label.moreActions": null,
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "Nastavení",
|
"settings.settings": "Nastavení",
|
||||||
"settings.camera": "Kamera",
|
"settings.camera": "Kamera",
|
||||||
|
|
@ -189,6 +190,7 @@
|
||||||
"moderator.muteAudio": null,
|
"moderator.muteAudio": null,
|
||||||
"moderator.muteVideo": null,
|
"moderator.muteVideo": null,
|
||||||
"moderator.muteScreenSharing": null,
|
"moderator.muteScreenSharing": null,
|
||||||
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": "Video hinzufügen",
|
"label.addVideo": "Video hinzufügen",
|
||||||
"label.promoteAllPeers": "Alle Teilnehmer reinlassen",
|
"label.promoteAllPeers": "Alle Teilnehmer reinlassen",
|
||||||
"label.moreActions": "Weitere Aktionen",
|
"label.moreActions": "Weitere Aktionen",
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "Einstellungen",
|
"settings.settings": "Einstellungen",
|
||||||
"settings.camera": "Kamera",
|
"settings.camera": "Kamera",
|
||||||
|
|
@ -190,6 +191,7 @@
|
||||||
"moderator.muteAudio": "Moderator hat dich stummgeschaltet",
|
"moderator.muteAudio": "Moderator hat dich stummgeschaltet",
|
||||||
"moderator.muteVideo": "Moderator hat dein Video gestoppt",
|
"moderator.muteVideo": "Moderator hat dein Video gestoppt",
|
||||||
"moderator.muteScreenSharing": null,
|
"moderator.muteScreenSharing": null,
|
||||||
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": null,
|
"label.addVideo": null,
|
||||||
"label.promoteAllPeers": null,
|
"label.promoteAllPeers": null,
|
||||||
"label.moreActions": null,
|
"label.moreActions": null,
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "Indstillinger",
|
"settings.settings": "Indstillinger",
|
||||||
"settings.camera": "Kamera",
|
"settings.camera": "Kamera",
|
||||||
|
|
@ -190,6 +191,7 @@
|
||||||
"moderator.muteAudio": null,
|
"moderator.muteAudio": null,
|
||||||
"moderator.muteVideo": null,
|
"moderator.muteVideo": null,
|
||||||
"moderator.muteScreenSharing": null,
|
"moderator.muteScreenSharing": null,
|
||||||
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": null,
|
"label.addVideo": null,
|
||||||
"label.promoteAllPeers": null,
|
"label.promoteAllPeers": null,
|
||||||
"label.moreActions": null,
|
"label.moreActions": null,
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "Ρυθμίσεις",
|
"settings.settings": "Ρυθμίσεις",
|
||||||
"settings.camera": "Κάμερα",
|
"settings.camera": "Κάμερα",
|
||||||
|
|
@ -190,6 +191,7 @@
|
||||||
"moderator.muteAudio": null,
|
"moderator.muteAudio": null,
|
||||||
"moderator.muteVideo": null,
|
"moderator.muteVideo": null,
|
||||||
"moderator.muteScreenSharing": null,
|
"moderator.muteScreenSharing": null,
|
||||||
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": "Add video",
|
"label.addVideo": "Add video",
|
||||||
"label.promoteAllPeers": "Promote all",
|
"label.promoteAllPeers": "Promote all",
|
||||||
"label.moreActions": "More actions",
|
"label.moreActions": "More actions",
|
||||||
|
"label.version": "Version",
|
||||||
|
|
||||||
"settings.settings": "Settings",
|
"settings.settings": "Settings",
|
||||||
"settings.camera": "Camera",
|
"settings.camera": "Camera",
|
||||||
|
|
@ -190,6 +191,7 @@
|
||||||
"moderator.muteAudio": "Moderator muted your audio",
|
"moderator.muteAudio": "Moderator muted your audio",
|
||||||
"moderator.muteVideo": "Moderator muted your video",
|
"moderator.muteVideo": "Moderator muted your video",
|
||||||
"moderator.muteScreenSharing": "Moderator muted your screen sharing",
|
"moderator.muteScreenSharing": "Moderator muted your screen sharing",
|
||||||
|
"moderator.stopScreenSharing": "Moderator stopped your screen sharing",
|
||||||
|
|
||||||
"unsupportedBrowser.titleUsnsupportedBrowser": "Detected unsupported browser!",
|
"unsupportedBrowser.titleUsnsupportedBrowser": "Detected unsupported browser!",
|
||||||
"unsupportedBrowser.titlewebrtcUnavailable": "Required functionality not available in your browser!",
|
"unsupportedBrowser.titlewebrtcUnavailable": "Required functionality not available in your browser!",
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": null,
|
"label.addVideo": null,
|
||||||
"label.promoteAllPeers": null,
|
"label.promoteAllPeers": null,
|
||||||
"label.moreActions": null,
|
"label.moreActions": null,
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "Ajustes",
|
"settings.settings": "Ajustes",
|
||||||
"settings.camera": "Cámara",
|
"settings.camera": "Cámara",
|
||||||
|
|
@ -190,6 +191,7 @@
|
||||||
"moderator.muteAudio": null,
|
"moderator.muteAudio": null,
|
||||||
"moderator.muteVideo": null,
|
"moderator.muteVideo": null,
|
||||||
"moderator.muteScreenSharing": null,
|
"moderator.muteScreenSharing": null,
|
||||||
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": null,
|
"label.addVideo": null,
|
||||||
"label.promoteAllPeers": null,
|
"label.promoteAllPeers": null,
|
||||||
"label.moreActions": null,
|
"label.moreActions": null,
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "Paramètres",
|
"settings.settings": "Paramètres",
|
||||||
"settings.camera": "Caméra",
|
"settings.camera": "Caméra",
|
||||||
|
|
@ -189,6 +190,7 @@
|
||||||
"moderator.muteAudio": null,
|
"moderator.muteAudio": null,
|
||||||
"moderator.muteVideo": null,
|
"moderator.muteVideo": null,
|
||||||
"moderator.muteScreenSharing": null,
|
"moderator.muteScreenSharing": null,
|
||||||
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": "Dodaj video",
|
"label.addVideo": "Dodaj video",
|
||||||
"label.promoteAllPeers": "Promoviraj sve",
|
"label.promoteAllPeers": "Promoviraj sve",
|
||||||
"label.moreActions": "Više akcija",
|
"label.moreActions": "Više akcija",
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "Postavke",
|
"settings.settings": "Postavke",
|
||||||
"settings.camera": "Kamera",
|
"settings.camera": "Kamera",
|
||||||
|
|
@ -190,6 +191,7 @@
|
||||||
"moderator.muteAudio": "Moderator je utišao tvoj zvuk",
|
"moderator.muteAudio": "Moderator je utišao tvoj zvuk",
|
||||||
"moderator.muteVideo": "Moderator je zaustavio tvoj video",
|
"moderator.muteVideo": "Moderator je zaustavio tvoj video",
|
||||||
"moderator.muteScreenSharing": null,
|
"moderator.muteScreenSharing": null,
|
||||||
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@
|
||||||
"room.browsePeersSpotlight": "Résztvevők böngészése",
|
"room.browsePeersSpotlight": "Résztvevők böngészése",
|
||||||
"room.stopAllScreenSharing": "Összes képernyőmegosztás leállítása",
|
"room.stopAllScreenSharing": "Összes képernyőmegosztás leállítása",
|
||||||
|
|
||||||
"me.mutedPTT": "Némítva vagy, ha beszélnél nyomd le a szóköz billentyűt",
|
"me.mutedPTT": "Némítva vagy, ha beszélnél nyomd le a SZÓKÖZ billentyűt",
|
||||||
|
|
||||||
"roles.gotRole": "{role} szerepet kaptál",
|
"roles.gotRole": "{role} szerepet kaptál",
|
||||||
"roles.lostRole": "Elvesztetted a {role} szerepet",
|
"roles.lostRole": "Elvesztetted a {role} szerepet",
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": "Videó hozzáadása",
|
"label.addVideo": "Videó hozzáadása",
|
||||||
"label.promoteAllPeers": "Mindenkit beengedek",
|
"label.promoteAllPeers": "Mindenkit beengedek",
|
||||||
"label.moreActions": "További műveletek",
|
"label.moreActions": "További műveletek",
|
||||||
|
"label.version": "Verzió",
|
||||||
|
|
||||||
"settings.settings": "Beállítások",
|
"settings.settings": "Beállítások",
|
||||||
"settings.camera": "Kamera",
|
"settings.camera": "Kamera",
|
||||||
|
|
@ -189,10 +190,10 @@
|
||||||
"moderator.clearFiles": "A moderátor kiürítette a file megosztás történelmet",
|
"moderator.clearFiles": "A moderátor kiürítette a file megosztás történelmet",
|
||||||
"moderator.muteAudio": "A moderátor elnémította a hangod",
|
"moderator.muteAudio": "A moderátor elnémította a hangod",
|
||||||
"moderator.muteVideo": "A moderátor elnémította a videód",
|
"moderator.muteVideo": "A moderátor elnémította a videód",
|
||||||
"moderator.muteScreenSharing": "A moderátor leállította képernyőmegosztásod",
|
"moderator.muteScreenSharing": "A moderátor szünetelteti képernyőmegosztásod",
|
||||||
|
"moderator.stopScreenSharing": "A moderátor leállította a képernyőmegosztásod",
|
||||||
|
|
||||||
"unsupportedBrowser.titleUnsupportedBrowser": "A bőngésző verziód sajnos nem támogatott! :-(",
|
"unsupportedBrowser.titleUnsupportedBrowser": "A bőngésző verziód sajnos nem támogatott! :-(",
|
||||||
"unsupportedBrowser.titlewebrtcUnavailable": "A böngésződ egy szükséges funkciója nem elérhető!",
|
"unsupportedBrowser.titlewebrtcUnavailable": "A böngésződ egy szükséges funkciója nem elérhető!",
|
||||||
"unsupportedBrowser.bodyText": "Kérlek frissítsd a böngésződ, válts másik böngészőre, vagy ellenőrizd a böngésződ beállításait! Támogatott böngészők:"
|
"unsupportedBrowser.bodyText": "Kérlek frissítsd a böngésződ, válts másik böngészőre, vagy ellenőrizd a böngésződ beállításait! Támogatott böngészők:"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": "Aggiungi video",
|
"label.addVideo": "Aggiungi video",
|
||||||
"label.promoteAllPeers": "Promuovi tutti",
|
"label.promoteAllPeers": "Promuovi tutti",
|
||||||
"label.moreActions": "Altre azioni",
|
"label.moreActions": "Altre azioni",
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "Impostazioni",
|
"settings.settings": "Impostazioni",
|
||||||
"settings.camera": "Videocamera",
|
"settings.camera": "Videocamera",
|
||||||
|
|
@ -190,9 +191,9 @@
|
||||||
"moderator.muteAudio": "Il moderatore ha mutato il tuo audio",
|
"moderator.muteAudio": "Il moderatore ha mutato il tuo audio",
|
||||||
"moderator.muteVideo": "Il moderatore ha fermato il tuo video",
|
"moderator.muteVideo": "Il moderatore ha fermato il tuo video",
|
||||||
"moderator.muteScreenSharing": null,
|
"moderator.muteScreenSharing": null,
|
||||||
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
"unsupportedBrowser.bodyText": null
|
"unsupportedBrowser.bodyText": null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,7 @@
|
||||||
"label.advanced": "Advancēts",
|
"label.advanced": "Advancēts",
|
||||||
"label.addVideo": "Pievienot video",
|
"label.addVideo": "Pievienot video",
|
||||||
"label.moreActions": null,
|
"label.moreActions": null,
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "Iestatījumi",
|
"settings.settings": "Iestatījumi",
|
||||||
"settings.camera": "Kamera",
|
"settings.camera": "Kamera",
|
||||||
|
|
@ -184,6 +185,7 @@
|
||||||
"moderator.muteAudio": "Moderators noklusināja jūsu mikrofonu",
|
"moderator.muteAudio": "Moderators noklusināja jūsu mikrofonu",
|
||||||
"moderator.muteVideo": "Moderators atslēdza jūsu kameru",
|
"moderator.muteVideo": "Moderators atslēdza jūsu kameru",
|
||||||
"moderator.muteScreenSharing": null,
|
"moderator.muteScreenSharing": null,
|
||||||
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": "Legg til video",
|
"label.addVideo": "Legg til video",
|
||||||
"label.promoteAllPeers": "Slipp inn alle",
|
"label.promoteAllPeers": "Slipp inn alle",
|
||||||
"label.moreActions": "Flere handlinger",
|
"label.moreActions": "Flere handlinger",
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "Innstillinger",
|
"settings.settings": "Innstillinger",
|
||||||
"settings.camera": "Kamera",
|
"settings.camera": "Kamera",
|
||||||
|
|
@ -190,6 +191,7 @@
|
||||||
"moderator.muteAudio": "Moderator mutet lyden din",
|
"moderator.muteAudio": "Moderator mutet lyden din",
|
||||||
"moderator.muteVideo": "Moderator mutet videoen din",
|
"moderator.muteVideo": "Moderator mutet videoen din",
|
||||||
"moderator.muteScreenSharing": null,
|
"moderator.muteScreenSharing": null,
|
||||||
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": "Dodaj wideo",
|
"label.addVideo": "Dodaj wideo",
|
||||||
"label.promoteAllPeers": "Wpuść wszystkich",
|
"label.promoteAllPeers": "Wpuść wszystkich",
|
||||||
"label.moreActions": "Więcej akcji",
|
"label.moreActions": "Więcej akcji",
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "Ustawienia",
|
"settings.settings": "Ustawienia",
|
||||||
"settings.camera": "Kamera",
|
"settings.camera": "Kamera",
|
||||||
|
|
@ -190,6 +191,7 @@
|
||||||
"moderator.muteAudio": "Moderator wyciszył audio",
|
"moderator.muteAudio": "Moderator wyciszył audio",
|
||||||
"moderator.muteVideo": "Moderator wyciszył twoje video",
|
"moderator.muteVideo": "Moderator wyciszył twoje video",
|
||||||
"moderator.muteScreenSharing": null,
|
"moderator.muteScreenSharing": null,
|
||||||
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": null,
|
"label.addVideo": null,
|
||||||
"label.promoteAllPeers": null,
|
"label.promoteAllPeers": null,
|
||||||
"label.moreActions": null,
|
"label.moreActions": null,
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "Definições",
|
"settings.settings": "Definições",
|
||||||
"settings.camera": "Camera",
|
"settings.camera": "Camera",
|
||||||
|
|
@ -190,6 +191,7 @@
|
||||||
"moderator.muteAudio": null,
|
"moderator.muteAudio": null,
|
||||||
"moderator.muteVideo": null,
|
"moderator.muteVideo": null,
|
||||||
"moderator.muteScreenSharing": null,
|
"moderator.muteScreenSharing": null,
|
||||||
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": null,
|
"label.addVideo": null,
|
||||||
"label.promoteAllPeers": null,
|
"label.promoteAllPeers": null,
|
||||||
"label.moreActions": null,
|
"label.moreActions": null,
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "Setări",
|
"settings.settings": "Setări",
|
||||||
"settings.camera": "Cameră video",
|
"settings.camera": "Cameră video",
|
||||||
|
|
@ -190,6 +191,7 @@
|
||||||
"moderator.muteAudio": null,
|
"moderator.muteAudio": null,
|
||||||
"moderator.muteVideo": null,
|
"moderator.muteVideo": null,
|
||||||
"moderator.muteScreenSharing": null,
|
"moderator.muteScreenSharing": null,
|
||||||
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": null,
|
"label.addVideo": null,
|
||||||
"label.promoteAllPeers": null,
|
"label.promoteAllPeers": null,
|
||||||
"label.moreActions": null,
|
"label.moreActions": null,
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "Ayarlar",
|
"settings.settings": "Ayarlar",
|
||||||
"settings.camera": "Kamera",
|
"settings.camera": "Kamera",
|
||||||
|
|
@ -181,7 +182,13 @@
|
||||||
|
|
||||||
"devices.cameraDisconnected": "Kamera bağlı değil",
|
"devices.cameraDisconnected": "Kamera bağlı değil",
|
||||||
"devices.cameraError": "Kameranıza erişilirken bir hata oluştu",
|
"devices.cameraError": "Kameranıza erişilirken bir hata oluştu",
|
||||||
|
|
||||||
|
"moderator.clearChat": null,
|
||||||
|
"moderator.clearFiles": null,
|
||||||
|
"moderator.muteAudio": null,
|
||||||
|
"moderator.muteVideo": null,
|
||||||
"moderator.muteScreenSharing": null,
|
"moderator.muteScreenSharing": null,
|
||||||
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
|
|
||||||
|
|
@ -118,6 +118,7 @@
|
||||||
"label.addVideo": "新增視訊",
|
"label.addVideo": "新增視訊",
|
||||||
"label.promoteAllPeers": "提升全部",
|
"label.promoteAllPeers": "提升全部",
|
||||||
"label.moreActions": "更多",
|
"label.moreActions": "更多",
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "設置",
|
"settings.settings": "設置",
|
||||||
"settings.camera": "視訊來源",
|
"settings.camera": "視訊來源",
|
||||||
|
|
@ -189,6 +190,7 @@
|
||||||
"moderator.muteAudio": "您已被管理員靜音",
|
"moderator.muteAudio": "您已被管理員靜音",
|
||||||
"moderator.muteVideo": "您的視訊已被管理員關閉",
|
"moderator.muteVideo": "您的視訊已被管理員關閉",
|
||||||
"moderator.muteScreenSharing": null,
|
"moderator.muteScreenSharing": null,
|
||||||
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": null,
|
"label.addVideo": null,
|
||||||
"label.promoteAllPeers": null,
|
"label.promoteAllPeers": null,
|
||||||
"label.moreActions": null,
|
"label.moreActions": null,
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "Налаштування",
|
"settings.settings": "Налаштування",
|
||||||
"settings.camera": "Камера",
|
"settings.camera": "Камера",
|
||||||
|
|
@ -190,6 +191,7 @@
|
||||||
"moderator.muteAudio": null,
|
"moderator.muteAudio": null,
|
||||||
"moderator.muteVideo": null,
|
"moderator.muteVideo": null,
|
||||||
"moderator.muteScreenSharing": null,
|
"moderator.muteScreenSharing": null,
|
||||||
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
|
|
||||||
|
|
@ -17,3 +17,21 @@ export const idle = (callback, delay) =>
|
||||||
handle = setTimeout(callback, delay);
|
handle = setTimeout(callback, delay);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error produced when a socket request has a timeout.
|
||||||
|
*/
|
||||||
|
export class SocketTimeoutError extends Error
|
||||||
|
{
|
||||||
|
constructor(message)
|
||||||
|
{
|
||||||
|
super(message);
|
||||||
|
|
||||||
|
this.name = 'SocketTimeoutError';
|
||||||
|
|
||||||
|
if (Error.hasOwnProperty('captureStackTrace')) // Just in V8.
|
||||||
|
Error.captureStackTrace(this, SocketTimeoutError);
|
||||||
|
else
|
||||||
|
this.stack = (new Error(message)).stack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -106,6 +106,12 @@
|
||||||
"no-invalid-regexp": 2,
|
"no-invalid-regexp": 2,
|
||||||
"no-invalid-this": 2,
|
"no-invalid-this": 2,
|
||||||
"no-irregular-whitespace": 2,
|
"no-irregular-whitespace": 2,
|
||||||
|
"no-trailing-spaces": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"ignoreComments": true
|
||||||
|
}
|
||||||
|
],
|
||||||
"no-lonely-if": 2,
|
"no-lonely-if": 2,
|
||||||
"no-mixed-operators": 2,
|
"no-mixed-operators": 2,
|
||||||
"no-mixed-spaces-and-tabs": 2,
|
"no-mixed-spaces-and-tabs": 2,
|
||||||
|
|
|
||||||
|
|
@ -276,6 +276,10 @@ module.exports =
|
||||||
// maxUsersPerRoom : 20,
|
// maxUsersPerRoom : 20,
|
||||||
// Room size before spreading to new router
|
// Room size before spreading to new router
|
||||||
routerScaleSize : 40,
|
routerScaleSize : 40,
|
||||||
|
// Socket timout value
|
||||||
|
requestTimeout : 20000,
|
||||||
|
// Socket retries when timeout
|
||||||
|
requestRetries : 3,
|
||||||
// Mediasoup settings
|
// Mediasoup settings
|
||||||
mediasoup :
|
mediasoup :
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ const AwaitQueue = require('awaitqueue');
|
||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
const Logger = require('./Logger');
|
const Logger = require('./Logger');
|
||||||
const Lobby = require('./Lobby');
|
const Lobby = require('./Lobby');
|
||||||
|
const { SocketTimeoutError } = require('./errors');
|
||||||
const { v4: uuidv4 } = require('uuid');
|
const { v4: uuidv4 } = require('uuid');
|
||||||
const jwt = require('jsonwebtoken');
|
const jwt = require('jsonwebtoken');
|
||||||
const userRoles = require('../userRoles');
|
const userRoles = require('../userRoles');
|
||||||
|
|
@ -1759,9 +1760,9 @@ class Room extends EventEmitter
|
||||||
if (called)
|
if (called)
|
||||||
return;
|
return;
|
||||||
called = true;
|
called = true;
|
||||||
callback(new Error('Request timeout.'));
|
callback(new SocketTimeoutError('Request timed out'));
|
||||||
},
|
},
|
||||||
10000
|
config.requestTimeout || 20000
|
||||||
);
|
);
|
||||||
|
|
||||||
return (...args) =>
|
return (...args) =>
|
||||||
|
|
@ -1775,7 +1776,7 @@ class Room extends EventEmitter
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
_request(socket, method, data = {})
|
_sendRequest(socket, method, data = {})
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) =>
|
return new Promise((resolve, reject) =>
|
||||||
{
|
{
|
||||||
|
|
@ -1797,6 +1798,33 @@ class Room extends EventEmitter
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _request(socket, method, data)
|
||||||
|
{
|
||||||
|
logger.debug('_request() [method:"%s", data:"%o"]', method, data);
|
||||||
|
|
||||||
|
const {
|
||||||
|
requestRetries = 3
|
||||||
|
} = config;
|
||||||
|
|
||||||
|
for (let tries = 0; tries < requestRetries; tries++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return await this._sendRequest(socket, method, data);
|
||||||
|
}
|
||||||
|
catch (error)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
error instanceof SocketTimeoutError &&
|
||||||
|
tries < requestRetries
|
||||||
|
)
|
||||||
|
logger.warn('_request() | timeout, retrying [attempt:"%s"]', tries);
|
||||||
|
else
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_notification(socket, method, data = {}, broadcast = false, includeSender = false)
|
_notification(socket, method, data = {}, broadcast = false, includeSender = false)
|
||||||
{
|
{
|
||||||
if (broadcast)
|
if (broadcast)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
/**
|
||||||
|
* Error produced when a socket request has a timeout.
|
||||||
|
*/
|
||||||
|
class SocketTimeoutError extends Error
|
||||||
|
{
|
||||||
|
constructor(message)
|
||||||
|
{
|
||||||
|
super(message);
|
||||||
|
|
||||||
|
this.name = 'SocketTimeoutError';
|
||||||
|
|
||||||
|
if (Error.hasOwnProperty('captureStackTrace')) // Just in V8.
|
||||||
|
Error.captureStackTrace(this, SocketTimeoutError);
|
||||||
|
else
|
||||||
|
this.stack = (new Error(message)).stack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports =
|
||||||
|
{
|
||||||
|
SocketTimeoutError
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue