@techsee/techsee-media-service 0.6.0-alpha.1 → 0.6.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["webrtc/helper.js"],"names":["trace","window","TSMediaServiceHelper","_resolutionToConstraints","resolution","split","width","height","CONSTRAINTS_TYPES","MIN","IDEAL","POSSIBLE_RESOLUTIONS","FALLBACK_RESOLUTION","_constraintByType","value","type","min","ideal","getMediaConstraints","deviceOpts","constraintType","TsMediaService","getDevices","then","devices","groupedDevices","video","_","filter","device","kind","toLowerCase","audio","videoDevice","last","audioDevice","mediaConstraints","videoResolution","assign","deviceId","facingMode","frameRate","max","getVideoTrackSettings","stream","videoTracks","getTracks","track","isEmpty","videoTrack","getSettings","_constraintsByResolution","_handleGetUserMediaError","error","errorName","get","code","name","getHighestResolutionStream","constraints","createLocalMediaStream","successfulConstraintsFound","Promise","resolve","reject","reduce","total","potentialConstraints","catch","err"],"mappings":"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","file":"helper.js","sourcesContent":["import {TsMediaService} from '../service';\n\nimport {getTracer} from '../tracer';\n\nconst trace = getTracer('TSMediaServiceHelper', () => window.TSMediaServiceHelper === true);\n\nfunction _resolutionToConstraints(resolution) {\n const [width, height] = resolution.split('x');\n\n return {width, height};\n}\n\nexport const CONSTRAINTS_TYPES = {\n MIN: 'min',\n IDEAL: 'ideal'\n};\n\nexport const POSSIBLE_RESOLUTIONS = [\n //'3840x2160', // 4k - disabled since it's an overkill\n '1920x1080', // FHD\n '1280x720' // HD\n];\n\n// In case all possible resolution fails, we'll attempt to set the highest resolution as ideal\nexport const FALLBACK_RESOLUTION = POSSIBLE_RESOLUTIONS[0];\n\nfunction _constraintByType(value, type) {\n switch (type) {\n case CONSTRAINTS_TYPES.MIN:\n return {min: value};\n default:\n return {ideal: value};\n }\n}\n\nexport const getMediaConstraints = ({resolution, deviceOpts, constraintType}) =>\n TsMediaService.getDevices()\n .then((devices) => {\n const groupedDevices = {\n video: _.filter(devices, (device) =>\n device.kind.toLowerCase() === 'videoinput'),\n audio: _.filter(devices, (device) =>\n device.kind.toLowerCase() === 'audioinput')\n };\n\n const videoDevice = deviceOpts.video && _.last(groupedDevices.video);\n const audioDevice = deviceOpts.audio && _.last(groupedDevices.audio);\n\n const mediaConstraints = {};\n trace('getMediaConstraints', videoDevice);\n if (videoDevice) {\n const videoResolution = _resolutionToConstraints(resolution);\n\n _.assign(mediaConstraints, {\n video: {\n deviceId: videoDevice.deviceId,\n width: _constraintByType(videoResolution.width, constraintType),\n height: _constraintByType(videoResolution.height, constraintType),\n facingMode: 'environment',\n frameRate: {ideal: 15, max: 30}\n }\n });\n }\n\n if (audioDevice) {\n _.assign(mediaConstraints, {\n audio: {deviceId: audioDevice.deviceId}\n });\n }\n\n return mediaConstraints;\n });\n\nexport const getVideoTrackSettings = (stream) => {\n const videoTracks = stream.getTracks()\n .filter((track) => (track.kind === 'video'));\n\n if (_.isEmpty(videoTracks)) {\n return;\n }\n\n const videoTrack = videoTracks[0];\n\n return videoTrack.getSettings && videoTrack.getSettings();\n};\n\nfunction _constraintsByResolution(resolution, deviceOpts, constraintType) {\n return getMediaConstraints({\n resolution: resolution,\n deviceOpts: deviceOpts,\n constraintType: constraintType\n });\n}\n\nfunction _handleGetUserMediaError(error) {\n const errorName = _.get(error, 'name');\n\n if (errorName === 'NotAllowedError') {\n return {code: 1500, name: 'NotAllowedError'};\n }\n\n if (errorName === 'PermissionDismissedError') {\n return {code: 8, name: 'PermissionDismissedError'};\n }\n\n return {code: 999, name: errorName || 'UnknownError'};\n}\n\n/**\n * Scan possible resolutions from high to low, trying to set each as minimal.\n * Eventually, use a fallback as ideal so the browser may decide which to use.\n *\n * @method\n * @param {Object} [deviceOpts] Devices to limit to in the constraints\n * @param {Object} [constraints] Media constraints\n *\n * @returns { Promise }\n *\n */\nexport const getHighestResolutionStream = (deviceOpts, constraints) => {\n // In case we had a constraints scan before, return the best\n if (constraints) {\n return TsMediaService.createLocalMediaStream(constraints)\n .then((stream) => ({stream, constraints}));\n }\n\n let successfulConstraintsFound = false;\n\n return new Promise((resolve, reject) => {\n Promise.reduce(POSSIBLE_RESOLUTIONS, (total, resolution) => {\n if (successfulConstraintsFound) {\n return;\n }\n\n return _constraintsByResolution(resolution, deviceOpts, CONSTRAINTS_TYPES.MIN)\n .then((potentialConstraints) => TsMediaService.createLocalMediaStream(potentialConstraints)\n .then((stream) => {\n successfulConstraintsFound = true;\n\n return resolve({stream, constraints: potentialConstraints});\n }))\n .catch(() => null);\n }, 0)\n .then(() => {\n if (successfulConstraintsFound) {\n return;\n }\n\n _constraintsByResolution(FALLBACK_RESOLUTION, deviceOpts, CONSTRAINTS_TYPES.IDEAL)\n .then((potentialConstraints) => TsMediaService.createLocalMediaStream(potentialConstraints)\n .then((stream) => resolve({stream, constraints: potentialConstraints})))\n .catch((err) => reject(_handleGetUserMediaError(err)));\n });\n });\n};\n"]}
1
+ {"version":3,"sources":["webrtc/helper.js"],"names":["tracer","_resolutionToConstraints","resolution","split","width","height","CONSTRAINTS_TYPES","MIN","IDEAL","POSSIBLE_RESOLUTIONS","FALLBACK_RESOLUTION","_constraintByType","value","type","min","ideal","getMediaConstraints","deviceOpts","constraintType","TsMediaService","getDevices","then","devices","groupedDevices","video","_","filter","device","kind","toLowerCase","audio","videoDevice","last","audioDevice","mediaConstraints","trace","videoResolution","assign","deviceId","facingMode","frameRate","max","getVideoTrackSettings","stream","videoTracks","getTracks","track","isEmpty","videoTrack","getSettings","_constraintsByResolution","_handleGetUserMediaError","error","errorName","get","code","name","getHighestResolutionStream","constraints","createLocalMediaStream","successfulConstraintsFound","Promise","resolve","reject","reduce","total","potentialConstraints","catch","err"],"mappings":"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","file":"helper.js","sourcesContent":["import {TsMediaService} from '../service';\n\nimport {getTracer} from '../tracer';\n\nconst tracer = getTracer('TSMediaServiceHelper');\n\nfunction _resolutionToConstraints(resolution) {\n const [width, height] = resolution.split('x');\n\n return {width, height};\n}\n\nexport const CONSTRAINTS_TYPES = {\n MIN: 'min',\n IDEAL: 'ideal'\n};\n\nexport const POSSIBLE_RESOLUTIONS = [\n //'3840x2160', // 4k - disabled since it's an overkill\n '1920x1080', // FHD\n '1280x720' // HD\n];\n\n// In case all possible resolution fails, we'll attempt to set the highest resolution as ideal\nexport const FALLBACK_RESOLUTION = POSSIBLE_RESOLUTIONS[0];\n\nfunction _constraintByType(value, type) {\n switch (type) {\n case CONSTRAINTS_TYPES.MIN:\n return {min: value};\n default:\n return {ideal: value};\n }\n}\n\nexport const getMediaConstraints = ({resolution, deviceOpts, constraintType}) =>\n TsMediaService.getDevices()\n .then((devices) => {\n const groupedDevices = {\n video: _.filter(devices, (device) =>\n device.kind.toLowerCase() === 'videoinput'),\n audio: _.filter(devices, (device) =>\n device.kind.toLowerCase() === 'audioinput')\n };\n\n const videoDevice = deviceOpts.video && _.last(groupedDevices.video);\n const audioDevice = deviceOpts.audio && _.last(groupedDevices.audio);\n\n const mediaConstraints = {};\n tracer.trace('getMediaConstraints', videoDevice);\n if (videoDevice) {\n const videoResolution = _resolutionToConstraints(resolution);\n\n _.assign(mediaConstraints, {\n video: {\n deviceId: videoDevice.deviceId,\n width: _constraintByType(videoResolution.width, constraintType),\n height: _constraintByType(videoResolution.height, constraintType),\n facingMode: 'environment',\n frameRate: {ideal: 15, max: 30}\n }\n });\n }\n\n if (audioDevice) {\n _.assign(mediaConstraints, {\n audio: {deviceId: audioDevice.deviceId}\n });\n }\n\n return mediaConstraints;\n });\n\nexport const getVideoTrackSettings = (stream) => {\n const videoTracks = stream.getTracks()\n .filter((track) => (track.kind === 'video'));\n\n if (_.isEmpty(videoTracks)) {\n return;\n }\n\n const videoTrack = videoTracks[0];\n\n return videoTrack.getSettings && videoTrack.getSettings();\n};\n\nfunction _constraintsByResolution(resolution, deviceOpts, constraintType) {\n return getMediaConstraints({\n resolution: resolution,\n deviceOpts: deviceOpts,\n constraintType: constraintType\n });\n}\n\nfunction _handleGetUserMediaError(error) {\n const errorName = _.get(error, 'name');\n\n if (errorName === 'NotAllowedError') {\n return {code: 1500, name: 'NotAllowedError'};\n }\n\n if (errorName === 'PermissionDismissedError') {\n return {code: 8, name: 'PermissionDismissedError'};\n }\n\n return {code: 999, name: errorName || 'UnknownError'};\n}\n\n/**\n * Scan possible resolutions from high to low, trying to set each as minimal.\n * Eventually, use a fallback as ideal so the browser may decide which to use.\n *\n * @method\n * @param {Object} [deviceOpts] Devices to limit to in the constraints\n * @param {Object} [constraints] Media constraints\n *\n * @returns { Promise }\n *\n */\nexport const getHighestResolutionStream = (deviceOpts, constraints) => {\n // In case we had a constraints scan before, return the best\n if (constraints) {\n return TsMediaService.createLocalMediaStream(constraints)\n .then((stream) => ({stream, constraints}));\n }\n\n let successfulConstraintsFound = false;\n\n return new Promise((resolve, reject) => {\n Promise.reduce(POSSIBLE_RESOLUTIONS, (total, resolution) => {\n if (successfulConstraintsFound) {\n return;\n }\n\n return _constraintsByResolution(resolution, deviceOpts, CONSTRAINTS_TYPES.MIN)\n .then((potentialConstraints) => TsMediaService.createLocalMediaStream(potentialConstraints)\n .then((stream) => {\n successfulConstraintsFound = true;\n\n return resolve({stream, constraints: potentialConstraints});\n }))\n .catch(() => null);\n }, 0)\n .then(() => {\n if (successfulConstraintsFound) {\n return;\n }\n\n _constraintsByResolution(FALLBACK_RESOLUTION, deviceOpts, CONSTRAINTS_TYPES.IDEAL)\n .then((potentialConstraints) => TsMediaService.createLocalMediaStream(potentialConstraints)\n .then((stream) => resolve({stream, constraints: potentialConstraints})))\n .catch((err) => reject(_handleGetUserMediaError(err)));\n });\n });\n};\n"]}
@@ -36,9 +36,7 @@ var isIE11 = new _tsEnvironmentDetect.TsEnvironmentDetect().isIE11();
36
36
  var _require = require('kurento-utils'),
