diff --git a/app/src/RoomClient.js b/app/src/RoomClient.js index 9527d9a..7cfd626 100644 --- a/app/src/RoomClient.js +++ b/app/src/RoomClient.js @@ -997,7 +997,11 @@ export default class RoomClient if (!this._harkStream.getAudioTracks()[0]) throw new Error('getMicStream():something went wrong with hark'); - this._hark = hark(this._harkStream, { play: false, interval: 5 }); + this._hark = hark(this._harkStream, + { + play : false, + interval : 5, + threshold : store.getState().settings.noiseThreshold }); // eslint-disable-next-line no-unused-vars this._hark.on('volume_change', (volume, threshold) => @@ -1013,19 +1017,25 @@ export default class RoomClient }); this._hark.on('speaking', () => { - this._hark.setInterval(300); + this._hark.setInterval(5); store.dispatch(meActions.setIsSpeaking(true)); - if (store.getState().settings.voiceActivatedUnmute && this._micProducer.paused) + if (store.getState().settings.voiceActivatedUnmute && + this._micProducer && + this._micProducer.paused) { - this.unmuteMic(); + this._micProducer.resume(); + store.dispatch(meActions.setAutoMuted(false)); } }); this._hark.on('stopped_speaking', () => { store.dispatch(meActions.setIsSpeaking(false)); - if (store.getState().settings.voiceActivatedUnmute && !this._micProducer.paused) + if (store.getState().settings.voiceActivatedUnmute && + this._micProducer && + !this._micProducer.paused) { - this.muteMic(); + this._micProducer.pause(); + store.dispatch(meActions.setAutoMuted(true)); } this._hark.setInterval(5); }); diff --git a/app/src/actions/meActions.js b/app/src/actions/meActions.js index 7fb34ea..be7c1ee 100644 --- a/app/src/actions/meActions.js +++ b/app/src/actions/meActions.js @@ -110,3 +110,9 @@ export const setIsSpeaking = (flag) => type : 'SET_IS_SPEAKING', payload : { flag } }); + +export const setAutoMuted = (flag) => + ({ + type : 'SET_AUTO_MUTED', + payload : { flag } + }); diff --git a/app/src/components/Containers/Me.js b/app/src/components/Containers/Me.js index b4de8b4..0ec1142 100644 --- a/app/src/components/Containers/Me.js +++ b/app/src/components/Containers/Me.js @@ -175,6 +175,7 @@ const Me = (props) => screenProducer, extraVideoProducers, canShareScreen, + noiseVolume, classes } = props; @@ -408,7 +409,12 @@ const Me = (props) => })} className={classes.smallContainer} disabled={!me.canSendMic || me.audioInProgress} - color={micState === 'on' ? 'primary' : 'secondary'} + color={ + micState === 'on' ? + settings.voiceActivatedUnmute && !me.isAutoMuted ? + 'primary' + : 'default' + : 'secondary'} size='small' onClick={() => { @@ -421,7 +427,10 @@ const Me = (props) => }} > { micState === 'on' ? - + : } @@ -436,7 +445,10 @@ const Me = (props) => })} className={classes.fab} disabled={!me.canSendMic || me.audioInProgress} - color={micState === 'on' ? 'default' : 'secondary'} + color={micState === 'on' ? + settings.voiceActivatedUnmute && !me.isAutoMuted? 'primary' + : 'default' + : 'secondary'} size='large' onClick={() => { @@ -449,7 +461,11 @@ const Me = (props) => }} > { micState === 'on' ? - + : } @@ -832,6 +848,7 @@ Me.propTypes = style : PropTypes.object, smallContainer : PropTypes.bool, canShareScreen : PropTypes.bool.isRequired, + noiseVolume : PropTypes.number, classes : PropTypes.object.isRequired, theme : PropTypes.object.isRequired }; @@ -842,12 +859,26 @@ const makeMapStateToProps = () => 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) / + state.settings.noiseThreshold) / 2; + } + // noiseVolume over threshold: no noise but voice + else { volume = 0; } + return { me : state.me, ...meProducersSelector(state), settings : state.settings, activeSpeaker : state.me.id === state.room.activeSpeakerId, - canShareScreen : hasPermission(state) + canShareScreen : hasPermission(state), + noiseVolume : volume }; }; @@ -864,6 +895,8 @@ export default withRoomContext(connect( return ( prev.room === next.room && prev.me === next.me && + Math.round(prev.peerVolumes[prev.me.id]) === + Math.round(next.peerVolumes[next.me.id]) && prev.peers === next.peers && prev.producers === next.producers && prev.settings === next.settings diff --git a/app/src/reducers/me.js b/app/src/reducers/me.js index f3fff66..35336a6 100644 --- a/app/src/reducers/me.js +++ b/app/src/reducers/me.js @@ -18,7 +18,8 @@ const initialState = raisedHand : false, raisedHandInProgress : false, loggedIn : false, - isSpeaking : false + isSpeaking : false, + isAutoMuted : true }; const me = (state = initialState, action) => @@ -162,6 +163,13 @@ const me = (state = initialState, action) => return { ...state, isSpeaking: flag }; } + case 'SET_AUTO_MUTED': + { + const { flag } = action.payload; + + return { ...state, isAutoMuted: flag }; + } + default: return state; } diff --git a/app/src/reducers/peerVolumes.js b/app/src/reducers/peerVolumes.js index cd5032f..826a038 100644 --- a/app/src/reducers/peerVolumes.js +++ b/app/src/reducers/peerVolumes.js @@ -32,7 +32,7 @@ const peerVolumes = (state = initialState, action) => case 'SET_PEER_VOLUME': { const { peerId } = action.payload; - const dBs = action.payload.volume; + const dBs = action.payload.volume < -100 ? -100 : action.payload.volume; return { ...state, [peerId]: Math.round(dBs) }; }