Socket
Socket
Sign inDemoInstall

getstats

Package Overview
Dependencies
0
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    getstats

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 published
Weekly downloads
2.3K
decreased by-10.33%
Maintainers
1
Install size
112 kB
Created
Weekly downloads
 

Readme

Source

getStats.js | WebRTC getStats API

Single Page Demo or Multi User P2P Demo

npm downloads Build Status: Linux

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.

It is MIT Licenced, which means that you can use it in any commercial/non-commercial product, free of cost.

getStats

npm install getstats

cd node_modules
cd getstats
node server.js

# and open:
# http://localhost:9999/

To use it:

<script src="./node_modules/getstats/getStats.js"></script>
<script src="https://cdn.webrtc-experiment.com/getStats.js"></script>

<!-- or min.js -->
<script src="https://cdn.webrtc-experiment.com/getStats.min.js"></script>

<!-- or without CDN -->
<script src="https://www.webrtc-experiment.com/getStats.js"></script>

<!-- or rawgit -->
<script src="https://rawgit.com/muaz-khan/getStats/master/getStats.js"></script>

Or link specific build:

Or:

const getStats = require('getstats');
import { getStats} from 'getstats';

Usage

var rtcPeerConnection = new RTCPeerConnection(rtcConfig);

var repeatInterval = 2000; // 2000 ms == 2 seconds
getStats(rtcPeerConnection, function(result) {
    result.connectionType.remote.ipAddress
    result.connectionType.remote.candidateType
    result.connectionType.transport
    
    result.bandwidth.speed // bandwidth download speed (bytes per second)
    
    // to access native "results" array
    result.results.forEach(function(item) {
        if (item.type === 'ssrc' && item.transportId === 'Channel-audio-1') {
            var packetsLost = item.packetsLost;
            var packetsSent = item.packetsSent;
            var audioInputLevel = item.audioInputLevel;
            var trackId = item.googTrackId; // media stream track id
            var isAudio = item.mediaType === 'audio'; // audio or video
            var isSending = item.id.indexOf('_send') !== -1; // sender or receiver

            console.log('SendRecv type', item.id.split('_send').pop());
            console.log('MediaStream track type', item.mediaType);
        }
    });
}, repeatInterval);

Safari?

var audioTrack = stream.getTracks().filter(function(t) {
    return t.kind === 'audio';
});

getStats(peer, audioTrack, function(results) {
    // rest goes here
}, 5 * 1000);

result.datachannel

// states => open or close
alert(result.datachannel.state === 'open');

result.isOfferer

Offerer is the person who invoked createOffer method.

result.encryption

To detect which tech is used to encrypt your connections.

alert(result.encryption === 'sha-256');

result.nomore()

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

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

result.bandwidth

You can use result.bandwidth.speed to detect your system's available download speed.

{
    "speed": 25191,
    "systemBandwidth": 0,
    "sentPerSecond": 0,
    "encodedPerSecond": 0,
    "helper": {
        "audioBytesSent": 103053,
        "videoBytestSent": 0,
        "videoBytesSent": 4316619
    },
    "availableSendBandwidth": "5181906",
    "googActualEncBitrate": "294608",
    "googAvailableSendBandwidth": "5181906",
    "googAvailableReceiveBandwidth": "0",
    "googRetransmitBitrate": "0",
    "googTargetEncBitrate": "1700000",
    "googBucketDelay": "0",
    "googTransmitBitrate": "198296"
}

result.audio

{
    "send": {
        "tracks": ["ab5be64a-00b0-4c69-9ffa-b934a3cdaf92"],
        "codecs": ["opus"],
        "availableBandwidth": "0.4",
        "streams": 1
    },
    "recv": {
        "tracks": ["ab5be64a-00b0-4c69-9ffa-b934a3cdaf92"],
        "codecs": ["opus"],
        "availableBandwidth": "0.4",
        "streams": 1
    },
    "bytesSent": 103053,
    "bytesReceived": 103053
}

result.video

{
    "send": {
        "tracks": ["c07bbd24-4e99-4b94-b429-5174370f8d12"],
        "codecs": ["VP9"],
        "availableBandwidth": "24.2",
        "streams": 1
    },
    "recv": {
        "tracks": ["c07bbd24-4e99-4b94-b429-5174370f8d12"],
        "codecs": ["VP9"],
        "availableBandwidth": "25.5",
        "streams": 1
    },
    "bytesSent": 4316619,
    "bytesReceived": 4294692
}

result.connectionType

{
    "systemNetworkType": "wifi",
    "systemIpAddress": ["192.168.1.2:66666"],
    "local": {
        "candidateType": ["host"],
        "transport": ["udp"],
        "ipAddress": ["192.168.1.2:66666"],
        "networkType": ["wlan"]
    },
    "remote": {
        "candidateType": ["host"],
        "transport": ["udp"],
        "ipAddress": ["192.168.1.2:66666"],
        "networkType": []
    },
    "transport": "udp"
}

result.resolutions

