@flashphoner/websdk 2.0.274 → 2.0.276
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/docTemplate/README.md +1 -1
- package/flashphoner-no-flash.js +19697 -11620
- package/flashphoner-no-flash.min.js +3 -3
- package/flashphoner-no-webrtc.js +19666 -11593
- package/flashphoner-no-webrtc.min.js +3 -3
- package/flashphoner-no-wsplayer.js +18916 -10839
- package/flashphoner-no-wsplayer.min.js +3 -3
- package/flashphoner-room-api-webrtc-only.js +16370 -8293
- package/flashphoner-room-api-webrtc-only.min.js +2 -2
- package/flashphoner-room-api.js +9725 -1763
- package/flashphoner-room-api.min.js +4 -4
- package/flashphoner-temasys-flash-websocket-without-adapterjs.js +20669 -12596
- package/flashphoner-temasys-flash-websocket.js +20666 -12593
- package/flashphoner-temasys-flash-websocket.min.js +3 -3
- package/flashphoner-webrtc-only.js +18941 -10864
- package/flashphoner-webrtc-only.min.js +2 -2
- package/flashphoner.js +19697 -11620
- package/flashphoner.min.js +3 -3
- package/package.json +2 -1
- package/src/flashphoner-core.js +63 -39
- package/src/stats-collector.js +0 -528
- package/src/util.js +0 -47
- package/src/webrtc-media-provider.js +5 -0
package/src/stats-collector.js
CHANGED
|
@@ -1,528 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const util = require('./util');
|
|
4
|
-
const LOG_PREFIX = "stats-collector";
|
|
5
|
-
const CONNECTION_TYPE = {
|
|
6
|
-
WEBSOCKET: "ws",
|
|
7
|
-
HTTP: "http"
|
|
8
|
-
}
|
|
9
|
-
const MAX_SEND_ERRORS = 3;
|
|
10
|
-
const CONNECTION_STATUS = {
|
|
11
|
-
INIT: 0,
|
|
12
|
-
OK: 200,
|
|
13
|
-
BAD_REQUEST: 400,
|
|
14
|
-
INTERNAL_SERVER_ERROR: 500
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
// Collect and send WebRTC statistics periodically
|
|
18
|
-
const StreamStatsCollector = function(description, id, mediaConnection, wsConnection, logger, maxErrors) {
|
|
19
|
-
let statCollector = {
|
|
20
|
-
description: description,
|
|
21
|
-
id: id,
|
|
22
|
-
mediaConnection: mediaConnection,
|
|
23
|
-
connection: Connection(wsConnection, maxErrors),
|
|
24
|
-
logger: getLogger(logger),
|
|
25
|
-
headers: "",
|
|
26
|
-
compression: "none",
|
|
27
|
-
metricsBatch: null,
|
|
28
|
-
timer: null,
|
|
29
|
-
batchCount: 0,
|
|
30
|
-
timerBusy: false,
|
|
31
|
-
start: async function() {
|
|
32
|
-
let error = "Can't collect WebRTC stats to send: ";
|
|
33
|
-
if (!statCollector.description.types) {
|
|
34
|
-
throw new Error(error + "no report types defined");
|
|
35
|
-
}
|
|
36
|
-
if (!statCollector.description.sampling) {
|
|
37
|
-
throw new Error(error + "no sampling interval defined");
|
|
38
|
-
}
|
|
39
|
-
if (!statCollector.description.batchSize) {
|
|
40
|
-
throw new Error(error + "no metrics batch size defined");
|
|
41
|
-
}
|
|
42
|
-
if (!statCollector.mediaConnection) {
|
|
43
|
-
throw new Error(error + "no media connection available");
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
statCollector.logger.debug(LOG_PREFIX, "RTCMetricsServerDescription: " + JSON.stringify(statCollector.description));
|
|
47
|
-
if (statCollector.description.ingestPoint) {
|
|
48
|
-
let authHeader = null;
|
|
49
|
-
if (statCollector.description.authorization) {
|
|
50
|
-
authHeader = {
|
|
51
|
-
Authorization: statCollector.description.authorization
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
statCollector.connection.setUp(statCollector.description.ingestPoint, authHeader);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
await statCollector.updateHeaders();
|
|
58
|
-
await statCollector.updateCompression();
|
|
59
|
-
await statCollector.sendHeaders();
|
|
60
|
-
if (statCollector.description.collect === "on") {
|
|
61
|
-
statCollector.collect(true);
|
|
62
|
-
}
|
|
63
|
-
},
|
|
64
|
-
collect: function(enable) {
|
|
65
|
-
if (enable && statCollector.connection.status === CONNECTION_STATUS.OK) {
|
|
66
|
-
statCollector.startTimer();
|
|
67
|
-
} else {
|
|
68
|
-
statCollector.stopTimer();
|
|
69
|
-
}
|
|
70
|
-
},
|
|
71
|
-
stop: function() {
|
|
72
|
-
statCollector.stopTimer();
|
|
73
|
-
statCollector.headers = "";
|
|
74
|
-
},
|
|
75
|
-
update: async function(description) {
|
|
76
|
-
if (!description) {
|
|
77
|
-
statCollector.logger.error(LOG_PREFIX + "-" + statCollector.id, "Can't update WebRTC metrics sending: no parameters passed");
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
statCollector.logger.debug(LOG_PREFIX, "New RTCMetricsServerDescription: " + JSON.stringify(description));
|
|
81
|
-
if (description.types || description.compression) {
|
|
82
|
-
statCollector.stop();
|
|
83
|
-
if (description.types) {
|
|
84
|
-
statCollector.description.types = description.types;
|
|
85
|
-
await statCollector.updateHeaders();
|
|
86
|
-
}
|
|
87
|
-
if (description.compression) {
|
|
88
|
-
statCollector.description.compression = description.compression;
|
|
89
|
-
await statCollector.updateCompression();
|
|
90
|
-
}
|
|
91
|
-
await statCollector.sendHeaders();
|
|
92
|
-
if (statCollector.connection.status !== CONNECTION_STATUS.OK) {
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
} else {
|
|
96
|
-
statCollector.collect(false);
|
|
97
|
-
}
|
|
98
|
-
if (description.batchSize) {
|
|
99
|
-
statCollector.description.batchSize = description.batchSize;
|
|
100
|
-
}
|
|
101
|
-
if (description.sampling) {
|
|
102
|
-
statCollector.description.sampling = description.sampling;
|
|
103
|
-
}
|
|
104
|
-
if (description.collect) {
|
|
105
|
-
statCollector.description.collect = description.collect;
|
|
106
|
-
}
|
|
107
|
-
switch(statCollector.description.collect) {
|
|
108
|
-
case "on":
|
|
109
|
-
statCollector.collect(true);
|
|
110
|
-
break;
|
|
111
|
-
case "off":
|
|
112
|
-
statCollector.collect(false);
|
|
113
|
-
break;
|
|
114
|
-
}
|
|
115
|
-
},
|
|
116
|
-
updateHeaders: async function(stats = null) {
|
|
117
|
-
let currentHeaders = "";
|
|
118
|
-
let headersChanged = false;
|
|
119
|
-
if (stats === null) {
|
|
120
|
-
stats = await statCollector.mediaConnection.getWebRTCStats();
|
|
121
|
-
}
|
|
122
|
-
Object.keys(statCollector.description.types).forEach((type) => {
|
|
123
|
-
let typeDescriptor = statCollector.description.types[type];
|
|
124
|
-
let metricsString = "";
|
|
125
|
-
let contentFilters = null;
|
|
126
|
-
if (typeDescriptor.metrics) {
|
|
127
|
-
metricsString = typeDescriptor.metrics;
|
|
128
|
-
}
|
|
129
|
-
if (typeDescriptor.contains) {
|
|
130
|
-
contentFilters = typeDescriptor.contains;
|
|
131
|
-
}
|
|
132
|
-
if (stats[type]) {
|
|
133
|
-
stats[type].forEach((report) => {
|
|
134
|
-
statCollector.logger.debug(LOG_PREFIX + "-" + statCollector.id, type + " report: " + JSON.stringify(report));
|
|
135
|
-
if (contentFilters) {
|
|
136
|
-
let filtersMatched = true;
|
|
137
|
-
for (const filter in contentFilters) {
|
|
138
|
-
statCollector.logger.debug(LOG_PREFIX + "-" + statCollector.id, type + " filter by " + filter + ": " + JSON.stringify(contentFilters[filter]));
|
|
139
|
-
let filterMatched = false;
|
|
140
|
-
if (report[filter]) {
|
|
141
|
-
for (const value of contentFilters[filter]) {
|
|
142
|
-
statCollector.logger.debug(LOG_PREFIX + "-" + statCollector.id, filter + ": " + value + " <> " + report[filter]);
|
|
143
|
-
if (report[filter] === value) {
|
|
144
|
-
filterMatched = true;
|
|
145
|
-
break;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
filtersMatched = filtersMatched && filterMatched;
|
|
150
|
-
if (!filterMatched) {
|
|
151
|
-
break;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
if (filtersMatched) {
|
|
155
|
-
currentHeaders = statCollector.addHeaders(currentHeaders, report, metricsString);
|
|
156
|
-
}
|
|
157
|
-
} else {
|
|
158
|
-
currentHeaders = statCollector.addHeaders(currentHeaders, report, metricsString);
|
|
159
|
-
}
|
|
160
|
-
});
|
|
161
|
-
} else {
|
|
162
|
-
statCollector.logger.debug(LOG_PREFIX + "-" + statCollector.id, "No report type found in RTC stats: '" + type + "'");
|
|
163
|
-
}
|
|
164
|
-
});
|
|
165
|
-
if (currentHeaders !== statCollector.headers) {
|
|
166
|
-
headersChanged = true;
|
|
167
|
-
let newMetrics = [];
|
|
168
|
-
currentHeaders.split(",").forEach((header) => {
|
|
169
|
-
if (statCollector.headers.indexOf(header) === -1) {
|
|
170
|
-
newMetrics.push(header);
|
|
171
|
-
}
|
|
172
|
-
});
|
|
173
|
-
if (newMetrics.length) {
|
|
174
|
-
statCollector.logger.info(LOG_PREFIX + "-" + statCollector.id, "RTC metrics to be collected: " + newMetrics.toString());
|
|
175
|
-
}
|
|
176
|
-
statCollector.headers = currentHeaders;
|
|
177
|
-
}
|
|
178
|
-
return headersChanged;
|
|
179
|
-
},
|
|
180
|
-
addHeaders: function(currentHeaders, report, metricsString) {
|
|
181
|
-
if (metricsString) {
|
|
182
|
-
let metrics = metricsString.split(",");
|
|
183
|
-
metrics.forEach((metric) => {
|
|
184
|
-
for (const key of Object.keys(report)) {
|
|
185
|
-
if (metric === key && report[key]) {
|
|
186
|
-
currentHeaders = util.addFieldToCsvString(currentHeaders, report.type + "." + report.id + "." + metric, ",");
|
|
187
|
-
break;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
|
-
return currentHeaders;
|
|
193
|
-
},
|
|
194
|
-
updateCompression: async function() {
|
|
195
|
-
if (statCollector.description.compression) {
|
|
196
|
-
if (statCollector.description.compression.indexOf("gzip") >= 0) {
|
|
197
|
-
await statCollector.checkForCompression("gzip");
|
|
198
|
-
} else if (statCollector.description.compression.indexOf("deflate") >= 0) {
|
|
199
|
-
await statCollector.checkForCompression("deflate");
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
},
|
|
203
|
-
updateHttpConnection: function(url, authorization) {
|
|
204
|
-
if (url.startsWith(CONNECTION_TYPE.HTTP) && authorization) {
|
|
205
|
-
statCollector.connection.http.setAuthorization(authorization);
|
|
206
|
-
}
|
|
207
|
-
},
|
|
208
|
-
checkForCompression: async function(compression) {
|
|
209
|
-
try {
|
|
210
|
-
await util.compress(compression, "test", false);
|
|
211
|
-
statCollector.compression = compression;
|
|
212
|
-
} catch (e) {
|
|
213
|
-
statCollector.logger.warn(LOG_PREFIX + "-" + statCollector.id, "Can't compress metrics data using " + compression + ": " + e);
|
|
214
|
-
statCollector.compression = "none";
|
|
215
|
-
}
|
|
216
|
-
},
|
|
217
|
-
sendHeaders: async function() {
|
|
218
|
-
let data = {
|
|
219
|
-
mediaSessionId: statCollector.id,
|
|
220
|
-
compression: statCollector.compression,
|
|
221
|
-
headers: statCollector.headers
|
|
222
|
-
};
|
|
223
|
-
await statCollector.send("webRTCMetricsClientDescription", data);
|
|
224
|
-
},
|
|
225
|
-
send: async function(message, data) {
|
|
226
|
-
if (statCollector.connection.status === CONNECTION_STATUS.INIT || statCollector.connection.status === CONNECTION_STATUS.OK) {
|
|
227
|
-
statCollector.logger.debug(LOG_PREFIX + "-" + statCollector.id, data);
|
|
228
|
-
await statCollector.connection.send(message, data);
|
|
229
|
-
if (statCollector.connection.status !== CONNECTION_STATUS.OK) {
|
|
230
|
-
statCollector.logger.error(LOG_PREFIX + "-" + statCollector.id, "Error " + statCollector.connection.status + " sending RTC metrics to the server, stop sending");
|
|
231
|
-
statCollector.stop();
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
},
|
|
235
|
-
startTimer: function() {
|
|
236
|
-
if (!statCollector.timer) {
|
|
237
|
-
statCollector.batchCount = statCollector.description.batchSize;
|
|
238
|
-
statCollector.timer = setInterval(statCollector.collectMetrics, statCollector.description.sampling);
|
|
239
|
-
}
|
|
240
|
-
},
|
|
241
|
-
stopTimer: function() {
|
|
242
|
-
if (statCollector.timer) {
|
|
243
|
-
clearInterval(statCollector.timer);
|
|
244
|
-
statCollector.timer = null;
|
|
245
|
-
statCollector.metricsBatch = null;
|
|
246
|
-
}
|
|
247
|
-
},
|
|
248
|
-
isMetricValid: function(value) {
|
|
249
|
-
return value != null && value !== "" && value !== "undefined" && value !== "null";
|
|
250
|
-
},
|
|
251
|
-
collectMetrics: async function() {
|
|
252
|
-
if (statCollector.timer && !statCollector.timerBusy) {
|
|
253
|
-
// Unfortunately there are no real atomics in JS unless SharedArrayBuffer is used
|
|
254
|
-
// So we guard the timer callback with a dumb boolean
|
|
255
|
-
statCollector.timerBusy = true;
|
|
256
|
-
let stats = await statCollector.mediaConnection.getWebRTCStats();
|
|
257
|
-
|
|
258
|
-
statCollector.startNewBatch();
|
|
259
|
-
|
|
260
|
-
let metrics = [];
|
|
261
|
-
let lostMetrics = [];
|
|
262
|
-
if (statCollector.headers) {
|
|
263
|
-
statCollector.headers.split(",").forEach((header) => {
|
|
264
|
-
let components = header.split(".");
|
|
265
|
-
let descriptor = {
|
|
266
|
-
type: components[0],
|
|
267
|
-
id: components[1],
|
|
268
|
-
name: components[2]
|
|
269
|
-
}
|
|
270
|
-
let value = null;
|
|
271
|
-
|
|
272
|
-
if (stats[descriptor.type]) {
|
|
273
|
-
for (const report of stats[descriptor.type]) {
|
|
274
|
-
if (report.id === descriptor.id) {
|
|
275
|
-
value = report[descriptor.name];
|
|
276
|
-
break;
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
if (statCollector.isMetricValid(value)) {
|
|
281
|
-
metrics.push(value);
|
|
282
|
-
} else {
|
|
283
|
-
lostMetrics.push(descriptor);
|
|
284
|
-
}
|
|
285
|
-
});
|
|
286
|
-
} else {
|
|
287
|
-
statCollector.logger.info(LOG_PREFIX + "-" + statCollector.id, "No RTC metrics to collect, trying to update metrics available list");
|
|
288
|
-
}
|
|
289
|
-
// Metrics list may change if some metrics are added or some metrics are lost #WCS-4627
|
|
290
|
-
let headersUpdated = await statCollector.updateHeaders(stats);
|
|
291
|
-
if (lostMetrics.length) {
|
|
292
|
-
statCollector.logger.info(LOG_PREFIX + "-" + statCollector.id, "Missing metrics: " + JSON.stringify(lostMetrics));
|
|
293
|
-
// Send metrics already collected and start a new batch with current metrics array to send them later #WCS-4627
|
|
294
|
-
await statCollector.sendMetrics();
|
|
295
|
-
statCollector.startNewBatch(metrics);
|
|
296
|
-
} else if (metrics.length) {
|
|
297
|
-
statCollector.metricsBatch.push(metrics);
|
|
298
|
-
statCollector.batchCount--;
|
|
299
|
-
if (statCollector.batchCount === 0 || headersUpdated) {
|
|
300
|
-
await statCollector.sendMetrics();
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
// Check if metrics list changed and send a new headers if needed #WCS-4619
|
|
304
|
-
if (headersUpdated) {
|
|
305
|
-
statCollector.logger.info(LOG_PREFIX + "-" + statCollector.id, "RTC metrics list has changed, sending a new metrics description");
|
|
306
|
-
await statCollector.sendHeaders();
|
|
307
|
-
}
|
|
308
|
-
statCollector.timerBusy = false;
|
|
309
|
-
}
|
|
310
|
-
},
|
|
311
|
-
sendMetrics: async function() {
|
|
312
|
-
let previous;
|
|
313
|
-
let metricsToSend = [];
|
|
314
|
-
let metricsData;
|
|
315
|
-
|
|
316
|
-
for (let i = 0; statCollector.metricsBatch && i < statCollector.metricsBatch.length; i++) {
|
|
317
|
-
let metricsString = "";
|
|
318
|
-
for (let j = 0; j < statCollector.metricsBatch[i].length; j++) {
|
|
319
|
-
let valueString = valueToString(statCollector.metricsBatch[i][j]);
|
|
320
|
-
let previousString = "";
|
|
321
|
-
let delimiter = ";";
|
|
322
|
-
if (previous) {
|
|
323
|
-
previousString = valueToString(previous[j]);
|
|
324
|
-
}
|
|
325
|
-
if (valueString === previousString) {
|
|
326
|
-
valueString = "";
|
|
327
|
-
}
|
|
328
|
-
metricsString = util.addFieldToCsvString(metricsString, valueString, delimiter);
|
|
329
|
-
if (j > 0 && metricsString === "") {
|
|
330
|
-
metricsString = delimiter;
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
previous = statCollector.metricsBatch[i];
|
|
334
|
-
metricsToSend.push(metricsString);
|
|
335
|
-
}
|
|
336
|
-
if (statCollector.compression !== "none") {
|
|
337
|
-
try {
|
|
338
|
-
metricsData = await util.compress(statCollector.compression, JSON.stringify(metricsToSend), true);
|
|
339
|
-
} catch(e) {
|
|
340
|
-
statCollector.logger.warn(LOG_PREFIX + "-" + statCollector.id, "Can't send metrics data using" + statCollector.compression + ": " + e);
|
|
341
|
-
metricsData = null;
|
|
342
|
-
}
|
|
343
|
-
} else {
|
|
344
|
-
metricsData = metricsToSend;
|
|
345
|
-
}
|
|
346
|
-
if (metricsData) {
|
|
347
|
-
let data = {
|
|
348
|
-
mediaSessionId: statCollector.id,
|
|
349
|
-
metrics: metricsData
|
|
350
|
-
};
|
|
351
|
-
await statCollector.send("webRTCMetricsBatch", data);
|
|
352
|
-
}
|
|
353
|
-
statCollector.cleanBatch();
|
|
354
|
-
},
|
|
355
|
-
startNewBatch: function(metrics) {
|
|
356
|
-
if (!statCollector.metricsBatch) {
|
|
357
|
-
statCollector.metricsBatch = [];
|
|
358
|
-
if (metrics) {
|
|
359
|
-
statCollector.metricsBatch.push(metrics);
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
},
|
|
363
|
-
cleanBatch: function() {
|
|
364
|
-
if (statCollector.metricsBatch) {
|
|
365
|
-
statCollector.metricsBatch = null;
|
|
366
|
-
statCollector.batchCount = statCollector.description.batchSize;
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
return statCollector;
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
// Wrapper to send metrics via Websocket or HTTP POST
|
|
374
|
-
const Connection = function(existingConnection = null, maxErrors = MAX_SEND_ERRORS) {
|
|
375
|
-
const connection = {
|
|
376
|
-
type: "",
|
|
377
|
-
websocket: null,
|
|
378
|
-
http: null,
|
|
379
|
-
maxErrors: maxErrors,
|
|
380
|
-
errorsCount: 0,
|
|
381
|
-
status: CONNECTION_STATUS.INIT,
|
|
382
|
-
setUp: function(url, headers = null, existingConnection = null) {
|
|
383
|
-
if (url.startsWith(CONNECTION_TYPE.WEBSOCKET)) {
|
|
384
|
-
connection.type = CONNECTION_TYPE.WEBSOCKET;
|
|
385
|
-
// ToDo: create a new Websocket connection
|
|
386
|
-
} else if (url.startsWith(CONNECTION_TYPE.HTTP)) {
|
|
387
|
-
connection.type = CONNECTION_TYPE.HTTP
|
|
388
|
-
connection.http = HttpConnection(url, headers);
|
|
389
|
-
} else if (existingConnection) {
|
|
390
|
-
connection.type = CONNECTION_TYPE.WEBSOCKET;
|
|
391
|
-
connection.websocket = WebsocketConnection(existingConnection);
|
|
392
|
-
}
|
|
393
|
-
connection.errorsCount = 0;
|
|
394
|
-
connection.status = CONNECTION_STATUS.INIT;
|
|
395
|
-
},
|
|
396
|
-
send: async function(message, data) {
|
|
397
|
-
let code = CONNECTION_STATUS.BAD_REQUEST;
|
|
398
|
-
switch(connection.type) {
|
|
399
|
-
case CONNECTION_TYPE.WEBSOCKET:
|
|
400
|
-
if (connection.websocket) {
|
|
401
|
-
code = connection.websocket.send(message, data);
|
|
402
|
-
}
|
|
403
|
-
break;
|
|
404
|
-
case CONNECTION_TYPE.HTTP:
|
|
405
|
-
if (connection.http) {
|
|
406
|
-
code = await connection.http.send(message, data);
|
|
407
|
-
}
|
|
408
|
-
break;
|
|
409
|
-
}
|
|
410
|
-
connection.status = code;
|
|
411
|
-
if (connection.status === CONNECTION_STATUS.OK) {
|
|
412
|
-
connection.errorsCount = 0;
|
|
413
|
-
}
|
|
414
|
-
else {
|
|
415
|
-
if (message === "webRTCMetricsBatch") {
|
|
416
|
-
connection.errorsCount++;
|
|
417
|
-
if (connection.errorsCount < connection.maxErrors) {
|
|
418
|
-
connection.status = CONNECTION_STATUS.OK;
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
};
|
|
424
|
-
connection.setUp("", null, existingConnection);
|
|
425
|
-
return connection;
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
// Websocket connection (using existing one)
|
|
429
|
-
const WebsocketConnection = function(wsConnection) {
|
|
430
|
-
const connection = {
|
|
431
|
-
websocket: wsConnection,
|
|
432
|
-
send: function(message, data) {
|
|
433
|
-
let code = CONNECTION_STATUS.BAD_REQUEST;
|
|
434
|
-
if (connection.websocket) {
|
|
435
|
-
if (connection.websocket.readyState === WebSocket.OPEN) {
|
|
436
|
-
connection.websocket.send(JSON.stringify({
|
|
437
|
-
message: message,
|
|
438
|
-
data: [data]
|
|
439
|
-
}));
|
|
440
|
-
}
|
|
441
|
-
code = CONNECTION_STATUS.OK;
|
|
442
|
-
}
|
|
443
|
-
return code;
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
return connection;
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
// HTTP connection using Fetch API
|
|
450
|
-
const HttpConnection = function(url, headers) {
|
|
451
|
-
const connection = {
|
|
452
|
-
url: addSlash(url),
|
|
453
|
-
headers: headers,
|
|
454
|
-
setAuthorization(token) {
|
|
455
|
-
this.headers.Authorization = token;
|
|
456
|
-
},
|
|
457
|
-
send: async function(message, data) {
|
|
458
|
-
let code = CONNECTION_STATUS.BAD_REQUEST;
|
|
459
|
-
if (connection.url) {
|
|
460
|
-
try {
|
|
461
|
-
const httpHeaders = new Headers();
|
|
462
|
-
httpHeaders.append("Content-Type", "application/json");
|
|
463
|
-
|
|
464
|
-
if (connection.headers) {
|
|
465
|
-
for (const [header, value] of Object.entries(connection.headers)) {
|
|
466
|
-
httpHeaders.append(header, value);
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
let response = await fetch(connection.url + message,{
|
|
470
|
-
method: "POST",
|
|
471
|
-
headers: httpHeaders,
|
|
472
|
-
mode: "cors",
|
|
473
|
-
body: JSON.stringify(data)
|
|
474
|
-
});
|
|
475
|
-
code = response.status;
|
|
476
|
-
} catch (e) {
|
|
477
|
-
code = CONNECTION_STATUS.INTERNAL_SERVER_ERROR;
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
return code;
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
return connection;
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
// Helper function to stringify a value
|
|
487
|
-
const valueToString = function(value) {
|
|
488
|
-
let valueString = "undefined";
|
|
489
|
-
if (value) {
|
|
490
|
-
if (typeof value === "object") {
|
|
491
|
-
valueString = JSON.stringify(value);
|
|
492
|
-
} else {
|
|
493
|
-
valueString = value.toString();
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
return valueString;
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
// Helper function to get logger object
|
|
500
|
-
const getLogger = function(logger) {
|
|
501
|
-
if (logger) {
|
|
502
|
-
if (logger.info !== undefined &&
|
|
503
|
-
logger.warn !== undefined &&
|
|
504
|
-
logger.error !== undefined &&
|
|
505
|
-
logger.debug !== undefined) {
|
|
506
|
-
return logger;
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
return {
|
|
510
|
-
info: function() {},
|
|
511
|
-
warn: function() {},
|
|
512
|
-
error: function() {},
|
|
513
|
-
debug: function() {}
|
|
514
|
-
};
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
// Helper function to add slash to endpoint
|
|
518
|
-
const addSlash = function(value) {
|
|
519
|
-
let endpoint = value;
|
|
520
|
-
if (endpoint && !endpoint.endsWith("/")) {
|
|
521
|
-
endpoint = endpoint + "/";
|
|
522
|
-
}
|
|
523
|
-
return endpoint;
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
module.exports = {
|
|
527
|
-
StreamStatsCollector: StreamStatsCollector
|
|
528
|
-
}
|
package/src/util.js
CHANGED
|
@@ -502,52 +502,6 @@ const addFieldToCsvString = function(csvString, field, delimiter) {
|
|
|
502
502
|
return csvString;
|
|
503
503
|
}
|
|
504
504
|
|
|
505
|
-
const compress = async function(compression, data, base64) {
|
|
506
|
-
// Throw exception if CompessionStream is not available
|
|
507
|
-
if (typeof CompressionStream === "undefined") {
|
|
508
|
-
throw new Error("Compression is not available");
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
// Convert incoming string to a stream
|
|
512
|
-
let stream;
|
|
513
|
-
if(typeof data == "string") {
|
|
514
|
-
stream = new Blob([data], {
|
|
515
|
-
type: 'text/plain',
|
|
516
|
-
}).stream();
|
|
517
|
-
} else {
|
|
518
|
-
// Assume blog
|
|
519
|
-
stream = data.stream();
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
// gzip stream
|
|
523
|
-
const compressedReadableStream = stream.pipeThrough(
|
|
524
|
-
new CompressionStream(compression)
|
|
525
|
-
);
|
|
526
|
-
|
|
527
|
-
// create Response
|
|
528
|
-
const compressedResponse = await new Response(compressedReadableStream);
|
|
529
|
-
|
|
530
|
-
// Get response Blob
|
|
531
|
-
const blob = await compressedResponse.blob();
|
|
532
|
-
|
|
533
|
-
if(base64) {
|
|
534
|
-
// Get the ArrayBuffer
|
|
535
|
-
const buffer = await blob.arrayBuffer();
|
|
536
|
-
|
|
537
|
-
// convert ArrayBuffer to base64 encoded string
|
|
538
|
-
const compressedBase64 = btoa(
|
|
539
|
-
String.fromCharCode(
|
|
540
|
-
...new Uint8Array(buffer)
|
|
541
|
-
)
|
|
542
|
-
);
|
|
543
|
-
|
|
544
|
-
return compressedBase64;
|
|
545
|
-
|
|
546
|
-
} else {
|
|
547
|
-
return blob;
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
|
|
551
505
|
module.exports = {
|
|
552
506
|
isEmptyObject,
|
|
553
507
|
copyObjectToArray,
|
|
@@ -561,5 +515,4 @@ module.exports = {
|
|
|
561
515
|
isPromise,
|
|
562
516
|
setPublishingBitrate,
|
|
563
517
|
addFieldToCsvString,
|
|
564
|
-
compress
|
|
565
518
|
};
|
|
@@ -963,6 +963,10 @@ var createConnection = function (options) {
|
|
|
963
963
|
});
|
|
964
964
|
};
|
|
965
965
|
|
|
966
|
+
var getRTCPeerConnection = function() {
|
|
967
|
+
return connection;
|
|
968
|
+
}
|
|
969
|
+
|
|
966
970
|
var exports = {};
|
|
967
971
|
exports.state = state;
|
|
968
972
|
exports.createOffer = createOffer;
|
|
@@ -996,6 +1000,7 @@ var createConnection = function (options) {
|
|
|
996
1000
|
exports.setZoom = setZoom;
|
|
997
1001
|
exports.getZoom = getZoom;
|
|
998
1002
|
exports.getWebRTCStats = getWebRTCStats;
|
|
1003
|
+
exports.getRTCPeerConnection = getRTCPeerConnection;
|
|
999
1004
|
connections[id] = exports;
|
|
1000
1005
|
resolve(exports);
|
|
1001
1006
|
});
|