Mostly working mediasoup v3

This commit is contained in:
Håvar Aambø Fosstveit
2019-06-03 11:55:23 +02:00
parent e9b946ba93
commit 30f42d6ced
31 changed files with 2563 additions and 1741 deletions
+1043 -775
View File
File diff suppressed because it is too large Load Diff
+76 -59
View File
@@ -5,11 +5,11 @@ const logger = new Logger('Spotlight');
export default class Spotlights extends EventEmitter
{
constructor(maxSpotlights, room)
constructor(maxSpotlights, signalingSocket)
{
super();
this._room = room;
this._signalingSocket = signalingSocket;
this._maxSpotlights = maxSpotlights;
this._peerList = [];
this._selectedSpotlights = [];
@@ -19,24 +19,25 @@ export default class Spotlights extends EventEmitter
start()
{
const peers = this._room.peers;
for (const peer of peers)
{
this._handlePeer(peer);
}
this._handleRoom();
this._handleSignaling();
this._started = true;
this._spotlightsUpdated();
}
peerInSpotlights(peerName)
addPeers(peers)
{
for (const peer of peers)
{
this._newPeer(peer.id);
}
}
peerInSpotlights(peerId)
{
if (this._started)
{
return this._currentSpotlights.indexOf(peerName) !== -1;
return this._currentSpotlights.indexOf(peerId) !== -1;
}
else
{
@@ -44,11 +45,11 @@ export default class Spotlights extends EventEmitter
}
}
setPeerSpotlight(peerName)
setPeerSpotlight(peerId)
{
logger.debug('setPeerSpotlight() [peerName:"%s"]', peerName);
logger.debug('setPeerSpotlight() [peerId:"%s"]', peerId);
const index = this._selectedSpotlights.indexOf(peerName);
const index = this._selectedSpotlights.indexOf(peerId);
if (index !== -1)
{
@@ -56,13 +57,13 @@ export default class Spotlights extends EventEmitter
}
else
{
this._selectedSpotlights = [ peerName ];
this._selectedSpotlights = [ peerId ];
}
/*
if (index === -1) // We don't have this peer in the list, adding
{
this._selectedSpotlights.push(peerName);
this._selectedSpotlights.push(peerId);
}
else // We have this peer, remove
{
@@ -74,16 +75,65 @@ export default class Spotlights extends EventEmitter
this._spotlightsUpdated();
}
_handleRoom()
_handleSignaling()
{
this._room.on('newpeer', (peer) =>
this._signalingSocket.on('notification', (notification) =>
{
logger.debug(
'room "newpeer" event [name:"%s", peer:%o]', peer.name, peer);
this._handlePeer(peer);
if (notification.method === 'newPeer')
{
const { id } = notification.data;
this._newPeer(id);
}
if (notification.method === 'peerClosed')
{
const { peerId } = notification.data;
this._closePeer(peerId);
}
});
}
_newPeer(id)
{
logger.debug(
'room "newpeer" event [id: "%s"]', id);
if (this._peerList.indexOf(id) === -1) // We don't have this peer in the list
{
logger.debug('_handlePeer() | adding peer [peerId: "%s"]', id);
this._peerList.push(id);
if (this._started)
this._spotlightsUpdated();
}
}
_closePeer(id)
{
logger.debug(
'room "peerClosed" event [peerId:%o]', id);
let index = this._peerList.indexOf(id);
if (index !== -1) // We have this peer in the list, remove
{
this._peerList.splice(index, 1);
}
index = this._selectedSpotlights.indexOf(id);
if (index !== -1) // We have this peer in the list, remove
{
this._selectedSpotlights.splice(index, 1);
}
if (this._started)
this._spotlightsUpdated();
}
addSpeakerList(speakerList)
{
this._peerList = [ ...new Set([ ...speakerList, ...this._peerList ]) ];
@@ -92,49 +142,16 @@ export default class Spotlights extends EventEmitter
this._spotlightsUpdated();
}
_handlePeer(peer)
handleActiveSpeaker(peerId)
{
logger.debug('_handlePeer() [peerName:"%s"]', peer.name);
logger.debug('handleActiveSpeaker() [peerId:"%s"]', peerId);
if (this._peerList.indexOf(peer.name) === -1) // We don't have this peer in the list
{
peer.on('close', () =>
{
let index = this._peerList.indexOf(peer.name);
if (index !== -1) // We have this peer in the list, remove
{
this._peerList.splice(index, 1);
}
index = this._selectedSpotlights.indexOf(peer.name);
if (index !== -1) // We have this peer in the list, remove
{
this._selectedSpotlights.splice(index, 1);
}
this._spotlightsUpdated();
});
logger.debug('_handlePeer() | adding peer [peerName:"%s"]', peer.name);
this._peerList.push(peer.name);
this._spotlightsUpdated();
}
}
handleActiveSpeaker(peerName)
{
logger.debug('handleActiveSpeaker() [peerName:"%s"]', peerName);
const index = this._peerList.indexOf(peerName);
const index = this._peerList.indexOf(peerId);
if (index > -1)
{
this._peerList.splice(index, 1);
this._peerList = [ peerName ].concat(this._peerList);
this._peerList = [ peerId ].concat(this._peerList);
this._spotlightsUpdated();
}
+61 -31
View File
@@ -14,11 +14,11 @@ export const setRoomState = (state) =>
};
};
export const setRoomActiveSpeaker = (peerName) =>
export const setRoomActiveSpeaker = (peerId) =>
{
return {
type : 'SET_ROOM_ACTIVE_SPEAKER',
payload : { peerName }
payload : { peerId }
};
};
@@ -57,19 +57,25 @@ export const setSettingsOpen = ({ settingsOpen }) =>
payload : { settingsOpen }
});
export const setMe = ({ peerName, device, loginEnabled }) =>
export const setMe = ({ peerId, device, loginEnabled }) =>
{
return {
type : 'SET_ME',
payload : { peerName, device, loginEnabled }
payload : { peerId, device, loginEnabled }
};
};
export const setMediaCapabilities = ({ canSendMic, canSendWebcam }) =>
export const setMediaCapabilities = ({
canSendMic,
canSendWebcam,
canShareScreen,
needExtension,
canShareFiles
}) =>
{
return {
type : 'SET_MEDIA_CAPABILITIES',
payload : { canSendMic, canSendWebcam }
payload : { canSendMic, canSendWebcam, canShareScreen, needExtension, canShareFiles }
};
};
@@ -150,27 +156,27 @@ export const setDisplayMode = (mode) =>
payload : { mode }
});
export const setPeerVideoInProgress = (peerName, flag) =>
export const setPeerVideoInProgress = (peerId, flag) =>
{
return {
type : 'SET_PEER_VIDEO_IN_PROGRESS',
payload : { peerName, flag }
payload : { peerId, flag }
};
};
export const setPeerAudioInProgress = (peerName, flag) =>
export const setPeerAudioInProgress = (peerId, flag) =>
{
return {
type : 'SET_PEER_AUDIO_IN_PROGRESS',
payload : { peerName, flag }
payload : { peerId, flag }
};
};
export const setPeerScreenInProgress = (peerName, flag) =>
export const setPeerScreenInProgress = (peerId, flag) =>
{
return {
type : 'SET_PEER_SCREEN_IN_PROGRESS',
payload : { peerName, flag }
payload : { peerId, flag }
};
};
@@ -226,11 +232,11 @@ export const setMyRaiseHandStateInProgress = (flag) =>
};
};
export const setPeerRaiseHandState = (peerName, raiseHandState) =>
export const setPeerRaiseHandState = (peerId, raiseHandState) =>
{
return {
type : 'SET_PEER_RAISE_HAND_STATE',
payload : { peerName, raiseHandState }
payload : { peerId, raiseHandState }
};
};
@@ -274,6 +280,14 @@ export const setProducerTrack = (producerId, track) =>
};
};
export const setProducerScore = (producerId, score) =>
{
return {
type : 'SET_PRODUCER_SCORE',
payload : { producerId, score }
};
};
export const setAudioInProgress = (flag) =>
{
return {
@@ -306,35 +320,35 @@ export const addPeer = (peer) =>
};
};
export const removePeer = (peerName) =>
export const removePeer = (peerId) =>
{
return {
type : 'REMOVE_PEER',
payload : { peerName }
payload : { peerId }
};
};
export const setPeerDisplayName = (displayName, peerName) =>
export const setPeerDisplayName = (displayName, peerId) =>
{
return {
type : 'SET_PEER_DISPLAY_NAME',
payload : { displayName, peerName }
payload : { displayName, peerId }
};
};
export const addConsumer = (consumer, peerName) =>
export const addConsumer = (consumer, peerId) =>
{
return {
type : 'ADD_CONSUMER',
payload : { consumer, peerName }
payload : { consumer, peerId }
};
};
export const removeConsumer = (consumerId, peerName) =>
export const removeConsumer = (consumerId, peerId) =>
{
return {
type : 'REMOVE_CONSUMER',
payload : { consumerId, peerName }
payload : { consumerId, peerId }
};
};
@@ -354,11 +368,19 @@ export const setConsumerResumed = (consumerId, originator) =>
};
};
export const setConsumerEffectiveProfile = (consumerId, profile) =>
export const setConsumerCurrentLayers = (consumerId, spatialLayer, temporalLayer) =>
{
return {
type : 'SET_CONSUMER_EFFECTIVE_PROFILE',
payload : { consumerId, profile }
type : 'SET_CONSUMER_CURRENT_LAYERS',
payload : { consumerId, spatialLayer, temporalLayer }
};
};
export const setConsumerPreferredLayers = (consumerId, spatialLayer, temporalLayer) =>
{
return {
type : 'SET_CONSUMER_PREFERRED_LAYERS',
payload : { consumerId, spatialLayer, temporalLayer }
};
};
@@ -370,11 +392,19 @@ export const setConsumerTrack = (consumerId, track) =>
};
};
export const setPeerVolume = (peerName, volume) =>
export const setConsumerScore = (consumerId, score) =>
{
return {
type : 'SET_CONSUMER_SCORE',
payload : { consumerId, score }
};
};
export const setPeerVolume = (peerId, volume) =>
{
return {
type : 'SET_PEER_VOLUME',
payload : { peerName, volume }
payload : { peerId, volume }
};
};
@@ -536,10 +566,10 @@ export const setPicture = (picture) =>
payload : { picture }
});
export const setPeerPicture = (peerName, picture) =>
export const setPeerPicture = (peerId, picture) =>
({
type : 'SET_PEER_PICTURE',
payload : { peerName, picture }
payload : { peerId, picture }
});
export const loggedIn = () =>
@@ -547,10 +577,10 @@ export const loggedIn = () =>
type : 'LOGGED_IN'
});
export const setSelectedPeer = (selectedPeerName) =>
export const setSelectedPeer = (selectedpeerId) =>
({
type : 'SET_SELECTED_PEER',
payload : { selectedPeerName }
payload : { selectedpeerId }
});
export const setSpotlights = (spotlights) =>
+3 -3
View File
@@ -95,7 +95,7 @@ const Me = (props) =>
roomClient.changeDisplayName(displayName);
}}
>
<Volume name={me.name} />
<Volume id={me.id} />
</VideoView>
</div>
</div>
@@ -138,7 +138,7 @@ const mapStateToProps = (state) =>
me : state.me,
...meProducersSelector(state),
settings : state.settings,
activeSpeaker : state.me.name === state.room.activeSpeakerName
activeSpeaker : state.me.id === state.room.activeSpeakerId
};
};
@@ -153,7 +153,7 @@ export default withRoomContext(connect(
prev.me === next.me &&
prev.producers === next.producers &&
prev.settings === next.settings &&
prev.room.activeSpeakerName === next.room.activeSpeakerName
prev.room.activeSpeakerId === next.room.activeSpeakerId
);
}
}
+9 -23
View File
@@ -196,13 +196,6 @@ const Peer = (props) =>
}}
>
<div className={classnames(classes.viewContainer)} style={style}>
{ videoVisible && !webcamConsumer.supported ?
<div className={classes.videoInfo}>
<p>incompatible video</p>
</div>
:null
}
{ !videoVisible ?
<div className={classes.videoInfo}>
<p>this video is paused</p>
@@ -210,7 +203,7 @@ const Peer = (props) =>
:null
}
{ videoVisible && webcamConsumer.supported ?
{ videoVisible ?
<div
className={classnames(classes.controls, webcamHover ? 'hover' : null)}
onMouseOver={() => setWebcamHover(true)}
@@ -240,8 +233,8 @@ const Peer = (props) =>
onClick={() =>
{
micEnabled ?
roomClient.modifyPeerConsumer(peer.name, 'mic', true) :
roomClient.modifyPeerConsumer(peer.name, 'mic', false);
roomClient.modifyPeerConsumer(peer.id, 'mic', true) :
roomClient.modifyPeerConsumer(peer.id, 'mic', false);
}}
>
{ micEnabled ?
@@ -295,7 +288,7 @@ const Peer = (props) =>
audioCodec={micConsumer ? micConsumer.codec : null}
videoCodec={webcamConsumer ? webcamConsumer.codec : null}
>
<Volume name={peer.name} />
<Volume id={peer.id} />
</VideoView>
</div>
</div>
@@ -323,13 +316,6 @@ const Peer = (props) =>
}, 2000);
}}
>
{ screenVisible && !screenConsumer.supported ?
<div className={classes.videoInfo} style={style}>
<p>incompatible video</p>
</div>
:null
}
{ !screenVisible ?
<div className={classes.videoInfo} style={style}>
<p>this video is paused</p>
@@ -337,7 +323,7 @@ const Peer = (props) =>
:null
}
{ screenVisible && screenConsumer.supported ?
{ screenVisible ?
<div className={classnames(classes.viewContainer)} style={style}>
<div
className={classnames(classes.controls, screenHover ? 'hover' : null)}
@@ -418,7 +404,7 @@ Peer.propTypes =
micConsumer : appPropTypes.Consumer,
webcamConsumer : appPropTypes.Consumer,
screenConsumer : appPropTypes.Consumer,
windowConsumer : PropTypes.number,
windowConsumer : PropTypes.string,
activeSpeaker : PropTypes.bool,
style : PropTypes.object,
toggleConsumerFullscreen : PropTypes.func.isRequired,
@@ -434,10 +420,10 @@ const makeMapStateToProps = (initialState, props) =>
const mapStateToProps = (state) =>
{
return {
peer : state.peers[props.name],
peer : state.peers[props.id],
...getPeerConsumers(state, props),
windowConsumer : state.room.windowConsumer,
activeSpeaker : props.name === state.room.activeSpeakerName
activeSpeaker : props.id === state.room.activeSpeakerId
};
};
@@ -470,7 +456,7 @@ export default withRoomContext(connect(
return (
prev.peers === next.peers &&
prev.consumers === next.consumers &&
prev.room.activeSpeakerName === next.room.activeSpeakerName &&
prev.room.activeSpeakerId === next.room.activeSpeakerId &&
prev.room.windowConsumer === next.room.windowConsumer
);
}
+1 -1
View File
@@ -150,7 +150,7 @@ const makeMapStateToProps = (initialState, props) =>
const mapStateToProps = (state) =>
{
return {
volume : state.peerVolumes[props.name]
volume : state.peerVolumes[props.id]
};
};
+2 -2
View File
@@ -158,8 +158,8 @@ const Sidebar = (props) =>
onClick={() =>
{
micState === 'on' ?
roomClient.muteMic() :
roomClient.unmuteMic();
roomClient.disableMic() :
roomClient.enableMic();
}}
>
{ micState === 'on' ?
@@ -55,7 +55,7 @@ class File extends React.PureComponent
{
const {
roomClient,
torrentSupport,
canShareFiles,
file,
classes
} = this.props;
@@ -105,7 +105,7 @@ class File extends React.PureComponent
<Typography className={classes.text}>
{magnet.decode(file.magnetUri).dn}
</Typography>
{ torrentSupport ?
{ canShareFiles ?
<Button
variant='contained'
component='span'
@@ -145,17 +145,17 @@ class File extends React.PureComponent
}
File.propTypes = {
roomClient : PropTypes.object.isRequired,
torrentSupport : PropTypes.bool.isRequired,
file : PropTypes.object.isRequired,
classes : PropTypes.object.isRequired
roomClient : PropTypes.object.isRequired,
canShareFiles : PropTypes.bool.isRequired,
file : PropTypes.object.isRequired,
classes : PropTypes.object.isRequired
};
const mapStateToProps = (state, { magnetUri }) =>
{
return {
file : state.files[magnetUri],
torrentSupport : state.room.torrentSupport
file : state.files[magnetUri],
canShareFiles : state.me.canShareFiles
};
};
@@ -46,11 +46,11 @@ class FileSharing extends React.PureComponent
render()
{
const {
torrentSupport,
canShareFiles,
classes
} = this.props;
const buttonDescription = torrentSupport ?
const buttonDescription = canShareFiles ?
'Share file' : 'File sharing not supported';
return (
@@ -67,7 +67,7 @@ class FileSharing extends React.PureComponent
variant='contained'
component='span'
className={classes.button}
disabled={!torrentSupport}
disabled={!canShareFiles}
>
{buttonDescription}
</Button>
@@ -80,17 +80,17 @@ class FileSharing extends React.PureComponent
}
FileSharing.propTypes = {
roomClient : PropTypes.any.isRequired,
torrentSupport : PropTypes.bool.isRequired,
tabOpen : PropTypes.bool.isRequired,
classes : PropTypes.object.isRequired
roomClient : PropTypes.any.isRequired,
canShareFiles : PropTypes.bool.isRequired,
tabOpen : PropTypes.bool.isRequired,
classes : PropTypes.object.isRequired
};
const mapStateToProps = (state) =>
{
return {
torrentSupport : state.room.torrentSupport,
tabOpen : state.toolarea.currentToolTab === 'files'
canShareFiles : state.me.canShareFiles,
tabOpen : state.toolarea.currentToolTab === 'files'
};
};
@@ -185,8 +185,8 @@ const ListPeer = (props) =>
{
e.stopPropagation();
screenVisible ?
roomClient.modifyPeerConsumer(peer.name, 'screen', true) :
roomClient.modifyPeerConsumer(peer.name, 'screen', false);
roomClient.modifyPeerConsumer(peer.id, 'screen', true) :
roomClient.modifyPeerConsumer(peer.id, 'screen', false);
}}
>
{ screenVisible ?
@@ -207,8 +207,8 @@ const ListPeer = (props) =>
{
e.stopPropagation();
micEnabled ?
roomClient.modifyPeerConsumer(peer.name, 'mic', true) :
roomClient.modifyPeerConsumer(peer.name, 'mic', false);
roomClient.modifyPeerConsumer(peer.id, 'mic', true) :
roomClient.modifyPeerConsumer(peer.id, 'mic', false);
}}
>
{ micEnabled ?
@@ -241,7 +241,7 @@ const makeMapStateToProps = (initialState, props) =>
const mapStateToProps = (state) =>
{
return {
peer : state.peers[props.name],
peer : state.peers[props.id],
...getPeerConsumers(state, props)
};
};
@@ -76,7 +76,7 @@ class ParticipantList extends React.PureComponent
roomClient,
advancedMode,
passivePeers,
selectedPeerName,
selectedPeerId,
spotlightPeers,
classes
} = this.props;
@@ -92,14 +92,14 @@ class ParticipantList extends React.PureComponent
<li className={classes.listheader}>Participants in Spotlight:</li>
{ spotlightPeers.map((peer) => (
<li
key={peer.name}
key={peer.id}
className={classNames(classes.listItem, {
selected : peer.name === selectedPeerName
selected : peer.id === selectedPeerId
})}
onClick={() => roomClient.setSelectedPeer(peer.name)}
onClick={() => roomClient.setSelectedPeer(peer.id)}
>
<ListPeer name={peer.name} advancedMode={advancedMode}>
<Volume small name={peer.name} />
<ListPeer id={peer.id} advancedMode={advancedMode}>
<Volume small id={peer.id} />
</ListPeer>
</li>
))}
@@ -107,15 +107,15 @@ class ParticipantList extends React.PureComponent
<br />
<ul className={classes.list}>
<li className={classes.listheader}>Passive Participants:</li>
{ passivePeers.map((peerName) => (
{ passivePeers.map((peerId) => (
<li
key={peerName}
key={peerId}
className={classNames(classes.listItem, {
selected : peerName === selectedPeerName
selected : peerId === selectedPeerId
})}
onClick={() => roomClient.setSelectedPeer(peerName)}
onClick={() => roomClient.setSelectedPeer(peerId)}
>
<ListPeer name={peerName} advancedMode={advancedMode} />
<ListPeer id={peerId} advancedMode={advancedMode} />
</li>
))}
</ul>
@@ -126,20 +126,20 @@ class ParticipantList extends React.PureComponent
ParticipantList.propTypes =
{
roomClient : PropTypes.any.isRequired,
advancedMode : PropTypes.bool,
passivePeers : PropTypes.array,
selectedPeerName : PropTypes.string,
spotlightPeers : PropTypes.array,
classes : PropTypes.object.isRequired
roomClient : PropTypes.any.isRequired,
advancedMode : PropTypes.bool,
passivePeers : PropTypes.array,
selectedPeerId : PropTypes.string,
spotlightPeers : PropTypes.array,
classes : PropTypes.object.isRequired
};
const mapStateToProps = (state) =>
{
return {
passivePeers : passivePeersSelector(state),
selectedPeerName : state.room.selectedPeerName,
spotlightPeers : spotlightPeersSelector(state)
passivePeers : passivePeersSelector(state),
selectedPeerId : state.room.selectedPeerId,
spotlightPeers : spotlightPeersSelector(state)
};
};
@@ -153,7 +153,7 @@ const ParticipantListContainer = withRoomContext(connect(
return (
prev.peers === next.peers &&
prev.room.spotlights === next.room.spotlights &&
prev.room.selectedPeerName === next.room.selectedPeerName
prev.room.selectedPeerId === next.room.selectedPeerId
);
}
}
@@ -139,9 +139,9 @@ class Democratic extends React.PureComponent
{
return (
<Peer
key={peer.name}
key={peer.id}
advancedMode={advancedMode}
name={peer.name}
id={peer.id}
style={style}
/>
);
+21 -21
View File
@@ -104,11 +104,11 @@ class Filmstrip extends React.PureComponent
// Find the name of the peer which is currently speaking. This is either
// the latest active speaker, or the manually selected peer, or, if no
// person has spoken yet, the first peer in the list of peers.
getActivePeerName = () =>
getActivePeerId = () =>
{
if (this.props.selectedPeerName)
if (this.props.selectedPeerId)
{
return this.props.selectedPeerName;
return this.props.selectedPeerId;
}
if (this.state.lastSpeaker)
@@ -116,23 +116,23 @@ class Filmstrip extends React.PureComponent
return this.state.lastSpeaker;
}
const peerNames = Object.keys(this.props.peers);
const peerIds = Object.keys(this.props.peers);
if (peerNames.length > 0)
if (peerIds.length > 0)
{
return peerNames[0];
return peerIds[0];
}
};
isSharingCamera = (peerName) => this.props.peers[peerName] &&
this.props.peers[peerName].consumers.some((consumer) =>
isSharingCamera = (peerId) => this.props.peers[peerId] &&
this.props.peers[peerId].consumers.some((consumer) =>
this.props.consumers[consumer].source === 'screen');
getRatio = () =>
{
let ratio = 4 / 3;
if (this.isSharingCamera(this.getActivePeerName()))
if (this.isSharingCamera(this.getActivePeerId()))
{
ratio *= 2;
}
@@ -202,12 +202,12 @@ class Filmstrip extends React.PureComponent
classes
} = this.props;
const activePeerName = this.getActivePeerName();
const activePeerId = this.getActivePeerId();
return (
<div className={classes.root}>
<div className={classes.activePeerContainer} ref={this.activePeerContainer}>
{ peers[activePeerName] ?
{ peers[activePeerId] ?
<div
className={classes.activePeer}
style={{
@@ -217,7 +217,7 @@ class Filmstrip extends React.PureComponent
>
<Peer
advancedMode={advancedMode}
name={activePeerName}
name={activePeerId}
/>
</div>
:null
@@ -226,23 +226,23 @@ class Filmstrip extends React.PureComponent
<div className={classes.filmStrip}>
<div className={classes.filmStripContent}>
{ Object.keys(peers).map((peerName) =>
{ Object.keys(peers).map((peerId) =>
{
if (spotlights.find((spotlightsElement) => spotlightsElement === peerName))
if (spotlights.find((spotlightsElement) => spotlightsElement === peerId))
{
return (
<div
key={peerName}
onClick={() => roomClient.setSelectedPeer(peerName)}
key={peerId}
onClick={() => roomClient.setSelectedPeer(peerId)}
className={classnames(classes.film, {
selected : this.props.selectedPeerName === peerName,
active : this.state.lastSpeaker === peerName
selected : this.props.selectedPeerId === peerId,
active : this.state.lastSpeaker === peerId
})}
>
<div className={classes.filmContent}>
<Peer
advancedMode={advancedMode}
name={peerName}
name={peerId}
/>
</div>
</div>
@@ -276,7 +276,7 @@ Filmstrip.propTypes = {
peers : PropTypes.object.isRequired,
consumers : PropTypes.object.isRequired,
myName : PropTypes.string.isRequired,
selectedPeerName : PropTypes.string,
selectedPeerId : PropTypes.string,
spotlightsLength : PropTypes.number,
spotlights : PropTypes.array.isRequired,
classes : PropTypes.object.isRequired
@@ -288,7 +288,7 @@ const mapStateToProps = (state) =>
return {
activeSpeakerName : state.room.activeSpeakerName,
selectedPeerName : state.room.selectedPeerName,
selectedPeerId : state.room.selectedPeerId,
peers : state.peers,
consumers : state.consumers,
myName : state.me.name,
+5 -5
View File
@@ -5,7 +5,7 @@ const consumersSelect = (state) => state.consumers;
const spotlightsSelector = (state) => state.room.spotlights;
const peersSelector = (state) => state.peers;
const getPeerConsumers = (state, props) =>
(state.peers[props.name] ? state.peers[props.name].consumers : null);
(state.peers[props.id] ? state.peers[props.id].consumers : null);
const getAllConsumers = (state) => state.consumers;
const peersKeySelector = createSelector(
peersSelector,
@@ -66,10 +66,10 @@ export const spotlightPeersSelector = createSelector(
spotlightsSelector,
peersSelector,
(spotlights, peers) =>
spotlights.reduce((result, peerName) =>
spotlights.reduce((result, peerId) =>
{
if (peers[peerName])
result.push(peers[peerName]);
if (peers[peerId])
result.push(peers[peerId]);
return result;
}, [])
@@ -83,7 +83,7 @@ export const peersLengthSelector = createSelector(
export const passivePeersSelector = createSelector(
peersKeySelector,
spotlightsSelector,
(peers, spotlights) => peers.filter((peerName) => !spotlights.includes(peerName))
(peers, spotlights) => peers.filter((peerId) => !spotlights.includes(peerId))
);
export const videoBoxesSelector = createSelector(
@@ -102,13 +102,6 @@ const FullScreenView = (props) =>
return (
<div className={classes.root}>
{ consumerVisible && !consumer.supported ?
<div className={classes.incompatibleVideo}>
<p>incompatible video</p>
</div>
:null
}
<div className={classes.controls}>
<div
className={classnames(classes.button, {
+14 -16
View File
@@ -5,7 +5,7 @@ export const Room = PropTypes.shape(
url : PropTypes.string.isRequired,
state : PropTypes.oneOf(
[ 'new', 'connecting', 'connected', 'closed' ]).isRequired,
activeSpeakerName : PropTypes.string
activeSpeakerId : PropTypes.string
});
export const Device = PropTypes.shape(
@@ -17,7 +17,7 @@ export const Device = PropTypes.shape(
export const Me = PropTypes.shape(
{
name : PropTypes.string.isRequired,
id : PropTypes.string.isRequired,
device : Device.isRequired,
canSendMic : PropTypes.bool.isRequired,
canSendWebcam : PropTypes.bool.isRequired,
@@ -26,30 +26,28 @@ export const Me = PropTypes.shape(
export const Producer = PropTypes.shape(
{
id : PropTypes.number.isRequired,
source : PropTypes.oneOf([ 'mic', 'webcam', 'screen' ]).isRequired,
deviceLabel : PropTypes.string,
type : PropTypes.oneOf([ 'front', 'back', 'screen' ]),
locallyPaused : PropTypes.bool.isRequired,
remotelyPaused : PropTypes.bool.isRequired,
track : PropTypes.any,
codec : PropTypes.string.isRequired
id : PropTypes.string.isRequired,
source : PropTypes.oneOf([ 'mic', 'webcam', 'screen' ]).isRequired,
deviceLabel : PropTypes.string,
type : PropTypes.oneOf([ 'front', 'back', 'screen' ]),
paused : PropTypes.bool.isRequired,
track : PropTypes.any,
codec : PropTypes.string.isRequired
});
export const Peer = PropTypes.shape(
{
name : PropTypes.string.isRequired,
id : PropTypes.string.isRequired,
displayName : PropTypes.string,
device : Device.isRequired,
consumers : PropTypes.arrayOf(PropTypes.number).isRequired
consumers : PropTypes.arrayOf(PropTypes.string).isRequired
});
export const Consumer = PropTypes.shape(
{
id : PropTypes.number.isRequired,
peerName : PropTypes.string.isRequired,
id : PropTypes.string.isRequired,
peerId : PropTypes.string.isRequired,
source : PropTypes.oneOf([ 'mic', 'webcam', 'screen' ]).isRequired,
supported : PropTypes.bool.isRequired,
locallyPaused : PropTypes.bool.isRequired,
remotelyPaused : PropTypes.bool.isRequired,
profile : PropTypes.oneOf([ 'none', 'default', 'low', 'medium', 'high' ]),
@@ -75,7 +73,7 @@ export const Message = PropTypes.shape(
export const FileEntryProps = PropTypes.shape(
{
data : PropTypes.shape({
name : PropTypes.string.isRequired,
id : PropTypes.string.isRequired,
picture : PropTypes.string,
file : PropTypes.shape({
magnet : PropTypes.string.isRequired
+31
View File
@@ -0,0 +1,31 @@
import bowser from 'bowser';
window.BB = bowser;
export default function()
{
const ua = navigator.userAgent;
const browser = bowser.getParser(ua);
let flag;
if (browser.satisfies({ chrome: '>=0', chromium: '>=0' }))
flag = 'chrome';
else if (browser.satisfies({ firefox: '>=0' }))
flag = 'firefox';
else if (browser.satisfies({ safari: '>=0' }))
flag = 'safari';
else if (browser.satisfies({ opera: '>=0' }))
flag = 'opera';
else if (browser.satisfies({ 'microsoft edge': '>=0' }))
flag = 'edge';
else
flag = 'unknown';
return {
flag,
name : browser.getBrowserName(),
version : browser.getBrowserVersion(),
bowser : browser
};
}
+7 -5
View File
@@ -3,12 +3,12 @@ import UrlParse from 'url-parse';
import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import { getDeviceInfo } from 'mediasoup-client';
import randomString from 'random-string';
import Logger from './Logger';
import debug from 'debug';
import RoomClient from './RoomClient';
import RoomContext from './RoomContext';
import deviceInfo from './deviceInfo';
import * as stateActions from './actions/stateActions';
import Room from './components/Room';
import LoadingView from './components/LoadingView';
@@ -44,13 +44,15 @@ function run()
{
logger.debug('run() [environment:%s]', process.env.NODE_ENV);
const peerName = randomString({ length: 8 }).toLowerCase();
const peerId = randomString({ length: 8 }).toLowerCase();
const urlParser = new UrlParse(window.location.href, true);
let roomId = (urlParser.pathname).substr(1)
? (urlParser.pathname).substr(1).toLowerCase() : urlParser.query.roomId.toLowerCase();
const produce = urlParser.query.produce !== 'false';
const consume = urlParser.query.consume !== 'false';
const useSimulcast = urlParser.query.simulcast === 'true';
const forceTcp = urlParser.query.forceTcp === 'true';
if (!roomId)
{
@@ -80,21 +82,21 @@ function run()
const roomUrl = roomUrlParser.toString();
// Get current device.
const device = getDeviceInfo();
const device = deviceInfo();
store.dispatch(
stateActions.setRoomUrl(roomUrl));
store.dispatch(
stateActions.setMe({
peerName,
peerId,
device,
loginEnabled : window.config.loginEnabled
})
);
roomClient = new RoomClient(
{ roomId, peerName, device, useSimulcast, produce });
{ roomId, peerId, device, useSimulcast, produce, consume, forceTcp });
global.CLIENT = roomClient;
+35 -3
View File
@@ -51,11 +51,30 @@ const consumers = (state = initialState, action) =>
return { ...state, [consumerId]: newConsumer };
}
case 'SET_CONSUMER_EFFECTIVE_PROFILE':
case 'SET_CONSUMER_CURRENT_LAYERS':
{
const { consumerId, profile } = action.payload;
const { consumerId, spatialLayer, temporalLayer } = action.payload;
const consumer = state[consumerId];
const newConsumer = { ...consumer, profile };
const newConsumer =
{
...consumer,
currentSpatialLayer : spatialLayer,
currentTemporalLayer : temporalLayer
};
return { ...state, [consumerId]: newConsumer };
}
case 'SET_CONSUMER_PREFERRED_LAYERS':
{
const { consumerId, spatialLayer, temporalLayer } = action.payload;
const consumer = state[consumerId];
const newConsumer =
{
...consumer,
preferredSpatialLayer : spatialLayer,
preferredTemporalLayer : temporalLayer
};
return { ...state, [consumerId]: newConsumer };
}
@@ -69,6 +88,19 @@ const consumers = (state = initialState, action) =>
return { ...state, [consumerId]: newConsumer };
}
case 'SET_CONSUMER_SCORE':
{
const { consumerId, score } = action.payload;
const consumer = state[consumerId];
if (!consumer)
return state;
const newConsumer = { ...consumer, score };
return { ...state, [consumerId]: newConsumer };
}
default:
return state;
}
+19 -5
View File
@@ -1,11 +1,12 @@
const initialState =
{
name : null,
id : null,
device : null,
canSendMic : false,
canSendWebcam : false,
canShareScreen : false,
needExtension : false,
canShareFiles : false,
audioDevices : null,
webcamDevices : null,
webcamInProgress : false,
@@ -24,14 +25,14 @@ const me = (state = initialState, action) =>
case 'SET_ME':
{
const {
peerName,
peerId,
device,
loginEnabled
} = action.payload;
return {
...state,
name : peerName,
id : peerId,
device,
loginEnabled
};
@@ -45,9 +46,22 @@ const me = (state = initialState, action) =>
case 'SET_MEDIA_CAPABILITIES':
{
const { canSendMic, canSendWebcam } = action.payload;
const {
canSendMic,
canSendWebcam,
canShareScreen,
needExtension,
canShareFiles
} = action.payload;
return { ...state, canSendMic, canSendWebcam };
return {
...state,
canSendMic,
canSendWebcam,
canShareScreen,
needExtension,
canShareFiles
};
}
case 'SET_SCREEN_CAPABILITIES':
+7 -7
View File
@@ -7,33 +7,33 @@ const peerVolumes = (state = initialState, action) =>
case 'SET_ME':
{
const {
peerName
peerId
} = action.payload;
return { ...state, [peerName]: 0 };
return { ...state, [peerId]: 0 };
}
case 'ADD_PEER':
{
const { peer } = action.payload;
return { ...state, [peer.name]: 0 };
return { ...state, [peer.id]: 0 };
}
case 'REMOVE_PEER':
{
const { peerName } = action.payload;
const { peerId } = action.payload;
const newState = { ...state };
delete newState[peerName];
delete newState[peerId];
return newState;
}
case 'SET_PEER_VOLUME':
{
const { peerName, volume } = action.payload;
const { peerId, volume } = action.payload;
return { ...state, [peerName]: volume };
return { ...state, [peerId]: volume };
}
default:
+6 -6
View File
@@ -53,12 +53,12 @@ const peers = (state = {}, action) =>
{
case 'ADD_PEER':
{
return { ...state, [action.payload.peer.name]: peer(undefined, action) };
return { ...state, [action.payload.peer.id]: peer(undefined, action) };
}
case 'REMOVE_PEER':
{
return omit(state, [ action.payload.peerName ]);
return omit(state, [ action.payload.peerId ]);
}
case 'SET_PEER_DISPLAY_NAME':
@@ -69,25 +69,25 @@ const peers = (state = {}, action) =>
case 'SET_PEER_PICTURE':
case 'ADD_CONSUMER':
{
const oldPeer = state[action.payload.peerName];
const oldPeer = state[action.payload.peerId];
if (!oldPeer)
{
throw new Error('no Peer found');
}
return { ...state, [oldPeer.name]: peer(oldPeer, action) };
return { ...state, [oldPeer.id]: peer(oldPeer, action) };
}
case 'REMOVE_CONSUMER':
{
const oldPeer = state[action.payload.peerName];
const oldPeer = state[action.payload.peerId];
// NOTE: This means that the Peer was closed before, so it's ok.
if (!oldPeer)
return state;
return { ...state, [oldPeer.name]: peer(oldPeer, action) };
return { ...state, [oldPeer.id]: peer(oldPeer, action) };
}
default:
+8 -8
View File
@@ -5,14 +5,14 @@ const initialState =
locked : false,
lockedOut : false,
audioSuspended : false,
activeSpeakerName : null,
activeSpeakerId : null,
torrentSupport : false,
showSettings : false,
fullScreenConsumer : null, // ConsumerID
windowConsumer : null, // ConsumerID
toolbarsVisible : true,
mode : 'democratic',
selectedPeerName : null,
selectedPeerId : null,
spotlights : [],
settingsOpen : false
};
@@ -35,7 +35,7 @@ const room = (state = initialState, action) =>
if (roomState === 'connected')
return { ...state, state: roomState };
else
return { ...state, state: roomState, activeSpeakerName: null };
return { ...state, state: roomState, activeSpeakerId: null };
}
case 'SET_ROOM_LOCKED':
@@ -69,9 +69,9 @@ const room = (state = initialState, action) =>
case 'SET_ROOM_ACTIVE_SPEAKER':
{
const { peerName } = action.payload;
const { peerId } = action.payload;
return { ...state, activeSpeakerName: peerName };
return { ...state, activeSpeakerId: peerId };
}
case 'FILE_SHARING_SUPPORTED':
@@ -119,13 +119,13 @@ const room = (state = initialState, action) =>
case 'SET_SELECTED_PEER':
{
const { selectedPeerName } = action.payload;
const { selectedPeerId } = action.payload;
return {
...state,
selectedPeerName : state.selectedPeerName === selectedPeerName ?
null : selectedPeerName
selectedPeerId : state.selectedPeerId === selectedPeerId ?
null : selectedPeerId
};
}
+2 -2
View File
@@ -1,10 +1,10 @@
export function getSignalingUrl(peerName, roomId)
export function getSignalingUrl(peerId, roomId)
{
const hostname = window.location.hostname;
const port = process.env.NODE_ENV !== 'production' ? window.config.developmentPort : window.location.port;
const url = `wss://${hostname}:${port}/?peerName=${peerName}&roomId=${roomId}`;
const url = `wss://${hostname}:${port}/?peerId=${peerId}&roomId=${roomId}`;
return url;
}