Room.getStreamStats() - A useful hidden API

I was playing with ErizoClient.Room.getStreamStats() and found it very useful to provide users some interesting information about the stream status. But the API seems to be unofficial since there is no documentation for it. The current output is hard to read and needs to be parsed and filtered. Consider the following output:

 {
  '888581ec-5d51-4881-b007-4f04983935cf': {
    0: {
      erizoAudioMute: 0,
      erizoVideoMute: 0,
    },
    2780458502: {
      bandwidth: 825600,
      bitrateCalculated: 176165,
      clientHostType: 'host',
      fractionLost: 0,
      jitter: 11619,
      keyFrames: 1,
      packetsLost: 0,
      sourceSsrc: 2780458502,
      type: 'video',
    },
    qualityLayers: {
      0: {
        0: 68968,
        1: 180976,
        2: 226672,
      },
      maxActiveSpatialLayer: 0,
      maxActiveTemporalLayer: 2,
    },
    total: {
      bitrateCalculated: 176165,
      paddingBitrate: 102048,
      senderBitrateEstimation: 825600,
    },
  },
  publisher: {
    2780458502: {
      PLI: 1,
      bitrateCalculated: 226499,
      bytesSent: 85942,
      clientHostType: 'host',
      erizoBandwidth: 796317,
      keyFrames: 2,
      packetsSent: 103,
      type: 'video',
    },
    total: {
      bitrateCalculated: 226499,
      paddingBitrate: 0,
    },
  },
}

At the moment you need to traverse the entire object and examine the type of keys to reach the data you need. One idea is to add the sourceSsrc (2780458502 in this example) to the stream attributes so finding the key is much easier.

In the other hand some data are ambiguous to me like bandwidth vs erizoBandwidth vs bitrateCalculated or packetsLost vs fractionLost vs jitter. BTW what is PLI??

Also the output seems incomplete. For example we have bytesSent for the publisher but there is no bytesReceived for the subscriber which could be useful for calculating the total upload/download traffic usage.

The PLI is the packet loss indicator.
Consider the following example:
You have a poor connection and, since the webrtc stream if not passing thru a special TURN is an UDP packets stream, your packets could be lost from your pc to the server.
So there’s a mechanism called NACK that starts to act.
The server send to you (client) a NACK request for the specific packet lost (he know that one packet is missing since they are ordered incrementally).
Your client has a small buffer of sent packet, so it resend the packet.
But this packet (if the loss rate is very high) could be lost again and again.
If you can’t retransmit this packet in a certain span of time, the server will request you a PLI, because your lost packet has interrupted the decoder and he can’t render no more since you send him a FULL picture called keyframe. A PLI is simple a keyframe request. you will always at least 1 PLI since it’s the first keyframe you send to server during the call initialization

Thanks for the explanation!
Then what’s your suggestion for a simple and easy to understand report of the connection quality to the end user? I mean how to benefit from these values (e.g. pli, jitter, packet loss, etc) to provide a real time feedback report?

this is a good starting point!
Callstats.io

Great article! Thanks.

The problem with the API is that it reports stats of all subscribers. So with a large number of participants it’s unwise to be used in the browser and to fetch a large amount of data every moment. I think adding a new param to the API to fetch only stats of a specific subscriber would be useful.

1 Like