Moderator: Mute or stop video for a peer globally (#316)
parent
837aa1ace2
commit
2eab32cafa
|
|
@ -1389,6 +1389,46 @@ export default class RoomClient
|
||||||
peerActions.setPeerKickInProgress(peerId, false));
|
peerActions.setPeerKickInProgress(peerId, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async mutePeer(peerId)
|
||||||
|
{
|
||||||
|
logger.debug('mutePeer() [peerId:"%s"]', peerId);
|
||||||
|
|
||||||
|
store.dispatch(
|
||||||
|
peerActions.setMutePeerInProgress(peerId, true));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await this.sendRequest('moderator:mute', { peerId });
|
||||||
|
}
|
||||||
|
catch (error)
|
||||||
|
{
|
||||||
|
logger.error('mutePeer() failed: %o', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
store.dispatch(
|
||||||
|
peerActions.setMutePeerInProgress(peerId, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
async stopPeerVideo(peerId)
|
||||||
|
{
|
||||||
|
logger.debug('stopPeerVideo() [peerId:"%s"]', peerId);
|
||||||
|
|
||||||
|
store.dispatch(
|
||||||
|
peerActions.setStopPeerVideoInProgress(peerId, true));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await this.sendRequest('moderator:stopVideo', { peerId });
|
||||||
|
}
|
||||||
|
catch (error)
|
||||||
|
{
|
||||||
|
logger.error('stopPeerVideo() failed: %o', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
store.dispatch(
|
||||||
|
peerActions.setStopPeerVideoInProgress(peerId, false));
|
||||||
|
}
|
||||||
|
|
||||||
async muteAllPeers()
|
async muteAllPeers()
|
||||||
{
|
{
|
||||||
logger.debug('muteAllPeers()');
|
logger.debug('muteAllPeers()');
|
||||||
|
|
|
||||||
|
|
@ -69,3 +69,15 @@ export const setPeerKickInProgress = (peerId, flag) =>
|
||||||
type : 'SET_PEER_KICK_IN_PROGRESS',
|
type : 'SET_PEER_KICK_IN_PROGRESS',
|
||||||
payload : { peerId, flag }
|
payload : { peerId, flag }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const setMutePeerInProgress = (peerId, flag) =>
|
||||||
|
({
|
||||||
|
type : 'STOP_PEER_AUDIO_IN_PROGRESS',
|
||||||
|
payload : { peerId, flag }
|
||||||
|
});
|
||||||
|
|
||||||
|
export const setStopPeerVideoInProgress = (peerId, flag) =>
|
||||||
|
({
|
||||||
|
type : 'STOP_PEER_VIDEO_IN_PROGRESS',
|
||||||
|
payload : { peerId, flag }
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@ import IconButton from '@material-ui/core/IconButton';
|
||||||
import Tooltip from '@material-ui/core/Tooltip';
|
import Tooltip from '@material-ui/core/Tooltip';
|
||||||
import VideocamIcon from '@material-ui/icons/Videocam';
|
import VideocamIcon from '@material-ui/icons/Videocam';
|
||||||
import VideocamOffIcon from '@material-ui/icons/VideocamOff';
|
import VideocamOffIcon from '@material-ui/icons/VideocamOff';
|
||||||
|
import MicIcon from '@material-ui/icons/Mic';
|
||||||
|
import MicOffIcon from '@material-ui/icons/MicOff';
|
||||||
import VolumeUpIcon from '@material-ui/icons/VolumeUp';
|
import VolumeUpIcon from '@material-ui/icons/VolumeUp';
|
||||||
import VolumeOffIcon from '@material-ui/icons/VolumeOff';
|
import VolumeOffIcon from '@material-ui/icons/VolumeOff';
|
||||||
import ScreenIcon from '@material-ui/icons/ScreenShare';
|
import ScreenIcon from '@material-ui/icons/ScreenShare';
|
||||||
|
|
@ -250,6 +252,60 @@ const ListPeer = (props) =>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
}
|
}
|
||||||
|
{ isModerator && micConsumer &&
|
||||||
|
<Tooltip
|
||||||
|
title={intl.formatMessage({
|
||||||
|
id : 'tooltip.muteParticipant',
|
||||||
|
defaultMessage : 'Mute globally participant mic'
|
||||||
|
})}
|
||||||
|
placement='bottom'
|
||||||
|
>
|
||||||
|
<IconButton
|
||||||
|
className={classes.buttons}
|
||||||
|
style={{ color: green[500] }}
|
||||||
|
disabled={!isModerator || peer.stopPeerAudioInProgress}
|
||||||
|
onClick={(e) =>
|
||||||
|
{
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
roomClient.mutePeer(peer.id);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{ !micConsumer.remotelyPaused ?
|
||||||
|
<MicIcon />
|
||||||
|
:
|
||||||
|
<MicOffIcon />
|
||||||
|
}
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
}
|
||||||
|
{ isModerator && webcamConsumer &&
|
||||||
|
<Tooltip
|
||||||
|
title={intl.formatMessage({
|
||||||
|
id : 'tooltip.muteParticipantVideo',
|
||||||
|
defaultMessage : 'Mute globally participant video'
|
||||||
|
})}
|
||||||
|
placement='bottom'
|
||||||
|
>
|
||||||
|
<IconButton
|
||||||
|
className={classes.buttons}
|
||||||
|
style={{ color: green[500] }}
|
||||||
|
disabled={!isModerator || peer.stopPeerVideoInProgress}
|
||||||
|
onClick={(e) =>
|
||||||
|
{
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
roomClient.stopPeerVideo(peer.id);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{ !webcamConsumer.remotelyPaused ?
|
||||||
|
<VideocamIcon />
|
||||||
|
:
|
||||||
|
<VideocamOffIcon />
|
||||||
|
}
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
}
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,18 @@ const peer = (state = {}, action) =>
|
||||||
return { ...state, roles };
|
return { ...state, roles };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'STOP_PEER_AUDIO_IN_PROGRESS':
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
stopPeerAudioInProgress : action.payload.flag
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'STOP_PEER_VIDEO_IN_PROGRESS':
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
stopPeerVideoInProgress : action.payload.flag
|
||||||
|
};
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
@ -102,6 +114,8 @@ const peers = (state = {}, action) =>
|
||||||
case 'ADD_CONSUMER':
|
case 'ADD_CONSUMER':
|
||||||
case 'ADD_PEER_ROLE':
|
case 'ADD_PEER_ROLE':
|
||||||
case 'REMOVE_PEER_ROLE':
|
case 'REMOVE_PEER_ROLE':
|
||||||
|
case 'STOP_PEER_AUDIO_IN_PROGRESS':
|
||||||
|
case 'STOP_PEER_VIDEO_IN_PROGRESS':
|
||||||
{
|
{
|
||||||
const oldPeer = state[action.payload.peerId];
|
const oldPeer = state[action.payload.peerId];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1369,6 +1369,29 @@ class Room extends EventEmitter
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'moderator:mute':
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
!peer.roles.some(
|
||||||
|
(role) => permissionsFromRoles.MODERATE_ROOM.includes(role)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
throw new Error('peer not authorized');
|
||||||
|
|
||||||
|
const { peerId } = request.data;
|
||||||
|
|
||||||
|
const mutePeer = this._peers[peerId];
|
||||||
|
|
||||||
|
if (!mutePeer)
|
||||||
|
throw new Error(`peer with id "${peerId}" not found`);
|
||||||
|
|
||||||
|
this._notification(mutePeer.socket, 'moderator:mute');
|
||||||
|
|
||||||
|
cb();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 'moderator:muteAll':
|
case 'moderator:muteAll':
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
|
|
@ -1386,6 +1409,29 @@ class Room extends EventEmitter
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'moderator:stopVideo':
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
!peer.roles.some(
|
||||||
|
(role) => permissionsFromRoles.MODERATE_ROOM.includes(role)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
throw new Error('peer not authorized');
|
||||||
|
|
||||||
|
const { peerId } = request.data;
|
||||||
|
|
||||||
|
const stopVideoPeer = this._peers[peerId];
|
||||||
|
|
||||||
|
if (!stopVideoPeer)
|
||||||
|
throw new Error(`peer with id "${peerId}" not found`);
|
||||||
|
|
||||||
|
this._notification(stopVideoPeer.socket, 'moderator:stopVideo');
|
||||||
|
|
||||||
|
cb();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 'moderator:stopAllVideo':
|
case 'moderator:stopAllVideo':
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue