You can include a connection quality indicator in your custom UI. This will give your users quick feedback about their current audio/video quality.
In its simplest form, you can use it as a traffic-light display for good / ok / bad connection. We also provide some more details and values, like bitrate, jitter, packet loss, and round-trip time.
You can read more about the data in the help center article.
You have to listen for the statistics_ready
event and this event includes the statistics interface with its important method onUpdate
.
onUpdate
is triggered roughly every 1s and provides an object with all values.
eyeson.onEvent(event => {
if (event.type === 'statistics_ready') {
event.statistics.onUpdate(showStatistics);
}
});
function showStatistics(stats) {
/*...*/
}
eyeson.start(/*...*/);
The onUpdate
function is called with a statistics object containing the following data:
status
can be “good”, “ok”, “bad”, or even “no connection” (please use Status.GOOD
etc.)bitrateSend
and bitrateRecv
are audio+video bitrates either send or received. Values are in kbps.jitter
is the sender’s jitter and it takes the worse value, either audio or video. Values are in s.packetLoss
is the sender’s packet loss and it takes the worse value, either audio or video. Values are between 0 and 1.0.roundTripTime
is the sender’s round-trip time and it takes the worse value, either audio or video. Values are in s.nack
is the sender’s video negative-acknowledge count rate. Values are between 0 and 1.0.Heads-up: In some cases values are null
. There are browsers where not all parameters are available.
Good to know: All values are the average over the last 3 entries (roughly the last 3 seconds) to avoid high-value jumps.
As the simplest approach, you might want to show only the connection quality status as a traffic-light indicator.
The ConnectionStatistics
interface provides a Status
object with named keys for the stats.status
value.
Currently, it contains 4 named keys: GOOD
, OK
, BAD
, and NO_CONNECTION
.
import { ConnectionStatistics } from 'eyeson';
const { Status } = ConnectionStatistics;
const connectionInfo = {};
connectionInfo[Status.GOOD] = { title: 'Excellent', className: 'good' };
connectionInfo[Status.OK] = { title: 'Unstable', className: 'ok' };
connectionInfo[Status.BAD] = { title: 'Poor', className: 'bad' };
connectionInfo[Status.NO_CONNECTION] = { title: 'No connection', className: 'none' };
function showStatistics(stats) {
indicator.className = connectionInfo[stats.status].className;
indicator.textContent = connectionInfo[stats.status].title;
}
The following example will show all available data and update automatically.
import { ConnectionStatistics } from 'eyeson';
const { Status } = ConnectionStatistics;
const numberFormat = new Intl.NumberFormat('en', { maximumFractionDigits: 0 });
const percentFormat = new Intl.NumberFormat('en', { style: 'percent', maximumFractionDigits: 0 });
const connectionInfo = {};
connectionInfo[Status.GOOD] = { title: 'Excellent', className: 'good' };
connectionInfo[Status.OK] = { title: 'Unstable', className: 'ok' };
connectionInfo[Status.BAD] = { title: 'Poor', className: 'bad' };
connectionInfo[Status.NO_CONNECTION] = { title: 'No connection', className: 'none' };
const showStatistics = stats => {
statisticsIcon.className = connectionInfo[stats.status].className;
outputStatus.textContent = connectionInfo[stats.status].title;
outputBitrateSend.textContent = numberFormat.format(stats.bitrateSend) + ' kbps';
outputBitrateReceive.textContent = numberFormat.format(stats.bitrateRecv) + ' kbps';
if (stats.jitter !== null) {
outputJitter.textContent = numberFormat.format(stats.jitter * 1000) + ' ms';
}
if (stats.packetLoss !== null) {
outputPacketLoss.textContent = percentFormat.format(stats.packetLoss);
}
if (stats.roundTripTime !== null) {
outputRoundTripTime.textContent = numberFormat.format(stats.roundTripTime * 1000) + ' ms';
}
if (stats.nack !== null) {
outputNack.textContent = percentFormat.format(stats.nack);
}
};
eyeson.onEvent(event => {
if (event.type === 'statistics_ready') {
event.statistics.onUpdate(showStatistics);
}
});
eyeson.start(/*...*/);
Whenever eyeson.destroy()
is called and the session ends, the instance of the statistics will automatically shut down. So the onUpdate
event is not triggered anymore.