@flashphoner/websdk 2.0.211 → 2.0.216

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/src/util.js CHANGED
@@ -1,147 +1,156 @@
1
1
  'use strict';
2
2
 
3
- module.exports = {
3
+ const isEmptyObject = function( obj ) {
4
+ for ( var name in obj ) {
5
+ return false;
6
+ }
7
+ return true;
8
+ };
4
9
 
5
- isEmptyObject: function( obj ) {
6
- for ( var name in obj ) {
7
- return false;
10
+ /**
11
+ * Copy values of object own properties to array.
12
+ *
13
+ * @param obj
14
+ * @returns {Array}
15
+ */
16
+ const copyObjectToArray = function(obj) {
17
+ var ret = [];
18
+ for (var prop in obj) {
19
+ if(obj.hasOwnProperty(prop)) {
20
+ ret.push(obj[prop]);
8
21
  }
9
- return true;
10
- },
22
+ }
23
+ return ret;
24
+ };
11
25
 
12
- /**
13
- * Copy values of object own properties to array.
14
- *
15
- * @param obj
16
- * @returns {Array}
17
- */
18
- copyObjectToArray: function(obj) {
19
- var ret = [];
20
- for (var prop in obj) {
21
- if(obj.hasOwnProperty(prop)) {
22
- ret.push(obj[prop]);
23
- }
26
+ /**
27
+ * Copy src properties to dst object.
28
+ * Will overwrite dst prop with src prop in case of dst prop exist.
29
+ */
30
+ const copyObjectPropsToAnotherObject = function(src, dst) {
31
+ for (var prop in src) {
32
+ if(src.hasOwnProperty(prop)) {
33
+ dst[prop] = src[prop];
24
34
  }
25
- return ret;
26
- },
27
- /**
28
- * Copy src properties to dst object.
29
- * Will overwrite dst prop with src prop in case of dst prop exist.
30
- */
31
- copyObjectPropsToAnotherObject: function(src, dst) {
32
- for (var prop in src) {
33
- if(src.hasOwnProperty(prop)) {
34
- dst[prop] = src[prop];
35
- }
36
- }
37
- },
38
- processRtcStatsReport: function(browser, report) {
39
- var result = {};
40
- if (browser == "chrome") {
41
- /**
42
- * Report types: googComponent, googCandidatePair, googCertificate, googLibjingleSession, googTrack, ssrc
43
- */
44
- var gotResult = false;
45
- if (report.type && report.type == "googCandidatePair") {
46
- //check if this is active pair
47
- if (report.googActiveConnection == "true") {
48
- gotResult = true;
49
- }
50
- }
35
+ }
36
+ };
51
37
 
52
- if (report.type && report.type == "ssrc") {
38
+ const processRtcStatsReport = function(browser, report) {
39
+ var result = {};
40
+ if (browser == "chrome") {
41
+ /**
42
+ * Report types: googComponent, googCandidatePair, googCertificate, googLibjingleSession, googTrack, ssrc
43
+ */
44
+ var gotResult = false;
45
+ if (report.type && report.type == "googCandidatePair") {
46
+ //check if this is active pair
47
+ if (report.googActiveConnection == "true") {
53
48
  gotResult = true;
54
49
  }
50
+ }
55
51
 
56
- if (gotResult) {
57
- for (var k in report) {
58
- if (report.hasOwnProperty(k)) {
59
- result[k] = report[k];
60
- }
52
+ if (report.type && report.type == "ssrc") {
53
+ gotResult = true;
54
+ }
55
+
56
+ if (gotResult) {
57
+ for (var k in report) {
58
+ if (report.hasOwnProperty(k)) {
59
+ result[k] = report[k];
61
60
  }
62
61
  }
63
- return result;
64
- } else if (browser == "firefox") {
65
- /**
66
- * RTCStatsReport http://mxr.mozilla.org/mozilla-central/source/dom/webidl/RTCStatsReport.webidl
67
- */
62
+ }
63
+ return result;
64
+ } else if (browser == "firefox") {
65
+ /**
66
+ * RTCStatsReport http://mxr.mozilla.org/mozilla-central/source/dom/webidl/RTCStatsReport.webidl
67
+ */
68
68
 
69
- if (report.type && (report.type == "outboundrtp" || report.type == "inboundrtp") && report.id.indexOf("rtcp") == -1) {
70
- result = {};
71
- for (var k in report) {
72
- if (report.hasOwnProperty(k)) {
73
- result[k] = report[k];
74
- }
69
+ if (report.type && (report.type == "outboundrtp" || report.type == "inboundrtp") && report.id.indexOf("rtcp") == -1) {
70
+ result = {};
71
+ for (var k in report) {
72
+ if (report.hasOwnProperty(k)) {
73
+ result[k] = report[k];
75
74
  }
76
75
  }
76
+ }
77
+
78
+ return result;
79
+ } else {
80
+ return result
81
+ }
82
+ };
77
83
 
78
- return result;
79
- } else { return result };
84
+ const Browser = {
85
+ isIE: function () {
86
+ return /*@cc_on!@*/false || !!document.documentMode;
80
87
  },
81
- Browser: {
82
- isIE: function () {
83
- return /*@cc_on!@*/false || !!document.documentMode;
84
- },
85
- isFirefox: function () {
86
- return typeof InstallTrigger !== 'undefined';
87
- },
88
- isChrome: function () {
89
- return !!window.chrome && /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor) && !/OPR/.test(navigator.userAgent);
90
- },
91
- isEdge: function () {
92
- return !isIE && !!window.StyleMedia;
93
- },
94
- isOpera: function () {
95
- return (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
96
- },
97
- isiOS: function () {
98
- return /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
99
- },
100
- isSafari: function () {
101
- var userAgent = navigator.userAgent.toLowerCase();
102
- return /(safari|applewebkit)/i.test(userAgent) && !userAgent.includes("chrome") && !userAgent.includes("android");
103
- },
104
- isAndroid: function () {
105
- return navigator.userAgent.toLowerCase().indexOf("android") > -1;
106
- },
107
- isSafariWebRTC: function () {
108
- return navigator.mediaDevices && this.isSafari();
109
- },
110
- isSamsungBrowser: function() {
111
- return /SamsungBrowser/i.test(navigator.userAgent);
112
- },
113
- isAndroidFirefox: function () {
114
- return this.isAndroid() && /Firefox/i.test(navigator.userAgent);
115
- }
88
+ isFirefox: function () {
89
+ return typeof InstallTrigger !== 'undefined';
116
90
  },
117
- SDP: {
118
- matchPrefix: function(sdp,prefix) {
119
- var parts = sdp.trim().split('\n').map(function(line) {
120
- return line.trim();
121
- });
122
- return parts.filter(function(line) {
123
- return line.indexOf(prefix) === 0;
124
- });
125
- },
126
- writeFmtp: function (sdp, param, codec) {
127
- var sdpArray = sdp.split("\n");
128
- var i;
129
- for (i = 0; i < sdpArray.length; i++) {
130
- if (sdpArray[i].search(codec) != -1 && sdpArray[i].indexOf("a=rtpmap") == 0) {
131
- sdpArray[i] += "\na=fmtp:" + sdpArray[i].match(/[0-9]+/)[0] + " " + param + "\r";
132
- }
91
+ isChrome: function () {
92
+ return !!window.chrome && /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor) && !/OPR/.test(navigator.userAgent);
93
+ },
94
+ isEdge: function () {
95
+ return !isIE && !!window.StyleMedia;
96
+ },
97
+ isOpera: function () {
98
+ return (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
99
+ },
100
+ isiOS: function () {
101
+ return /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
102
+ },
103
+ isSafari: function () {
104
+ var userAgent = navigator.userAgent.toLowerCase();
105
+ return /(safari|applewebkit)/i.test(userAgent) && !userAgent.includes("chrome") && !userAgent.includes("android");
106
+ },
107
+ isAndroid: function () {
108
+ return navigator.userAgent.toLowerCase().indexOf("android") > -1;
109
+ },
110
+ isSafariWebRTC: function () {
111
+ return navigator.mediaDevices && this.isSafari();
112
+ },
113
+ isSamsungBrowser: function() {
114
+ return /SamsungBrowser/i.test(navigator.userAgent);
115
+ },
116
+ isAndroidFirefox: function () {
117
+ return this.isAndroid() && /Firefox/i.test(navigator.userAgent);
118
+ },
119
+ isChromiumEdge: function () {
120
+ return /Chrome/i.test(navigator.userAgent) && /Edg/i.test(navigator.userAgent);
121
+ }
122
+ };
123
+
124
+ const SDP = {
125
+ matchPrefix: function(sdp,prefix) {
126
+ var parts = sdp.trim().split('\n').map(function(line) {
127
+ return line.trim();
128
+ });
129
+ return parts.filter(function(line) {
130
+ return line.indexOf(prefix) === 0;
131
+ });
132
+ },
133
+ writeFmtp: function (sdp, param, codec) {
134
+ var sdpArray = sdp.split("\n");
135
+ var i;
136
+ for (i = 0; i < sdpArray.length; i++) {
137
+ if (sdpArray[i].search(codec) != -1 && sdpArray[i].indexOf("a=rtpmap") == 0) {
138
+ sdpArray[i] += "\na=fmtp:" + sdpArray[i].match(/[0-9]+/)[0] + " " + param + "\r";
133
139
  }
134
- //normalize sdp after modifications
135
- var result = "";
136
- for (i = 0; i < sdpArray.length; i++) {
137
- if (sdpArray[i] != "") {
138
- result += sdpArray[i] + "\n";
139
- }
140
+ }
141
+ //normalize sdp after modifications
142
+ var result = "";
143
+ for (i = 0; i < sdpArray.length; i++) {
144
+ if (sdpArray[i] != "") {
145
+ result += sdpArray[i] + "\n";
140
146
  }
141
- return result;
142
147
  }
143
- },
144
- logger: {
148
+ return result;
149
+ }
150
+ };
151
+
152
+ const logger = function() {
153
+ return {
145
154
  init: function (verbosity, enablePushLogs, customLogger, enableLogs) {
146
155
  switch (verbosity.toUpperCase()) {
147
156
  case "DEBUG":
@@ -178,7 +187,6 @@ module.exports = {
178
187
  data: [{logs: delayedLogs[i]}]
179
188
  }));
180
189
  }
181
-
182
190
  }
183
191
  delayedLogs = [];
184
192
  this.wsConnection.send(JSON.stringify({
@@ -202,7 +210,7 @@ module.exports = {
202
210
  this.customLogger.info(text);
203
211
  } else {
204
212
  console.log(prefix,text);
205
- }
213
+ }
206
214
  }
207
215
  },
208
216
  debug: function (src, text) {
@@ -223,7 +231,7 @@ module.exports = {
223
231
  if (!this.enableLogs){
224
232
  return;
225
233
  }
226
- var prefix = this.date() + " TRACE " + src + " - ";
234
+ var prefix = this.date() + " TRACE " + src + " - ";
227
235
  this.pushLogs(prefix + JSON.stringify(text) + '\n');
228
236
  if (this.verbosity >= 4) {
229
237
  if (this.customLogger != null) {
@@ -237,7 +245,7 @@ module.exports = {
237
245
  if (!this.enableLogs){
238
246
  return;
239
247
  }
240
- var prefix = this.date() + " WARN " + src + " - ";
248
+ var prefix = this.date() + " WARN " + src + " - ";
241
249
  this.pushLogs(prefix + JSON.stringify(text) + '\n');
242
250
  if (this.verbosity >= 1) {
243
251
  if (this.customLogger != null) {
@@ -251,7 +259,7 @@ module.exports = {
251
259
  if (!this.enableLogs){
252
260
  return;
253
261
  }
254
- var prefix = this.date() + " ERROR " + src + " - ";
262
+ var prefix = this.date() + " ERROR " + src + " - ";
255
263
  this.pushLogs(prefix + JSON.stringify(text) + '\n');
256
264
  if (this.verbosity >= 0) {
257
265
  if (this.customLogger != null) {
@@ -293,80 +301,94 @@ module.exports = {
293
301
  break;
294
302
  default :
295
303
  this.verbosity = 2;
296
- };
304
+ }
297
305
  }
298
- },
299
- stripCodecs: function(sdp, codecs) {
300
- if (!codecs.length) return sdp;
306
+ }
307
+ };
301
308
 
302
- var sdpArray = sdp.split("\n");
303
- var codecsArray = codecs.split(",");
309
+ const stripCodecs = function(sdp, codecs) {
310
+ if (!codecs.length) return sdp;
304
311
 
305
- //search and delete codecs line
306
- var pt = [];
307
- var i;
308
- for (var p = 0; p < codecsArray.length; p++) {
309
- console.log("Searching for codec " + codecsArray[p]);
312
+ var sdpArray = sdp.split("\n");
313
+ var codecsArray = codecs.split(",");
314
+
315
+ //search and delete codecs line
316
+ var pt = [];
317
+ var i;
318
+ for (var p = 0; p < codecsArray.length; p++) {
319
+ console.log("Searching for codec " + codecsArray[p]);
320
+ for (i = 0; i < sdpArray.length; i++) {
321
+ if (sdpArray[i].search(new RegExp(codecsArray[p],'i')) != -1 && sdpArray[i].indexOf("a=rtpmap") == 0) {
322
+ console.log(codecsArray[p] + " detected");
323
+ pt.push(sdpArray[i].match(/[0-9]+/)[0]);
324
+ sdpArray[i] = "";
325
+ }
326
+ }
327
+ }
328
+ if (pt.length) {
329
+ //searching for fmtp
330
+ for (p = 0; p < pt.length; p++) {
310
331
  for (i = 0; i < sdpArray.length; i++) {
311
- if (sdpArray[i].search(new RegExp(codecsArray[p],'i')) != -1 && sdpArray[i].indexOf("a=rtpmap") == 0) {
312
- console.log(codecsArray[p] + " detected");
313
- pt.push(sdpArray[i].match(/[0-9]+/)[0]);
332
+ if (sdpArray[i].search("a=fmtp:" + pt[p]) != -1 || sdpArray[i].search("a=rtcp-fb:" + pt[p]) != -1) {
314
333
  sdpArray[i] = "";
315
334
  }
316
335
  }
317
336
  }
318
- if (pt.length) {
319
- //searching for fmtp
320
- for (p = 0; p < pt.length; p++) {
321
- for (i = 0; i < sdpArray.length; i++) {
322
- if (sdpArray[i].search("a=fmtp:" + pt[p]) != -1 || sdpArray[i].search("a=rtcp-fb:" + pt[p]) != -1) {
323
- sdpArray[i] = "";
324
- }
325
- }
326
- }
327
337
 
328
- //delete entries from m= line
329
- for (i = 0; i < sdpArray.length; i++) {
330
- if (sdpArray[i].search("m=audio") != -1 || sdpArray[i].search("m=video") != -1) {
331
- var mLineSplitted = sdpArray[i].split(" ");
332
- var newMLine = "";
333
- for (var m = 0; m < mLineSplitted.length; m++) {
334
- if (pt.indexOf(mLineSplitted[m].trim()) == -1 || m <= 2) {
335
- newMLine += mLineSplitted[m];
336
- if (m < mLineSplitted.length - 1) {
337
- newMLine = newMLine + " ";
338
- }
338
+ //delete entries from m= line
339
+ for (i = 0; i < sdpArray.length; i++) {
340
+ if (sdpArray[i].search("m=audio") != -1 || sdpArray[i].search("m=video") != -1) {
341
+ var mLineSplitted = sdpArray[i].split(" ");
342
+ var newMLine = "";
343
+ for (var m = 0; m < mLineSplitted.length; m++) {
344
+ if (pt.indexOf(mLineSplitted[m].trim()) == -1 || m <= 2) {
345
+ newMLine += mLineSplitted[m];
346
+ if (m < mLineSplitted.length - 1) {
347
+ newMLine = newMLine + " ";
339
348
  }
340
349
  }
341
- sdpArray[i] = newMLine;
342
350
  }
351
+ sdpArray[i] = newMLine;
343
352
  }
344
353
  }
354
+ }
345
355
 
346
- //normalize sdp after modifications
347
- var result = "";
348
- for (i = 0; i < sdpArray.length; i++) {
349
- if (sdpArray[i] != "") {
350
- result += sdpArray[i] + "\n";
351
- }
356
+ //normalize sdp after modifications
357
+ var result = "";
358
+ for (i = 0; i < sdpArray.length; i++) {
359
+ if (sdpArray[i] != "") {
360
+ result += sdpArray[i] + "\n";
352
361
  }
353
- return result;
354
- },
355
- getCurrentCodecAndSampleRate: function(sdp, mediaType) {
356
- var rows = sdp.split("\n");
357
- var codecPt;
358
- for (var i = 0; i < rows.length ; i++) {
359
- if (codecPt && rows[i].indexOf("a=rtpmap:" + codecPt) != -1) {
360
- var ret = {};
361
- ret.name = rows[i].split(" ")[1].split("/")[0];
362
- ret.sampleRate = rows[i].split(" ")[1].split("/")[1];
363
- return ret;
364
- }
365
- //WCS-2136. WebRTC statistics doesn't work for VP8
366
- if (rows[i].indexOf("m=" + mediaType) != -1) {
367
- codecPt = rows[i].split(" ")[3].trim();
368
- }
362
+ }
363
+ return result;
364
+ };
365
+
366
+ const getCurrentCodecAndSampleRate = function(sdp, mediaType) {
367
+ var rows = sdp.split("\n");
368
+ var codecPt;
369
+ for (var i = 0; i < rows.length ; i++) {
370
+ if (codecPt && rows[i].indexOf("a=rtpmap:" + codecPt) != -1) {
371
+ var ret = {};
372
+ ret.name = rows[i].split(" ")[1].split("/")[0];
373
+ ret.sampleRate = rows[i].split(" ")[1].split("/")[1];
374
+ return ret;
375
+ }
376
+ //WCS-2136. WebRTC statistics doesn't work for VP8
377
+ if (rows[i].indexOf("m=" + mediaType) != -1) {
378
+ codecPt = rows[i].split(" ")[3].trim();
369
379
  }
370
380
  }
381
+ };
382
+
371
383
 
384
+ module.exports = {
385
+ isEmptyObject,
386
+ copyObjectToArray,
387
+ copyObjectPropsToAnotherObject,
388
+ processRtcStatsReport,
389
+ Browser,
390
+ SDP,
391
+ logger,
392
+ stripCodecs,
393
+ getCurrentCodecAndSampleRate
372
394
  };
@@ -23,6 +23,11 @@ var mics = [];
23
23
  var createConnection = function (options) {
24
24
  return new Promise(function (resolve, reject) {
25
25
 
26
+ // Set connection logger #WCS-2434
27
+ if (options.logger) {
28
+ logger = options.logger;
29
+ }
30
+
26
31
  var id = options.id;
27
32
  var connectionConfig = options.connectionConfig || {"iceServers": []};
28
33
  var connectionConstraints = options.connectionConstraints || {};
@@ -131,9 +136,9 @@ var createConnection = function (options) {
131
136
  function setContentHint(stream, hint) {
132
137
  stream.getVideoTracks().forEach(function(track) {
133
138
  if(track.contentHint === undefined) {
134
- logger.warn("contentHint unsupported");
139
+ logger.warn(LOG_PREFIX, "Track contentHint unsupported");
135
140
  } else {
136
- logger.info("Set video track contentHint to " + hint);
141
+ logger.info(LOG_PREFIX, "Set video track contentHint to " + hint);
137
142
  track.contentHint = hint;
138
143
  }
139
144
  });
@@ -168,7 +173,7 @@ var createConnection = function (options) {
168
173
  //WCS-2771 add playback delay
169
174
  connection.getReceivers().forEach((track) => {
170
175
  if (track.playoutDelayHint === undefined) {
171
- logger.warn("playout delay unsupported");
176
+ logger.warn(LOG_PREFIX, "Playout delay unsupported");
172
177
  }
173
178
  track.playoutDelayHint = playoutDelay;
174
179
  });
@@ -518,7 +523,7 @@ var createConnection = function (options) {
518
523
  if (localVideo.srcObject.getAudioTracks().length == 0 && audioTrack) {
519
524
  localVideo.srcObject.addTrack(audioTrack);
520
525
  }
521
- logger.info("Switch camera to " + cam);
526
+ logger.info(LOG_PREFIX, "Switch camera to " + cam);
522
527
  resolve(cam);
523
528
  }).catch(function (reason) {
524
529
  logger.error(LOG_PREFIX, reason);
@@ -569,7 +574,7 @@ var createConnection = function (options) {
569
574
  if (videoTrack) {
570
575
  localVideo.srcObject.addTrack(videoTrack);
571
576
  }
572
- logger.info("Switch mic to " + mic);
577
+ logger.info(LOG_PREFIX, "Switch mic to " + mic);
573
578
  resolve(mic);
574
579
  }).catch(function (reason) {
575
580
  logger.error(LOG_PREFIX, reason);
@@ -657,7 +662,7 @@ var createConnection = function (options) {
657
662
  localVideo.srcObject.addTrack(currentAudioTrack);
658
663
  }
659
664
  });
660
- logger.info("Switch to screen");
665
+ logger.info(LOG_PREFIX, "Switch to screen");
661
666
  screenShare = true;
662
667
  resolve();
663
668
  };
@@ -685,7 +690,7 @@ var createConnection = function (options) {
685
690
  }
686
691
  });
687
692
  }
688
- logger.info("Switch to cam");
693
+ logger.info(LOG_PREFIX, "Switch to cam");
689
694
  screenShare = false;
690
695
  };
691
696
 
@@ -1399,6 +1404,8 @@ var playFirstVideo = function (display, isLocal, src) {
1399
1404
  var video = document.createElement('video');
1400
1405
  video.setAttribute("playsinline", "");
1401
1406
  video.setAttribute("webkit-playsinline", "");
1407
+ //Mute video tag to prevent local audio playback in Safari #WCS-3430
1408
+ video.muted = true;
1402
1409
  video.id = uuid_v1() + (isLocal ? LOCAL_CACHED_VIDEO : REMOTE_CACHED_VIDEO);
1403
1410
 
1404
1411
  //in WCS-1560 we removed video.play() call, because it triggers the “Unhandled Promise Rejection” exception in iOS Safari
@@ -27,6 +27,11 @@ var createConnection = function(options, handlers) {
27
27
  var id = options.id;
28
28
  var display = options.display;
29
29
 
30
+ // Set connection logger #WCS-2434
31
+ if (options.logger) {
32
+ logger = options.logger;
33
+ }
34
+
30
35
  var canvas = document.createElement("canvas");
31
36
  display.appendChild(canvas);
32
37
  canvas.id = id;