diff --git a/.npmignore b/.npmignore index ba8de40..e15a22c 100644 --- a/.npmignore +++ b/.npmignore @@ -1,15 +1,11 @@ -node_modules -bower_components +# ignore everything +* -.*.swp -._* -.DS_Store -.git -.hg -.npmrc -.lock-wscript -.svn -.wafpickle-* -config.gypi -CVS -npm-debug.log \ No newline at end of file +# but not these files... +!getStats.js +!getStats.min.js +!index.html +!package.json +!bower.json +!server.js +!README.md \ No newline at end of file diff --git a/Gruntfile.js b/Gruntfile.js index 5e11b2e..1410e9e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -45,9 +45,9 @@ module.exports = function(grunt) { 'dev/googCodecName.audio.js', 'dev/googCodecName.video.js', 'dev/bweforvideo.js', - 'dev/googCandidatePair.js', - 'dev/localcandidate.js', - 'dev/remotecandidate.js', + 'dev/candidate-pair.js', + 'dev/local-candidate.js', + 'dev/remote-candidate.js', 'dev/dataSentReceived.js', 'dev/ssrc.js', 'dev/tail.js' diff --git a/README.md b/README.md index 86b80f8..75c9dbb 100755 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ -# [getStats.js](https://github.com/muaz-khan/getStats) / [Demo](https://www.webrtc-experiment.com/getStats/) +# [getStats.js](https://github.com/muaz-khan/getStats) + +# [Single Page Demo](https://www.webrtc-experiment.com/getStats/) or [Multi User P2P Demo](https://rtcmulticonnection.herokuapp.com/demos/getStats.html) [![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) [![Build Status: Linux](https://travis-ci.org/muaz-khan/getStats.png?branch=master)](https://travis-ci.org/muaz-khan/getStats) @@ -6,6 +8,8 @@ A tiny JavaScript library using [WebRTC getStats API](http://dev.w3.org/2011/web It is MIT Licenced, which means that you can use it in any commercial/non-commercial product, free of cost. +![getStats](https://cdn.webrtc-experiment.com/images/getStats.png) + ``` npm install getstats @@ -33,6 +37,9 @@ To use it: + + + ``` Or link specific build: @@ -40,7 +47,7 @@ Or link specific build: * https://github.com/muaz-khan/getStats/releases ```html - + ``` # `window.getStats` @@ -92,8 +99,7 @@ rtcPeerConnection.getPeerStats(function(result) { result.connectionType.remote.candidateType result.connectionType.transport - result.audio.send.availableBandwidth - result.audio.recv.availableBandwidth + result.bandwidth.availableSendBandwidth // it will be your system bandwidth for STUN connections result.audio.packetsSent result.audio.packetsLost result.audio.rtt @@ -142,6 +148,10 @@ btnStopGetStats.onclick = function() { }; ``` +# `result.bandwidth` + +1. `result.bandwidth.availableSendBandwidth` + # `result.audio` 1. `result.audio.send.availableBandwidth` diff --git a/bower.json b/bower.json index 1f46b18..5741f71 100644 --- a/bower.json +++ b/bower.json @@ -1,7 +1,7 @@ { "name": "getstats", "description": "A tiny JavaScript library using WebRTC getStats API to return peer connection stats i.e. bandwidth usage, packets lost, local/remote ip addresses and ports, type of connection etc.", - "version": "1.0.4", + "version": "1.0.5", "authors": [ { "name": "Muaz Khan", diff --git a/dev/bweforvideo.js b/dev/bweforvideo.js index 14a8319..e870de1 100644 --- a/dev/bweforvideo.js +++ b/dev/bweforvideo.js @@ -1,15 +1,13 @@ getStatsParser.bweforvideo = function(result) { if (result.type !== 'VideoBwe') return; - // id === 'bweforvideo' + getStatsResult.bandwidth.availableSendBandwidth = result.googAvailableSendBandwidth; - getStatsResult.video.bandwidth = { - googActualEncBitrate: result.googActualEncBitrate, - googAvailableSendBandwidth: result.googAvailableSendBandwidth, - googAvailableReceiveBandwidth: result.googAvailableReceiveBandwidth, - googRetransmitBitrate: result.googRetransmitBitrate, - googTargetEncBitrate: result.googTargetEncBitrate, - googBucketDelay: result.googBucketDelay, - googTransmitBitrate: result.googTransmitBitrate - }; + getStatsResult.bandwidth.googActualEncBitrate = result.googActualEncBitrate; + getStatsResult.bandwidth.googAvailableSendBandwidth = result.googAvailableSendBandwidth; + getStatsResult.bandwidth.googAvailableReceiveBandwidth = result.googAvailableReceiveBandwidth; + getStatsResult.bandwidth.googRetransmitBitrate = result.googRetransmitBitrate; + getStatsResult.bandwidth.googTargetEncBitrate = result.googTargetEncBitrate; + getStatsResult.bandwidth.googBucketDelay = result.googBucketDelay; + getStatsResult.bandwidth.googTransmitBitrate = result.googTransmitBitrate; }; diff --git a/dev/candidate-pair.js b/dev/candidate-pair.js new file mode 100644 index 0000000..2c4a3fe --- /dev/null +++ b/dev/candidate-pair.js @@ -0,0 +1,54 @@ +getStatsParser.candidatePair = function(result) { + if (result.type !== 'googCandidatePair' && result.type !== 'candidate-pair') return; + + // result.googActiveConnection means either STUN or TURN is used. + + if (result.googActiveConnection == 'true') { + // id === 'Conn-audio-1-0' + // localCandidateId, remoteCandidateId + + // bytesSent, bytesReceived + + Object.keys(getStatsResult.internal.candidates).forEach(function(cid) { + var candidate = getStatsResult.internal.candidates[cid]; + if (candidate.ipAddress.indexOf(result.googLocalAddress) !== -1) { + getStatsResult.connectionType.local.candidateType = candidate.candidateType; + getStatsResult.connectionType.local.ipAddress = candidate.ipAddress; + getStatsResult.connectionType.local.networkType = candidate.networkType; + getStatsResult.connectionType.local.transport = candidate.transport; + } + if (candidate.ipAddress.indexOf(result.googRemoteAddress) !== -1) { + getStatsResult.connectionType.remote.candidateType = candidate.candidateType; + getStatsResult.connectionType.remote.ipAddress = candidate.ipAddress; + getStatsResult.connectionType.remote.networkType = candidate.networkType; + getStatsResult.connectionType.remote.transport = candidate.transport; + } + }); + + getStatsResult.connectionType.transport = result.googTransportType; + + var localCandidate = getStatsResult.internal.candidates[result.localCandidateId]; + if (localCandidate) { + if (localCandidate.ipAddress) { + getStatsResult.connectionType.systemIpAddress = localCandidate.ipAddress; + } + } + + var remoteCandidate = getStatsResult.internal.candidates[result.remoteCandidateId]; + if (remoteCandidate) { + if (remoteCandidate.ipAddress) { + getStatsResult.connectionType.systemIpAddress = remoteCandidate.ipAddress; + } + } + } + + if (result.type === 'candidate-pair') { + if (result.selected === true && result.nominated === true && result.state === 'succeeded') { + // remoteCandidateId, localCandidateId, componentId + var localCandidate = getStatsResult.internal.candidates[result.remoteCandidateId]; + var remoteCandidate = getStatsResult.internal.candidates[result.remoteCandidateId]; + + // Firefox used above two pairs for connection + } + } +}; diff --git a/dev/getStats.js b/dev/getStats.js index 07a39ba..98aa7e4 100644 --- a/dev/getStats.js +++ b/dev/getStats.js @@ -8,6 +8,10 @@ function getStatsLooper() { getStatsParser[key](result); } }); + + if (result.type !== 'local-candidate' && result.type !== 'remote-candidate' && result.type !== 'candidate-pair') { + // console.error('result', result); + } }); try { diff --git a/dev/globals.js b/dev/globals.js index ca05cd5..aee8b8f 100644 --- a/dev/globals.js +++ b/dev/globals.js @@ -40,6 +40,11 @@ var getStatsResult = { bytesSent: 0, bytesReceived: 0 }, + bandwidth: { + systemBandwidth: 0, + sentPerSecond: 0, + encodedPerSecond: 0 + }, results: {}, connectionType: { systemNetworkType: systemNetworkType, diff --git a/dev/googCandidatePair.js b/dev/googCandidatePair.js deleted file mode 100644 index 45a4e7c..0000000 --- a/dev/googCandidatePair.js +++ /dev/null @@ -1,30 +0,0 @@ -getStatsParser.googCandidatePair = function(result) { - if (result.type !== 'googCandidatePair') return; - - // result.googActiveConnection means either STUN or TURN is used. - - if (result.googActiveConnection == 'true') { - // id === 'Conn-audio-1-0' - // localCandidateId, remoteCandidateId - - // bytesSent, bytesReceived - - getStatsResult.connectionType.local.ipAddress = result.googLocalAddress; - getStatsResult.connectionType.remote.ipAddress = result.googRemoteAddress; - getStatsResult.connectionType.transport = result.googTransportType; - - var localCandidate = getStatsResult.internal.candidates[result.localCandidateId]; - if (localCandidate) { - if (localCandidate.ipAddress) { - getStatsResult.connectionType.systemIpAddress = localCandidate.ipAddress; - } - } - - var remoteCandidate = getStatsResult.internal.candidates[result.remoteCandidateId]; - if (remoteCandidate) { - if (remoteCandidate.ipAddress) { - getStatsResult.connectionType.systemIpAddress = remoteCandidate.ipAddress; - } - } - } -}; diff --git a/dev/local-candidate.js b/dev/local-candidate.js new file mode 100644 index 0000000..2f932ba --- /dev/null +++ b/dev/local-candidate.js @@ -0,0 +1,58 @@ +var LOCAL_candidateType = {}; +var LOCAL_transport = {}; +var LOCAL_ipAddress = {}; +var LOCAL_networkType = {}; + +getStatsParser.localcandidate = function(result) { + if (result.type !== 'localcandidate' && result.type !== 'local-candidate') return; + if (!result.id) return; + + if (!LOCAL_candidateType[result.id]) { + LOCAL_candidateType[result.id] = []; + } + + if (!LOCAL_transport[result.id]) { + LOCAL_transport[result.id] = []; + } + + if (!LOCAL_ipAddress[result.id]) { + LOCAL_ipAddress[result.id] = []; + } + + if (!LOCAL_networkType[result.id]) { + LOCAL_networkType[result.id] = []; + } + + if (result.candidateType && LOCAL_candidateType[result.id].indexOf(result.candidateType) === -1) { + LOCAL_candidateType[result.id].push(result.candidateType); + } + + if (result.transport && LOCAL_transport[result.id].indexOf(result.transport) === -1) { + LOCAL_transport[result.id].push(result.transport); + } + + if (result.ipAddress && LOCAL_ipAddress[result.id].indexOf(result.ipAddress + ':' + result.portNumber) === -1) { + LOCAL_ipAddress[result.id].push(result.ipAddress + ':' + result.portNumber); + } + + if (result.networkType && LOCAL_networkType[result.id].indexOf(result.networkType) === -1) { + LOCAL_networkType[result.id].push(result.networkType); + } + + getStatsResult.internal.candidates[result.id] = { + candidateType: LOCAL_candidateType[result.id], + ipAddress: LOCAL_ipAddress[result.id], + portNumber: result.portNumber, + networkType: LOCAL_networkType[result.id], + priority: result.priority, + transport: LOCAL_transport[result.id], + timestamp: result.timestamp, + id: result.id, + type: result.type + }; + + getStatsResult.connectionType.local.candidateType = LOCAL_candidateType[result.id]; + getStatsResult.connectionType.local.ipAddress = LOCAL_ipAddress[result.id]; + getStatsResult.connectionType.local.networkType = LOCAL_networkType[result.id]; + getStatsResult.connectionType.local.transport = LOCAL_transport[result.id]; +}; diff --git a/dev/localcandidate.js b/dev/localcandidate.js deleted file mode 100644 index 74caf44..0000000 --- a/dev/localcandidate.js +++ /dev/null @@ -1,41 +0,0 @@ -var LOCAL_candidateType = []; -var LOCAL_transport = []; -var LOCAL_ipAddress = []; -var LOCAL_networkType = []; - -getStatsParser.localcandidate = function(result) { - if (result.type !== 'localcandidate') return; - - if (result.candidateType && LOCAL_candidateType.indexOf(result.candidateType) === -1) { - LOCAL_candidateType.push(result.candidateType); - } - - if (result.transport && LOCAL_transport.indexOf(result.transport) === -1) { - LOCAL_transport.push(result.transport); - } - - if (result.ipAddress && LOCAL_ipAddress.indexOf(result.ipAddress + ':' + result.portNumber) === -1) { - LOCAL_ipAddress.push(result.ipAddress + ':' + result.portNumber); - } - - if (result.networkType && LOCAL_networkType.indexOf(result.networkType) === -1) { - LOCAL_networkType.push(result.networkType); - } - - getStatsResult.internal.candidates[result.id] = { - candidateType: LOCAL_candidateType, - ipAddress: LOCAL_ipAddress, - portNumber: result.portNumber, - networkType: LOCAL_networkType, - priority: result.priority, - transport: LOCAL_transport, - timestamp: result.timestamp, - id: result.id, - type: result.type - }; - - getStatsResult.connectionType.local.candidateType = LOCAL_candidateType; - getStatsResult.connectionType.local.ipAddress = LOCAL_ipAddress; - getStatsResult.connectionType.local.networkType = LOCAL_networkType; - getStatsResult.connectionType.local.transport = LOCAL_transport; -}; diff --git a/dev/remote-candidate.js b/dev/remote-candidate.js new file mode 100644 index 0000000..ec2f689 --- /dev/null +++ b/dev/remote-candidate.js @@ -0,0 +1,58 @@ +var REMOTE_candidateType = {}; +var REMOTE_transport = {}; +var REMOTE_ipAddress = {}; +var REMOTE_networkType = {}; + +getStatsParser.remotecandidate = function(result) { + if (result.type !== 'remotecandidate' && result.type !== 'remote-candidate') return; + if (!result.id) return; + + if (!REMOTE_candidateType[result.id]) { + REMOTE_candidateType[result.id] = []; + } + + if (!REMOTE_transport[result.id]) { + REMOTE_transport[result.id] = []; + } + + if (!REMOTE_ipAddress[result.id]) { + REMOTE_ipAddress[result.id] = []; + } + + if (!REMOTE_networkType[result.id]) { + REMOTE_networkType[result.id] = []; + } + + if (result.candidateType && REMOTE_candidateType[result.id].indexOf(result.candidateType) === -1) { + REMOTE_candidateType[result.id].push(result.candidateType); + } + + if (result.transport && REMOTE_transport[result.id].indexOf(result.transport) === -1) { + REMOTE_transport[result.id].push(result.transport); + } + + if (result.ipAddress && REMOTE_ipAddress[result.id].indexOf(result.ipAddress + ':' + result.portNumber) === -1) { + REMOTE_ipAddress[result.id].push(result.ipAddress + ':' + result.portNumber); + } + + if (result.networkType && REMOTE_networkType[result.id].indexOf(result.networkType) === -1) { + REMOTE_networkType[result.id].push(result.networkType); + } + + getStatsResult.internal.candidates[result.id] = { + candidateType: REMOTE_candidateType[result.id], + ipAddress: REMOTE_ipAddress[result.id], + portNumber: result.portNumber, + networkType: REMOTE_networkType[result.id], + priority: result.priority, + transport: REMOTE_transport[result.id], + timestamp: result.timestamp, + id: result.id, + type: result.type + }; + + getStatsResult.connectionType.remote.candidateType = REMOTE_candidateType[result.id]; + getStatsResult.connectionType.remote.ipAddress = REMOTE_ipAddress[result.id]; + getStatsResult.connectionType.remote.networkType = REMOTE_networkType[result.id]; + getStatsResult.connectionType.remote.transport = REMOTE_transport[result.id]; +}; diff --git a/dev/remotecandidate.js b/dev/remotecandidate.js deleted file mode 100644 index fed1734..0000000 --- a/dev/remotecandidate.js +++ /dev/null @@ -1,41 +0,0 @@ -var REMOTE_candidateType = []; -var REMOTE_transport = []; -var REMOTE_ipAddress = []; -var REMOTE_networkType = []; - -getStatsParser.remotecandidate = function(result) { - if (result.type !== 'remotecandidate') return; - - if (result.candidateType && REMOTE_candidateType.indexOf(result.candidateType) === -1) { - REMOTE_candidateType.push(result.candidateType); - } - - if (result.transport && REMOTE_transport.indexOf(result.transport) === -1) { - REMOTE_transport.push(result.transport); - } - - if (result.ipAddress && REMOTE_ipAddress.indexOf(result.ipAddress + ':' + result.portNumber) === -1) { - REMOTE_ipAddress.push(result.ipAddress + ':' + result.portNumber); - } - - if (result.networkType && REMOTE_networkType.indexOf(result.networkType) === -1) { - REMOTE_networkType.push(result.networkType); - } - - getStatsResult.internal.candidates[result.id] = { - candidateType: REMOTE_candidateType, - ipAddress: REMOTE_ipAddress, - portNumber: result.portNumber, - networkType: REMOTE_networkType, - priority: result.priority, - transport: REMOTE_transport, - timestamp: result.timestamp, - id: result.id, - type: result.type - }; - - getStatsResult.connectionType.remote.candidateType = REMOTE_candidateType; - getStatsResult.connectionType.remote.ipAddress = REMOTE_ipAddress; - getStatsResult.connectionType.remote.networkType = REMOTE_networkType; - getStatsResult.connectionType.remote.transport = REMOTE_transport; -}; diff --git a/getStats.js b/getStats.js index 6f17957..eae2892 100755 --- a/getStats.js +++ b/getStats.js @@ -1,6 +1,6 @@ 'use strict'; -// Last time updated: 2017-08-13 4:33:11 PM UTC +// Last time updated: 2017-08-26 5:42:35 AM UTC // _______________ // getStats v1.0.4 @@ -56,6 +56,11 @@ window.getStats = function(mediaStreamTrack, callback, interval) { bytesSent: 0, bytesReceived: 0 }, + bandwidth: { + systemBandwidth: 0, + sentPerSecond: 0, + encodedPerSecond: 0 + }, results: {}, connectionType: { systemNetworkType: systemNetworkType, @@ -135,6 +140,10 @@ window.getStats = function(mediaStreamTrack, callback, interval) { getStatsParser[key](result); } }); + + if (result.type !== 'local-candidate' && result.type !== 'remote-candidate' && result.type !== 'candidate-pair') { + // console.error('result', result); + } }); try { @@ -323,21 +332,19 @@ window.getStats = function(mediaStreamTrack, callback, interval) { getStatsParser.bweforvideo = function(result) { if (result.type !== 'VideoBwe') return; - // id === 'bweforvideo' + getStatsResult.bandwidth.availableSendBandwidth = result.googAvailableSendBandwidth; - getStatsResult.video.bandwidth = { - googActualEncBitrate: result.googActualEncBitrate, - googAvailableSendBandwidth: result.googAvailableSendBandwidth, - googAvailableReceiveBandwidth: result.googAvailableReceiveBandwidth, - googRetransmitBitrate: result.googRetransmitBitrate, - googTargetEncBitrate: result.googTargetEncBitrate, - googBucketDelay: result.googBucketDelay, - googTransmitBitrate: result.googTransmitBitrate - }; + getStatsResult.bandwidth.googActualEncBitrate = result.googActualEncBitrate; + getStatsResult.bandwidth.googAvailableSendBandwidth = result.googAvailableSendBandwidth; + getStatsResult.bandwidth.googAvailableReceiveBandwidth = result.googAvailableReceiveBandwidth; + getStatsResult.bandwidth.googRetransmitBitrate = result.googRetransmitBitrate; + getStatsResult.bandwidth.googTargetEncBitrate = result.googTargetEncBitrate; + getStatsResult.bandwidth.googBucketDelay = result.googBucketDelay; + getStatsResult.bandwidth.googTransmitBitrate = result.googTransmitBitrate; }; - getStatsParser.googCandidatePair = function(result) { - if (result.type !== 'googCandidatePair') return; + getStatsParser.candidatePair = function(result) { + if (result.type !== 'googCandidatePair' && result.type !== 'candidate-pair') return; // result.googActiveConnection means either STUN or TURN is used. @@ -347,8 +354,22 @@ window.getStats = function(mediaStreamTrack, callback, interval) { // bytesSent, bytesReceived - getStatsResult.connectionType.local.ipAddress = result.googLocalAddress; - getStatsResult.connectionType.remote.ipAddress = result.googRemoteAddress; + Object.keys(getStatsResult.internal.candidates).forEach(function(cid) { + var candidate = getStatsResult.internal.candidates[cid]; + if (candidate.ipAddress.indexOf(result.googLocalAddress) !== -1) { + getStatsResult.connectionType.local.candidateType = candidate.candidateType; + getStatsResult.connectionType.local.ipAddress = candidate.ipAddress; + getStatsResult.connectionType.local.networkType = candidate.networkType; + getStatsResult.connectionType.local.transport = candidate.transport; + } + if (candidate.ipAddress.indexOf(result.googRemoteAddress) !== -1) { + getStatsResult.connectionType.remote.candidateType = candidate.candidateType; + getStatsResult.connectionType.remote.ipAddress = candidate.ipAddress; + getStatsResult.connectionType.remote.networkType = candidate.networkType; + getStatsResult.connectionType.remote.transport = candidate.transport; + } + }); + getStatsResult.connectionType.transport = result.googTransportType; var localCandidate = getStatsResult.internal.candidates[result.localCandidateId]; @@ -365,90 +386,134 @@ window.getStats = function(mediaStreamTrack, callback, interval) { } } } + + if (result.type === 'candidate-pair') { + if (result.selected === true && result.nominated === true && result.state === 'succeeded') { + // remoteCandidateId, localCandidateId, componentId + var localCandidate = getStatsResult.internal.candidates[result.remoteCandidateId]; + var remoteCandidate = getStatsResult.internal.candidates[result.remoteCandidateId]; + + // Firefox used above two pairs for connection + } + } }; - var LOCAL_candidateType = []; - var LOCAL_transport = []; - var LOCAL_ipAddress = []; - var LOCAL_networkType = []; + var LOCAL_candidateType = {}; + var LOCAL_transport = {}; + var LOCAL_ipAddress = {}; + var LOCAL_networkType = {}; getStatsParser.localcandidate = function(result) { - if (result.type !== 'localcandidate') return; + if (result.type !== 'localcandidate' && result.type !== 'local-candidate') return; + if (!result.id) return; + + if (!LOCAL_candidateType[result.id]) { + LOCAL_candidateType[result.id] = []; + } - if (result.candidateType && LOCAL_candidateType.indexOf(result.candidateType) === -1) { - LOCAL_candidateType.push(result.candidateType); + if (!LOCAL_transport[result.id]) { + LOCAL_transport[result.id] = []; } - if (result.transport && LOCAL_transport.indexOf(result.transport) === -1) { - LOCAL_transport.push(result.transport); + if (!LOCAL_ipAddress[result.id]) { + LOCAL_ipAddress[result.id] = []; } - if (result.ipAddress && LOCAL_ipAddress.indexOf(result.ipAddress + ':' + result.portNumber) === -1) { - LOCAL_ipAddress.push(result.ipAddress + ':' + result.portNumber); + if (!LOCAL_networkType[result.id]) { + LOCAL_networkType[result.id] = []; } - if (result.networkType && LOCAL_networkType.indexOf(result.networkType) === -1) { - LOCAL_networkType.push(result.networkType); + if (result.candidateType && LOCAL_candidateType[result.id].indexOf(result.candidateType) === -1) { + LOCAL_candidateType[result.id].push(result.candidateType); + } + + if (result.transport && LOCAL_transport[result.id].indexOf(result.transport) === -1) { + LOCAL_transport[result.id].push(result.transport); + } + + if (result.ipAddress && LOCAL_ipAddress[result.id].indexOf(result.ipAddress + ':' + result.portNumber) === -1) { + LOCAL_ipAddress[result.id].push(result.ipAddress + ':' + result.portNumber); + } + + if (result.networkType && LOCAL_networkType[result.id].indexOf(result.networkType) === -1) { + LOCAL_networkType[result.id].push(result.networkType); } getStatsResult.internal.candidates[result.id] = { - candidateType: LOCAL_candidateType, - ipAddress: LOCAL_ipAddress, + candidateType: LOCAL_candidateType[result.id], + ipAddress: LOCAL_ipAddress[result.id], portNumber: result.portNumber, - networkType: LOCAL_networkType, + networkType: LOCAL_networkType[result.id], priority: result.priority, - transport: LOCAL_transport, + transport: LOCAL_transport[result.id], timestamp: result.timestamp, id: result.id, type: result.type }; - getStatsResult.connectionType.local.candidateType = LOCAL_candidateType; - getStatsResult.connectionType.local.ipAddress = LOCAL_ipAddress; - getStatsResult.connectionType.local.networkType = LOCAL_networkType; - getStatsResult.connectionType.local.transport = LOCAL_transport; + getStatsResult.connectionType.local.candidateType = LOCAL_candidateType[result.id]; + getStatsResult.connectionType.local.ipAddress = LOCAL_ipAddress[result.id]; + getStatsResult.connectionType.local.networkType = LOCAL_networkType[result.id]; + getStatsResult.connectionType.local.transport = LOCAL_transport[result.id]; }; - var REMOTE_candidateType = []; - var REMOTE_transport = []; - var REMOTE_ipAddress = []; - var REMOTE_networkType = []; + var REMOTE_candidateType = {}; + var REMOTE_transport = {}; + var REMOTE_ipAddress = {}; + var REMOTE_networkType = {}; getStatsParser.remotecandidate = function(result) { - if (result.type !== 'remotecandidate') return; + if (result.type !== 'remotecandidate' && result.type !== 'remote-candidate') return; + if (!result.id) return; + + if (!REMOTE_candidateType[result.id]) { + REMOTE_candidateType[result.id] = []; + } + + if (!REMOTE_transport[result.id]) { + REMOTE_transport[result.id] = []; + } + + if (!REMOTE_ipAddress[result.id]) { + REMOTE_ipAddress[result.id] = []; + } + + if (!REMOTE_networkType[result.id]) { + REMOTE_networkType[result.id] = []; + } - if (result.candidateType && REMOTE_candidateType.indexOf(result.candidateType) === -1) { - REMOTE_candidateType.push(result.candidateType); + if (result.candidateType && REMOTE_candidateType[result.id].indexOf(result.candidateType) === -1) { + REMOTE_candidateType[result.id].push(result.candidateType); } - if (result.transport && REMOTE_transport.indexOf(result.transport) === -1) { - REMOTE_transport.push(result.transport); + if (result.transport && REMOTE_transport[result.id].indexOf(result.transport) === -1) { + REMOTE_transport[result.id].push(result.transport); } - if (result.ipAddress && REMOTE_ipAddress.indexOf(result.ipAddress + ':' + result.portNumber) === -1) { - REMOTE_ipAddress.push(result.ipAddress + ':' + result.portNumber); + if (result.ipAddress && REMOTE_ipAddress[result.id].indexOf(result.ipAddress + ':' + result.portNumber) === -1) { + REMOTE_ipAddress[result.id].push(result.ipAddress + ':' + result.portNumber); } - if (result.networkType && REMOTE_networkType.indexOf(result.networkType) === -1) { - REMOTE_networkType.push(result.networkType); + if (result.networkType && REMOTE_networkType[result.id].indexOf(result.networkType) === -1) { + REMOTE_networkType[result.id].push(result.networkType); } getStatsResult.internal.candidates[result.id] = { - candidateType: REMOTE_candidateType, - ipAddress: REMOTE_ipAddress, + candidateType: REMOTE_candidateType[result.id], + ipAddress: REMOTE_ipAddress[result.id], portNumber: result.portNumber, - networkType: REMOTE_networkType, + networkType: REMOTE_networkType[result.id], priority: result.priority, - transport: REMOTE_transport, + transport: REMOTE_transport[result.id], timestamp: result.timestamp, id: result.id, type: result.type }; - getStatsResult.connectionType.remote.candidateType = REMOTE_candidateType; - getStatsResult.connectionType.remote.ipAddress = REMOTE_ipAddress; - getStatsResult.connectionType.remote.networkType = REMOTE_networkType; - getStatsResult.connectionType.remote.transport = REMOTE_transport; + getStatsResult.connectionType.remote.candidateType = REMOTE_candidateType[result.id]; + getStatsResult.connectionType.remote.ipAddress = REMOTE_ipAddress[result.id]; + getStatsResult.connectionType.remote.networkType = REMOTE_networkType[result.id]; + getStatsResult.connectionType.remote.transport = REMOTE_transport[result.id]; }; getStatsParser.dataSentReceived = function(result) { diff --git a/getStats.min.js b/getStats.min.js index b6c5fb6..8df5b10 100644 --- a/getStats.min.js +++ b/getStats.min.js @@ -1,6 +1,6 @@ 'use strict'; -// Last time updated: 2017-08-13 4:33:11 PM UTC +// Last time updated: 2017-08-26 5:42:36 AM UTC // _______________ // getStats v1.0.4 @@ -12,4 +12,4 @@ // MIT License - www.WebRTC-Experiment.com/licence // -------------------------------------------------- -"use strict";window.getStats=function(mediaStreamTrack,callback,interval){function getStatsLooper(){getStatsWrapper(function(results){results.forEach(function(result){Object.keys(getStatsParser).forEach(function(key){"function"==typeof getStatsParser[key]&&getStatsParser[key](result)})});try{peer.iceConnectionState.search(/failed/gi)!==-1&&(nomore=!0)}catch(e){nomore=!0}nomore===!0&&(getStatsResult.datachannel&&(getStatsResult.datachannel.state="close"),getStatsResult.ended=!0),getStatsResult.results=results,callback(getStatsResult),nomore||void 0!=typeof interval&&interval&&setTimeout(getStatsLooper,interval||1e3)})}function getStatsWrapper(cb){"undefined"!=typeof window.InstallTrigger?peer.getStats(mediaStreamTrack,function(res){var items=[];res.forEach(function(r){items.push(r)}),cb(items)},cb):peer.getStats(function(res){var items=[];res.result().forEach(function(res){var item={};res.names().forEach(function(name){item[name]=res.stat(name)}),item.id=res.id,item.type=res.type,item.timestamp=res.timestamp,items.push(item)}),cb(items)})}var RTCPeerConnection=window.RTCPeerConnection||window.mozRTCPeerConnection||window.webkitRTCPeerConnection;"undefined"==typeof MediaStreamTrack&&(MediaStreamTrack={});var systemNetworkType=((navigator.connection||{}).type||"unknown").toString().toLowerCase(),getStatsResult={encryption:"sha-256",audio:{send:{tracks:[],codecs:[],availableBandwidth:0,streams:0},recv:{tracks:[],codecs:[],availableBandwidth:0,streams:0},bytesSent:0,bytesReceived:0},video:{send:{tracks:[],codecs:[],availableBandwidth:0,streams:0},recv:{tracks:[],codecs:[],availableBandwidth:0,streams:0},bytesSent:0,bytesReceived:0},results:{},connectionType:{systemNetworkType:systemNetworkType,systemIpAddress:"192.168.1.2",local:{candidateType:[],transport:[],ipAddress:[],networkType:[]},remote:{candidateType:[],transport:[],ipAddress:[],networkType:[]}},resolutions:{send:{width:0,height:0},recv:{width:0,height:0}},internal:{audio:{send:{},recv:{}},video:{send:{},recv:{}},candidates:{}},nomore:function(){nomore=!0}},getStatsParser={checkIfOfferer:function(result){"googLibjingleSession"===result.type&&(getStatsResult.isOfferer=result.googInitiator)}},peer=this;if(arguments[0]instanceof RTCPeerConnection){if(peer=arguments[0],navigator.mozGetUserMedia&&(mediaStreamTrack=arguments[1],callback=arguments[2],interval=arguments[3]),!(mediaStreamTrack instanceof MediaStreamTrack)&&navigator.mozGetUserMedia)throw"2nd argument is not instance of MediaStreamTrack."}else if(!(mediaStreamTrack instanceof MediaStreamTrack)&&navigator.mozGetUserMedia)throw"1st argument is not instance of MediaStreamTrack.";var nomore=!1;getStatsParser.datachannel=function(result){"datachannel"===result.type&&(getStatsResult.datachannel={state:result.state})},getStatsParser.googCertificate=function(result){"googCertificate"==result.type&&(getStatsResult.encryption=result.googFingerprintAlgorithm)};var AUDIO_codecs=["opus","isac","ilbc"];getStatsParser.checkAudioTracks=function(result){if(result.googCodecName&&"audio"===result.mediaType&&AUDIO_codecs.indexOf(result.googCodecName.toLowerCase())!==-1){var sendrecvType=result.id.split("_").pop();if(getStatsResult.audio[sendrecvType].codecs.indexOf(result.googCodecName)===-1&&getStatsResult.audio[sendrecvType].codecs.push(result.googCodecName),result.bytesSent){var kilobytes=0;if(result.bytesSent){getStatsResult.internal.audio[sendrecvType].prevBytesSent||(getStatsResult.internal.audio[sendrecvType].prevBytesSent=result.bytesSent);var bytes=result.bytesSent-getStatsResult.internal.audio[sendrecvType].prevBytesSent;getStatsResult.internal.audio[sendrecvType].prevBytesSent=result.bytesSent,kilobytes=bytes/1024}getStatsResult.audio[sendrecvType].availableBandwidth=kilobytes.toFixed(1)}if(result.bytesReceived){var kilobytes=0;if(result.bytesReceived){getStatsResult.internal.audio[sendrecvType].prevBytesReceived||(getStatsResult.internal.audio[sendrecvType].prevBytesReceived=result.bytesReceived);var bytes=result.bytesReceived-getStatsResult.internal.audio[sendrecvType].prevBytesReceived;getStatsResult.internal.audio[sendrecvType].prevBytesReceived=result.bytesReceived,kilobytes=bytes/1024}getStatsResult.audio[sendrecvType].availableBandwidth=kilobytes.toFixed(1)}getStatsResult.audio[sendrecvType].tracks.indexOf(result.googTrackId)===-1&&getStatsResult.audio[sendrecvType].tracks.push(result.googTrackId)}};var VIDEO_codecs=["vp9","vp8","h264"];getStatsParser.checkVideoTracks=function(result){if(result.googCodecName&&"video"===result.mediaType&&VIDEO_codecs.indexOf(result.googCodecName.toLowerCase())!==-1){var sendrecvType=result.id.split("_").pop();if(getStatsResult.video[sendrecvType].codecs.indexOf(result.googCodecName)===-1&&getStatsResult.video[sendrecvType].codecs.push(result.googCodecName),result.bytesSent){var kilobytes=0;getStatsResult.internal.video[sendrecvType].prevBytesSent||(getStatsResult.internal.video[sendrecvType].prevBytesSent=result.bytesSent);var bytes=result.bytesSent-getStatsResult.internal.video[sendrecvType].prevBytesSent;getStatsResult.internal.video[sendrecvType].prevBytesSent=result.bytesSent,kilobytes=bytes/1024}if(result.bytesReceived){var kilobytes=0;getStatsResult.internal.video[sendrecvType].prevBytesReceived||(getStatsResult.internal.video[sendrecvType].prevBytesReceived=result.bytesReceived);var bytes=result.bytesReceived-getStatsResult.internal.video[sendrecvType].prevBytesReceived;getStatsResult.internal.video[sendrecvType].prevBytesReceived=result.bytesReceived,kilobytes=bytes/1024}getStatsResult.video[sendrecvType].availableBandwidth=kilobytes.toFixed(1),result.googFrameHeightReceived&&result.googFrameWidthReceived&&(getStatsResult.resolutions[sendrecvType].width=result.googFrameWidthReceived,getStatsResult.resolutions[sendrecvType].height=result.googFrameHeightReceived),result.googFrameHeightSent&&result.googFrameWidthSent&&(getStatsResult.resolutions[sendrecvType].width=result.googFrameWidthSent,getStatsResult.resolutions[sendrecvType].height=result.googFrameHeightSent),getStatsResult.video[sendrecvType].tracks.indexOf(result.googTrackId)===-1&&getStatsResult.video[sendrecvType].tracks.push(result.googTrackId)}},getStatsParser.bweforvideo=function(result){"VideoBwe"===result.type&&(getStatsResult.video.bandwidth={googActualEncBitrate:result.googActualEncBitrate,googAvailableSendBandwidth:result.googAvailableSendBandwidth,googAvailableReceiveBandwidth:result.googAvailableReceiveBandwidth,googRetransmitBitrate:result.googRetransmitBitrate,googTargetEncBitrate:result.googTargetEncBitrate,googBucketDelay:result.googBucketDelay,googTransmitBitrate:result.googTransmitBitrate})},getStatsParser.googCandidatePair=function(result){if("googCandidatePair"===result.type&&"true"==result.googActiveConnection){getStatsResult.connectionType.local.ipAddress=result.googLocalAddress,getStatsResult.connectionType.remote.ipAddress=result.googRemoteAddress,getStatsResult.connectionType.transport=result.googTransportType;var localCandidate=getStatsResult.internal.candidates[result.localCandidateId];localCandidate&&localCandidate.ipAddress&&(getStatsResult.connectionType.systemIpAddress=localCandidate.ipAddress);var remoteCandidate=getStatsResult.internal.candidates[result.remoteCandidateId];remoteCandidate&&remoteCandidate.ipAddress&&(getStatsResult.connectionType.systemIpAddress=remoteCandidate.ipAddress)}};var LOCAL_candidateType=[],LOCAL_transport=[],LOCAL_ipAddress=[],LOCAL_networkType=[];getStatsParser.localcandidate=function(result){"localcandidate"===result.type&&(result.candidateType&&LOCAL_candidateType.indexOf(result.candidateType)===-1&&LOCAL_candidateType.push(result.candidateType),result.transport&&LOCAL_transport.indexOf(result.transport)===-1&&LOCAL_transport.push(result.transport),result.ipAddress&&LOCAL_ipAddress.indexOf(result.ipAddress+":"+result.portNumber)===-1&&LOCAL_ipAddress.push(result.ipAddress+":"+result.portNumber),result.networkType&&LOCAL_networkType.indexOf(result.networkType)===-1&&LOCAL_networkType.push(result.networkType),getStatsResult.internal.candidates[result.id]={candidateType:LOCAL_candidateType,ipAddress:LOCAL_ipAddress,portNumber:result.portNumber,networkType:LOCAL_networkType,priority:result.priority,transport:LOCAL_transport,timestamp:result.timestamp,id:result.id,type:result.type},getStatsResult.connectionType.local.candidateType=LOCAL_candidateType,getStatsResult.connectionType.local.ipAddress=LOCAL_ipAddress,getStatsResult.connectionType.local.networkType=LOCAL_networkType,getStatsResult.connectionType.local.transport=LOCAL_transport)};var REMOTE_candidateType=[],REMOTE_transport=[],REMOTE_ipAddress=[],REMOTE_networkType=[];getStatsParser.remotecandidate=function(result){"remotecandidate"===result.type&&(result.candidateType&&REMOTE_candidateType.indexOf(result.candidateType)===-1&&REMOTE_candidateType.push(result.candidateType),result.transport&&REMOTE_transport.indexOf(result.transport)===-1&&REMOTE_transport.push(result.transport),result.ipAddress&&REMOTE_ipAddress.indexOf(result.ipAddress+":"+result.portNumber)===-1&&REMOTE_ipAddress.push(result.ipAddress+":"+result.portNumber),result.networkType&&REMOTE_networkType.indexOf(result.networkType)===-1&&REMOTE_networkType.push(result.networkType),getStatsResult.internal.candidates[result.id]={candidateType:REMOTE_candidateType,ipAddress:REMOTE_ipAddress,portNumber:result.portNumber,networkType:REMOTE_networkType,priority:result.priority,transport:REMOTE_transport,timestamp:result.timestamp,id:result.id,type:result.type},getStatsResult.connectionType.remote.candidateType=REMOTE_candidateType,getStatsResult.connectionType.remote.ipAddress=REMOTE_ipAddress,getStatsResult.connectionType.remote.networkType=REMOTE_networkType,getStatsResult.connectionType.remote.transport=REMOTE_transport)},getStatsParser.dataSentReceived=function(result){!result.googCodecName||"video"!==result.mediaType&&"audio"!==result.mediaType||(result.bytesSent&&(getStatsResult[result.mediaType].bytesSent=parseInt(result.bytesSent)),result.bytesReceived&&(getStatsResult[result.mediaType].bytesReceived=parseInt(result.bytesReceived)))};var SSRC={audio:{send:[],recv:[]},video:{send:[],recv:[]}};getStatsParser.ssrc=function(result){if(result.googCodecName&&("video"===result.mediaType||"audio"===result.mediaType)&&"ssrc"===result.type){var sendrecvType=result.id.split("_").pop();SSRC[result.mediaType][sendrecvType].indexOf(result.ssrc)===-1&&SSRC[result.mediaType][sendrecvType].push(result.ssrc),getStatsResult[result.mediaType][sendrecvType].streams=SSRC[result.mediaType][sendrecvType].length}},getStatsLooper()}; \ No newline at end of file +"use strict";window.getStats=function(mediaStreamTrack,callback,interval){function getStatsLooper(){getStatsWrapper(function(results){results.forEach(function(result){Object.keys(getStatsParser).forEach(function(key){"function"==typeof getStatsParser[key]&&getStatsParser[key](result)}),"local-candidate"!==result.type&&"remote-candidate"!==result.type&&"candidate-pair"!==result.type});try{peer.iceConnectionState.search(/failed/gi)!==-1&&(nomore=!0)}catch(e){nomore=!0}nomore===!0&&(getStatsResult.datachannel&&(getStatsResult.datachannel.state="close"),getStatsResult.ended=!0),getStatsResult.results=results,callback(getStatsResult),nomore||void 0!=typeof interval&&interval&&setTimeout(getStatsLooper,interval||1e3)})}function getStatsWrapper(cb){"undefined"!=typeof window.InstallTrigger?peer.getStats(mediaStreamTrack,function(res){var items=[];res.forEach(function(r){items.push(r)}),cb(items)},cb):peer.getStats(function(res){var items=[];res.result().forEach(function(res){var item={};res.names().forEach(function(name){item[name]=res.stat(name)}),item.id=res.id,item.type=res.type,item.timestamp=res.timestamp,items.push(item)}),cb(items)})}var RTCPeerConnection=window.RTCPeerConnection||window.mozRTCPeerConnection||window.webkitRTCPeerConnection;"undefined"==typeof MediaStreamTrack&&(MediaStreamTrack={});var systemNetworkType=((navigator.connection||{}).type||"unknown").toString().toLowerCase(),getStatsResult={encryption:"sha-256",audio:{send:{tracks:[],codecs:[],availableBandwidth:0,streams:0},recv:{tracks:[],codecs:[],availableBandwidth:0,streams:0},bytesSent:0,bytesReceived:0},video:{send:{tracks:[],codecs:[],availableBandwidth:0,streams:0},recv:{tracks:[],codecs:[],availableBandwidth:0,streams:0},bytesSent:0,bytesReceived:0},bandwidth:{systemBandwidth:0,sentPerSecond:0,encodedPerSecond:0},results:{},connectionType:{systemNetworkType:systemNetworkType,systemIpAddress:"192.168.1.2",local:{candidateType:[],transport:[],ipAddress:[],networkType:[]},remote:{candidateType:[],transport:[],ipAddress:[],networkType:[]}},resolutions:{send:{width:0,height:0},recv:{width:0,height:0}},internal:{audio:{send:{},recv:{}},video:{send:{},recv:{}},candidates:{}},nomore:function(){nomore=!0}},getStatsParser={checkIfOfferer:function(result){"googLibjingleSession"===result.type&&(getStatsResult.isOfferer=result.googInitiator)}},peer=this;if(arguments[0]instanceof RTCPeerConnection){if(peer=arguments[0],navigator.mozGetUserMedia&&(mediaStreamTrack=arguments[1],callback=arguments[2],interval=arguments[3]),!(mediaStreamTrack instanceof MediaStreamTrack)&&navigator.mozGetUserMedia)throw"2nd argument is not instance of MediaStreamTrack."}else if(!(mediaStreamTrack instanceof MediaStreamTrack)&&navigator.mozGetUserMedia)throw"1st argument is not instance of MediaStreamTrack.";var nomore=!1;getStatsParser.datachannel=function(result){"datachannel"===result.type&&(getStatsResult.datachannel={state:result.state})},getStatsParser.googCertificate=function(result){"googCertificate"==result.type&&(getStatsResult.encryption=result.googFingerprintAlgorithm)};var AUDIO_codecs=["opus","isac","ilbc"];getStatsParser.checkAudioTracks=function(result){if(result.googCodecName&&"audio"===result.mediaType&&AUDIO_codecs.indexOf(result.googCodecName.toLowerCase())!==-1){var sendrecvType=result.id.split("_").pop();if(getStatsResult.audio[sendrecvType].codecs.indexOf(result.googCodecName)===-1&&getStatsResult.audio[sendrecvType].codecs.push(result.googCodecName),result.bytesSent){var kilobytes=0;if(result.bytesSent){getStatsResult.internal.audio[sendrecvType].prevBytesSent||(getStatsResult.internal.audio[sendrecvType].prevBytesSent=result.bytesSent);var bytes=result.bytesSent-getStatsResult.internal.audio[sendrecvType].prevBytesSent;getStatsResult.internal.audio[sendrecvType].prevBytesSent=result.bytesSent,kilobytes=bytes/1024}getStatsResult.audio[sendrecvType].availableBandwidth=kilobytes.toFixed(1)}if(result.bytesReceived){var kilobytes=0;if(result.bytesReceived){getStatsResult.internal.audio[sendrecvType].prevBytesReceived||(getStatsResult.internal.audio[sendrecvType].prevBytesReceived=result.bytesReceived);var bytes=result.bytesReceived-getStatsResult.internal.audio[sendrecvType].prevBytesReceived;getStatsResult.internal.audio[sendrecvType].prevBytesReceived=result.bytesReceived,kilobytes=bytes/1024}getStatsResult.audio[sendrecvType].availableBandwidth=kilobytes.toFixed(1)}getStatsResult.audio[sendrecvType].tracks.indexOf(result.googTrackId)===-1&&getStatsResult.audio[sendrecvType].tracks.push(result.googTrackId)}};var VIDEO_codecs=["vp9","vp8","h264"];getStatsParser.checkVideoTracks=function(result){if(result.googCodecName&&"video"===result.mediaType&&VIDEO_codecs.indexOf(result.googCodecName.toLowerCase())!==-1){var sendrecvType=result.id.split("_").pop();if(getStatsResult.video[sendrecvType].codecs.indexOf(result.googCodecName)===-1&&getStatsResult.video[sendrecvType].codecs.push(result.googCodecName),result.bytesSent){var kilobytes=0;getStatsResult.internal.video[sendrecvType].prevBytesSent||(getStatsResult.internal.video[sendrecvType].prevBytesSent=result.bytesSent);var bytes=result.bytesSent-getStatsResult.internal.video[sendrecvType].prevBytesSent;getStatsResult.internal.video[sendrecvType].prevBytesSent=result.bytesSent,kilobytes=bytes/1024}if(result.bytesReceived){var kilobytes=0;getStatsResult.internal.video[sendrecvType].prevBytesReceived||(getStatsResult.internal.video[sendrecvType].prevBytesReceived=result.bytesReceived);var bytes=result.bytesReceived-getStatsResult.internal.video[sendrecvType].prevBytesReceived;getStatsResult.internal.video[sendrecvType].prevBytesReceived=result.bytesReceived,kilobytes=bytes/1024}getStatsResult.video[sendrecvType].availableBandwidth=kilobytes.toFixed(1),result.googFrameHeightReceived&&result.googFrameWidthReceived&&(getStatsResult.resolutions[sendrecvType].width=result.googFrameWidthReceived,getStatsResult.resolutions[sendrecvType].height=result.googFrameHeightReceived),result.googFrameHeightSent&&result.googFrameWidthSent&&(getStatsResult.resolutions[sendrecvType].width=result.googFrameWidthSent,getStatsResult.resolutions[sendrecvType].height=result.googFrameHeightSent),getStatsResult.video[sendrecvType].tracks.indexOf(result.googTrackId)===-1&&getStatsResult.video[sendrecvType].tracks.push(result.googTrackId)}},getStatsParser.bweforvideo=function(result){"VideoBwe"===result.type&&(getStatsResult.bandwidth.availableSendBandwidth=result.googAvailableSendBandwidth,getStatsResult.bandwidth.googActualEncBitrate=result.googActualEncBitrate,getStatsResult.bandwidth.googAvailableSendBandwidth=result.googAvailableSendBandwidth,getStatsResult.bandwidth.googAvailableReceiveBandwidth=result.googAvailableReceiveBandwidth,getStatsResult.bandwidth.googRetransmitBitrate=result.googRetransmitBitrate,getStatsResult.bandwidth.googTargetEncBitrate=result.googTargetEncBitrate,getStatsResult.bandwidth.googBucketDelay=result.googBucketDelay,getStatsResult.bandwidth.googTransmitBitrate=result.googTransmitBitrate)},getStatsParser.candidatePair=function(result){if("googCandidatePair"===result.type||"candidate-pair"===result.type){if("true"==result.googActiveConnection){Object.keys(getStatsResult.internal.candidates).forEach(function(cid){var candidate=getStatsResult.internal.candidates[cid];candidate.ipAddress.indexOf(result.googLocalAddress)!==-1&&(getStatsResult.connectionType.local.candidateType=candidate.candidateType,getStatsResult.connectionType.local.ipAddress=candidate.ipAddress,getStatsResult.connectionType.local.networkType=candidate.networkType,getStatsResult.connectionType.local.transport=candidate.transport),candidate.ipAddress.indexOf(result.googRemoteAddress)!==-1&&(getStatsResult.connectionType.remote.candidateType=candidate.candidateType,getStatsResult.connectionType.remote.ipAddress=candidate.ipAddress,getStatsResult.connectionType.remote.networkType=candidate.networkType,getStatsResult.connectionType.remote.transport=candidate.transport)}),getStatsResult.connectionType.transport=result.googTransportType;var localCandidate=getStatsResult.internal.candidates[result.localCandidateId];localCandidate&&localCandidate.ipAddress&&(getStatsResult.connectionType.systemIpAddress=localCandidate.ipAddress);var remoteCandidate=getStatsResult.internal.candidates[result.remoteCandidateId];remoteCandidate&&remoteCandidate.ipAddress&&(getStatsResult.connectionType.systemIpAddress=remoteCandidate.ipAddress)}if("candidate-pair"===result.type&&result.selected===!0&&result.nominated===!0&&"succeeded"===result.state)var localCandidate=getStatsResult.internal.candidates[result.remoteCandidateId],remoteCandidate=getStatsResult.internal.candidates[result.remoteCandidateId]}};var LOCAL_candidateType={},LOCAL_transport={},LOCAL_ipAddress={},LOCAL_networkType={};getStatsParser.localcandidate=function(result){"localcandidate"!==result.type&&"local-candidate"!==result.type||result.id&&(LOCAL_candidateType[result.id]||(LOCAL_candidateType[result.id]=[]),LOCAL_transport[result.id]||(LOCAL_transport[result.id]=[]),LOCAL_ipAddress[result.id]||(LOCAL_ipAddress[result.id]=[]),LOCAL_networkType[result.id]||(LOCAL_networkType[result.id]=[]),result.candidateType&&LOCAL_candidateType[result.id].indexOf(result.candidateType)===-1&&LOCAL_candidateType[result.id].push(result.candidateType),result.transport&&LOCAL_transport[result.id].indexOf(result.transport)===-1&&LOCAL_transport[result.id].push(result.transport),result.ipAddress&&LOCAL_ipAddress[result.id].indexOf(result.ipAddress+":"+result.portNumber)===-1&&LOCAL_ipAddress[result.id].push(result.ipAddress+":"+result.portNumber),result.networkType&&LOCAL_networkType[result.id].indexOf(result.networkType)===-1&&LOCAL_networkType[result.id].push(result.networkType),getStatsResult.internal.candidates[result.id]={candidateType:LOCAL_candidateType[result.id],ipAddress:LOCAL_ipAddress[result.id],portNumber:result.portNumber,networkType:LOCAL_networkType[result.id],priority:result.priority,transport:LOCAL_transport[result.id],timestamp:result.timestamp,id:result.id,type:result.type},getStatsResult.connectionType.local.candidateType=LOCAL_candidateType[result.id],getStatsResult.connectionType.local.ipAddress=LOCAL_ipAddress[result.id],getStatsResult.connectionType.local.networkType=LOCAL_networkType[result.id],getStatsResult.connectionType.local.transport=LOCAL_transport[result.id])};var REMOTE_candidateType={},REMOTE_transport={},REMOTE_ipAddress={},REMOTE_networkType={};getStatsParser.remotecandidate=function(result){"remotecandidate"!==result.type&&"remote-candidate"!==result.type||result.id&&(REMOTE_candidateType[result.id]||(REMOTE_candidateType[result.id]=[]),REMOTE_transport[result.id]||(REMOTE_transport[result.id]=[]),REMOTE_ipAddress[result.id]||(REMOTE_ipAddress[result.id]=[]),REMOTE_networkType[result.id]||(REMOTE_networkType[result.id]=[]),result.candidateType&&REMOTE_candidateType[result.id].indexOf(result.candidateType)===-1&&REMOTE_candidateType[result.id].push(result.candidateType),result.transport&&REMOTE_transport[result.id].indexOf(result.transport)===-1&&REMOTE_transport[result.id].push(result.transport),result.ipAddress&&REMOTE_ipAddress[result.id].indexOf(result.ipAddress+":"+result.portNumber)===-1&&REMOTE_ipAddress[result.id].push(result.ipAddress+":"+result.portNumber),result.networkType&&REMOTE_networkType[result.id].indexOf(result.networkType)===-1&&REMOTE_networkType[result.id].push(result.networkType),getStatsResult.internal.candidates[result.id]={candidateType:REMOTE_candidateType[result.id],ipAddress:REMOTE_ipAddress[result.id],portNumber:result.portNumber,networkType:REMOTE_networkType[result.id],priority:result.priority,transport:REMOTE_transport[result.id],timestamp:result.timestamp,id:result.id,type:result.type},getStatsResult.connectionType.remote.candidateType=REMOTE_candidateType[result.id],getStatsResult.connectionType.remote.ipAddress=REMOTE_ipAddress[result.id],getStatsResult.connectionType.remote.networkType=REMOTE_networkType[result.id],getStatsResult.connectionType.remote.transport=REMOTE_transport[result.id])},getStatsParser.dataSentReceived=function(result){!result.googCodecName||"video"!==result.mediaType&&"audio"!==result.mediaType||(result.bytesSent&&(getStatsResult[result.mediaType].bytesSent=parseInt(result.bytesSent)),result.bytesReceived&&(getStatsResult[result.mediaType].bytesReceived=parseInt(result.bytesReceived)))};var SSRC={audio:{send:[],recv:[]},video:{send:[],recv:[]}};getStatsParser.ssrc=function(result){if(result.googCodecName&&("video"===result.mediaType||"audio"===result.mediaType)&&"ssrc"===result.type){var sendrecvType=result.id.split("_").pop();SSRC[result.mediaType][sendrecvType].indexOf(result.ssrc)===-1&&SSRC[result.mediaType][sendrecvType].push(result.ssrc),getStatsResult[result.mediaType][sendrecvType].streams=SSRC[result.mediaType][sendrecvType].length}},getStatsLooper()}; \ No newline at end of file diff --git a/index.html b/index.html index 9ac1369..4087fb0 100644 --- a/index.html +++ b/index.html @@ -1,4 +1,4 @@ - + @@ -100,7 +126,7 @@

