Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
muaz-khan committed Feb 8, 2016
1 parent ccc1285 commit 1022f19
Show file tree
Hide file tree
Showing 5 changed files with 627 additions and 105 deletions.
153 changes: 95 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
## [getStats.js](https://github.com/muaz-khan/getStats) [![npm](https://img.shields.io/npm/v/getstats.svg)](https://npmjs.org/package/getstats) [![downloads](https://img.shields.io/npm/dm/getstats.svg)](https://npmjs.org/package/getstats)
# [getStats.js](https://github.com/muaz-khan/getStats) / [Demo](https://www.webrtc-experiment.com/getStats/)

[![npm](https://img.shields.io/npm/v/getstats.svg)](https://npmjs.org/package/getstats) [![downloads](https://img.shields.io/npm/dm/getstats.svg)](https://npmjs.org/package/getstats)

A tiny JavaScript library using [WebRTC getStats API](http://dev.w3.org/2011/webrtc/editor/webrtc.html#dom-peerconnection-getstats) to return peer connection stats i.e. bandwidth usage, packets lost, local/remote ip addresses and ports, type of connection etc.

It is <a href="https://www.webrtc-experiment.com/licence/">MIT Licenced</a>, which means that you can use it in any commercial/non-commercial product, free of cost.

```
npm install getstats
cd node_modules
cd getstats
node server.js
# and open:
# http://localhost:9999/
```

To use it:
Expand All @@ -14,7 +23,7 @@ To use it:
<script src="./node_modules/getstats/getStats.js"></script>
```

## Link the library
# Link the library

```html
<script src="https://cdn.webrtc-experiment.com/getStats.js"></script>
Expand All @@ -24,15 +33,19 @@ Or link specific build:

* https://github.com/muaz-khan/getStats/releases

## window.getStats
```html
<script src="https://github.com/muaz-khan/getStats/releases/download/1.0.4/getStats.js"></script>
```

# `window.getStats`

To invoke directly:

```javascript
getStats(peer, callback, interval);
```

## RTCPeerConnection.prototype.getPeerStats
# RTCPeerConnection.prototype.getPeerStats

Or, to setup an instance method:

Expand Down Expand Up @@ -62,10 +75,10 @@ RTCPeerConnection.prototype.getStats = window.getStats;
RTCPeerConnection.prototype.intanceMethodNamae = window.getStats;
```

## Usage
# Usage

```javascript
var rtcPeerConnection = new RTCPeerConnection(iceServers);
var rtcPeerConnection = new RTCPeerConnection(rtcConfig);

var repeatInterval = 2000; // 2000 ms == 2 seconds
rtcPeerConnection.getPeerStats(function(result) {
Expand All @@ -85,69 +98,93 @@ rtcPeerConnection.getPeerStats(function(result) {
}, repeatInterval);
```

## Firefox?
# Firefox?

```javascript
peer.getStats(peer.getLocalStreams()[0].getAudioTracks()[0], function(results) {
// rest goes here
}, 5 * 1000);
```

## result.audio

1. availableBandwidth
2. inputLevel
3. packetsLost
3. rtt
4. packetsSent
5. bytesSent

## result.video

1. availableBandwidth
2. googFrameHeightInput
3. googFrameWidthInput
4. googCaptureQueueDelayMsPerS
5. rtt
6. packetsLost
7. packetsSent
8. googEncodeUsagePercent
9. googCpuLimitedResolution
10. googNacksReceived
11. googFrameRateInput
12. googPlisReceived
13. googViewLimitedResolution
14. googCaptureJitterMs
15. googAvgEncodeMs
16. googFrameHeightSent
17. googFrameRateSent
18. googBandwidthLimitedResolution
19. googFrameWidthSent
20. googFirsReceived
21. bytesSent

## result.connectionType

1. local.candidateType
2. local.ipAddress
3. remote.candidateType
4. remote.ipAddress
5. transport

## result.results
# `result.datachannel`

It is an array that is returned by browser's native PeerConnection API.
```javascript
// states => open or close
alert(result.datachannel.state === 'open');
```

# `result.isOfferer`

Offerer is the person who invoked `createOffer` method.

# `result.encryption`

## Credits
To detect which tech is used to encrypt your connections.

[Muaz Khan](https://github.com/muaz-khan):
```javascript
alert(result.encryption === 'sha-256');
```

# `result.nomore()`

This function can be used to ask to stop invoking getStats API.

```javascript
btnStopGetStats.onclick = function() {
getStatsResult.nomore();
};
```

# `result.audio`

1. `result.audio.availableBandwidth`
2. `result.audio.inputLevel`
3. `result.audio.packetsLost`
3. `result.audio.rtt`
4. `result.audio.packetsSent`
5. `result.audio.bytesSent`

# `result.video`

1. `result.video.availableBandwidth`
2. `result.video.googFrameHeightInput`
3. `result.video.googFrameWidthInput`
4. `result.video.googCaptureQueueDelayMsPerS`
5. `result.video.rtt`
6. `result.video.packetsLost`
7. `result.video.packetsSent`
8. `result.video.googEncodeUsagePercent`
9. `result.video.googCpuLimitedResolution`
10. `result.video.googNacksReceived`
11. `result.video.googFrameRateInput`
12. `result.video.googPlisReceived`
13. `result.video.googViewLimitedResolution`
14. `result.video.googCaptureJitterMs`
15. `result.video.googAvgEncodeMs`
16. `result.video.googFrameHeightSent`
17. `result.video.googFrameRateSent`
18. `result.video.googBandwidthLimitedResolution`
19. `result.video.googFrameWidthSent`
20. `result.video.googFirsReceived`
21. `result.video.bytesSent`

# `result.connectionType`

1. `result.connectionType.local.candidateType`
2. `result.connectionType.local.ipAddress`
3. `result.connectionType.local.networkType`
4. `result.connectionType.remote.candidateType`
5. `result.connectionType.remote.ipAddress`
6. `result.connectionType.transport`

# `result.results`

It is an array that is returned by browser's native PeerConnection API.

1. Personal Webpage: http://www.muazkhan.com
2. Email: [email protected]
3. Twitter: https://twitter.com/muazkh and https://twitter.com/WebRTCWeb
4. Google+: https://plus.google.com/+WebRTC-Experiment
5. Facebook: https://www.facebook.com/WebRTC
```javascript
console.log(result.results);
```

## License

[getStats.js](https://github.com/muaz-khan/getStats) is released under [MIT licence](https://www.webrtc-experiment.com/licence/) . Copyright (c) [Muaz Khan](https://plus.google.com/+MuazKhan).
[getStats.js](https://github.com/muaz-khan/getStats) is released under [MIT licence](https://www.webrtc-experiment.com/licence/) . Copyright (c) [Muaz Khan](http://www.MuazKhan.com/).
146 changes: 102 additions & 44 deletions getStats.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Last time updated at Jan 07, 2016, 08:32:23
// Last time updated at Feb 08, 2016, 08:32:23

// Latest file can be found here: https://cdn.webrtc-experiment.com/getStats.js
// Muaz Khan - www.MuazKhan.com
// MIT License - www.WebRTC-Experiment.com/licence
Expand All @@ -15,7 +16,8 @@ getStats(rtcPeerConnection, function(result) {
result.connectionType.transport
});
*/
(function() {

;(function() {
var RTCPeerConnection;
if (typeof webkitRTCPeerConnection !== 'undefined') {
RTCPeerConnection = webkitRTCPeerConnection;
Expand Down Expand Up @@ -69,57 +71,69 @@ getStats(rtcPeerConnection, function(result) {
for (var i = 0; i < results.length; ++i) {
var res = results[i];

if(res.datachannelid && res.type === 'datachannel') {
result.datachannel = {
state: res.state // open or connecting
}
}

if(res.type === 'googLibjingleSession') {
result.isOfferer = res.googInitiator;
}

if(res.type == 'googCertificate') {
result.encryption = res.googFingerprintAlgorithm;
}

if (res.googCodecName == 'opus' && res.bytesSent) {
if (!globalObject.audio.prevBytesSent)
globalObject.audio.prevBytesSent = res.bytesSent;
var kilobytes = 0;
if(!!res.bytesSent) {
if (!globalObject.audio.prevBytesSent) {
globalObject.audio.prevBytesSent = res.bytesSent;
}

var bytes = res.bytesSent - globalObject.audio.prevBytesSent;
globalObject.audio.prevBytesSent = res.bytesSent;
var bytes = res.bytesSent - globalObject.audio.prevBytesSent;
globalObject.audio.prevBytesSent = res.bytesSent;

var kilobytes = bytes / 1024;
kilobytes = bytes / 1024;
}

result.audio = merge(result.audio, {
availableBandwidth: kilobytes.toFixed(1),
inputLevel: res.audioInputLevel,
packetsLost: res.packetsLost,
rtt: res.googRtt,
packetsSent: res.packetsSent,
bytesSent: res.bytesSent
});
if(!result.audio) {
result.audio = res;
}

result.audio.availableBandwidth = kilobytes.toFixed(1);
}

if (res.googCodecName == 'VP8') {
if (!globalObject.video.prevBytesSent)
// if(!globalObject.)
// bytesReceived
// packetsReceived
// timestamp
var kilobytes = 0;
if(!!res.bytesSent) {
if (!globalObject.video.prevBytesSent) {
globalObject.video.prevBytesSent = res.bytesSent;
}

var bytes = res.bytesSent - globalObject.video.prevBytesSent;
globalObject.video.prevBytesSent = res.bytesSent;

var bytes = res.bytesSent - globalObject.video.prevBytesSent;
globalObject.video.prevBytesSent = res.bytesSent;

var kilobytes = bytes / 1024;

result.video = merge(result.video, {
availableBandwidth: kilobytes.toFixed(1),
googFrameHeightInput: res.googFrameHeightInput,
googFrameWidthInput: res.googFrameWidthInput,
googCaptureQueueDelayMsPerS: res.googCaptureQueueDelayMsPerS,
rtt: res.googRtt,
packetsLost: res.packetsLost,
packetsSent: res.packetsSent,
googEncodeUsagePercent: res.googEncodeUsagePercent,
googCpuLimitedResolution: res.googCpuLimitedResolution,
googNacksReceived: res.googNacksReceived,
googFrameRateInput: res.googFrameRateInput,
googPlisReceived: res.googPlisReceived,
googViewLimitedResolution: res.googViewLimitedResolution,
googCaptureJitterMs: res.googCaptureJitterMs,
googAvgEncodeMs: res.googAvgEncodeMs,
googFrameHeightSent: res.googFrameHeightSent,
googFrameRateSent: res.googFrameRateSent,
googBandwidthLimitedResolution: res.googBandwidthLimitedResolution,
googFrameWidthSent: res.googFrameWidthSent,
googFirsReceived: res.googFirsReceived,
bytesSent: res.bytesSent
});
kilobytes = bytes / 1024;
}

if(!result.video) {
result.video = res;
}

result.video.availableBandwidth = kilobytes.toFixed(1);

if(res.googFrameHeightReceived && res.googFrameWidthReceived) {
result.resolutions = {
width: res.googFrameWidthReceived,
height: res.googFrameHeightReceived
};
}
}

if (res.type == 'VideoBwe') {
Expand Down Expand Up @@ -149,6 +163,50 @@ getStats(rtcPeerConnection, function(result) {
transport: res.googTransportType
};
}

var systemNetworkType = ((navigator.connection || {}).type || 'unknown').toString().toLowerCase();

if(res.type === 'localcandidate') {
if(!result.connectionType) {
result.connectionType = {};
}

result.connectionType.local = {
candidateType: res.candidateType,
ipAddress: res.ipAddress + ':' + res.portNumber,
networkType: res.networkType/* || systemNetworkType */ || 'unknown',
transport: res.transport
}
}

if(res.type === 'remotecandidate') {
if(!result.connectionType) {
result.connectionType = {};
}

result.connectionType.local = {
candidateType: res.candidateType,
ipAddress: res.ipAddress + ':' + res.portNumber,
networkType: res.networkType || systemNetworkType,
transport: res.transport
}
}
}

try {
if(peer.iceConnectionState.search(/failed|closed/gi) !== -1) {
nomore = true;
}
}
catch(e) {
nomore = true;
}

if(nomore === true) {
if(result.datachannel) {
result.datachannel.state = 'close';
}
result.ended = true;
}

callback(result);
Expand Down
Loading

0 comments on commit 1022f19

Please sign in to comment.