diff --git a/app/src/RoomClient.js b/app/src/RoomClient.js
index 5d6efad..b39b2b9 100644
--- a/app/src/RoomClient.js
+++ b/app/src/RoomClient.js
@@ -13,6 +13,7 @@ import * as lobbyPeerActions from './actions/lobbyPeerActions';
import * as consumerActions from './actions/consumerActions';
import * as producerActions from './actions/producerActions';
import * as notificationActions from './actions/notificationActions';
+import * as transportActions from './actions/transportActions';
let createTorrent;
@@ -258,6 +259,8 @@ export default class RoomClient
this._startDevicesListener();
+ this._getTransportStats();
+
}
close()
@@ -595,14 +598,33 @@ export default class RoomClient
});
}
- async getTransportStats(transportId)
+ async _getTransportStats()
{
-
- logger.debug('getTransportStats() [transportId: "%s"]', transportId);
-
try
{
- return await this.sendRequest('getTransportStats', { transportId: transportId });
+ setInterval(async () =>
+ {
+ if (this._recvTransport)
+ {
+ logger.debug('getTransportStats() - recv [transportId: "%s"]', this._recvTransport.id);
+
+ const recv = await this.sendRequest('getTransportStats', { transportId: this._recvTransport.id });
+
+ store.dispatch(
+ transportActions.addTransportStats(recv, 'recv'));
+ }
+
+ if (this._sendTransport)
+ {
+ logger.debug('getTransportStats() - send [transportId: "%s"]', this._sendTransport.id);
+
+ const send = await this.sendRequest('getTransportStats', { transportId: this._sendTransport.id });
+
+ store.dispatch(
+ transportActions.addTransportStats(send, 'send'));
+ }
+
+ }, 1000);
}
catch (error)
{
diff --git a/app/src/actions/transportActions.js b/app/src/actions/transportActions.js
new file mode 100644
index 0000000..46b901e
--- /dev/null
+++ b/app/src/actions/transportActions.js
@@ -0,0 +1,5 @@
+export const addTransportStats = (transport, type) =>
+ ({
+ type : 'ADD_TRANSPORT_STATS',
+ payload : { transport, type }
+ });
\ No newline at end of file
diff --git a/app/src/components/Containers/Me.js b/app/src/components/Containers/Me.js
index b79c5d0..fb5b60a 100644
--- a/app/src/components/Containers/Me.js
+++ b/app/src/components/Containers/Me.js
@@ -141,7 +141,8 @@ const Me = (props) =>
webcamProducer,
screenProducer,
canShareScreen,
- classes
+ classes,
+ transports
} = props;
const videoVisible = (
@@ -445,6 +446,7 @@ const Me = (props) =>
videoVisible={videoVisible}
audioCodec={micProducer && micProducer.codec}
videoCodec={webcamProducer && webcamProducer.codec}
+ netInfo={transports && transports}
onChangeDisplayName={(displayName) =>
{
roomClient.changeDisplayName(displayName);
@@ -541,7 +543,9 @@ Me.propTypes =
smallButtons : PropTypes.bool,
canShareScreen : PropTypes.bool.isRequired,
classes : PropTypes.object.isRequired,
- theme : PropTypes.object.isRequired
+ theme : PropTypes.object.isRequired,
+ transports : PropTypes.object.isRequired
+
};
const mapStateToProps = (state) =>
@@ -553,7 +557,8 @@ const mapStateToProps = (state) =>
activeSpeaker : state.me.id === state.room.activeSpeakerId,
canShareScreen :
state.me.roles.some((role) =>
- state.room.permissionsFromRoles.SHARE_SCREEN.includes(role))
+ state.room.permissionsFromRoles.SHARE_SCREEN.includes(role)),
+ transports : state.transports
};
};
@@ -569,7 +574,8 @@ export default withRoomContext(connect(
prev.me === next.me &&
prev.producers === next.producers &&
prev.settings === next.settings &&
- prev.room.activeSpeakerId === next.room.activeSpeakerId
+ prev.room.activeSpeakerId === next.room.activeSpeakerId &&
+ prev.transports === next.transports
);
}
}
diff --git a/app/src/components/Controls/NetworkIndicator.js b/app/src/components/Controls/NetworkIndicator.js
deleted file mode 100644
index 694dd6e..0000000
--- a/app/src/components/Controls/NetworkIndicator.js
+++ /dev/null
@@ -1,294 +0,0 @@
-import React from 'react';
-import { connect } from 'react-redux';
-import PropTypes from 'prop-types';
-import {
- peersLengthSelector
-} from '../Selectors';
-import * as appPropTypes from '../appPropTypes';
-import { withRoomContext } from '../../RoomContext';
-import { withStyles } from '@material-ui/core/styles';
-import WifiIndicator from 'react-wifi-indicator';
-import Logger from '../../Logger';
-
-const logger = new Logger('NetworkIndicator');
-
-const styles = () =>
- ({
- root : {
- verticalAlign : 'middle',
- '& img' : {
- display : 'inline',
- width : '1.7em',
- height : '1.7em',
- margin : '10px'
- }
- },
-
- label : {
- color : 'white'
- },
-
- strength :
- {
- margin : 0,
- padding : 0
- }
-
- });
-
-class NetworkIndicator extends React.Component
-{
- constructor(props)
- {
- super(props);
-
- this.state = {
- strengthScale : { // text statuses prowived by the "react-wifi-indicator"
- 1 : 'EXCELLENT',
- 2 : 'GREAT',
- 3 : 'OKAY',
- 4 : 'WEAK',
- 5 : 'UNUSABLE',
- 6 : 'DISCONNECTED'
- },
- strength : 6,
- recv : {},
- send : {},
- probe : [],
- currBitrate : 0,
- maxBitrate : 0,
- avgBitrate : 0,
- medBitrate : 0,
- probeCount : 0,
- probeLimit : 3,
- highestBitrate : 0,
- resolution : ''
- };
- }
-
- // const intl = useIntl();
- async handleUpdateStrength()
- {
- // if (this.props.peersLength == 0)
- // {
-
- const percent = this.state.percent;
-
- logger.warn('[percent: "%s"]', percent);
-
- switch (true)
- {
- case (percent <= 20):
-
- await this.setState({ strength: 5 });
- break;
-
- case (percent <= 40):
-
- await this.setState({ strength: 4 });
- break;
-
- case (percent <= 60):
-
- await this.setState({ strength: 3 });
- break;
-
- case (percent <= 80):
-
- await this.setState({ strength: 2 });
- break;
-
- case (percent <= 100):
-
- await this.setState({ strength: 1 });
- break;
-
- default:
- break;
- }
-
- // }
- // else
- // {
- // this.setState({ strength: 6 });
- // }
- }
-
- async handleGetData()
- {
- const rc = this.props.roomClient;
-
- const probe = [ ...this.state.probe ]; // clone
-
- const probeCount = this.state.probeCount;
-
- const probeLimit = this.state.probeLimit;
-
- const currBitrate = this.state.currBitrate;
-
- let highestBitrate = this.state.highestBitrate;
-
- const recv = this.state.recv;
-
- const send = this.state.send;
-
- probe[probeCount] = currBitrate; // add/update next element
-
- // median
- const med = (arr) =>
- {
- const mid = Math.floor(arr.length / 2);
- const nums = [ ...arr ].sort((a, b) => a - b);
-
- return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2;
- };
-
- const medBitrate = med([ ...probe ]);
-
- // maximum
- let maxBitrate = Math.max(...probe);
-
- // highest
- this.setState({ resolution: this.props.resolution });
-
- highestBitrate = (currBitrate > highestBitrate) ? currBitrate : highestBitrate;
-
- maxBitrate = (currBitrate > maxBitrate) ? currBitrate : maxBitrate;
-
- // average
- const avgBitrate = [ ...probe ]
- .map((x, i, avg) => x/avg.length)
- .reduce((a, b) => a + b);
-
- const percent =
- await Math.round(currBitrate / medBitrate * 100);
-
- const x = (rc._recvTransport)
- ? (await rc.getTransportStats(rc._recvTransport.id))
- : null;
-
- const y = (rc._sendTransport)
- ? (await rc.getTransportStats(rc._sendTransport.id))
- : null;
-
- if (x && y)
- {
-
- this.setState({
- recv : x[0],
- send : y[0]
- });
- }
-
- this.setState({
- probe,
- probeCount : (probeCount < probeLimit - 1) ? probeCount + 1 : 0,
- currBitrate : (send) ? Math.round(send.recvBitrate / 1024 / 8) : 0,
- maxBitrate,
- avgBitrate,
- medBitrate,
- percent,
- highestBitrate
- });
-
- logger.warn('[currBitrate: "%s"]', currBitrate);
- logger.warn('[maxBitrate: "%s"]', maxBitrate);
- logger.warn('[medBitrate: "%s"]', medBitrate);
- logger.warn('[avgBitrate: "%s"]', avgBitrate);
- logger.warn('[probeCount: "%s"]', this.state.probeCount);
- }
-
- componentDidMount()
- {
- this.update = setInterval(async () =>
- {
- await this.handleGetData();
- await this.handleUpdateStrength();
- }, 1000);
- }
-
- componentWillUnmount()
- {
- clearInterval(this.update);
- }
-
- // componentDidUpdate(prevProps, prevState) {
- // if (this.prevState.resolution !== this.state.resolution) {
- // this.setState({ highestBitrate: 0});
- // }
- // }
-
- render()
- {
- const {
- classes,
- advancedMode,
- resolution
- } = this.props;
-
- return (
-
{audioCodec}
} +
+ { audioCodec &&
+
- {videoCodec} -
- } + { videoCodec && +
- {`current spatial-temporal layers: ${consumerCurrentSpatialLayer} ${consumerCurrentTemporalLayer}`}
-
- {`preferred spatial-temporal layers: ${consumerPreferredSpatialLayer} ${consumerPreferredTemporalLayer}`}
-
{videoWidth}x{videoHeight}
- }