@rtcstats/rtcstats-js 2.2.4 → 2.4.0

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 CHANGED
@@ -9,6 +9,26 @@ an Experience Score, and a plain-English AI summary of what went wrong on the ca
9
9
  For a complete reference of every getStats() metric rtcstats collects and analyzes, see
10
10
  the [WebRTC Stats Reference](https://rtcstats.com/kb/webrtc-stats-reference-page).
11
11
 
12
+ ## Why rtcStats is built this way
13
+
14
+ rtcStats keeps collecting session data, storing it, and analyzing it separate. The
15
+ first two are open source and run in your stack. The third is optional and yours to
16
+ trigger.
17
+
18
+ - **Collection is a client SDK you control.** `rtcstats-js` runs in your client and
19
+ streams a dump of what WebRTC is doing to a server you run.
20
+ - **Storage runs on your infrastructure.** `rtcstats-server` receives the stream and
21
+ writes each dump to your own storage. Session data lands and lives in your stack.
22
+ - **Analysis is the layer you opt into.** You choose which stored dumps to send to
23
+ rtcstats.com: a random sample, per-user, per-region, a single dump when one call
24
+ goes bad, or none at all. rtcstats.com returns Observations, an Experience Score,
25
+ and a plain-English summary of what went wrong. It is the layer above
26
+ `webrtc-internals`, not a replacement for it.
27
+
28
+ Send what you want, keep the rest.
29
+
30
+ Start at https://rtcstats.com
31
+
12
32
  # rtcstats-js: A Javascript client SDK for monitoring WebRTC
13
33
 
14
34
  The Javascript SDK provides low-level logging on peerconnection API calls and periodic getStats calls for analytics/debugging purposes.
package/media.js CHANGED
@@ -10,7 +10,7 @@ import {compressMethod, dumpTrackWithStreams} from '@rtcstats/rtcstats-shared';
10
10
  * @param {string} property - the track whose property (e.g. `enabled`) should be wrapped.
11
11
  * @param {function} trace - RTCStats trace callback.
12
12
  */
13
- function wrapTrackProperty(track, property, trace) {
13
+ function wrapTrackProperty(track, property, trace, MediaStreamTrack) {
14
14
  const prop = Object.getOwnPropertyDescriptor(
15
15
  MediaStreamTrack.prototype, property);
16
16
  if (!prop || !prop.get || !prop.set) {
@@ -72,8 +72,8 @@ export function wrapGetUserMedia(trace, {navigator, MediaStreamTrack}) {
72
72
  track.addEventListener('ended', () => {
73
73
  trace('MediaStreamTrack.onended', null, track.id, track.__rtcStatsId);
74
74
  });
75
- wrapTrackProperty(track, 'enabled', trace);
76
- wrapTrackProperty(track, 'contentHint', trace);
75
+ wrapTrackProperty(track, 'enabled', trace, MediaStreamTrack);
76
+ wrapTrackProperty(track, 'contentHint', trace, MediaStreamTrack);
77
77
  });
78
78
  return stream;
79
79
  }, (err) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rtcstats/rtcstats-js",
3
- "version": "2.2.4",
3
+ "version": "2.4.0",
4
4
  "description": "gather WebRTC API traces and statistics",
5
5
  "main": "rtcstats.js",
6
6
  "type": "module",
package/peerconnection.js CHANGED
@@ -91,9 +91,8 @@ export function wrapRTCPeerConnection(trace, window, {getStatsInterval}) {
91
91
  }
92
92
  let lastComputePressureRecord;
93
93
  if (window.PressureObserver && getStatsInterval) {
94
- const observer = new PressureObserver((records) => {
95
- const lastRecord = records[records.length - 1]; // Usually only one record.
96
- lastComputePressureRecord = [Date.now(), lastRecord];
94
+ const observer = new window.PressureObserver((records) => {
95
+ lastComputePressureRecord = records[records.length - 1]; // Usually only one record.
97
96
  });
98
97
  observer.observe('cpu', {sampleInterval: getStatsInterval});
99
98
  }
@@ -148,14 +147,9 @@ export function wrapRTCPeerConnection(trace, window, {getStatsInterval}) {
148
147
  e.track.addEventListener('mute', () => {
149
148
  trace('MediaStreamTrack.onmute', pcId, e.track.id);
150
149
  });
151
- if (e.transceiver) {
152
- e.transceiver.__rtcStatsId = pcId;
153
- e.transceiver.sender.__rtcStatsId = pcId;
154
- e.transceiver.sender.__rtcStatsSenderId = e.track.id;
155
- }
156
- if (e.track.kind === 'video' && typeof document !== 'undefined' && document.querySelectorAll) {
150
+ if (e.track.kind === 'video' && window.document?.querySelectorAll) {
157
151
  setTimeout(() => {
158
- document.querySelectorAll('video').forEach(el => {
152
+ window.document.querySelectorAll('video').forEach(el => {
159
153
  if (!el.srcObject) return;
160
154
  if (el.srcObject.getTracks().indexOf(e.track) === -1) return;
161
155
  el.addEventListener('resize', () => {
@@ -199,10 +193,10 @@ export function wrapRTCPeerConnection(trace, window, {getStatsInterval}) {
199
193
  return;
200
194
  }
201
195
  if (lastComputePressureRecord) {
202
- const [timestamp, record] = lastComputePressureRecord;
196
+ const record = lastComputePressureRecord;
203
197
  stats['rtcStatsComputePressure'] = {
204
198
  type: 'compute-pressure',
205
- timestamp,
199
+ timestamp: window.performance.timeOrigin + record.time,
206
200
  cpuState: computePressureTable[record.state] || record.state,
207
201
  };
208
202
  }
@@ -376,6 +370,11 @@ export function wrapRTCPeerConnection(trace, window, {getStatsInterval}) {
376
370
 
377
371
  return nativeMethod.apply(this, [description, ...args])
378
372
  .then(() => {
373
+ this.getTransceivers().forEach((transceiver) => {
374
+ transceiver.__rtcStatsId = this.__rtcStatsId;
375
+ transceiver.sender.__rtcStatsId = this.__rtcStatsId;
376
+ transceiver.sender.__rtcStatsSenderId = transceiver.receiver.track.id;
377
+ });
379
378
  trace(method + 'OnSuccess', this.__rtcStatsId, undefined,
380
379
  trackingId);
381
380
  }, (err) => {
package/rtcstats.js CHANGED
@@ -7,15 +7,15 @@ import {WebSocketTrace} from './trace-websocket.js';
7
7
  *
8
8
  * @returns {function} RTCStats trace function.
9
9
  */
10
- export function wrapRTCStatsWithDefaultOptions(config = {getStatsInterval: 1000}) {
10
+ export function wrapRTCStatsWithDefaultOptions(config = {getStatsInterval: 1000}, target = globalThis) {
11
11
  const trace = new WebSocketTrace(config);
12
12
 
13
13
  // Wrap RTCPeerConnection-related APIs and events
14
- wrapRTCPeerConnection(trace, window, config);
14
+ wrapRTCPeerConnection(trace, target, config);
15
15
  // Wrap getUserMedia, getDisplayMedia and related events.
16
- wrapGetUserMedia(trace, window);
16
+ wrapGetUserMedia(trace, target);
17
17
  // Wrap enumerateDevices.
18
- wrapEnumerateDevices(trace, window);
18
+ wrapEnumerateDevices(trace, target);
19
19
 
20
20
  return trace;
21
21
  }
@@ -44,7 +44,6 @@ export function WebSocketTrace(config = {}) {
44
44
  buffer.push(args);
45
45
  }
46
46
  };
47
-
48
47
  trace.close = () => {
49
48
  if (window.sessionStorage && config.countReloads) {
50
49
  // A clean disconnect clears the reload count.
@@ -67,9 +66,10 @@ export function WebSocketTrace(config = {}) {
67
66
  hardwareConcurrency: navigator.hardwareConcurrency,
68
67
  userAgentData: navigator.userAgentData,
69
68
  deviceMemory: navigator.deviceMemory,
69
+ cpuPerformance: navigator.cpuPerformance,
70
70
  screen: {
71
- width: window.screen.availWidth,
72
- height: window.screen.availHeight,
71
+ width: window.screen?.availWidth,
72
+ height: window.screen?.availHeight,
73
73
  devicePixelRatio: window.devicePixelRatio,
74
74
  },
75
75
  window: {