import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { Appear } from './transitions';
import { withRoomContext } from '../RoomContext';
import * as stateActions from '../redux/stateActions';
class Stats extends React.Component
{
constructor(props)
{
super(props);
this.state =
{
sendTransportRemoteStats : null,
sendTransportLocalStats : null,
recvTransportRemoteStats : null,
recvTransportLocalStats : null,
audioProducerRemoteStats : null,
audioProducerLocalStats : null,
videoProducerRemoteStats : null,
videoProducerLocalStats : null,
chatDataProducerRemoteStats : null,
botDataProducerRemoteStats : null,
audioConsumerRemoteStats : null,
audioConsumerLocalStats : null,
videoConsumerRemoteStats : null,
videoConsumerLocalStats : null,
chatDataConsumerRemoteStats : null,
botDataConsumerRemoteStats : null
};
this._delayTimer = null;
}
render()
{
const {
peerId,
peerDisplayName,
isMe,
onClose
} = this.props;
const {
sendTransportRemoteStats,
sendTransportLocalStats,
recvTransportRemoteStats,
recvTransportLocalStats,
audioProducerRemoteStats,
audioProducerLocalStats,
videoProducerRemoteStats,
videoProducerLocalStats,
chatDataProducerRemoteStats,
botDataProducerRemoteStats,
audioConsumerRemoteStats,
audioConsumerLocalStats,
videoConsumerRemoteStats,
videoConsumerLocalStats,
chatDataConsumerRemoteStats,
botDataConsumerRemoteStats
} = this.state;
return (
Your Stats
Stats of {peerDisplayName}
{this._printStats('send transport remote stats', sendTransportRemoteStats)}
{this._printStats('send transport local stats', sendTransportLocalStats)}
{this._printStats('recv transport remote stats', recvTransportRemoteStats)}
{this._printStats('recv transport local stats', recvTransportLocalStats)}
{this._printStats('audio producer remote stats', audioProducerRemoteStats)}
{this._printStats('audio producer local stats', audioProducerLocalStats)}
{this._printStats('video producer remote stats', videoProducerRemoteStats)}
{this._printStats('video producer local stats', videoProducerLocalStats)}
{this._printStats('chat dataproducer remote stats', chatDataProducerRemoteStats)}
{this._printStats('bot dataproducer remote stats', botDataProducerRemoteStats)}
{this._printStats('audio consumer remote stats', audioConsumerRemoteStats)}
{this._printStats('audio consumer local stats', audioConsumerLocalStats)}
{this._printStats('video consumer remote stats', videoConsumerRemoteStats)}
{this._printStats('video consumer local stats', videoConsumerLocalStats)}
{this._printStats('chat dataconsumer remote stats', chatDataConsumerRemoteStats)}
{this._printStats('bot dataconsumer remote stats', botDataConsumerRemoteStats)}
);
}
componentDidUpdate(prevProps)
{
const { peerId } = this.props;
if (peerId && !prevProps.peerId)
{
this._delayTimer = setTimeout(() => this._start(), 250);
}
else if (!peerId && prevProps.peerId)
{
this._stop();
}
else if (peerId && prevProps.peerId && peerId !== prevProps.peerId)
{
this._stop();
this._start();
}
}
async _start()
{
const {
roomClient,
isMe,
audioConsumerId,
videoConsumerId,
chatDataConsumerId,
botDataConsumerId
} = this.props;
let sendTransportRemoteStats = null;
let sendTransportLocalStats = null;
let recvTransportRemoteStats = null;
let recvTransportLocalStats = null;
let audioProducerRemoteStats = null;
let audioProducerLocalStats = null;
let videoProducerRemoteStats = null;
let videoProducerLocalStats = null;
let chatDataProducerRemoteStats = null;
let botDataProducerRemoteStats = null;
let audioConsumerRemoteStats = null;
let audioConsumerLocalStats = null;
let videoConsumerRemoteStats = null;
let videoConsumerLocalStats = null;
let chatDataConsumerRemoteStats = null;
let botDataConsumerRemoteStats = null;
if (isMe)
{
sendTransportRemoteStats = await roomClient.getSendTransportRemoteStats()
.catch(() => {});
sendTransportLocalStats = await roomClient.getSendTransportLocalStats()
.catch(() => {});
recvTransportRemoteStats = await roomClient.getRecvTransportRemoteStats()
.catch(() => {});
recvTransportLocalStats = await roomClient.getRecvTransportLocalStats()
.catch(() => {});
audioProducerRemoteStats = await roomClient.getAudioRemoteStats()
.catch(() => {});
audioProducerLocalStats = await roomClient.getAudioLocalStats()
.catch(() => {});
videoProducerRemoteStats = await roomClient.getVideoRemoteStats()
.catch(() => {});
videoProducerLocalStats = await roomClient.getVideoLocalStats()
.catch(() => {});
chatDataProducerRemoteStats = await roomClient.getChatDataProducerRemoteStats()
.catch(() => {});
botDataProducerRemoteStats = await roomClient.getBotDataProducerRemoteStats()
.catch(() => {});
botDataConsumerRemoteStats =
await roomClient.getDataConsumerRemoteStats(botDataConsumerId)
.catch(() => {});
}
else
{
audioConsumerRemoteStats = await roomClient.getConsumerRemoteStats(audioConsumerId)
.catch(() => {});
audioConsumerLocalStats = await roomClient.getConsumerLocalStats(audioConsumerId)
.catch(() => {});
videoConsumerRemoteStats = await roomClient.getConsumerRemoteStats(videoConsumerId)
.catch(() => {});
videoConsumerLocalStats = await roomClient.getConsumerLocalStats(videoConsumerId)
.catch(() => {});
chatDataConsumerRemoteStats =
await roomClient.getDataConsumerRemoteStats(chatDataConsumerId)
.catch(() => {});
}
this.setState(
{
sendTransportRemoteStats,
sendTransportLocalStats,
recvTransportRemoteStats,
recvTransportLocalStats,
audioProducerRemoteStats,
audioProducerLocalStats,
videoProducerRemoteStats,
videoProducerLocalStats,
chatDataProducerRemoteStats,
botDataProducerRemoteStats,
audioConsumerRemoteStats,
audioConsumerLocalStats,
videoConsumerRemoteStats,
videoConsumerLocalStats,
chatDataConsumerRemoteStats,
botDataConsumerRemoteStats
});
this._delayTimer = setTimeout(() => this._start(), 2500);
}
_stop()
{
clearTimeout(this._delayTimer);
this.setState(
{
sendTransportRemoteStats : null,
sendTransportLocalStats : null,
recvTransportRemoteStats : null,
recvTransportLocalStats : null,
audioProducerRemoteStats : null,
audioProducerLocalStats : null,
videoProducerRemoteStats : null,
videoProducerLocalStats : null,
chatDataProducerRemoteStats : null,
botDataProducerRemoteStats : null,
audioConsumerRemoteStats : null,
audioConsumerLocalStats : null,
videoConsumerRemoteStats : null,
videoConsumerLocalStats : null,
chatDataConsumerRemoteStats : null,
botDataConsumerRemoteStats : null
});
}
_printStats(title, stats)
{
const anchor = title
.replace(/[ ]+/g, '-');
if (typeof stats.values === 'function')
stats = Array.from(stats.values());
return (
{title}
{
stats.map((item, idx) => (
{
Object.keys(item).map((key) => (
{key}
{JSON.stringify(Math.round(item[key] * 100) / 100, null, ' ')}
{JSON.stringify(item[key], null, ' ')}
))
}
))
}
);
}
}
Stats.propTypes =
{
roomClient : PropTypes.any.isRequired,
peerId : PropTypes.string,
peerDisplayName : PropTypes.string,
isMe : PropTypes.bool,
audioConsumerId : PropTypes.string,
videoConsumerId : PropTypes.string,
chatDataConsumerId : PropTypes.string,
botDataConsumerId : PropTypes.string,
onClose : PropTypes.func.isRequired
};
const mapStateToProps = (state) =>
{
const { room, me, peers, consumers, dataConsumers } = state;
const { statsPeerId } = room;
if (!statsPeerId)
return {};
const isMe = statsPeerId === me.id;
const peer = isMe ? me : peers[statsPeerId];
let audioConsumerId;
let videoConsumerId;
let chatDataConsumerId;
let botDataConsumerId;
if (isMe)
{
for (const dataConsumerId of Object.keys(dataConsumers))
{
const dataConsumer = dataConsumers[dataConsumerId];
if (dataConsumer.label === 'bot')
botDataConsumerId = dataConsumer.id;
}
}
else
{
for (const consumerId of peer.consumers)
{
const consumer = consumers[consumerId];
switch (consumer.track.kind)
{
case 'audio':
audioConsumerId = consumer.id;
break;
case 'video':
videoConsumerId = consumer.id;
break;
}
}
for (const dataConsumerId of peer.dataConsumers)
{
const dataConsumer = dataConsumers[dataConsumerId];
if (dataConsumer.label === 'chat')
chatDataConsumerId = dataConsumer.id;
}
}
return {
peerId : peer.id,
peerDisplayName : peer.displayName,
isMe,
audioConsumerId,
videoConsumerId,
chatDataConsumerId,
botDataConsumerId
};
};
const mapDispatchToProps = (dispatch) =>
{
return {
onClose : () => dispatch(stateActions.setRoomStatsPeerId(null))
};
};
const StatsContainer = withRoomContext(connect(
mapStateToProps,
mapDispatchToProps
)(Stats));
export default StatsContainer;