Show remote audio levels
This commit is contained in:
+13
-1
@@ -28,6 +28,9 @@ export default class Client extends events.EventEmitter
|
||||
super();
|
||||
this.setMaxListeners(Infinity);
|
||||
|
||||
// TODO: TMP
|
||||
global.CLIENT = this;
|
||||
|
||||
let url = urlFactory.getProtooUrl(peerId, roomId);
|
||||
let transport = new protooClient.WebSocketTransport(url);
|
||||
|
||||
@@ -708,6 +711,16 @@ export default class Client extends events.EventEmitter
|
||||
break;
|
||||
}
|
||||
|
||||
case 'activespeaker':
|
||||
{
|
||||
let data = request.data;
|
||||
|
||||
this.emit('activespeaker', data.peer, data.level);
|
||||
accept();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
logger.error('unknown method');
|
||||
@@ -776,7 +789,6 @@ export default class Client extends events.EventEmitter
|
||||
this._peerconnection = new RTCPeerConnection({ iceServers: [] });
|
||||
|
||||
// TODO: TMP
|
||||
global.CLIENT = this;
|
||||
global.PC = this._peerconnection;
|
||||
|
||||
if (this._localStream)
|
||||
|
||||
@@ -5,6 +5,7 @@ import IconButton from 'material-ui/IconButton/IconButton';
|
||||
import MicOffIcon from 'material-ui/svg-icons/av/mic-off';
|
||||
import VideoCamOffIcon from 'material-ui/svg-icons/av/videocam-off';
|
||||
import ChangeVideoCamIcon from 'material-ui/svg-icons/av/repeat';
|
||||
import classnames from 'classnames';
|
||||
import Video from './Video';
|
||||
import Logger from '../Logger';
|
||||
|
||||
@@ -30,7 +31,12 @@ export default class LocalVideo extends React.Component
|
||||
let state = this.state;
|
||||
|
||||
return (
|
||||
<div data-component='LocalVideo' className={`state-${props.connectionState}`}>
|
||||
<div
|
||||
data-component='LocalVideo'
|
||||
className={classnames(`state-${props.connectionState}`, {
|
||||
'active-speaker' : props.isActiveSpeaker
|
||||
})}
|
||||
>
|
||||
{props.stream ?
|
||||
<Video
|
||||
stream={props.stream}
|
||||
@@ -141,6 +147,7 @@ LocalVideo.propTypes =
|
||||
multipleWebcams : React.PropTypes.bool.isRequired,
|
||||
webcamType : React.PropTypes.string,
|
||||
connectionState : React.PropTypes.string,
|
||||
isActiveSpeaker : React.PropTypes.bool.isRequired,
|
||||
onMicMute : React.PropTypes.func.isRequired,
|
||||
onWebcamToggle : React.PropTypes.func.isRequired,
|
||||
onWebcamChange : React.PropTypes.func.isRequired,
|
||||
|
||||
@@ -33,7 +33,10 @@ export default class RemoteVideo extends React.Component
|
||||
return (
|
||||
<div
|
||||
data-component='RemoteVideo'
|
||||
className={classnames({ fullsize: !!props.fullsize })}
|
||||
className={classnames({
|
||||
fullsize : !!props.fullsize,
|
||||
'active-speaker' : props.isActiveSpeaker
|
||||
})}
|
||||
>
|
||||
<Video
|
||||
stream={props.stream}
|
||||
@@ -93,9 +96,10 @@ export default class RemoteVideo extends React.Component
|
||||
|
||||
RemoteVideo.propTypes =
|
||||
{
|
||||
peer : React.PropTypes.object.isRequired,
|
||||
stream : React.PropTypes.object.isRequired,
|
||||
fullsize : React.PropTypes.bool,
|
||||
onDisableVideo : React.PropTypes.func.isRequired,
|
||||
onEnableVideo : React.PropTypes.func.isRequired
|
||||
peer : React.PropTypes.object.isRequired,
|
||||
stream : React.PropTypes.object.isRequired,
|
||||
fullsize : React.PropTypes.bool,
|
||||
isActiveSpeaker : React.PropTypes.bool.isRequired,
|
||||
onDisableVideo : React.PropTypes.func.isRequired,
|
||||
onEnableVideo : React.PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
@@ -29,7 +29,8 @@ export default class Room extends React.Component
|
||||
connectionState : null,
|
||||
remoteStreams : {},
|
||||
showStats : false,
|
||||
stats : null
|
||||
stats : null,
|
||||
activeSpeakerId : null
|
||||
};
|
||||
|
||||
// Mounted flag
|
||||
@@ -89,6 +90,7 @@ export default class Room extends React.Component
|
||||
peer={peer}
|
||||
stream={stream}
|
||||
fullsize={numPeers === 1}
|
||||
isActiveSpeaker={peer.id === state.activeSpeakerId}
|
||||
onDisableVideo={this.handleDisableRemoteVideo.bind(this)}
|
||||
onEnableVideo={this.handleEnableRemoteVideo.bind(this)}
|
||||
/>
|
||||
@@ -107,6 +109,7 @@ export default class Room extends React.Component
|
||||
multipleWebcams={state.multipleWebcams}
|
||||
webcamType={state.webcamType}
|
||||
connectionState={state.connectionState}
|
||||
isActiveSpeaker={props.peerId === state.activeSpeakerId}
|
||||
onMicMute={this.handleLocalMute.bind(this)}
|
||||
onWebcamToggle={this.handleLocalWebcamToggle.bind(this)}
|
||||
onWebcamChange={this.handleLocalWebcamChange.bind(this)}
|
||||
@@ -296,8 +299,12 @@ export default class Room extends React.Component
|
||||
|
||||
this._client.on('close', (error) =>
|
||||
{
|
||||
// Clear remote streams (for reconnections).
|
||||
this.setState({ remoteStreams: {} });
|
||||
// Clear remote streams (for reconnections) and more stuff.
|
||||
this.setState(
|
||||
{
|
||||
remoteStreams : {},
|
||||
activeSpeakerId : null
|
||||
});
|
||||
|
||||
if (error)
|
||||
{
|
||||
@@ -431,6 +438,14 @@ export default class Room extends React.Component
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1347578
|
||||
this.forceUpdate();
|
||||
});
|
||||
|
||||
this._client.on('activespeaker', (peer) =>
|
||||
{
|
||||
this.setState(
|
||||
{
|
||||
activeSpeakerId : (peer ? peer.id : null)
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
_startStats()
|
||||
|
||||
@@ -90,12 +90,12 @@ export default class Video extends React.Component
|
||||
|
||||
this._hark.on('speaking', () =>
|
||||
{
|
||||
logger.debug('hark "speaking" event');
|
||||
// logger.debug('hark "speaking" event');
|
||||
});
|
||||
|
||||
this._hark.on('stopped_speaking', () =>
|
||||
{
|
||||
logger.debug('hark "stopped_speaking" event');
|
||||
// logger.debug('hark "stopped_speaking" event');
|
||||
|
||||
this.setState({ volume: 0 });
|
||||
});
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
}
|
||||
|
||||
&.state-checking {
|
||||
animation: LocalVideo-state-checking .75s infinite linear;
|
||||
animation: LocalVideo-state-checking .5s infinite linear;
|
||||
}
|
||||
|
||||
&.state-connected,
|
||||
@@ -35,6 +35,10 @@
|
||||
border-color: rgba(#ff2000, 0.75);
|
||||
}
|
||||
|
||||
&.active-speaker {
|
||||
border-color: rgba(#fff, 0.9);
|
||||
}
|
||||
|
||||
> .controls {
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
|
||||
@@ -47,6 +47,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.active-speaker {
|
||||
border-color: rgba(#fff, 0.9);
|
||||
}
|
||||
|
||||
> .controls {
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
z-index: 5;
|
||||
top: 0
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
right: 2px;
|
||||
width: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
Reference in New Issue
Block a user