37
37
  WebRtcPeer = _require.WebRtcPeer; // eslint-disable-line global-require
38
38
 
39
- var trace = (0, _tracer.getTracer)('TurnWebRTCSession', function () {
40
- return window.TurnSessionDebug === true || true;
41
- });
39
+ var tracer = (0, _tracer.getTracer)();
42
40
 
43
41
  /**
44
42
  * WebRTC-specific implementation of TsMediaSession.
@@ -65,7 +63,7 @@ var TurnWebRTCSession = exports.TurnWebRTCSession = function (_TsMediaSession) {
65
63
 
66
64
  var _this = _possibleConstructorReturn(this, _TsMediaSession.call(this));
67
65
 
68
- trace('Constructor');
66
+ tracer.trace('Constructor');
69
67
 
70
68
  _this._credentials = credentials;
71
69
  _this._isMobile = isMobile;
@@ -127,7 +125,7 @@ var TurnWebRTCSession = exports.TurnWebRTCSession = function (_TsMediaSession) {
127
125
  var _this2 = this;
128
126
 
129
127
  return new Promise(function (resolve, reject) {
130
- trace('Connect socket');
128
+ tracer.trace('Connect socket');
131
129
  var socket = io.connect(url, {
132
130
  'forceNew': true,
133
131
  'reconnectionDelay': _constants.SOCKET_RECONNECTION_DELAY,
@@ -137,7 +135,7 @@ var TurnWebRTCSession = exports.TurnWebRTCSession = function (_TsMediaSession) {
137
135
  });
138
136
 
139
137
  var done = _.once(function (err) {
140
- trace(err ? 'Error' : 'Connected', err);
138
+ tracer.trace(err ? 'Error' : 'Connected', err);
141
139
  err ? reject(err) : resolve();
142
140
  });
143
141
 
@@ -162,12 +160,12 @@ var TurnWebRTCSession = exports.TurnWebRTCSession = function (_TsMediaSession) {
162
160
  uid = _ref2.uid,
163
161
  peerId = _ref2.peerId;
164
162
 
165
- trace('SOCKET_EVENTS.INCOMING.JOIN_RESPONSE');
163
+ tracer.trace('SOCKET_EVENTS.INCOMING.JOIN_RESPONSE');
166
164
 
167
165
  var pc = _this2._pcs[peerId];
168
166
 
169
167
  if (!pc) {
170
- trace('No peer found');
168
+ tracer.trace('No peer found');
171
169
  var error = 'pc not found. peer=' + peerId + ' uid=' + uid;
172
170
 
173
171
  _this2.emit(_session.EVENTS.EXCEPTION, { source: 'JOIN_RESPONSE', error: error });
@@ -182,12 +180,12 @@ var TurnWebRTCSession = exports.TurnWebRTCSession = function (_TsMediaSession) {
182
180
  return done(error);
183
181
  }
184
182
 
185
- trace('ANSWER PROCESSED');
183
+ tracer.trace('ANSWER PROCESSED');
186
184
 
187
185
  // FIXME why don't we have _incomingIce per PC? current assumes we don't have parallel connections, not good
188
186
  _.forEach(_this2._incomingIce, function (candidate) {
189
187
  pc.addIceCandidate(candidate, function (error) {
190
- trace('ICE ADDED AFTER ANSWER');
188
+ tracer.trace('ICE ADDED AFTER ANSWER');
191
189
  if (error) {
192
190
  _this2.emit(_session.EVENTS.EXCEPTION, { source: 'JOIN_RESPONSE addIceCandidate', error: error });
193
191
  }
@@ -208,18 +206,18 @@ var TurnWebRTCSession = exports.TurnWebRTCSession = function (_TsMediaSession) {
208
206
  var candidate = _ref3.candidate,
209
207
  peerId = _ref3.peerId;
210
208
 
211
- trace('SOCKET_EVENTS.INCOMING.ICE_CANDIDATE');
209
+ tracer.trace('SOCKET_EVENTS.INCOMING.ICE_CANDIDATE');
212
210
  var pc = _this2._pcs[peerId];
213
211
 
214
212
  if (!pc) {
215
- trace('NO PEER FOUND ADD TO ICE QUEUE');
213
+ tracer.trace('NO PEER FOUND ADD TO ICE QUEUE');
216
214
  _this2._incomingIce.push(candidate);
217
215
 
218
216
  return;
219
217
  }
220
218
 
221
219
  pc.addIceCandidate(candidate, function (error) {
222
- trace('ICE ADDED AFTER INCOMING');
220
+ tracer.trace('ICE ADDED AFTER INCOMING');
223
221
  if (error) {
224
222
  _this2.emit(_session.EVENTS.EXCEPTION, { source: 'ICE_CANDIDATE addIceCandidate', error: error });
225
223
  }
@@ -231,13 +229,13 @@ var TurnWebRTCSession = exports.TurnWebRTCSession = function (_TsMediaSession) {
231
229
  var uid = _ref4.uid,
232
230
  peerId = _ref4.peerId;
233
231
 
234
- trace('SOCKET_EVENTS.INCOMING.SEND_OFFER');
232
+ tracer.trace('SOCKET_EVENTS.INCOMING.SEND_OFFER');
235
233
 
236
234
  _this2._createRTCPeerConnection(peerId).then(function (pc) {
237
- trace('GENERATING OFFER');
235
+ tracer.trace('GENERATING OFFER');
238
236
 
239
237
  pc.generateOffer(function (error, offer) {
240
- trace('OFFER GENERATED');
238
+ tracer.trace('OFFER GENERATED');
241
239
 
242
240
  if (error) {
243
241
  return done(error);
@@ -264,21 +262,21 @@ var TurnWebRTCSession = exports.TurnWebRTCSession = function (_TsMediaSession) {
264
262
  peerId = _ref5.peerId,
265
263
  uid = _ref5.uid;
266
264
 
267
- trace('SOCKET_EVENTS.INCOMING.SDP_OFFER');
265
+ tracer.trace('SOCKET_EVENTS.INCOMING.SDP_OFFER');
268
266
 
269
267
  Promise.resolve().then(function () {
270
268
  var pc = _this2._pcs[peerId];
271
269
 
272
270
  if (pc) {
273
- trace('PEER ALREADY EXISTS');
271
+ tracer.trace('PEER ALREADY EXISTS');
274
272
  return pc;
275
273
  }
276
274
 
277
275
  return _this2._createRTCPeerConnection(peerId);
278
276
  }).then(function (pc) {
279
- trace('PROCESS OFFER');
277
+ tracer.trace('PROCESS OFFER');
280
278
  pc.processOffer(sdpOffer, function (error, sdpAnswer) {
281
- trace('OFFER PROCESSED');
279
+ tracer.trace('OFFER PROCESSED');
282
280
  if (error) {
283
281
  return done(error);
284
282
  }
@@ -300,7 +298,7 @@ var TurnWebRTCSession = exports.TurnWebRTCSession = function (_TsMediaSession) {
300
298
 
301
299
  // Received by subscriber after a publisher reconnects to room
302
300
  socket.on(_constants.SOCKET_EVENTS.INCOMING.PUBLISHER_RECONNECT, function () {
303
- trace('SOCKET_EVENTS.INCOMING.PUBLISHER_RECONNECT');
301
+ tracer.trace('SOCKET_EVENTS.INCOMING.PUBLISHER_RECONNECT');
304
302
 
305
303
  // Clean up and reconnect with a new peer-connection,
306
304
  // to prevent reconnection issues
@@ -310,7 +308,7 @@ var TurnWebRTCSession = exports.TurnWebRTCSession = function (_TsMediaSession) {
310
308
  _.forEach(_this2._pcs, function (_ref6) {
311
309
  var peerConnection = _ref6.peerConnection;
312
310
 
313
- trace('CLOSING PEER');
311
+ tracer.trace('CLOSING PEER');
314
312
  peerConnection.close();
315
313
  });
316
314
  _this2._pcs = {};
@@ -323,7 +321,7 @@ var TurnWebRTCSession = exports.TurnWebRTCSession = function (_TsMediaSession) {
323
321
  var _ref7 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
324
322
  peerId = _ref7.peerId;
325
323
 
326
- trace('SOCKET_EVENTS.INCOMING.PEER_DISCONNECTED');
324
+ tracer.trace('SOCKET_EVENTS.INCOMING.PEER_DISCONNECTED');
327
325
 
328
326
  if (peerId && _this2._pcs[peerId]) {
329
327
  if (_this2._lastPc === _this2._pcs[peerId]) {
@@ -348,9 +346,9 @@ var TurnWebRTCSession = exports.TurnWebRTCSession = function (_TsMediaSession) {
348
346
  var _this3 = this;
349
347
 
350
348
  return new Promise(function (resolve) {
351
- trace('_setupConnection');
349
+ tracer.trace('_setupConnection');
352
350
  pc.peerConnection.oniceconnectionstatechange = function (e) {
353
- trace('oniceconnectionstatechange', e);
351
+ tracer.trace('oniceconnectionstatechange', e);
354
352
 
355
353
  if (_this3.iceCheckingTimeout) {
356
354
  clearTimeout(_this3.iceCheckingTimeout);
@@ -390,7 +388,7 @@ var TurnWebRTCSession = exports.TurnWebRTCSession = function (_TsMediaSession) {
390
388
  pc.peerConnection.onremovestream = function (_ref8) {
391
389
  var stream = _ref8.stream;
392
390
 
393
- trace('onremovestream');
391
+ tracer.trace('onremovestream');
394
392
  _this3._streams.delete(stream.id);
395
393
  };
396
394
 
@@ -416,21 +414,21 @@ var TurnWebRTCSession = exports.TurnWebRTCSession = function (_TsMediaSession) {
416
414
  peerId = _ref9.peerId;
417
415
 
418
416
  return new Promise(function (resolve, reject) {
419
- trace('_connectRTCPeer');
417
+ tracer.trace('_connectRTCPeer');
420
418
 
421
419
  var done = _.once(function (err, pc) {
422
- trace(err ? 'Error' : 'Peer Connected', err);
420
+ tracer.trace(err ? 'Error' : 'Peer Connected', err);
423
421
  err ? reject(err) : resolve(pc);
424
422
  });
425
423
  var setupWebRtcPeer = function setupWebRtcPeer(stream) {
426
- trace('setupWebRtcPeer');
424
+ tracer.trace('setupWebRtcPeer');
427
425
  var peerConnectionType = _this4._getPeerType(constraints, isMobile);
428
426
  var peerConfig = {
429
427
  configuration: configuration,
430
428
  videoStream: isMobile ? stream : undefined,
431
429
  mediaConstraints: constraints,
432
430
  onicecandidate: function onicecandidate(candidate) {
433
- trace('onicecandidate', candidate);
431
+ tracer.trace('onicecandidate', candidate);
434
432
  _this4._socket.emit(_constants.SOCKET_EVENTS.OUTGOING.ICE_CANDIDATE, {
435
433
  sessionId: sessionId,
436
434
  peerId: peerId,
@@ -463,7 +461,7 @@ var TurnWebRTCSession = exports.TurnWebRTCSession = function (_TsMediaSession) {
463
461
  };
464
462
 
465
463
  TurnWebRTCSession.prototype._setTrackStateTo = function _setTrackStateTo(state) {
466
- trace('_setTrackStateTo');
464
+ tracer.trace('_setTrackStateTo');
467
465
  return function (track) {
468
466
  if (track.setEnabled) {
469
467
  track.setEnabled(state);
@@ -486,17 +484,20 @@ var TurnWebRTCSession = exports.TurnWebRTCSession = function (_TsMediaSession) {
486
484
  TurnWebRTCSession.prototype.connect = function connect() {
487
485
  var _this5 = this;
488
486
 
489
- trace('connect');
487
+ tracer.trace('connect');
490
488
  return this._connectSocket(this._credentials.url).then(function () {
491
- trace('Socket connected getting constraints');
489
+ tracer.trace('Socket connected getting constraints');
492
490
  return (0, _helper.getMediaConstraints)({
493
491
  resolution: _this5._resolution,
494
492
  deviceOpts: _this5._deviceOpts
495
493
  });
496
494
  }).then(function (constraints) {
495
+ tracer.trace('connect - constraints', constraints);
496
+
497
497
  // streaming from dashboard is not supported and we
498
498
  // don't want to access the camera without a reason
499
499
  if (!_this5._isMobile && constraints.video) {
500
+ tracer.trace('connect - deleting video for non mobile');
500
501
  delete constraints.video;
501
502
  }
502
503
 
@@ -504,11 +505,16 @@ var TurnWebRTCSession = exports.TurnWebRTCSession = function (_TsMediaSession) {
504
505
 
505
506
  var clientType = _this5._isMobile ? _constants.CLIENT_TYPES.PUBLISHER : _constants.CLIENT_TYPES.SUBSCRIBER;
506
507
 
508
+ tracer.trace('connect - emitting joinRoom', {
509
+ clientType: clientType,
510
+ sessionId: _this5._credentials.sessionId
511
+ });
507
512
  _this5._socket.emit(_constants.SOCKET_EVENTS.OUTGOING.JOIN_ROOM, {
508
513
  clientType: clientType,
509
514
  sessionId: _this5._credentials.sessionId
510
515
  });
511
516
  }).catch(function (error) {
517
+ tracer.trace('connect error', error);
512
518
  _this5.emit(_session.EVENTS.EXCEPTION, { source: 'connect', error: error });
513
519
  throw error;
514
520
  });
@@ -517,7 +523,7 @@ var TurnWebRTCSession = exports.TurnWebRTCSession = function (_TsMediaSession) {
517
523
  TurnWebRTCSession.prototype._createRTCPeerConnection = function _createRTCPeerConnection(peerId) {
518
524
  var _this6 = this;
519
525
 
520
- trace('_createRTCPeerConnection');
526
+ tracer.trace('_createRTCPeerConnection');
521
527
  return this._connectRTCPeer({
522
528
  constraints: this._constraints,
523
529
  configuration: this._configuration,
@@ -525,7 +531,7 @@ var TurnWebRTCSession = exports.TurnWebRTCSession = function (_TsMediaSession) {
525
531
  isMobile: this._isMobile,
526
532
  peerId: peerId
527
533
  }).then(function (pc) {
528
- trace('peer connection created');
534
+ tracer.trace('peer connection created');
529
535
 
530
536
  if (_this6._isMobile) {
531
537
  pc.peerConnection.getLocalStreams().forEach(function (stream) {
@@ -538,7 +544,7 @@ var TurnWebRTCSession = exports.TurnWebRTCSession = function (_TsMediaSession) {
538
544
  pc.peerConnection.onaddstream = function (_ref10) {
539
545
  var stream = _ref10.stream;
540
546
 
541
- trace('peer connection onaddstream', stream);
547
+ tracer.trace('peer connection onaddstream', stream);
542
548
  var tsStream = new _stream.TsWebRTCStream(_this6, stream);
543
549
 
544
550
  _this6.emit(_session.EVENTS.STREAM_CREATED, tsStream);
@@ -591,7 +597,7 @@ var TurnWebRTCSession = exports.TurnWebRTCSession = function (_TsMediaSession) {
591
597
  TurnWebRTCSession.prototype.disconnect = function disconnect() {
592
598
  var _this9 = this;
593
599
 
594
- trace('disconnect');
600
+ tracer.trace('disconnect');
595
601
  return Promise.resolve().then(function () {
596
602
  if (_this9.destroyed) {
597
603
  return null;
@@ -615,7 +621,7 @@ var TurnWebRTCSession = exports.TurnWebRTCSession = function (_TsMediaSession) {
615
621
  };
616
622
 
617
623
  TurnWebRTCSession.prototype._waitForPublishingApproval = function _waitForPublishingApproval(caller, cb) {
618
- trace('_waitForPublishingApproval');
624
+ tracer.trace('_waitForPublishingApproval');
619
625
  try {
620
626
  var pc = _.get(caller, '_lastPc.peerConnection');
621
627
 
@@ -673,7 +679,7 @@ var TurnWebRTCSession = exports.TurnWebRTCSession = function (_TsMediaSession) {
673
679
  target = null;
674
680
  }
675
681
 
676
- trace('createPublisher');
682
+ tracer.trace('createPublisher');
677
683
 
678
684
  return (this._lastPc ? Promise.resolve() : Promise.delay(_constants.WAIT_FOR_PC_INTERVAL)).then(function () {
679
685
  return new Promise(function (resolve, reject) {
@@ -699,8 +705,6 @@ var TurnWebRTCSession = exports.TurnWebRTCSession = function (_TsMediaSession) {
699
705
  return result;
700
706
  }, []);
701
707
 
702
- trace('createPublisher tracks', tracks);
703
-
704
708
  var tsstream = new _stream.TsWebRTCStream(_this10, mediaStream, params.name);
705
709
 
706
710
  tsstream.remote = false;
@@ -745,7 +749,7 @@ var TurnWebRTCSession = exports.TurnWebRTCSession = function (_TsMediaSession) {
745
749
  TurnWebRTCSession.prototype.publish = function publish(publisher) {
746
750
  var _this11 = this;
747
751
 
748
- trace('publish');
752
+ tracer.trace('publish');
749
753
  return Promise.resolve().then(function () {
750
754
  if (!publisher) {
751
755
  return;
@@ -849,7 +853,7 @@ var TurnWebRTCSession = exports.TurnWebRTCSession = function (_TsMediaSession) {
849
853
  TurnWebRTCSession.prototype.destroyPublisher = function destroyPublisher(publisher) {
850
854
  var _this12 = this;
851
855
 
852
- trace('destroyPublisher');
856
+ tracer.trace('destroyPublisher');
853
857
  return new Promise(function (resolve) {
854
858
  _this12._toggleAllStreams(false);
855
859
 
@@ -1 +1 @@
1
- {"version":3,"sources":["webrtc/session-turn.js"],"names":["io","isIE11","TsEnvironmentDetect","require","WebRtcPeer","trace","window","TurnSessionDebug","TurnWebRTCSession","localStreamFactory","credentials","isMobile","resolution","deviceOpts","_credentials","_isMobile","_resolution","_deviceOpts","_incomingIce","_localStreamFactory","iceServers","ice","map","item","urls","url","username","login","credential","password","_configuration","iceTransportPolicy","_socket","_pcs","_connectSocket","Promise","resolve","reject","socket","connect","SOCKET_RECONNECTION_DELAY","SOCKET_RECONNECTION_DELAY_MAX","SOCKET_RECONNECTION_ATTEMPTS","SOCKET_PATH","done","_","once","err","on","SOCKET_EVENTS","INCOMING","ERROR","JOIN_RESPONSE","sdpAnswer","uid","peerId","pc","error","emit","EVENTS","EXCEPTION","source","processAnswer","forEach","candidate","addIceCandidate","length","CONNECTED","publish","publisher","catch","ICE_CANDIDATE","push","SEND_OFFER","_createRTCPeerConnection","then","generateOffer","offer","OUTGOING","SDP_OFFER","sessionId","sdpOffer","name","lastError","processOffer","SDP_ANSWER","PUBLISHER_RECONNECT","_streams","clear","off","peerConnection","close","RECONNECT_TURN_SERVER","PEER_DISCONNECTED","_lastPc","Object","getOwnPropertyNames","_toggleAllStreams","_setupConnection","oniceconnectionstatechange","e","iceCheckingTimeout","clearTimeout","target","iceConnectionState","_turnServerReconnectInterval","setInterval","navigator","onLine","clearInterval","connected","disconnected","RECONNECT_TURN_SERVER_INTERVAL","setTimeout","TURN_SERVER_CONNECTION_FAILED","FAILED_CONNECTING_TURN_SERVER_INTERVAL","onremovestream","stream","delete","id","_getPeerType","constraints","audio","PEER_CONNECTION_TYPES","SEND_RECV","RECV_ONLY","_connectRTCPeer","configuration","setupWebRtcPeer","peerConnectionType","peerConfig","videoStream","undefined","mediaConstraints","onicecandidate","clientType","CLIENT_TYPES","PUBLISHER","SUBSCRIBER","localStream","_setTrackStateTo","state","track","setEnabled","enabled","video","_constraints","JOIN_ROOM","getLocalStreams","getTracks","onaddstream","tsStream","TsWebRTCStream","STREAM_CREATED","_stopStream","stop","_stopAllStreams","disconnect","destroyed","event","reason","DISCONNECTED","_waitForPublishingApproval","caller","cb","get","Error","mediaStream","code","PUBLISH_APPROVAL_CHECK_INTERVAL","createPublisher","params","delay","WAIT_FOR_PC_INTERVAL","tracks","reduce","result","filter","kind","videoDevice","audioDevice","tsstream","remote","TsMediaPublisher","videoParams","videoHeight","videoDimensions","height","videoWidth","width","_target","PUBLISHER_EVENTS","STREAM_PROPERTY_CHANGED","property","value","hasVideo","hasAudio","_element","document","createElement","videoTracks","_mediaStream","getVideoTracks","srcObject","MediaStream","playsInline","autoplay","muted","appendChild","attachMediaStream","assign","fitMode","insertMode","mirror","elementHeight","elementWidth","style","position","setupDimensionsListener","destroyPublisher","remove","DESTROYED","TsMediaSession"],"mappings":"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","file":"session-turn.js","sourcesContent":["import {\n EVENTS,\n TsMediaSession\n} from '../session';\n\nimport {\n EVENTS as PUBLISHER_EVENTS,\n TsMediaPublisher\n} from '../publisher';\n\nimport {\n TsWebRTCStream\n} from './stream';\n\nimport * as io from 'socket.io-client';\n\nimport {TsEnvironmentDetect} from '@techsee/techsee-common/lib/helpers/ts-environment-detect';\n\nconst isIE11 = (new TsEnvironmentDetect()).isIE11();\n\nconst {WebRtcPeer} = require('kurento-utils'); // eslint-disable-line global-require\n\nimport {\n CLIENT_TYPES,\n FAILED_CONNECTING_TURN_SERVER_INTERVAL,\n PEER_CONNECTION_TYPES,\n PUBLISH_APPROVAL_CHECK_INTERVAL,\n RECONNECT_TURN_SERVER_INTERVAL,\n SOCKET_EVENTS,\n SOCKET_PATH,\n SOCKET_RECONNECTION_ATTEMPTS,\n SOCKET_RECONNECTION_DELAY,\n SOCKET_RECONNECTION_DELAY_MAX,\n WAIT_FOR_PC_INTERVAL\n} from './constants';\n\nimport {\n getMediaConstraints\n} from './helper';\n\nimport {getTracer} from '../tracer';\n\nconst trace = getTracer('TurnWebRTCSession', () => window.TurnSessionDebug === true || true);\n\n/**\n * WebRTC-specific implementation of TsMediaSession.\n *\n * Instance of this class is returned by TsMediaService.initSession call\n * with 'TURN_SERVER' as desired mediaType.\n *\n * @class\n * @extends TsMediaSession\n *\n * @see TsMediaSession\n */\nexport class TurnWebRTCSession extends TsMediaSession {\n constructor({credentials, isMobile, resolution, deviceOpts}, localStreamFactory) {\n super();\n\n trace('Constructor');\n\n this._credentials = credentials;\n this._isMobile = isMobile;\n this._resolution = resolution;\n this._deviceOpts = deviceOpts;\n this._incomingIce = [];\n this._localStreamFactory = localStreamFactory;\n\n const iceServers = credentials.ice.map((item) => ({\n urls: item.url,\n username: item.login,\n credential: item.password\n }));\n\n this._configuration = {\n iceServers,\n\n iceTransportPolicy: 'relay'\n };\n\n /**\n * Socket.io connection to the signaling server\n *\n * @private\n * @member { Object }\n */\n this._socket = null;\n\n /**\n * RTCPeerConnection to the media server.\n *\n * For now kurento-utils is used for connection establishment.\n *\n * @private\n * @member { Object }\n */\n this._pcs = {};\n }\n\n /**\n * Id of the session.\n *\n * @member { String }\n *\n * @type { String }\n */\n get id() {\n return this._credentials.sessionId;\n }\n\n /**\n *\n * @member { String }\n *\n * @type { String }\n */\n _connectSocket(url) {\n return new Promise((resolve, reject) => {\n trace('Connect socket');\n const socket = io.connect(url, {\n 'forceNew': true,\n 'reconnectionDelay': SOCKET_RECONNECTION_DELAY,\n 'reconnectionDelayMax': SOCKET_RECONNECTION_DELAY_MAX,\n 'reconnectionAttempts': SOCKET_RECONNECTION_ATTEMPTS,\n 'path': SOCKET_PATH\n });\n\n const done = _.once((err) => {\n trace(err ? 'Error' : 'Connected', err);\n err ? reject(err) : resolve();\n });\n\n //\n // When connection is established\n //\n socket.once('connect', () => done());\n //\n // errorOccured is ts-media-client signal\n //\n socket.on(SOCKET_EVENTS.INCOMING.ERROR, done);\n //\n // And these 2 are socket.io connection failed events\n //\n socket.on('connect_error', done);\n socket.on('connect_timeout', done);\n\n socket.on(SOCKET_EVENTS.INCOMING.JOIN_RESPONSE, ({\n sdpAnswer,\n uid,\n peerId\n }) => {\n trace('SOCKET_EVENTS.INCOMING.JOIN_RESPONSE');\n\n const pc = this._pcs[peerId];\n\n if (!pc) {\n trace('No peer found');\n const error = `pc not found. peer=${peerId} uid=${uid}`;\n\n this.emit(EVENTS.EXCEPTION, {source: 'JOIN_RESPONSE', error});\n\n return done(error);\n }\n\n pc.processAnswer(sdpAnswer, (error) => {\n if (error) {\n this.emit(EVENTS.EXCEPTION, {source: 'processAnswer', error});\n\n return done(error);\n }\n\n trace('ANSWER PROCESSED');\n\n // FIXME why don't we have _incomingIce per PC? current assumes we don't have parallel connections, not good\n _.forEach(this._incomingIce, (candidate) => {\n pc.addIceCandidate(candidate, (error) => {\n trace('ICE ADDED AFTER ANSWER');\n if (error) {\n this.emit(EVENTS.EXCEPTION, {source: 'JOIN_RESPONSE addIceCandidate', error});\n }\n });\n });\n\n this._incomingIce.length = 0;\n });\n\n this.emit(EVENTS.CONNECTED);\n\n this.publish(this.publisher)\n .catch((error) => {\n this.emit(EVENTS.EXCEPTION, {source: 'publish', error});\n });\n });\n\n socket.on(SOCKET_EVENTS.INCOMING.ICE_CANDIDATE, ({\n candidate,\n peerId\n }) => {\n trace('SOCKET_EVENTS.INCOMING.ICE_CANDIDATE');\n const pc = this._pcs[peerId];\n\n if (!pc) {\n trace('NO PEER FOUND ADD TO ICE QUEUE');\n this._incomingIce.push(candidate);\n\n return;\n }\n\n pc.addIceCandidate(candidate, (error) => {\n trace('ICE ADDED AFTER INCOMING');\n if (error) {\n this.emit(EVENTS.EXCEPTION, {source: 'ICE_CANDIDATE addIceCandidate', error});\n }\n });\n });\n\n // Received by publisher, causing him to emit SDP_OFFER\n socket.on(SOCKET_EVENTS.INCOMING.SEND_OFFER, ({\n uid,\n peerId\n }) => {\n trace('SOCKET_EVENTS.INCOMING.SEND_OFFER');\n\n this._createRTCPeerConnection(peerId)\n .then((pc) => {\n trace('GENERATING OFFER');\n\n pc.generateOffer((error, offer) => {\n trace('OFFER GENERATED');\n\n if (error) {\n return done(error);\n }\n\n socket.emit(SOCKET_EVENTS.OUTGOING.SDP_OFFER, {\n uid,\n peerId,\n sessionId: this._credentials.sessionId,\n sdpOffer: offer\n });\n });\n })\n .catch((error) => {\n this.emit(EVENTS.EXCEPTION, {source: '_createRTCPeerConnection', error});\n if (error && error.name) {\n this.lastError = error.name;\n }\n });\n });\n\n // Received by subscriber, causing him to emit SDP_ANSWER\n socket.on(SOCKET_EVENTS.INCOMING.SDP_OFFER, ({\n sdpOffer,\n peerId,\n uid\n }) => {\n trace('SOCKET_EVENTS.INCOMING.SDP_OFFER');\n\n Promise.resolve()\n .then(() => {\n const pc = this._pcs[peerId];\n\n if (pc) {\n trace('PEER ALREADY EXISTS');\n return pc;\n }\n\n return this._createRTCPeerConnection(peerId);\n })\n .then((pc) => {\n trace('PROCESS OFFER');\n pc.processOffer(sdpOffer, (error, sdpAnswer) => {\n trace('OFFER PROCESSED');\n if (error) {\n return done(error);\n }\n\n socket.emit(SOCKET_EVENTS.OUTGOING.SDP_ANSWER, {\n uid,\n peerId,\n sessionId: this._credentials.sessionId,\n sdpAnswer: sdpAnswer\n });\n });\n })\n .catch((error) => {\n this.emit(EVENTS.EXCEPTION, {source: 'response on INCOMING.SDP_OFFER', error});\n if (error && error.name) {\n this.lastError = error.name;\n }\n });\n });\n\n // Received by subscriber after a publisher reconnects to room\n socket.on(SOCKET_EVENTS.INCOMING.PUBLISHER_RECONNECT, () => {\n trace('SOCKET_EVENTS.INCOMING.PUBLISHER_RECONNECT');\n\n // Clean up and reconnect with a new peer-connection,\n // to prevent reconnection issues\n\n this._streams.clear();\n socket.off();\n _.forEach(this._pcs, ({peerConnection}) => {\n trace('CLOSING PEER');\n peerConnection.close();\n });\n this._pcs = {};\n\n this.emit(EVENTS.RECONNECT_TURN_SERVER);\n });\n\n // Received by publisher after a subscriber's socket has been disconnected\n socket.on(SOCKET_EVENTS.INCOMING.PEER_DISCONNECTED, ({\n peerId\n } = {}) => {\n trace('SOCKET_EVENTS.INCOMING.PEER_DISCONNECTED');\n\n if (peerId && this._pcs[peerId]) {\n if (this._lastPc === this._pcs[peerId]) {\n this._lastPc = null;\n }\n\n if (Object.getOwnPropertyNames(this._pcs).length === 1) {\n this._toggleAllStreams(false);\n }\n\n this._pcs[peerId].peerConnection.close();\n\n delete this._pcs[peerId];\n }\n });\n\n this._socket = socket;\n });\n }\n\n _setupConnection(pc) {\n return new Promise((resolve) => {\n trace('_setupConnection');\n pc.peerConnection.oniceconnectionstatechange = (e) => {\n trace('oniceconnectionstatechange', e);\n\n if (this.iceCheckingTimeout) {\n clearTimeout(this.iceCheckingTimeout);\n this.iceCheckingTimeout = null;\n }\n\n if (e.target.iceConnectionState === 'failed') {\n // if this is one of many in the publisher, skip\n\n // already attempting a reconnect\n if (this._turnServerReconnectInterval) {\n return;\n }\n\n this._turnServerReconnectInterval = setInterval(() => {\n if (!navigator.onLine) {\n return;\n }\n\n clearInterval(this._turnServerReconnectInterval);\n this._turnServerReconnectInterval = null;\n\n if (!this._socket.connected) {\n this.disconnected = false;\n this._socket.connect();\n }\n\n this.emit(EVENTS.RECONNECT_TURN_SERVER);\n }, RECONNECT_TURN_SERVER_INTERVAL);\n } else if (e.target.iceConnectionState === 'checking') {\n this.iceCheckingTimeout = setTimeout(() => {\n this.emit(EVENTS.TURN_SERVER_CONNECTION_FAILED);\n }, FAILED_CONNECTING_TURN_SERVER_INTERVAL);\n }\n };\n\n pc.peerConnection.onremovestream = ({stream}) => {\n trace('onremovestream');\n this._streams.delete(stream.id);\n };\n\n resolve();\n });\n }\n\n _getPeerType(constraints, isMobile) {\n if (isMobile || constraints.audio) {\n return PEER_CONNECTION_TYPES.SEND_RECV;\n }\n\n return PEER_CONNECTION_TYPES.RECV_ONLY;\n }\n\n _connectRTCPeer({\n constraints,\n configuration,\n sessionId,\n isMobile,\n peerId\n }) {\n return new Promise((resolve, reject) => {\n trace('_connectRTCPeer');\n\n const done = _.once((err, pc) => {\n trace(err ? 'Error' : 'Peer Connected', err);\n err ? reject(err) : resolve(pc);\n });\n const setupWebRtcPeer = (stream) => {\n trace('setupWebRtcPeer');\n const peerConnectionType = this._getPeerType(constraints, isMobile);\n const peerConfig = {\n configuration,\n videoStream: isMobile ? stream : undefined,\n mediaConstraints: constraints,\n onicecandidate: (candidate) => {\n trace('onicecandidate', candidate);\n this._socket.emit(SOCKET_EVENTS.OUTGOING.ICE_CANDIDATE, {\n sessionId,\n peerId,\n candidate,\n clientType: isMobile ? CLIENT_TYPES.PUBLISHER : CLIENT_TYPES.SUBSCRIBER\n });\n }\n };\n\n const pc = WebRtcPeer[peerConnectionType](peerConfig, (error) => {\n if (error) {\n return done(error);\n }\n\n this._setupConnection(pc)\n .then(() => done(null, pc))\n .catch(done);\n });\n\n this._pcs[peerId] = pc;\n this._lastPc = pc;\n };\n\n this._localStreamFactory(constraints)\n .then((localStream) => {\n setupWebRtcPeer(localStream);\n })\n .catch(() => {\n setupWebRtcPeer(undefined);\n });\n });\n }\n\n _setTrackStateTo(state) {\n trace('_setTrackStateTo');\n return function (track) {\n if (track.setEnabled) {\n track.setEnabled(state);\n } else {\n track.enabled = state;\n }\n };\n }\n\n /**\n * Establish socket and peer connection to the media server.\n *\n * @method\n * @returns { Promise }\n *\n * @fires SESSION_EVENTS#CONNECTED\n */\n connect() {\n trace('connect');\n return this._connectSocket(this._credentials.url)\n .then(() => {\n trace('Socket connected getting constraints');\n return getMediaConstraints({\n resolution: this._resolution,\n deviceOpts: this._deviceOpts\n });\n })\n .then((constraints) => {\n // streaming from dashboard is not supported and we\n // don't want to access the camera without a reason\n if (!this._isMobile && constraints.video) {\n delete constraints.video;\n }\n\n this._constraints = constraints;\n\n const clientType = this._isMobile ? CLIENT_TYPES.PUBLISHER : CLIENT_TYPES.SUBSCRIBER;\n\n this._socket.emit(SOCKET_EVENTS.OUTGOING.JOIN_ROOM, {\n clientType,\n sessionId: this._credentials.sessionId\n });\n })\n .catch((error) => {\n this.emit(EVENTS.EXCEPTION, {source: 'connect', error});\n throw error;\n });\n }\n\n _createRTCPeerConnection(peerId) {\n trace('_createRTCPeerConnection');\n return this._connectRTCPeer({\n constraints: this._constraints,\n configuration: this._configuration,\n sessionId: this._credentials.sessionId,\n isMobile: this._isMobile,\n peerId: peerId\n })\n .then((pc) => {\n trace('peer connection created');\n\n if (this._isMobile) {\n pc.peerConnection.getLocalStreams().forEach((stream) => {\n if (!this.publisher) {\n stream.getTracks().forEach(this._setTrackStateTo(false));\n }\n });\n }\n\n pc.peerConnection.onaddstream = ({stream}) => {\n trace('peer connection onaddstream', stream);\n const tsStream = new TsWebRTCStream(this, stream);\n\n this.emit(EVENTS.STREAM_CREATED, tsStream);\n };\n\n return pc;\n });\n }\n\n _toggleAllStreams(state) {\n if (this._isMobile) {\n _.forEach(this._pcs, (pc) => {\n pc.peerConnection.getLocalStreams().forEach((stream) => {\n stream.getTracks().forEach(this._setTrackStateTo(state));\n });\n });\n }\n }\n\n _stopStream(pc) {\n if (this._isMobile) {\n pc.peerConnection.getLocalStreams().forEach((stream) => {\n stream.getTracks().forEach((track) => track.stop());\n });\n }\n }\n\n _stopAllStreams() {\n _.forEach(this._pcs, (pc) => this._stopStream(pc));\n }\n\n /**\n * Close all media streams, disconnect RTCPeerConnection and socket.io\n *\n * @method\n * @returns { Promise }\n *\n * @fires SESSION_EVENTS#DISCONNECTED\n */\n disconnect() {\n trace('disconnect');\n return Promise.resolve()\n .then(() => {\n if (this.destroyed) {\n return null;\n }\n\n this._stopAllStreams();\n\n _.forEach(this._pcs, ({peerConnection}) => peerConnection.close());\n this._pcs = {};\n this._socket.disconnect();\n\n const event = {reason: 'disconnected'};\n\n this.emit(EVENTS.DISCONNECTED, event);\n\n return event;\n });\n }\n\n _waitForPublishingApproval(caller, cb) {\n trace('_waitForPublishingApproval');\n try {\n const pc = _.get(caller, '_lastPc.peerConnection');\n\n if (!pc) {\n throw new Error('No peer connection for publishing');\n }\n\n //\n // Get media streams that were created on session initialization\n //\n const mediaStream = pc.getLocalStreams()[0];\n\n if (mediaStream) {\n return cb(null, mediaStream);\n }\n\n if (caller.lastError === 'NotAllowedError') {\n return cb({code: 1500, name: 'NotAllowedError'});\n } else if (caller.lastError === 'PermissionDismissedError') {\n return cb({code: 8, name: 'PermissionDismissedError'});\n }\n\n setTimeout(caller._waitForPublishingApproval, PUBLISH_APPROVAL_CHECK_INTERVAL, caller, cb);\n } catch (err) {\n return cb(err);\n }\n }\n\n /**\n * Create new TsMediaPublisher instance\n *\n * @method\n *\n * @param { DOMElement } [target] Video element\n * that will be used to render publishing video stream\n * @param { Object } params\n * @param { String } [params.videoDevice] Video device id\n * @param { String } [params.videoParams] Video device id\n * @param { String } [params.videoParams.fitMode] Video fit mode\n * @param { Number|String } [params.videoParams.width] Video element width\n * @param { Number|String } [params.videoParams.height] Video element height\n * @param { String } [params.audioDevice] Video device id\n *\n * @returns { Promise<TsMediaPublisher> } publisher\n *\n * @see TsMediaPublisher\n */\n createPublisher(target, params) {\n if (!params) {\n params = target;\n target = null;\n }\n\n trace('createPublisher');\n\n return (this._lastPc ? Promise.resolve() : Promise.delay(WAIT_FOR_PC_INTERVAL))\n .then(() => new Promise((resolve, reject) => {\n this._waitForPublishingApproval(this, (err, mediaStream) => {\n if (err) {\n return reject(err);\n }\n\n return resolve(mediaStream);\n });\n }))\n .then((mediaStream) => {\n //\n // Get tracks that are related to the publisher (audio or video)\n //\n const tracks = this._lastPc.peerConnection.getLocalStreams().reduce((result, mediaStream) => {\n mediaStream.getTracks()\n .filter((track) => (track.kind === 'video' && params.videoDevice) ||\n (track.kind === 'audio' && params.audioDevice))\n .forEach((track) => result.push(track));\n\n return result;\n }, []);\n\n trace('createPublisher tracks', tracks);\n\n const tsstream = new TsWebRTCStream(this, mediaStream, params.name);\n\n tsstream.remote = false;\n\n const publisher = new TsMediaPublisher(this, {\n stream: tsstream,\n tracks,\n videoParams: params.videoParams,\n\n videoHeight: tsstream.videoDimensions.height,\n videoWidth: tsstream.videoDimensions.width,\n\n _target: target\n });\n\n tsstream.publisher = publisher;\n this.publisher = publisher;\n\n return publisher;\n });\n }\n\n /**\n * Publish stream from previously create TsMediaPublisher instance.\n *\n * Used internally by TsMediaPublisher.publish\n *\n * @method\n *\n * @param { TsMediaPublisher } publisher\n *\n * @returns { Promise }\n *\n * @fires PUBLISHER_EVENTS#STREAM_CREATED\n * @fires SESSION_EVENTS#STREAM_PROPERTY_CHANGED\n * @fires STREAM_EVENTS#PROPERTY_CHANGED\n *\n * @see TsMediaPublisher#publish\n */\n publish(publisher) {\n trace('publish');\n return Promise.resolve()\n .then(() => {\n if (!publisher) {\n return;\n }\n\n publisher.emit(PUBLISHER_EVENTS.STREAM_CREATED, publisher.stream);\n this.emit(EVENTS.STREAM_PROPERTY_CHANGED, {\n stream: publisher.stream,\n property: 'hasVideo',\n value: publisher.stream.hasVideo\n });\n this.emit(EVENTS.STREAM_PROPERTY_CHANGED, {\n stream: publisher.stream,\n property: 'hasAudio',\n value: publisher.stream.hasAudio\n });\n\n if (this.publisher._element) {\n return;\n }\n\n if (publisher._target) {\n //\n // New video element where publishing video stream will be rendered\n //\n const video = document.createElement('video');\n\n //Currently this code is used only in mobile, so when publishing, then we always need only video track\n //to set to video element. Otherwise, when VOIP enabled, technician side will hear himself through this video element.\n const videoTracks = publisher.stream._mediaStream.getVideoTracks();\n\n if (!isIE11) {\n video.srcObject = new MediaStream(videoTracks);\n }\n\n video.playsInline = true;\n video.autoplay = true;\n\n if (this._isMobile) {\n video.muted = true;\n }\n\n if (isIE11) {\n publisher._target.appendChild(video);\n publisher._element = attachMediaStream(video, publisher.stream._mediaStream);\n }\n\n const params = _.assign({}, {\n fitMode: 'contain',\n insertMode: 'append',\n mirror: false,\n resolution: '480x640',\n width: '100%',\n height: '100%'\n }, publisher.videoParams);\n\n const elementHeight = (typeof params.height === 'string') ? params.height : params.height + 'px';\n const elementWidth = (typeof params.width === 'string') ? params.width : params.width + 'px';\n\n _.assign((isIE11 ? publisher._element : video).style, {\n height: elementHeight,\n width: elementWidth,\n\n position: 'relative',\n 'object-fit': params.fitMode\n });\n\n if (!isIE11) {\n publisher._target.appendChild(video);\n publisher._element = video;\n }\n\n publisher.stream.setupDimensionsListener(video);\n }\n\n //\n // Enable (unpause) all media tracks related to publisher.\n // They are sending data to the server from this moment.\n //\n this._toggleAllStreams(true);\n });\n }\n\n /**\n * Unpublish stream and destroy publisher's view.\n *\n * Used internally by TsMediaPublisher.destroy\n *\n * @method\n *\n * @param { TsMediaPublisher } publisher\n *\n * @returns { Promise }\n *\n * @fires PUBLISHER_EVENTS#DESTROYED\n *\n * @see TsMediaPublisher#destroy\n */\n destroyPublisher(publisher) {\n trace('destroyPublisher');\n return new Promise((resolve) => {\n this._toggleAllStreams(false);\n\n if (publisher._element) {\n publisher._element.remove();\n }\n\n this.publisher = null;\n publisher.emit(PUBLISHER_EVENTS.DESTROYED);\n\n return resolve();\n });\n }\n}\n"]}
1
+ {"version":3,"sources":["webrtc/session-turn.js"],"names":["io","isIE11","TsEnvironmentDetect","require","WebRtcPeer","tracer","TurnWebRTCSession","localStreamFactory","credentials","isMobile","resolution","deviceOpts","trace","_credentials","_isMobile","_resolution","_deviceOpts","_incomingIce","_localStreamFactory","iceServers","ice","map","item","urls","url","username","login","credential","password","_configuration","iceTransportPolicy","_socket","_pcs","_connectSocket","Promise","resolve","reject","socket","connect","SOCKET_RECONNECTION_DELAY","SOCKET_RECONNECTION_DELAY_MAX","SOCKET_RECONNECTION_ATTEMPTS","SOCKET_PATH","done","_","once","err","on","SOCKET_EVENTS","INCOMING","ERROR","JOIN_RESPONSE","sdpAnswer","uid","peerId","pc","error","emit","EVENTS","EXCEPTION","source","processAnswer","forEach","candidate","addIceCandidate","length","CONNECTED","publish","publisher","catch","ICE_CANDIDATE","push","SEND_OFFER","_createRTCPeerConnection","then","generateOffer","offer","OUTGOING","SDP_OFFER","sessionId","sdpOffer","name","lastError","processOffer","SDP_ANSWER","PUBLISHER_RECONNECT","_streams","clear","off","peerConnection","close","RECONNECT_TURN_SERVER","PEER_DISCONNECTED","_lastPc","Object","getOwnPropertyNames","_toggleAllStreams","_setupConnection","oniceconnectionstatechange","e","iceCheckingTimeout","clearTimeout","target","iceConnectionState","_turnServerReconnectInterval","setInterval","navigator","onLine","clearInterval","connected","disconnected","RECONNECT_TURN_SERVER_INTERVAL","setTimeout","TURN_SERVER_CONNECTION_FAILED","FAILED_CONNECTING_TURN_SERVER_INTERVAL","onremovestream","stream","delete","id","_getPeerType","constraints","audio","PEER_CONNECTION_TYPES","SEND_RECV","RECV_ONLY","_connectRTCPeer","configuration","setupWebRtcPeer","peerConnectionType","peerConfig","videoStream","undefined","mediaConstraints","onicecandidate","clientType","CLIENT_TYPES","PUBLISHER","SUBSCRIBER","localStream","_setTrackStateTo","state","track","setEnabled","enabled","video","_constraints","JOIN_ROOM","getLocalStreams","getTracks","onaddstream","tsStream","TsWebRTCStream","STREAM_CREATED","_stopStream","stop","_stopAllStreams","disconnect","destroyed","event","reason","DISCONNECTED","_waitForPublishingApproval","caller","cb","get","Error","mediaStream","code","PUBLISH_APPROVAL_CHECK_INTERVAL","createPublisher","params","delay","WAIT_FOR_PC_INTERVAL","tracks","reduce","result","filter","kind","videoDevice","audioDevice","tsstream","remote","TsMediaPublisher","videoParams","videoHeight","videoDimensions","height","videoWidth","width","_target","PUBLISHER_EVENTS","STREAM_PROPERTY_CHANGED","property","value","hasVideo","hasAudio","_element","document","createElement","videoTracks","_mediaStream","getVideoTracks","srcObject","MediaStream","playsInline","autoplay","muted","appendChild","attachMediaStream","assign","fitMode","insertMode","mirror","elementHeight","elementWidth","style","position","setupDimensionsListener","destroyPublisher","remove","DESTROYED","TsMediaSession"],"mappings":"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","file":"session-turn.js","sourcesContent":["import {\n EVENTS,\n TsMediaSession\n} from '../session';\n\nimport {\n EVENTS as PUBLISHER_EVENTS,\n TsMediaPublisher\n} from '../publisher';\n\nimport {\n TsWebRTCStream\n} from './stream';\n\nimport * as io from 'socket.io-client';\n\nimport {TsEnvironmentDetect} from '@techsee/techsee-common/lib/helpers/ts-environment-detect';\n\nconst isIE11 = (new TsEnvironmentDetect()).isIE11();\n\nconst {WebRtcPeer} = require('kurento-utils'); // eslint-disable-line global-require\n\nimport {\n CLIENT_TYPES,\n FAILED_CONNECTING_TURN_SERVER_INTERVAL,\n PEER_CONNECTION_TYPES,\n PUBLISH_APPROVAL_CHECK_INTERVAL,\n RECONNECT_TURN_SERVER_INTERVAL,\n SOCKET_EVENTS,\n SOCKET_PATH,\n SOCKET_RECONNECTION_ATTEMPTS,\n SOCKET_RECONNECTION_DELAY,\n SOCKET_RECONNECTION_DELAY_MAX,\n WAIT_FOR_PC_INTERVAL\n} from './constants';\n\nimport {\n getMediaConstraints\n} from './helper';\n\nimport {getTracer} from '../tracer';\n\nconst tracer = getTracer();\n\n/**\n * WebRTC-specific implementation of TsMediaSession.\n *\n * Instance of this class is returned by TsMediaService.initSession call\n * with 'TURN_SERVER' as desired mediaType.\n *\n * @class\n * @extends TsMediaSession\n *\n * @see TsMediaSession\n */\nexport class TurnWebRTCSession extends TsMediaSession {\n constructor({credentials, isMobile, resolution, deviceOpts}, localStreamFactory) {\n super();\n\n tracer.trace('Constructor');\n\n this._credentials = credentials;\n this._isMobile = isMobile;\n this._resolution = resolution;\n this._deviceOpts = deviceOpts;\n this._incomingIce = [];\n this._localStreamFactory = localStreamFactory;\n\n const iceServers = credentials.ice.map((item) => ({\n urls: item.url,\n username: item.login,\n credential: item.password\n }));\n\n this._configuration = {\n iceServers,\n\n iceTransportPolicy: 'relay'\n };\n\n /**\n * Socket.io connection to the signaling server\n *\n * @private\n * @member { Object }\n */\n this._socket = null;\n\n /**\n * RTCPeerConnection to the media server.\n *\n * For now kurento-utils is used for connection establishment.\n *\n * @private\n * @member { Object }\n */\n this._pcs = {};\n }\n\n /**\n * Id of the session.\n *\n * @member { String }\n *\n * @type { String }\n */\n get id() {\n return this._credentials.sessionId;\n }\n\n /**\n *\n * @member { String }\n *\n * @type { String }\n */\n _connectSocket(url) {\n return new Promise((resolve, reject) => {\n tracer.trace('Connect socket');\n const socket = io.connect(url, {\n 'forceNew': true,\n 'reconnectionDelay': SOCKET_RECONNECTION_DELAY,\n 'reconnectionDelayMax': SOCKET_RECONNECTION_DELAY_MAX,\n 'reconnectionAttempts': SOCKET_RECONNECTION_ATTEMPTS,\n 'path': SOCKET_PATH\n });\n\n const done = _.once((err) => {\n tracer.trace(err ? 'Error' : 'Connected', err);\n err ? reject(err) : resolve();\n });\n\n //\n // When connection is established\n //\n socket.once('connect', () => done());\n //\n // errorOccured is ts-media-client signal\n //\n socket.on(SOCKET_EVENTS.INCOMING.ERROR, done);\n //\n // And these 2 are socket.io connection failed events\n //\n socket.on('connect_error', done);\n socket.on('connect_timeout', done);\n\n socket.on(SOCKET_EVENTS.INCOMING.JOIN_RESPONSE, ({\n sdpAnswer,\n uid,\n peerId\n }) => {\n tracer.trace('SOCKET_EVENTS.INCOMING.JOIN_RESPONSE');\n\n const pc = this._pcs[peerId];\n\n if (!pc) {\n tracer.trace('No peer found');\n const error = `pc not found. peer=${peerId} uid=${uid}`;\n\n this.emit(EVENTS.EXCEPTION, {source: 'JOIN_RESPONSE', error});\n\n return done(error);\n }\n\n pc.processAnswer(sdpAnswer, (error) => {\n if (error) {\n this.emit(EVENTS.EXCEPTION, {source: 'processAnswer', error});\n\n return done(error);\n }\n\n tracer.trace('ANSWER PROCESSED');\n\n // FIXME why don't we have _incomingIce per PC? current assumes we don't have parallel connections, not good\n _.forEach(this._incomingIce, (candidate) => {\n pc.addIceCandidate(candidate, (error) => {\n tracer.trace('ICE ADDED AFTER ANSWER');\n if (error) {\n this.emit(EVENTS.EXCEPTION, {source: 'JOIN_RESPONSE addIceCandidate', error});\n }\n });\n });\n\n this._incomingIce.length = 0;\n });\n\n this.emit(EVENTS.CONNECTED);\n\n this.publish(this.publisher)\n .catch((error) => {\n this.emit(EVENTS.EXCEPTION, {source: 'publish', error});\n });\n });\n\n socket.on(SOCKET_EVENTS.INCOMING.ICE_CANDIDATE, ({\n candidate,\n peerId\n }) => {\n tracer.trace('SOCKET_EVENTS.INCOMING.ICE_CANDIDATE');\n const pc = this._pcs[peerId];\n\n if (!pc) {\n tracer.trace('NO PEER FOUND ADD TO ICE QUEUE');\n this._incomingIce.push(candidate);\n\n return;\n }\n\n pc.addIceCandidate(candidate, (error) => {\n tracer.trace('ICE ADDED AFTER INCOMING');\n if (error) {\n this.emit(EVENTS.EXCEPTION, {source: 'ICE_CANDIDATE addIceCandidate', error});\n }\n });\n });\n\n // Received by publisher, causing him to emit SDP_OFFER\n socket.on(SOCKET_EVENTS.INCOMING.SEND_OFFER, ({\n uid,\n peerId\n }) => {\n tracer.trace('SOCKET_EVENTS.INCOMING.SEND_OFFER');\n\n this._createRTCPeerConnection(peerId)\n .then((pc) => {\n tracer.trace('GENERATING OFFER');\n\n pc.generateOffer((error, offer) => {\n tracer.trace('OFFER GENERATED');\n\n if (error) {\n return done(error);\n }\n\n socket.emit(SOCKET_EVENTS.OUTGOING.SDP_OFFER, {\n uid,\n peerId,\n sessionId: this._credentials.sessionId,\n sdpOffer: offer\n });\n });\n })\n .catch((error) => {\n this.emit(EVENTS.EXCEPTION, {source: '_createRTCPeerConnection', error});\n if (error && error.name) {\n this.lastError = error.name;\n }\n });\n });\n\n // Received by subscriber, causing him to emit SDP_ANSWER\n socket.on(SOCKET_EVENTS.INCOMING.SDP_OFFER, ({\n sdpOffer,\n peerId,\n uid\n }) => {\n tracer.trace('SOCKET_EVENTS.INCOMING.SDP_OFFER');\n\n Promise.resolve()\n .then(() => {\n const pc = this._pcs[peerId];\n\n if (pc) {\n tracer.trace('PEER ALREADY EXISTS');\n return pc;\n }\n\n return this._createRTCPeerConnection(peerId);\n })\n .then((pc) => {\n tracer.trace('PROCESS OFFER');\n pc.processOffer(sdpOffer, (error, sdpAnswer) => {\n tracer.trace('OFFER PROCESSED');\n if (error) {\n return done(error);\n }\n\n socket.emit(SOCKET_EVENTS.OUTGOING.SDP_ANSWER, {\n uid,\n peerId,\n sessionId: this._credentials.sessionId,\n sdpAnswer: sdpAnswer\n });\n });\n })\n .catch((error) => {\n this.emit(EVENTS.EXCEPTION, {source: 'response on INCOMING.SDP_OFFER', error});\n if (error && error.name) {\n this.lastError = error.name;\n }\n });\n });\n\n // Received by subscriber after a publisher reconnects to room\n socket.on(SOCKET_EVENTS.INCOMING.PUBLISHER_RECONNECT, () => {\n tracer.trace('SOCKET_EVENTS.INCOMING.PUBLISHER_RECONNECT');\n\n // Clean up and reconnect with a new peer-connection,\n // to prevent reconnection issues\n\n this._streams.clear();\n socket.off();\n _.forEach(this._pcs, ({peerConnection}) => {\n tracer.trace('CLOSING PEER');\n peerConnection.close();\n });\n this._pcs = {};\n\n this.emit(EVENTS.RECONNECT_TURN_SERVER);\n });\n\n // Received by publisher after a subscriber's socket has been disconnected\n socket.on(SOCKET_EVENTS.INCOMING.PEER_DISCONNECTED, ({\n peerId\n } = {}) => {\n tracer.trace('SOCKET_EVENTS.INCOMING.PEER_DISCONNECTED');\n\n if (peerId && this._pcs[peerId]) {\n if (this._lastPc === this._pcs[peerId]) {\n this._lastPc = null;\n }\n\n if (Object.getOwnPropertyNames(this._pcs).length === 1) {\n this._toggleAllStreams(false);\n }\n\n this._pcs[peerId].peerConnection.close();\n\n delete this._pcs[peerId];\n }\n });\n\n this._socket = socket;\n });\n }\n\n _setupConnection(pc) {\n return new Promise((resolve) => {\n tracer.trace('_setupConnection');\n pc.peerConnection.oniceconnectionstatechange = (e) => {\n tracer.trace('oniceconnectionstatechange', e);\n\n if (this.iceCheckingTimeout) {\n clearTimeout(this.iceCheckingTimeout);\n this.iceCheckingTimeout = null;\n }\n\n if (e.target.iceConnectionState === 'failed') {\n // if this is one of many in the publisher, skip\n\n // already attempting a reconnect\n if (this._turnServerReconnectInterval) {\n return;\n }\n\n this._turnServerReconnectInterval = setInterval(() => {\n if (!navigator.onLine) {\n return;\n }\n\n clearInterval(this._turnServerReconnectInterval);\n this._turnServerReconnectInterval = null;\n\n if (!this._socket.connected) {\n this.disconnected = false;\n this._socket.connect();\n }\n\n this.emit(EVENTS.RECONNECT_TURN_SERVER);\n }, RECONNECT_TURN_SERVER_INTERVAL);\n } else if (e.target.iceConnectionState === 'checking') {\n this.iceCheckingTimeout = setTimeout(() => {\n this.emit(EVENTS.TURN_SERVER_CONNECTION_FAILED);\n }, FAILED_CONNECTING_TURN_SERVER_INTERVAL);\n }\n };\n\n pc.peerConnection.onremovestream = ({stream}) => {\n tracer.trace('onremovestream');\n this._streams.delete(stream.id);\n };\n\n resolve();\n });\n }\n\n _getPeerType(constraints, isMobile) {\n if (isMobile || constraints.audio) {\n return PEER_CONNECTION_TYPES.SEND_RECV;\n }\n\n return PEER_CONNECTION_TYPES.RECV_ONLY;\n }\n\n _connectRTCPeer({\n constraints,\n configuration,\n sessionId,\n isMobile,\n peerId\n }) {\n return new Promise((resolve, reject) => {\n tracer.trace('_connectRTCPeer');\n\n const done = _.once((err, pc) => {\n tracer.trace(err ? 'Error' : 'Peer Connected', err);\n err ? reject(err) : resolve(pc);\n });\n const setupWebRtcPeer = (stream) => {\n tracer.trace('setupWebRtcPeer');\n const peerConnectionType = this._getPeerType(constraints, isMobile);\n const peerConfig = {\n configuration,\n videoStream: isMobile ? stream : undefined,\n mediaConstraints: constraints,\n onicecandidate: (candidate) => {\n tracer.trace('onicecandidate', candidate);\n this._socket.emit(SOCKET_EVENTS.OUTGOING.ICE_CANDIDATE, {\n sessionId,\n peerId,\n candidate,\n clientType: isMobile ? CLIENT_TYPES.PUBLISHER : CLIENT_TYPES.SUBSCRIBER\n });\n }\n };\n\n const pc = WebRtcPeer[peerConnectionType](peerConfig, (error) => {\n if (error) {\n return done(error);\n }\n\n this._setupConnection(pc)\n .then(() => done(null, pc))\n .catch(done);\n });\n\n this._pcs[peerId] = pc;\n this._lastPc = pc;\n };\n\n this._localStreamFactory(constraints)\n .then((localStream) => {\n setupWebRtcPeer(localStream);\n })\n .catch(() => {\n setupWebRtcPeer(undefined);\n });\n });\n }\n\n _setTrackStateTo(state) {\n tracer.trace('_setTrackStateTo');\n return function (track) {\n if (track.setEnabled) {\n track.setEnabled(state);\n } else {\n track.enabled = state;\n }\n };\n }\n\n /**\n * Establish socket and peer connection to the media server.\n *\n * @method\n * @returns { Promise }\n *\n * @fires SESSION_EVENTS#CONNECTED\n */\n connect() {\n tracer.trace('connect');\n return this._connectSocket(this._credentials.url)\n .then(() => {\n tracer.trace('Socket connected getting constraints');\n return getMediaConstraints({\n resolution: this._resolution,\n deviceOpts: this._deviceOpts\n });\n })\n .then((constraints) => {\n tracer.trace('connect - constraints', constraints);\n\n // streaming from dashboard is not supported and we\n // don't want to access the camera without a reason\n if (!this._isMobile && constraints.video) {\n tracer.trace('connect - deleting video for non mobile');\n delete constraints.video;\n }\n\n this._constraints = constraints;\n\n const clientType = this._isMobile ? CLIENT_TYPES.PUBLISHER : CLIENT_TYPES.SUBSCRIBER;\n\n tracer.trace('connect - emitting joinRoom', {\n clientType,\n sessionId: this._credentials.sessionId\n });\n this._socket.emit(SOCKET_EVENTS.OUTGOING.JOIN_ROOM, {\n clientType,\n sessionId: this._credentials.sessionId\n });\n })\n .catch((error) => {\n tracer.trace('connect error', error);\n this.emit(EVENTS.EXCEPTION, {source: 'connect', error});\n throw error;\n });\n }\n\n _createRTCPeerConnection(peerId) {\n tracer.trace('_createRTCPeerConnection');\n return this._connectRTCPeer({\n constraints: this._constraints,\n configuration: this._configuration,\n sessionId: this._credentials.sessionId,\n isMobile: this._isMobile,\n peerId: peerId\n })\n .then((pc) => {\n tracer.trace('peer connection created');\n\n if (this._isMobile) {\n pc.peerConnection.getLocalStreams().forEach((stream) => {\n if (!this.publisher) {\n stream.getTracks().forEach(this._setTrackStateTo(false));\n }\n });\n }\n\n pc.peerConnection.onaddstream = ({stream}) => {\n tracer.trace('peer connection onaddstream', stream);\n const tsStream = new TsWebRTCStream(this, stream);\n\n this.emit(EVENTS.STREAM_CREATED, tsStream);\n };\n\n return pc;\n });\n }\n\n _toggleAllStreams(state) {\n if (this._isMobile) {\n _.forEach(this._pcs, (pc) => {\n pc.peerConnection.getLocalStreams().forEach((stream) => {\n stream.getTracks().forEach(this._setTrackStateTo(state));\n });\n });\n }\n }\n\n _stopStream(pc) {\n if (this._isMobile) {\n pc.peerConnection.getLocalStreams().forEach((stream) => {\n stream.getTracks().forEach((track) => track.stop());\n });\n }\n }\n\n _stopAllStreams() {\n _.forEach(this._pcs, (pc) => this._stopStream(pc));\n }\n\n /**\n * Close all media streams, disconnect RTCPeerConnection and socket.io\n *\n * @method\n * @returns { Promise }\n *\n * @fires SESSION_EVENTS#DISCONNECTED\n */\n disconnect() {\n tracer.trace('disconnect');\n return Promise.resolve()\n .then(() => {\n if (this.destroyed) {\n return null;\n }\n\n this._stopAllStreams();\n\n _.forEach(this._pcs, ({peerConnection}) => peerConnection.close());\n this._pcs = {};\n this._socket.disconnect();\n\n const event = {reason: 'disconnected'};\n\n this.emit(EVENTS.DISCONNECTED, event);\n\n return event;\n });\n }\n\n _waitForPublishingApproval(caller, cb) {\n tracer.trace('_waitForPublishingApproval');\n try {\n const pc = _.get(caller, '_lastPc.peerConnection');\n\n if (!pc) {\n throw new Error('No peer connection for publishing');\n }\n\n //\n // Get media streams that were created on session initialization\n //\n const mediaStream = pc.getLocalStreams()[0];\n\n if (mediaStream) {\n return cb(null, mediaStream);\n }\n\n if (caller.lastError === 'NotAllowedError') {\n return cb({code: 1500, name: 'NotAllowedError'});\n } else if (caller.lastError === 'PermissionDismissedError') {\n return cb({code: 8, name: 'PermissionDismissedError'});\n }\n\n setTimeout(caller._waitForPublishingApproval, PUBLISH_APPROVAL_CHECK_INTERVAL, caller, cb);\n } catch (err) {\n return cb(err);\n }\n }\n\n /**\n * Create new TsMediaPublisher instance\n *\n * @method\n *\n * @param { DOMElement } [target] Video element\n * that will be used to render publishing video stream\n * @param { Object } params\n * @param { String } [params.videoDevice] Video device id\n * @param { String } [params.videoParams] Video device id\n * @param { String } [params.videoParams.fitMode] Video fit mode\n * @param { Number|String } [params.videoParams.width] Video element width\n * @param { Number|String } [params.videoParams.height] Video element height\n * @param { String } [params.audioDevice] Video device id\n *\n * @returns { Promise<TsMediaPublisher> } publisher\n *\n * @see TsMediaPublisher\n */\n createPublisher(target, params) {\n if (!params) {\n params = target;\n target = null;\n }\n\n tracer.trace('createPublisher');\n\n return (this._lastPc ? Promise.resolve() : Promise.delay(WAIT_FOR_PC_INTERVAL))\n .then(() => new Promise((resolve, reject) => {\n this._waitForPublishingApproval(this, (err, mediaStream) => {\n if (err) {\n return reject(err);\n }\n\n return resolve(mediaStream);\n });\n }))\n .then((mediaStream) => {\n //\n // Get tracks that are related to the publisher (audio or video)\n //\n const tracks = this._lastPc.peerConnection.getLocalStreams().reduce((result, mediaStream) => {\n mediaStream.getTracks()\n .filter((track) => (track.kind === 'video' && params.videoDevice) ||\n (track.kind === 'audio' && params.audioDevice))\n .forEach((track) => result.push(track));\n\n return result;\n }, []);\n\n const tsstream = new TsWebRTCStream(this, mediaStream, params.name);\n\n tsstream.remote = false;\n\n const publisher = new TsMediaPublisher(this, {\n stream: tsstream,\n tracks,\n videoParams: params.videoParams,\n\n videoHeight: tsstream.videoDimensions.height,\n videoWidth: tsstream.videoDimensions.width,\n\n _target: target\n });\n\n tsstream.publisher = publisher;\n this.publisher = publisher;\n\n return publisher;\n });\n }\n\n /**\n * Publish stream from previously create TsMediaPublisher instance.\n *\n * Used internally by TsMediaPublisher.publish\n *\n * @method\n *\n * @param { TsMediaPublisher } publisher\n *\n * @returns { Promise }\n *\n * @fires PUBLISHER_EVENTS#STREAM_CREATED\n * @fires SESSION_EVENTS#STREAM_PROPERTY_CHANGED\n * @fires STREAM_EVENTS#PROPERTY_CHANGED\n *\n * @see TsMediaPublisher#publish\n */\n publish(publisher) {\n tracer.trace('publish');\n return Promise.resolve()\n .then(() => {\n if (!publisher) {\n return;\n }\n\n publisher.emit(PUBLISHER_EVENTS.STREAM_CREATED, publisher.stream);\n this.emit(EVENTS.STREAM_PROPERTY_CHANGED, {\n stream: publisher.stream,\n property: 'hasVideo',\n value: publisher.stream.hasVideo\n });\n this.emit(EVENTS.STREAM_PROPERTY_CHANGED, {\n stream: publisher.stream,\n property: 'hasAudio',\n value: publisher.stream.hasAudio\n });\n\n if (this.publisher._element) {\n return;\n }\n\n if (publisher._target) {\n //\n // New video element where publishing video stream will be rendered\n //\n const video = document.createElement('video');\n\n //Currently this code is used only in mobile, so when publishing, then we always need only video track\n //to set to video element. Otherwise, when VOIP enabled, technician side will hear himself through this video element.\n const videoTracks = publisher.stream._mediaStream.getVideoTracks();\n\n if (!isIE11) {\n video.srcObject = new MediaStream(videoTracks);\n }\n\n video.playsInline = true;\n video.autoplay = true;\n\n if (this._isMobile) {\n video.muted = true;\n }\n\n if (isIE11) {\n publisher._target.appendChild(video);\n publisher._element = attachMediaStream(video, publisher.stream._mediaStream);\n }\n\n const params = _.assign({}, {\n fitMode: 'contain',\n insertMode: 'append',\n mirror: false,\n resolution: '480x640',\n width: '100%',\n height: '100%'\n }, publisher.videoParams);\n\n const elementHeight = (typeof params.height === 'string') ? params.height : params.height + 'px';\n const elementWidth = (typeof params.width === 'string') ? params.width : params.width + 'px';\n\n _.assign((isIE11 ? publisher._element : video).style, {\n height: elementHeight,\n width: elementWidth,\n\n position: 'relative',\n 'object-fit': params.fitMode\n });\n\n if (!isIE11) {\n publisher._target.appendChild(video);\n publisher._element = video;\n }\n\n publisher.stream.setupDimensionsListener(video);\n }\n\n //\n // Enable (unpause) all media tracks related to publisher.\n // They are sending data to the server from this moment.\n //\n this._toggleAllStreams(true);\n });\n }\n\n /**\n * Unpublish stream and destroy publisher's view.\n *\n * Used internally by TsMediaPublisher.destroy\n *\n * @method\n *\n * @param { TsMediaPublisher } publisher\n *\n * @returns { Promise }\n *\n * @fires PUBLISHER_EVENTS#DESTROYED\n *\n * @see TsMediaPublisher#destroy\n */\n destroyPublisher(publisher) {\n tracer.trace('destroyPublisher');\n return new Promise((resolve) => {\n this._toggleAllStreams(false);\n\n if (publisher._element) {\n publisher._element.remove();\n }\n\n this.publisher = null;\n publisher.emit(PUBLISHER_EVENTS.DESTROYED);\n\n return resolve();\n });\n }\n}\n"]}