@flashphoner/websdk 2.0.210 → 2.0.215

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,153 @@
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
+ };
120
+
121
+ const SDP = {
122
+ matchPrefix: function(sdp,prefix) {
123
+ var parts = sdp.trim().split('\n').map(function(line) {
124
+ return line.trim();
125
+ });
126
+ return parts.filter(function(line) {
127
+ return line.indexOf(prefix) === 0;
128
+ });
129
+ },
130
+ writeFmtp: function (sdp, param, codec) {
131
+ var sdpArray = sdp.split("\n");
132
+ var i;
133
+ for (i = 0; i < sdpArray.length; i++) {
134
+ if (sdpArray[i].search(codec) != -1 && sdpArray[i].indexOf("a=rtpmap") == 0) {
135
+ sdpArray[i] += "\na=fmtp:" + sdpArray[i].match(/[0-9]+/)[0] + " " + param + "\r";
133
136
  }
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
- }
137
+ }
138
+ //normalize sdp after modifications
139
+ var result = "";
140
+ for (i = 0; i < sdpArray.length; i++) {
141
+ if (sdpArray[i] != "") {
142
+ result += sdpArray[i] + "\n";
140
143
  }
141
- return result;
142
144
  }
143
- },
144
- logger: {
145
+ return result;
146
+ }
147
+ };
148
+
149
+ const logger = function() {
150
+ return {
145
151
  init: function (verbosity, enablePushLogs, customLogger, enableLogs) {
146
152
  switch (verbosity.toUpperCase()) {
147
153
  case "DEBUG":
@@ -178,7 +184,6 @@ module.exports = {
178
184
  data: [{logs: delayedLogs[i]}]
179
185
  }));
180
186
  }
181
-
182
187
  }
183
188
  delayedLogs = [];
184
189
  this.wsConnection.send(JSON.stringify({
@@ -202,7 +207,7 @@ module.exports = {
202
207
  this.customLogger.info(text);
203
208
  } else {
204
209
  console.log(prefix,text);
205
- }
210
+ }
206
211
  }
207
212
  },
208
213
  debug: function (src, text) {
@@ -223,7 +228,7 @@ module.exports = {
223
228
  if (!this.enableLogs){
224
229
  return;
225
230
  }
226
- var prefix = this.date() + " TRACE " + src + " - ";
231
+ var prefix = this.date() + " TRACE " + src + " - ";
227
232
  this.pushLogs(prefix + JSON.stringify(text) + '\n');
228
233
  if (this.verbosity >= 4) {
229
234
  if (this.customLogger != null) {
@@ -237,7 +242,7 @@ module.exports = {
237
242
  if (!this.enableLogs){
238
243
  return;
239
244
  }
240
- var prefix = this.date() + " WARN " + src + " - ";
245
+ var prefix = this.date() + " WARN " + src + " - ";
241
246
  this.pushLogs(prefix + JSON.stringify(text) + '\n');
242
247
  if (this.verbosity >= 1) {
243
248
  if (this.customLogger != null) {
@@ -251,7 +256,7 @@ module.exports = {
251
256
  if (!this.enableLogs){
252
257
  return;
253
258
  }
254
- var prefix = this.date() + " ERROR " + src + " - ";
259
+ var prefix = this.date() + " ERROR " + src + " - ";
255
260
  this.pushLogs(prefix + JSON.stringify(text) + '\n');
256
261
  if (this.verbosity >= 0) {
257
262
  if (this.customLogger != null) {
@@ -293,80 +298,94 @@ module.exports = {
293
298
  break;
294
299
  default :
295
300
  this.verbosity = 2;
296
- };
301
+ }
297
302
  }
298
- },
299
- stripCodecs: function(sdp, codecs) {
300
- if (!codecs.length) return sdp;
303
+ }
304
+ };
301
305
 
302
- var sdpArray = sdp.split("\n");
303
- var codecsArray = codecs.split(",");
306
+ const stripCodecs = function(sdp, codecs) {
307
+ if (!codecs.length) return sdp;
304
308
 
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]);
309
+ var sdpArray = sdp.split("\n");
310
+ var codecsArray = codecs.split(",");
311
+
312
+ //search and delete codecs line
313
+ var pt = [];
314
+ var i;
315
+ for (var p = 0; p < codecsArray.length; p++) {
316
+ console.log("Searching for codec " + codecsArray[p]);
317
+ for (i = 0; i < sdpArray.length; i++) {
318
+ if (sdpArray[i].search(new RegExp(codecsArray[p],'i')) != -1 && sdpArray[i].indexOf("a=rtpmap") == 0) {
319
+ console.log(codecsArray[p] + " detected");
320
+ pt.push(sdpArray[i].match(/[0-9]+/)[0]);
321
+ sdpArray[i] = "";
322
+ }
323
+ }
324
+ }
325
+ if (pt.length) {
326
+ //searching for fmtp
327
+ for (p = 0; p < pt.length; p++) {
310
328
  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]);
329
+ if (sdpArray[i].search("a=fmtp:" + pt[p]) != -1 || sdpArray[i].search("a=rtcp-fb:" + pt[p]) != -1) {
314
330
  sdpArray[i] = "";
315
331
  }
316
332
  }
317
333
  }
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
334
 
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
- }
335
+ //delete entries from m= line
336
+ for (i = 0; i < sdpArray.length; i++) {
337
+ if (sdpArray[i].search("m=audio") != -1 || sdpArray[i].search("m=video") != -1) {
338
+ var mLineSplitted = sdpArray[i].split(" ");
339
+ var newMLine = "";
340
+ for (var m = 0; m < mLineSplitted.length; m++) {
341
+ if (pt.indexOf(mLineSplitted[m].trim()) == -1 || m <= 2) {
342
+ newMLine += mLineSplitted[m];
343
+ if (m < mLineSplitted.length - 1) {
344
+ newMLine = newMLine + " ";
339
345
  }
340
346
  }
341
- sdpArray[i] = newMLine;
342
347
  }
348
+ sdpArray[i] = newMLine;
343
349
  }
344
350
  }
351
+ }
345
352
 
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
- }
353
+ //normalize sdp after modifications
354
+ var result = "";
355
+ for (i = 0; i < sdpArray.length; i++) {
356
+ if (sdpArray[i] != "") {
357
+ result += sdpArray[i] + "\n";
352
358
  }
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
- }
359
+ }
360
+ return result;
361
+ };
362
+
363
+ const getCurrentCodecAndSampleRate = function(sdp, mediaType) {
364
+ var rows = sdp.split("\n");
365
+ var codecPt;
366
+ for (var i = 0; i < rows.length ; i++) {
367
+ if (codecPt && rows[i].indexOf("a=rtpmap:" + codecPt) != -1) {
368
+ var ret = {};
369
+ ret.name = rows[i].split(" ")[1].split("/")[0];
370
+ ret.sampleRate = rows[i].split(" ")[1].split("/")[1];
371
+ return ret;
372
+ }
373
+ //WCS-2136. WebRTC statistics doesn't work for VP8
374
+ if (rows[i].indexOf("m=" + mediaType) != -1) {
375
+ codecPt = rows[i].split(" ")[3].trim();
369
376
  }
370
377
  }
378
+ };
379
+
371
380
 
381
+ module.exports = {
382
+ isEmptyObject,
383
+ copyObjectToArray,
384
+ copyObjectPropsToAnotherObject,
385
+ processRtcStatsReport,
386
+ Browser,
387
+ SDP,
388
+ logger,
389
+ stripCodecs,
390
+ getCurrentCodecAndSampleRate
372
391
  };
@@ -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;