- getStats.js Demo | Muaz Khan + getStats.js Demo | WebRTC getStats API

HOME @@ -117,79 +143,166 @@

+ + +
- -
-
- -

Offerer-to-Answerer

-

EncryptedAs:

-

Codecs send:

-

Codecs recv:

-

Local ICE type:

-

Remote ICE type:

-

Local Network type:

-

Remote Network type:

-

Local transport:

-

Remote transport:

- -

Sender IP:

-

Receiver IP:

-

System/Local IP:

- -

Audio Send bandwidth: kbps

-

Audio Recv bandwidth: kbps

-

Video Send bandwidth: kbps

-

Video Recv bandwidth: kbps

-

Video Send resolutions:

-

Video Recv resolutions:

-

Send tracks:

-

Recv tracks:

-

Total Data Sent:

-

Total Data Recv:

-
-
- -

Answerer-to-Offerer

-

EncryptedAs:

-

Codecs send:

-

Codecs recv:

-

Local ICE type:

-

Remote ICE type:

-

Local Network type:

-

Remote Network type:

-

Local transport:

-

Remote transport:

- -

Sender IP:

-

Receiver IP:

-

System/Local IP:

- -

Audio Send bandwidth: kbps

-

Audio Recv bandwidth: kbps

-

Video Send bandwidth: kbps

-

Video Recv bandwidth: kbps

-

Video Send resolutions:

-

Video Recv resolutions:

-

Send tracks:

-

Recv tracks:

-

Total Data Sent:

-

Total Data Recv:

-
-
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
First PeerSecond Peer
+ Videos + + + + +
Available Bandwidth
STUN/TURN? + ()
+ ()
+
+ ()
+ ()
+
Codecs +
+
+
+
+
+
Encryption
IP Address +
+ +
+
+ +
Resolutions +
+ +
+
+ +
Data +
+ +
+
+ +
+ +
+ Multi-user peer-to-peer demo: getStats using RTCMultiConnection +
+ + -
+

getStats Issues

-
+

Feedback

@@ -401,7 +521,7 @@

Feedback

Enter your email too; if you want "direct" reply!
-
+

Latest Updates

diff --git a/package.json b/package.json index 359211c..dc95c0c 100755 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "getstats", "preferGlobal": true, - "version": "1.0.4", + "version": "1.0.5", "author": { "name": "Muaz Khan", "email": "muazkh@gmail.com",