{
    "send": {
        "width": "640",
        "height": "480"
    },
    "recv": {
        "width": "640",
        "height": "480"
    }
}

result.results

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

// "getStatsResult" is your "result" object
getStatsResult.results.forEach(function(item) {
    if (item.type === 'ssrc' && item.transportId === 'Channel-audio-1') {
        var packetsLost = item.packetsLost;
        var packetsSent = item.packetsSent;
        var audioInputLevel = item.audioInputLevel;
        var trackId = item.googTrackId; // media stream track id
        var isAudio = item.mediaType === 'audio'; // audio or video
        var isSending = item.id.indexOf('_send') !== -1; // sender or receiver

        console.log('SendRecv type', item.id.split('_send').pop());
        console.log('MediaStream track type', item.mediaType);
    }
});

Above array looks like this:

[{
    "googTrackId": "ab5be64a-00b0-4c69-9ffa-b934a3cdaf92",
    "id": "googTrack_ab5be64a-00b0-4c69-9ffa-b934a3cdaf92",
    "type": "googTrack",
    "timestamp": "2017-11-21T04:10:10.905Z"
}, {
    "googInitiator": "true",
    "id": "googLibjingleSession_2403774673032347671",
    "type": "googLibjingleSession",
    "timestamp": "2017-11-21T04:10:10.905Z"
}, {
    "googActualEncBitrate": "294608",
    "googAvailableSendBandwidth": "5181906",
    "googRetransmitBitrate": "0",
    "googAvailableReceiveBandwidth": "0",
    "googTargetEncBitrate": "1700000",
    "googBucketDelay": "0",
    "googTransmitBitrate": "198296",
    "id": "bweforvideo",
    "type": "VideoBwe",
    "timestamp": "2017-11-21T04:10:10.905Z"
}, {
    "googTrackId": "c07bbd24-4e99-4b94-b429-5174370f8d12",
    "id": "googTrack_c07bbd24-4e99-4b94-b429-5174370f8d12",
    "type": "googTrack",
    "timestamp": "2017-11-21T04:10:10.905Z"
}, {
    "googFingerprint": "8B:---:70",
    "googFingerprintAlgorithm": "sha-256",
    "googDerBase64": "MII----FdhT",
    "id": "googCertificate_8B:---:70",
    "type": "googCertificate",
    "timestamp": "2017-11-21T04:10:10.905Z"
}, {
    "googFingerprint": "EE:---:80",
    "googFingerprintAlgorithm": "sha-256",
    "googDerBase64": "MI----kr",
    "id": "googCertificate_EE:13:---:80",
    "type": "googCertificate",
    "timestamp": "2017-11-21T04:10:10.905Z"
}, {
    "googComponent": "1",
    "remoteCertificateId": "googCertificate_EE:---:80",
    "selectedCandidatePairId": "Conn-audio-1-0",
    "dtlsCipher": "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
    "localCertificateId": "googCertificate_8B:---:70",
    "srtpCipher": "AES_CM_128_HMAC_SHA1_32",
    "id": "Channel-audio-1",
    "type": "googComponent",
    "timestamp": "2017-11-21T04:10:10.905Z"
}, {
    "responsesSent": "12",
    "requestsReceived": "12",
    "googRemoteCandidateType": "local",
    "googReadable": "true",
    "googLocalAddress": "192.168.1.2:61885",
    "consentRequestsSent": "1",
    "googTransportType": "udp",
    "googChannelId": "Channel-audio-1",
    "googLocalCandidateType": "local",
    "googWritable": "true",
    "requestsSent": "12",
    "googRemoteAddress": "192.168.1.2:60256",
    "googRtt": "0",
    "googActiveConnection": "true",
    "packetsDiscardedOnSend": "0",
    "bytesReceived": "4455306",
    "responsesReceived": "12",
    "remoteCandidateId": "Cand-aws75dws",
    "localCandidateId": "Cand-4hzYq0su",
    "bytesSent": "4466782",
    "packetsSent": "5437",
    "id": "Conn-audio-1-0",
    "type": "googCandidatePair",
    "timestamp": "2017-11-21T04:10:10.905Z"
}, {
    "portNumber": "61885",
    "networkType": "wlan",
    "ipAddress": "192.168.1.2",
    "transport": "udp",
    "candidateType": "host",
    "priority": "2122260223",
    "id": "Cand-4hzYq0su",
    "type": "localcandidate",
    "timestamp": "2017-11-21T04:09:48.850Z"
}, {
    "portNumber": "60256",
    "ipAddress": "192.168.1.2",
    "transport": "udp",
    "candidateType": "host",
    "priority": "2122260223",
    "id": "Cand-aws75dws",
    "type": "remotecandidate",
    "timestamp": "2017-11-21T04:09:48.850Z"
}, {
    "googDecodingCTN": "2206",
    "packetsLost": "0",
    "googSecondaryDecodedRate": "0",
    "googDecodingPLC": "21",
    "packetsReceived": "1056",
    "googExpandRate": "0.900574",
    "googJitterReceived": "1",
    "googDecodingCNG": "0",
    "ssrc": "3719978459",
    "googPreferredJitterBufferMs": "20",
    "googSpeechExpandRate": "0.178711",
    "totalSamplesDuration": "22.06",
    "totalAudioEnergy": "0",
    "transportId": "Channel-audio-1",
    "mediaType": "audio",
    "googDecodingPLCCNG": "72",
    "googCodecName": "opus",
    "googSecondaryDiscardedRate": "0",
    "googDecodingNormal": "2113",
    "googTrackId": "ab5be64a-00b0-4c69-9ffa-b934a3cdaf92",
    "audioOutputLevel": "0",
    "googAccelerateRate": "0",
    "bytesReceived": "103053",
    "googCurrentDelayMs": "61",
    "googDecodingCTSG": "0",
    "googCaptureStartNtpTimeMs": "3720226188883",
    "googPreemptiveExpandRate": "0",
    "googJitterBufferMs": "5",
    "googDecodingMuted": "71",
    "id": "ssrc_3719978459_recv",
    "type": "ssrc",
    "timestamp": "2017-11-21T04:10:10.905Z"
}, {
    "audioInputLevel": "38",
    "packetsLost": "0",
    "googTrackId": "ab5be64a-00b0-4c69-9ffa-b934a3cdaf92",
    "googRtt": "1",
    "googResidualEchoLikelihoodRecentMax": "0",
    "googEchoCancellationReturnLossEnhancement": "-100",
    "totalSamplesDuration": "0",
    "googCodecName": "opus",
    "transportId": "Channel-audio-1",
    "mediaType": "audio",
    "aecDivergentFilterFraction": "0",
    "googEchoCancellationReturnLoss": "-100",
    "googResidualEchoLikelihood": "0",
    "googEchoCancellationQualityMin": "0",
    "totalAudioEnergy": "0",
    "ssrc": "4057371623",
    "googJitterReceived": "1",
    "googTypingNoiseState": "false",
    "packetsSent": "1056",
    "bytesSent": "103053",
    "id": "ssrc_4057371623_send",
    "type": "ssrc",
    "timestamp": "2017-11-21T04:10:10.905Z"
}, {
    "googContentType": "realtime",
    "googCaptureStartNtpTimeMs": "3720226188863",
    "googTargetDelayMs": "28",
    "packetsLost": "0",
    "googDecodeMs": "3",
    "googFrameHeightReceived": "480",
    "googFrameRateOutput": "2",
    "packetsReceived": "3843",
    "ssrc": "2926085704",
    "googRenderDelayMs": "10",
    "googMaxDecodeMs": "4",
    "googTrackId": "c07bbd24-4e99-4b94-b429-5174370f8d12",
    "googFrameWidthReceived": "640",
    "codecImplementationName": "libvpx",
    "transportId": "Channel-audio-1",
    "mediaType": "video",
    "googTimingFrameInfo": "2498355253,490771956,490771960,490771967,490771967,490771974,0,1",
    "googInterframeDelayMax": "67",
    "googCodecName": "VP9",
    "googFrameRateReceived": "2",
    "qpSum": "35281",
    "framesDecoded": "348",
    "googNacksSent": "0",
    "googFirsSent": "0",
    "bytesReceived": "4294692",
    "googCurrentDelayMs": "28",
    "googMinPlayoutDelayMs": "0",
    "googFrameRateDecoded": "2",
    "googJitterBufferMs": "14",
    "googPlisSent": "0",
    "id": "ssrc_2926085704_recv",
    "type": "ssrc",
    "timestamp": "2017-11-21T04:10:10.905Z"
}, {
    "googFrameWidthSent": "640",
    "packetsLost": "0",
    "googRtt": "1",
    "googEncodeUsagePercent": "19",
    "googCpuLimitedResolution": "false",
    "googNacksReceived": "0",
    "googBandwidthLimitedResolution": "false",
    "googPlisReceived": "0",
    "googAvgEncodeMs": "7",
    "googTrackId": "c07bbd24-4e99-4b94-b429-5174370f8d12",
    "googFrameRateInput": "2",
    "framesEncoded": "348",
    "codecImplementationName": "libvpx",
    "transportId": "Channel-audio-1",
    "mediaType": "video",
    "googFrameHeightSent": "480",
    "googFrameRateSent": "18",
    "googCodecName": "VP9",
    "qpSum": "35291",
    "googAdaptationChanges": "0",
    "ssrc": "3181351409",
    "googFirsReceived": "0",
    "packetsSent": "3884",
    "bytesSent": "4316619",
    "id": "ssrc_3181351409_send",
    "type": "ssrc",
    "timestamp": "2017-11-21T04:10:10.905Z"
}]

Disclaimer

There is no warranty, expressed or implied, associated with this product. Use at your own risk.

License

getStats.js is released under MIT licence . Copyright (c) Muaz Khan.

Keywords

FAQs

Last updated on 20 Feb 2019

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc