@rtcstats/rtcstats-js 2.2.2 → 2.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -3
- package/media.js +3 -0
- package/package.json +1 -1
- package/peerconnection.js +11 -18
- package/trace-websocket.js +8 -8
package/README.md
CHANGED
|
@@ -3,7 +3,11 @@ This is part of the [monorepo](https://github.com/rtcstats/rtcstats) for rtcstat
|
|
|
3
3
|
dump-importer (supporting rtcstats and webrtc-internals formats).
|
|
4
4
|
|
|
5
5
|
It is part of a bigger offering that includes [rtcstats.com](https://rtcstats.com),
|
|
6
|
-
|
|
6
|
+
the hosted WebRTC observability service that reads collected dumps and returns Observations,
|
|
7
|
+
an Experience Score, and a plain-English AI summary of what went wrong on the call.
|
|
8
|
+
|
|
9
|
+
For a complete reference of every getStats() metric rtcstats collects and analyzes, see
|
|
10
|
+
the [WebRTC Stats Reference](https://rtcstats.com/kb/webrtc-stats-reference-page).
|
|
7
11
|
|
|
8
12
|
# rtcstats-js: A Javascript client SDK for monitoring WebRTC
|
|
9
13
|
|
|
@@ -71,6 +75,7 @@ trace(method name, e.g. `:userRating`,
|
|
|
71
75
|
* The trace function will internally add a timestamp to the event.
|
|
72
76
|
* rtcstats-server will not process such events by default.
|
|
73
77
|
* A dump-importer should still display a generic rendering of the event.
|
|
78
|
+
* Compression should not be used for custom methods.
|
|
74
79
|
|
|
75
80
|
### Using a JWT to connect to rtcstats-server
|
|
76
81
|
See [the server README](https://github.com/rtcstats/rtcstats/blob/main/packages/rtcstats-server/README.md) for how to
|
|
@@ -111,6 +116,7 @@ Note that RTCStats is not keeping track of whether all RTCPeerConnections have b
|
|
|
111
116
|
have been stopped.
|
|
112
117
|
|
|
113
118
|
### See also
|
|
114
|
-
|
|
115
|
-
the (internal) API docs [here](docs/index.md).
|
|
119
|
+
* the [end-to-end example](/example/) in `example/` directory and
|
|
120
|
+
* the (internal) API docs [here](docs/index.md) - note that these may not be fully up-to-date.
|
|
121
|
+
* the [WebRTC Stats Reference](https://rtcstats.com/kb/webrtc-stats-reference-page) which tells you what each getStats() metric means, expected values, and common issues.
|
|
116
122
|
|
package/media.js
CHANGED
|
@@ -13,6 +13,9 @@ import {compressMethod, dumpTrackWithStreams} from '@rtcstats/rtcstats-shared';
|
|
|
13
13
|
function wrapTrackProperty(track, property, trace) {
|
|
14
14
|
const prop = Object.getOwnPropertyDescriptor(
|
|
15
15
|
MediaStreamTrack.prototype, property);
|
|
16
|
+
if (!prop || !prop.get || !prop.set) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
16
19
|
|
|
17
20
|
// Replace the property with a custom one
|
|
18
21
|
Object.defineProperty(track, property, {
|
package/package.json
CHANGED
package/peerconnection.js
CHANGED
|
@@ -13,7 +13,7 @@ import {map2obj, dumpTrackWithStreams, copyAndSanitizeConfig} from '@rtcstats/rt
|
|
|
13
13
|
*
|
|
14
14
|
* @protected
|
|
15
15
|
* @param {function} trace - RTCStats trace callback
|
|
16
|
-
* @param {object} window - window object from which to take the RTCRtpTransceiver
|
|
16
|
+
* @param {object} window - window object from which to take the RTCRtpTransceiver prototype.
|
|
17
17
|
*/
|
|
18
18
|
function wrapRTCRtpTransceiver(trace, window) {
|
|
19
19
|
if (!window.RTCRtpTransceiver) {
|
|
@@ -31,13 +31,13 @@ function wrapRTCRtpTransceiver(trace, window) {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
|
-
* Wraps a
|
|
34
|
+
* Wraps a RTCRtpSender for RTCStats. Currently applied to these methods:
|
|
35
35
|
* * setParameters
|
|
36
|
-
* * replaceTrack
|
|
36
|
+
* * replaceTrack
|
|
37
37
|
*
|
|
38
38
|
* @protected
|
|
39
39
|
* @param {function} trace - RTCStats trace callback
|
|
40
|
-
* @param {object} window - window object from which to take the RTCRtpSender
|
|
40
|
+
* @param {object} window - window object from which to take the RTCRtpSender prototype.
|
|
41
41
|
*/
|
|
42
42
|
function wrapRTCRtpSender(trace, window) {
|
|
43
43
|
if (!window.RTCRtpSender) {
|
|
@@ -77,7 +77,7 @@ function wrapRTCRtpSender(trace, window) {
|
|
|
77
77
|
* Legacy methods and events are not wrapped.
|
|
78
78
|
*
|
|
79
79
|
* @param {function} trace - RTCStats trace callback
|
|
80
|
-
* @param {object} window - window object from which to take the RTCPeerConnection
|
|
80
|
+
* @param {object} window - window object from which to take the RTCPeerConnection prototype.
|
|
81
81
|
* @param {object} configuration - various configurable properties. Currently:
|
|
82
82
|
* * getStatsInterval {number} - interval at which getStats will be polled.
|
|
83
83
|
*/
|
|
@@ -90,7 +90,7 @@ export function wrapRTCPeerConnection(trace, window, {getStatsInterval}) {
|
|
|
90
90
|
return;
|
|
91
91
|
}
|
|
92
92
|
let lastComputePressureRecord;
|
|
93
|
-
if (window.PressureObserver) {
|
|
93
|
+
if (window.PressureObserver && getStatsInterval) {
|
|
94
94
|
const observer = new PressureObserver((records) => {
|
|
95
95
|
const lastRecord = records[records.length - 1]; // Usually only one record.
|
|
96
96
|
lastComputePressureRecord = [Date.now(), lastRecord];
|
|
@@ -153,7 +153,7 @@ export function wrapRTCPeerConnection(trace, window, {getStatsInterval}) {
|
|
|
153
153
|
e.transceiver.sender.__rtcStatsId = pcId;
|
|
154
154
|
e.transceiver.sender.__rtcStatsSenderId = e.track.id;
|
|
155
155
|
}
|
|
156
|
-
if (e.track.kind === 'video') {
|
|
156
|
+
if (e.track.kind === 'video' && typeof document !== 'undefined' && document.querySelectorAll) {
|
|
157
157
|
setTimeout(() => {
|
|
158
158
|
document.querySelectorAll('video').forEach(el => {
|
|
159
159
|
if (!el.srcObject) return;
|
|
@@ -188,7 +188,7 @@ export function wrapRTCPeerConnection(trace, window, {getStatsInterval}) {
|
|
|
188
188
|
let statsInterval;
|
|
189
189
|
const statsIdMap = {};
|
|
190
190
|
const getStats = async (reason) => {
|
|
191
|
-
if (pc.signalingState === 'closed') {
|
|
191
|
+
if (pc.signalingState === 'closed' || pc.connectionState === 'closed') {
|
|
192
192
|
if (statsInterval) {
|
|
193
193
|
window.clearInterval(statsInterval);
|
|
194
194
|
}
|
|
@@ -279,7 +279,7 @@ export function wrapRTCPeerConnection(trace, window, {getStatsInterval}) {
|
|
|
279
279
|
}
|
|
280
280
|
trace(method, this.__rtcStatsId, serializedArgs);
|
|
281
281
|
const transceiver = nativeMethod.apply(this, [trackOrKind, ...args]);
|
|
282
|
-
transceiver.__rtcStatsId =
|
|
282
|
+
transceiver.__rtcStatsId = this.__rtcStatsId;
|
|
283
283
|
transceiver.sender.__rtcStatsId = this.__rtcStatsId;
|
|
284
284
|
transceiver.sender.__rtcStatsSenderId = transceiver.receiver.track.id;
|
|
285
285
|
trace(method + 'OnSuccess', this.__rtcStatsId, null, transceiver.receiver.track.id);
|
|
@@ -393,10 +393,9 @@ export function wrapRTCPeerConnection(trace, window, {getStatsInterval}) {
|
|
|
393
393
|
const trackingId = compressMethod(method) + '-' + (counters[method]++);
|
|
394
394
|
trace(method, this.__rtcStatsId, args[0], trackingId);
|
|
395
395
|
return nativeMethod.apply(this, args)
|
|
396
|
-
.then((
|
|
396
|
+
.then(() => {
|
|
397
397
|
trace(method + 'OnSuccess', this.__rtcStatsId, undefined,
|
|
398
398
|
trackingId);
|
|
399
|
-
return description;
|
|
400
399
|
}, (err) => {
|
|
401
400
|
trace(method + 'OnFailure', this.__rtcStatsId, err.toString(),
|
|
402
401
|
trackingId);
|
|
@@ -417,13 +416,7 @@ export function wrapRTCPeerConnection(trace, window, {getStatsInterval}) {
|
|
|
417
416
|
|
|
418
417
|
// wrap static methods. Currently just generateCertificate.
|
|
419
418
|
if (OrigPeerConnection.generateCertificate) {
|
|
420
|
-
|
|
421
|
-
get(...args) {
|
|
422
|
-
return args.length ?
|
|
423
|
-
OrigPeerConnection.generateCertificate.apply(null, args)
|
|
424
|
-
: OrigPeerConnection.generateCertificate;
|
|
425
|
-
},
|
|
426
|
-
});
|
|
419
|
+
RTCStatsPeerConnection.generateCertificate = OrigPeerConnection.generateCertificate;
|
|
427
420
|
}
|
|
428
421
|
window.RTCPeerConnection = RTCStatsPeerConnection;
|
|
429
422
|
window.RTCPeerConnection.prototype = OrigPeerConnection.prototype;
|
package/trace-websocket.js
CHANGED
|
@@ -14,11 +14,8 @@ export function WebSocketTrace(config = {}) {
|
|
|
14
14
|
// on that does not require listening for onload etc.
|
|
15
15
|
let reloadCount = undefined;
|
|
16
16
|
if (window.sessionStorage && config.countReloads) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
reloadCount = -1;
|
|
20
|
-
}
|
|
21
|
-
reloadCount = parseInt(reloadCount, 10) + 1;
|
|
17
|
+
const stored = parseInt(window.sessionStorage.getItem(RELOAD_COUNT_KEY), 10);
|
|
18
|
+
reloadCount = Number.isNaN(stored) ? 0 : stored + 1;
|
|
22
19
|
window.sessionStorage.setItem(RELOAD_COUNT_KEY, reloadCount);
|
|
23
20
|
}
|
|
24
21
|
const trace = function(...args) {
|
|
@@ -56,14 +53,15 @@ export function WebSocketTrace(config = {}) {
|
|
|
56
53
|
if (connection) {
|
|
57
54
|
connection.close();
|
|
58
55
|
connection = null;
|
|
56
|
+
// New traces need to get an absolute timestamp.
|
|
57
|
+
lastTime = 0;
|
|
59
58
|
}
|
|
60
|
-
// New traces need to get an absolute timestamp.
|
|
61
|
-
lastTime = 0;
|
|
62
59
|
};
|
|
63
60
|
trace.connect = (wsURL) => {
|
|
64
61
|
if (connection) {
|
|
65
62
|
connection.close();
|
|
66
63
|
lastTime = 0;
|
|
64
|
+
connection = null;
|
|
67
65
|
}
|
|
68
66
|
trace('create', null, {
|
|
69
67
|
hardwareConcurrency: navigator.hardwareConcurrency,
|
|
@@ -83,7 +81,9 @@ export function WebSocketTrace(config = {}) {
|
|
|
83
81
|
connectionStartTime = Date.now();
|
|
84
82
|
connection = new WebSocket(wsURL, 'rtcstats#' + PROTOCOL_VERSION);
|
|
85
83
|
connection.addEventListener('error', (e) => {
|
|
86
|
-
|
|
84
|
+
if (config.log) {
|
|
85
|
+
config.log('rtcstats websocket connection error', e, connection.readyState);
|
|
86
|
+
}
|
|
87
87
|
});
|
|
88
88
|
|
|
89
89
|
connection.addEventListener('close', (e) => {
|