@techsee/techsee-media-service 0.4.0 → 0.4.2-alpha.1

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.
@@ -13,8 +13,6 @@ var io = _interopRequireWildcard(_socket);
13
13
 
14
14
  var _constants = require('./constants');
15
15
 
16
- var _helper = require('./helper');
17
-
18
16
  var _stream = require('./stream');
19
17
 
20
18
  var _tracer = require('../tracer');
@@ -28,7 +26,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
28
26
  function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
29
27
 
30
28
  var trace = (0, _tracer.getTracer)('TurnWebRtcSessionV2', function () {
31
- return window.TurnSessionDebugV2 === true || true;
29
+ return window.TurnSessionDebugV2 === true;
32
30
  });
33
31
 
34
32
  //Currently this version supports subscribing only. Publishing will be implemented as needed.
@@ -43,11 +41,11 @@ var TurnWebRtcSessionV2 = exports.TurnWebRtcSessionV2 = function (_TsMediaSessio
43
41
  }
44
42
  }]);
45
43
 
46
- function TurnWebRtcSessionV2(_ref, localStreamFactory) {
44
+ function TurnWebRtcSessionV2(_ref) {
47
45
  var credentials = _ref.credentials,
48
- isMobile = _ref.isMobile,
49
- resolution = _ref.resolution,
50
- deviceOpts = _ref.deviceOpts;
46
+ constraints = _ref.constraints,
47
+ clientType = _ref.clientType,
48
+ streamFactory = _ref.streamFactory;
51
49
 
52
50
  _classCallCheck(this, TurnWebRtcSessionV2);
53
51
 
@@ -55,17 +53,13 @@ var TurnWebRtcSessionV2 = exports.TurnWebRtcSessionV2 = function (_TsMediaSessio
55
53
 
56
54
  _this._socket = null;
57
55
  _this._localPeer = null;
56
+ _this._pendingPeersIce = {};
58
57
  _this._peerConnections = new Map();
59
58
 
60
59
  _this._credentials = credentials;
61
- _this._localStreamFactory = localStreamFactory;
62
-
63
- _this._isMobile = isMobile;
64
- _this._resolution = resolution;
65
- _this._deviceOpts = deviceOpts;
66
- _this._pendingPeersIce = {};
67
-
68
- _this._selfClientType = isMobile ? _constants.CLIENT_TYPES.PUBLISHER : _constants.CLIENT_TYPES.SUBSCRIBER;
60
+ _this._constraints = constraints;
61
+ _this._selfClientType = clientType;
62
+ _this._localStreamFactory = streamFactory;
69
63
 
70
64
  var iceServers = credentials.ice.map(function (item) {
71
65
  return {
@@ -80,12 +74,12 @@ var TurnWebRtcSessionV2 = exports.TurnWebRtcSessionV2 = function (_TsMediaSessio
80
74
  iceTransportPolicy: 'relay'
81
75
  };
82
76
 
83
- _this.joinResponseHandler = _this.joinResponseHandler.bind(_this);
84
- _this.iceCandidateReceivedHandler = _this.iceCandidateReceivedHandler.bind(_this);
85
- _this.sendOfferHandler = _this.sendOfferHandler.bind(_this);
86
- _this.sdpOfferHandler = _this.sdpOfferHandler.bind(_this);
87
- _this.publisherReconnectHandler = _this.publisherReconnectHandler.bind(_this);
88
- _this.peerDisconnectedHandler = _this.peerDisconnectedHandler.bind(_this);
77
+ _this._joinResponseHandler = _this._joinResponseHandler.bind(_this);
78
+ _this._iceCandidateReceivedHandler = _this._iceCandidateReceivedHandler.bind(_this);
79
+ _this._sendOfferHandler = _this._sendOfferHandler.bind(_this);
80
+ _this._sdpOfferHandler = _this._sdpOfferHandler.bind(_this);
81
+ _this._initiatorReconnectHandler = _this._initiatorReconnectHandler.bind(_this);
82
+ _this._peerDisconnectedHandler = _this._peerDisconnectedHandler.bind(_this);
89
83
 
90
84
  _this._extendPeerConnection();
91
85
  return _this;
@@ -101,29 +95,10 @@ var TurnWebRtcSessionV2 = exports.TurnWebRtcSessionV2 = function (_TsMediaSessio
101
95
  trace('connect');
102
96
 
103
97
  return this._connectSocket(this._credentials.url, connectOnly).then(function () {
104
- trace('Socket connected getting constraints');
105
-
106
- return (0, _helper.getMediaConstraints)({
107
- resolution: _this2._resolution,
108
- deviceOpts: _this2._deviceOpts
109
- }).then(function (constraints) {
110
-
111
- // streaming from dashboard is not supported and we
112
- // don't want to access the camera without a reason
113
- if (_this2._selfClientType === _constants.CLIENT_TYPES.SUBSCRIBER) {
114
- delete constraints.video;
115
- }
116
-
117
- _this2._constraints = constraints;
118
-
119
- trace('Constraints generated', constraints);
120
- });
121
- }).then(function () {
122
- var clientType = _this2._isMobile ? _constants.CLIENT_TYPES.PUBLISHER : _constants.CLIENT_TYPES.SUBSCRIBER;
123
-
124
98
  trace('Joining SessionId: ' + _this2._credentials.sessionId);
99
+
125
100
  _this2._socket.emit(_constants.SOCKET_EVENTS.OUTGOING.JOIN_ROOM, {
126
- clientType: clientType,
101
+ clientType: _this2._selfClientType,
127
102
  sessionId: _this2._credentials.sessionId
128
103
  });
129
104
  }).catch(function (error) {
@@ -139,6 +114,8 @@ var TurnWebRtcSessionV2 = exports.TurnWebRtcSessionV2 = function (_TsMediaSessio
139
114
  _this3._destroyPeerConnection(peerConnection);
140
115
  });
141
116
 
117
+ this.emit(_session.SESSION_EVENTS.DISCONNECTED, { reason: 'disconnected' });
118
+
142
119
  this._socket.off();
143
120
  this._socket.disconnect();
144
121
  };
@@ -168,38 +145,38 @@ var TurnWebRtcSessionV2 = exports.TurnWebRtcSessionV2 = function (_TsMediaSessio
168
145
 
169
146
  if (!connectOnly) {
170
147
  //PUBLISHING NOT SUPPORTED YET
171
- //socket.on(SOCKET_EVENTS.INCOMING.SEND_OFFER, this.sendOfferHandler);
172
- //socket.on(SOCKET_EVENTS.INCOMING.JOIN_RESPONSE, this.joinResponseHandler);
173
- //socket.on(SOCKET_EVENTS.INCOMING.PEER_DISCONNECTED, this.peerDisconnectedHandler);
148
+ //socket.on(SOCKET_EVENTS.INCOMING.SEND_OFFER, this._sendOfferHandler);
149
+ //socket.on(SOCKET_EVENTS.INCOMING.JOIN_RESPONSE, this._joinResponseHandler);
150
+ //socket.on(SOCKET_EVENTS.INCOMING.PEER_DISCONNECTED, this._peerDisconnectedHandler);
174
151
 
175
- socket.on(_constants.SOCKET_EVENTS.INCOMING.SDP_OFFER, _this4.sdpOfferHandler);
176
- socket.on(_constants.SOCKET_EVENTS.INCOMING.PUBLISHER_RECONNECT, _this4.publisherReconnectHandler);
152
+ socket.on(_constants.SOCKET_EVENTS.INCOMING.SDP_OFFER, _this4._sdpOfferHandler);
153
+ socket.on(_constants.SOCKET_EVENTS.INCOMING.PUBLISHER_RECONNECT, _this4._initiatorReconnectHandler);
177
154
 
178
- socket.on(_constants.SOCKET_EVENTS.INCOMING.ICE_CANDIDATE, _this4.iceCandidateReceivedHandler);
155
+ socket.on(_constants.SOCKET_EVENTS.INCOMING.ICE_CANDIDATE, _this4._iceCandidateReceivedHandler);
179
156
  }
180
157
  });
181
158
  };
182
159
 
183
160
  //#endregion
184
161
 
185
- //#region Publisher
162
+ //#region WebRTC Initiator - session Initiator (User on mobile device)
186
163
 
187
- // Received by publisher, causing him to emit SDP_OFFER
164
+ // Received by Initiator, causing him to emit SDP_OFFER
188
165
 
189
166
 
190
- TurnWebRtcSessionV2.prototype.sendOfferHandler = function sendOfferHandler(_ref2) {
167
+ TurnWebRtcSessionV2.prototype._sendOfferHandler = function _sendOfferHandler(_ref2) {
191
168
  var _this5 = this;
192
169
 
193
170
  var uid = _ref2.uid,
194
171
  peerId = _ref2.peerId;
195
172
 
196
- trace('sendOfferHandler');
173
+ trace('_sendOfferHandler');
197
174
 
198
- var peerConnection = this._createPeerConnection(peerId, _constants.CLIENT_TYPES.SUBSCRIBER);
175
+ var peerConnection = this._createPeerConnection(peerId, _constants.CLIENT_TYPES.GUEST);
199
176
  var offerParams = { offerToReceiveAudio: true, offerToReceiveVideo: true };
200
177
 
201
178
  this._localStreamFactory(this._constraints).then(function (localStream) {
202
- trace('sendOfferHandler stream and peer created');
179
+ trace('_sendOfferHandler stream and peer created');
203
180
 
204
181
  var peerConnectionStream = new _stream.TsWebRTCStream(_this5, localStream.clone(), _constants.DEFAULT_STREAM_NAMES.MOBILE_CLIENT_VIDEO_STREAM, false);
205
182
 
@@ -214,7 +191,7 @@ var TurnWebRtcSessionV2 = exports.TurnWebRtcSessionV2 = function (_TsMediaSessio
214
191
  }).then(function () {
215
192
  return peerConnection.createOffer(offerParams);
216
193
  }).then(function (offerDesc) {
217
- trace('Publisher has created sdp offer', { offerDesc: offerDesc });
194
+ trace('Initiator has created sdp offer', { offerDesc: offerDesc });
218
195
 
219
196
  _this5._socket.emit(_constants.SOCKET_EVENTS.OUTGOING.SDP_OFFER, {
220
197
  uid: uid,
@@ -231,10 +208,10 @@ var TurnWebRtcSessionV2 = exports.TurnWebRtcSessionV2 = function (_TsMediaSessio
231
208
  });
232
209
  };
233
210
 
234
- // Received by the publisher: Indicates that publish should be started
211
+ // Received by the Initiator: Indicates that publish should be started
235
212
 
236
213
 
237
- TurnWebRtcSessionV2.prototype.joinResponseHandler = function joinResponseHandler(_ref3) {
214
+ TurnWebRtcSessionV2.prototype._joinResponseHandler = function _joinResponseHandler(_ref3) {
238
215
  var _this6 = this;
239
216
 
240
217
  var sdpAnswer = _ref3.sdpAnswer,
@@ -259,81 +236,112 @@ var TurnWebRtcSessionV2 = exports.TurnWebRtcSessionV2 = function (_TsMediaSessio
259
236
  });
260
237
  };
261
238
 
262
- // Received by publisher after a subscriber's socket has been disconnected
239
+ // Received by Initiator after a guests socket has been disconnected
263
240
 
264
241
 
265
- TurnWebRtcSessionV2.prototype.peerDisconnectedHandler = function peerDisconnectedHandler(_ref4) {
242
+ TurnWebRtcSessionV2.prototype._peerDisconnectedHandler = function _peerDisconnectedHandler(_ref4) {
266
243
  var peerId = _ref4.peerId;
267
244
 
268
- trace('peerDisconnectedHandler');
245
+ trace('_peerDisconnectedHandler');
269
246
  };
270
247
 
271
- //#endregion Publisher
248
+ //#endregion WebRTC Initiator - session Initiator (User on mobile device)
272
249
 
273
- //#region Subscriber
250
+ //#region WebRTC Guest - session Guest (Agent on dashboard platform)
274
251
 
275
- // Received by subscriber, causing him to emit SDP_ANSWER
252
+ // Received by Guest, causing him to emit SDP_ANSWER
276
253
 
277
254
 
278
- TurnWebRtcSessionV2.prototype.sdpOfferHandler = function sdpOfferHandler(_ref5) {
255
+ TurnWebRtcSessionV2.prototype._sdpOfferHandler = function _sdpOfferHandler(_ref5) {
279
256
  var _this7 = this;
280
257
 
281
258
  var sdpOffer = _ref5.sdpOffer,
282
259
  peerId = _ref5.peerId,
283
260
  uid = _ref5.uid;
284
261
 
285
- trace('sdpOffer Received', sdpOffer);
262
+ trace('sdpOffer Received', { sdpOffer: sdpOffer });
286
263
 
287
- var peerConnection = this._createPeerConnection(peerId, _constants.CLIENT_TYPES.PUBLISHER);
264
+ var peerConnection = this._createPeerConnection(peerId, _constants.CLIENT_TYPES.INITIATOR);
288
265
 
289
- var remoteDesc = new RTCSessionDescription({ type: 'offer', sdp: sdpOffer });
266
+ var subscriberInitChain = Promise.resolve();
290
267
 
291
- peerConnection.setRemoteDescription(remoteDesc).then(function () {
292
- trace('Remote description was set', remoteDesc);
268
+ if (this._constraints.audio) {
269
+ subscriberInitChain = subscriberInitChain.then(function () {
270
+ trace('Creating agent local streams');
293
271
 
294
- return peerConnection.createAnswer().then(function (sdpAnswer) {
295
- trace('sdpOfferHandler answer created', sdpAnswer);
272
+ return _this7._localStreamFactory(_this7._constraints).then(function (localStream) {
273
+ localStream.getTracks().forEach(function (track) {
274
+ trace('Adding local tracks to peer connection');
296
275
 
297
- _this7._socket.emit(_constants.SOCKET_EVENTS.OUTGOING.SDP_ANSWER, {
298
- uid: uid,
299
- peerId: peerId,
300
- sessionId: _this7._credentials.sessionId,
301
- sdpAnswer: sdpAnswer.sdp
276
+ if (track.kind === 'audio') {
277
+
278
+ var stream = new MediaStream([track]);
279
+ var streamName = _constants.DEFAULT_STREAM_NAMES.DASHBOARD_AUDIO_STREAM;
280
+ var agentAudioStream = new _stream.TsWebRTCStream(_this7, stream, streamName, false);
281
+
282
+ _this7.registerStream(agentAudioStream.id, agentAudioStream);
283
+ peerConnection.addTrack(track, peerConnection.peerLogicalStream);
284
+
285
+ trace('Agent audio stream added to peerConnection');
286
+ }
287
+ });
302
288
  });
289
+ });
290
+ }
291
+
292
+ subscriberInitChain.then(function () {
293
+ var remoteDesc = new RTCSessionDescription({ type: 'offer', sdp: sdpOffer });
294
+
295
+ return peerConnection.setRemoteDescription(remoteDesc).then(function () {
296
+ trace('Remote description was set', remoteDesc);
297
+
298
+ return peerConnection.createAnswer().then(function (sdpAnswer) {
299
+ trace('_sdpOfferHandler answer created', sdpAnswer);
303
300
 
304
- return peerConnection.setLocalDescription(sdpAnswer).then(function () {
305
- trace('sdpOfferHandler local desc was set');
301
+ _this7._socket.emit(_constants.SOCKET_EVENTS.OUTGOING.SDP_ANSWER, {
302
+ uid: uid,
303
+ peerId: peerId,
304
+ sessionId: _this7._credentials.sessionId,
305
+ sdpAnswer: sdpAnswer.sdp
306
+ });
306
307
 
307
- _this7._processQueuedIceCandidates(peerId);
308
+ return peerConnection.setLocalDescription(sdpAnswer).then(function () {
309
+ trace('_sdpOfferHandler local desc was set');
310
+
311
+ _this7._processQueuedIceCandidates(peerId);
312
+ });
308
313
  });
309
314
  });
310
- }).catch(function (e) {
311
- trace('Error in sdpOfferHandler', e);
315
+ });
316
+
317
+ return subscriberInitChain.catch(function (e) {
318
+ trace('Error in _sdpOfferHandler', e);
319
+ throw e;
312
320
  });
313
321
  };
314
322
 
315
- // Received by subscriber after a publisher reconnects to room
323
+ // Received by Guest after an Initiator reconnects to room
316
324
 
317
325
 
318
- TurnWebRtcSessionV2.prototype.publisherReconnectHandler = function publisherReconnectHandler() {
319
- trace('publisherReconnectHandler');
326
+ TurnWebRtcSessionV2.prototype._initiatorReconnectHandler = function _initiatorReconnectHandler() {
327
+ trace('_initiatorReconnectHandler');
320
328
 
321
- var publisherPeer = this._getPublisherPeer();
329
+ var initiatorPeer = this._getInitiatorPeer();
322
330
 
323
- if (publisherPeer) {
324
- this._destroyPeerConnection(publisherPeer);
331
+ if (initiatorPeer) {
332
+ this._destroyPeerConnection(initiatorPeer);
325
333
  }
326
334
 
327
335
  this.emit(_session.SESSION_EVENTS.RECONNECT_TURN_SERVER);
328
336
  };
329
337
 
330
- TurnWebRtcSessionV2.prototype._getPublisherPeer = function _getPublisherPeer() {
331
- var publisherPeer = this._getPeerConnectionsByType(_constants.CLIENT_TYPES.PUBLISHER);
338
+ TurnWebRtcSessionV2.prototype._getInitiatorPeer = function _getInitiatorPeer() {
339
+ var peer = this._getPeerConnectionsByType(_constants.CLIENT_TYPES.INITIATOR);
332
340
 
333
- return publisherPeer.length > 0 ? publisherPeer[0] : null;
341
+ return peer.length > 0 ? peer[0] : null;
334
342
  };
335
343
 
336
- //#endregion Subscriber
344
+ //#endregion WebRTC Guest - session Guest (Agent on dashboard platform)
337
345
 
338
346
  //#region Peer Connection
339
347
 
@@ -348,6 +356,7 @@ var TurnWebRtcSessionV2 = exports.TurnWebRtcSessionV2 = function (_TsMediaSessio
348
356
 
349
357
  peerConnection.peerId = peerId;
350
358
  peerConnection.peerType = peerConnectionType;
359
+ peerConnection.peerLogicalStream = new MediaStream();
351
360
 
352
361
  peerConnection.oniceconnectionstatechange = function (state) {
353
362
  trace('ICE Connection state for peer ' + peerId + ' was changed to: ' + state.currentTarget.iceConnectionState, state);
@@ -370,13 +379,15 @@ var TurnWebRtcSessionV2 = exports.TurnWebRtcSessionV2 = function (_TsMediaSessio
370
379
  }
371
380
  };
372
381
 
373
- if (this._selfClientType === _constants.CLIENT_TYPES.SUBSCRIBER) {
374
- peerConnection.ontrack = function (track) {
375
- var stream = track.streams[0];
382
+ if (this._selfClientType === _constants.CLIENT_TYPES.GUEST) {
383
+ peerConnection.ontrack = function (trackEvent) {
384
+ var track = trackEvent.track,
385
+ streams = trackEvent.streams;
376
386
 
377
- trace('Stream created from peer connection track: ' + track.kind, stream);
378
387
 
379
- var tsStream = new _stream.TsWebRTCStream(_this8, stream);
388
+ trace('Stream created from peer connection track: ' + track.kind, track, streams.length > 0 ? streams[0] : 'NO STREAM');
389
+
390
+ var tsStream = new _stream.TsWebRTCStream(_this8, streams[0]);
380
391
 
381
392
  tsStream.peerConnection = peerConnection;
382
393
  tsStream.remote = true;
@@ -397,15 +408,15 @@ var TurnWebRtcSessionV2 = exports.TurnWebRtcSessionV2 = function (_TsMediaSessio
397
408
  TurnWebRtcSessionV2.prototype._destroyPeerConnection = function _destroyPeerConnection(peerConnection) {
398
409
  var _this9 = this;
399
410
 
400
- if (this._selfClientType === _constants.CLIENT_TYPES.SUBSCRIBER) {
411
+ if (this._selfClientType === _constants.CLIENT_TYPES.GUEST) {
401
412
  this._getRemoteStreams(peerConnection).forEach(function (stream) {
402
413
  _this9.unregisterStream(stream.id);
403
414
  _this9.emit(_session.SESSION_EVENTS.STREAM_DESTROYED, { stream: stream });
404
415
  });
405
416
  }
406
417
 
407
- if (this._selfClientType === _constants.CLIENT_TYPES.PUBLISHER && this._peerConnections.size === 0) {
408
- //TODO - ALEX: When publisher will be implemented, here we need to destroy local stream (or better raise, event).
418
+ if (this._selfClientType === _constants.CLIENT_TYPES.INITIATOR && this._peerConnections.size === 0) {
419
+ //TODO - ALEX: When initiator will be implemented, here we need to destroy local stream (or better raise, event).
409
420
  }
410
421
 
411
422
  this._peerConnections.delete(peerConnection.peerId);
@@ -454,17 +465,21 @@ var TurnWebRtcSessionV2 = exports.TurnWebRtcSessionV2 = function (_TsMediaSessio
454
465
  if (!RTCPeerConnection.prototype.peerType) {
455
466
  RTCPeerConnection.prototype.peerType = null;
456
467
  }
468
+
469
+ if (!RTCPeerConnection.prototype.peerLogicalStream) {
470
+ RTCPeerConnection.prototype.peerLogicalStream = null;
471
+ }
457
472
  };
458
473
 
459
474
  //#endregion
460
475
 
461
476
  //#region ICE Candidates
462
477
 
463
- TurnWebRtcSessionV2.prototype.iceCandidateReceivedHandler = function iceCandidateReceivedHandler(_ref6) {
478
+ TurnWebRtcSessionV2.prototype._iceCandidateReceivedHandler = function _iceCandidateReceivedHandler(_ref6) {
464
479
  var candidate = _ref6.candidate,
465
480
  peerId = _ref6.peerId;
466
481
 
467
- trace('iceCandidateReceivedHandler', candidate);
482
+ trace('_iceCandidateReceivedHandler', candidate);
468
483
  if (!candidate) {
469
484
  trace('NO iceCandidate');
470
485
 
@@ -518,7 +533,7 @@ var TurnWebRtcSessionV2 = exports.TurnWebRtcSessionV2 = function (_TsMediaSessio
518
533
  };
519
534
 
520
535
  TurnWebRtcSessionV2.prototype._iceStateDisconnected = function _iceStateDisconnected(peerConnection) {
521
- if (peerConnection.peerType === _constants.CLIENT_TYPES.PUBLISHER) {
536
+ if (peerConnection.peerType === _constants.CLIENT_TYPES.INITIATOR) {
522
537
  this._destroyPeerConnection(peerConnection);
523
538
  }
524
539
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["webrtc/session-turn.v2.js"],"names":["io","trace","window","TurnSessionDebugV2","TurnWebRtcSessionV2","_credentials","sessionId","localStreamFactory","credentials","isMobile","resolution","deviceOpts","_socket","_localPeer","_peerConnections","Map","_localStreamFactory","_isMobile","_resolution","_deviceOpts","_pendingPeersIce","_selfClientType","CLIENT_TYPES","PUBLISHER","SUBSCRIBER","iceServers","ice","map","item","urls","url","username","login","credential","password","_configuration","iceTransportPolicy","joinResponseHandler","bind","iceCandidateReceivedHandler","sendOfferHandler","sdpOfferHandler","publisherReconnectHandler","peerDisconnectedHandler","_extendPeerConnection","connect","connectOnly","_connectSocket","then","constraints","video","_constraints","clientType","emit","SOCKET_EVENTS","OUTGOING","JOIN_ROOM","catch","error","SESSION_EVENTS","EXCEPTION","source","disconnect","forEach","peerConnection","_destroyPeerConnection","off","Promise","resolve","reject","socket","SOCKET_RECONNECTION_DELAY","SOCKET_RECONNECTION_DELAY_MAX","SOCKET_RECONNECTION_ATTEMPTS","SOCKET_PATH","done","_","once","err","on","INCOMING","ERROR","SDP_OFFER","PUBLISHER_RECONNECT","ICE_CANDIDATE","uid","peerId","_createPeerConnection","offerParams","offerToReceiveAudio","offerToReceiveVideo","localStream","peerConnectionStream","TsWebRTCStream","clone","DEFAULT_STREAM_NAMES","MOBILE_CLIENT_VIDEO_STREAM","getTracks","track","addTrack","_mediaStream","registerStream","id","createOffer","offerDesc","sdpOffer","sdp","setLocalDescription","e","sdpAnswer","_withPeerConnection","answer","RTCSessionDescription","type","setRemoteDescription","_processQueuedIceCandidates","remoteDesc","createAnswer","SDP_ANSWER","publisherPeer","_getPublisherPeer","RECONNECT_TURN_SERVER","_getPeerConnectionsByType","length","peerConnectionType","get","Error","RTCPeerConnection","peerType","oniceconnectionstatechange","state","currentTarget","iceConnectionState","_iceStateDisconnected","onicecandidate","event","candidate","ontrack","stream","streams","kind","tsStream","remote","STREAM_CREATED","set","_getRemoteStreams","unregisterStream","STREAM_DESTROYED","size","delete","close","result","push","callback","prototype","_queueIceCandidate","_addIceCandidateToPeer","iceCandidate","addIceCandidate","pendingIces","pendingIce","TsMediaSession"],"mappings":"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","file":"session-turn.v2.js","sourcesContent":["import {SESSION_EVENTS, TsMediaSession} from '../session';\nimport * as io from 'socket.io-client';\nimport {\n CLIENT_TYPES, DEFAULT_STREAM_NAMES,\n SOCKET_EVENTS,\n SOCKET_PATH,\n SOCKET_RECONNECTION_ATTEMPTS,\n SOCKET_RECONNECTION_DELAY,\n SOCKET_RECONNECTION_DELAY_MAX\n} from './constants';\nimport {getMediaConstraints} from './helper';\nimport {TsWebRTCStream} from './stream';\n\nimport {getTracer} from '../tracer';\n\nconst trace = getTracer('TurnWebRtcSessionV2', () => window.TurnSessionDebugV2 === true || true);\n\n//Currently this version supports subscribing only. Publishing will be implemented as needed.\nexport class TurnWebRtcSessionV2 extends TsMediaSession {\n get id() {\n return this._credentials.sessionId;\n }\n\n constructor({credentials, isMobile, resolution, deviceOpts}, localStreamFactory) {\n super();\n\n this._socket = null;\n this._localPeer = null;\n this._peerConnections = new Map();\n\n this._credentials = credentials;\n this._localStreamFactory = localStreamFactory;\n\n this._isMobile = isMobile;\n this._resolution = resolution;\n this._deviceOpts = deviceOpts;\n this._pendingPeersIce = {};\n\n this._selfClientType = isMobile\n ? CLIENT_TYPES.PUBLISHER : CLIENT_TYPES.SUBSCRIBER;\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 iceTransportPolicy: 'relay'\n };\n\n this.joinResponseHandler = this.joinResponseHandler.bind(this);\n this.iceCandidateReceivedHandler = this.iceCandidateReceivedHandler.bind(this);\n this.sendOfferHandler = this.sendOfferHandler.bind(this);\n this.sdpOfferHandler = this.sdpOfferHandler.bind(this);\n this.publisherReconnectHandler = this.publisherReconnectHandler.bind(this);\n this.peerDisconnectedHandler = this.peerDisconnectedHandler.bind(this);\n\n this._extendPeerConnection();\n }\n\n //#region Socket Connectivity\n\n connect(connectOnly = false) {\n trace('connect');\n\n return this._connectSocket(this._credentials.url, connectOnly)\n .then(() => {\n trace('Socket connected getting constraints');\n\n return getMediaConstraints({\n resolution: this._resolution,\n deviceOpts: this._deviceOpts\n }).then((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._selfClientType === CLIENT_TYPES.SUBSCRIBER) {\n delete constraints.video;\n }\n\n this._constraints = constraints;\n\n trace('Constraints generated', constraints);\n });\n })\n .then(() => {\n const clientType = this._isMobile ? CLIENT_TYPES.PUBLISHER : CLIENT_TYPES.SUBSCRIBER;\n\n trace('Joining SessionId: ' + this._credentials.sessionId);\n this._socket.emit(SOCKET_EVENTS.OUTGOING.JOIN_ROOM, {\n clientType,\n sessionId: this._credentials.sessionId\n });\n })\n .catch((error) => {\n this.emit(SESSION_EVENTS.EXCEPTION, {source: 'connect', error});\n throw error;\n });\n }\n\n disconnect() {\n this._peerConnections.forEach((peerConnection) => {\n this._destroyPeerConnection(peerConnection);\n });\n\n this._socket.off();\n this._socket.disconnect();\n }\n\n _connectSocket(url, connectOnly) {\n return new Promise((resolve, reject) => {\n const socket = this._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 err ? reject(err) : resolve();\n });\n\n socket.once('connect', () => done());\n socket.on(SOCKET_EVENTS.INCOMING.ERROR, done);\n socket.on('connect_error', done);\n socket.on('connect_timeout', done);\n\n if (!connectOnly) {\n //PUBLISHING NOT SUPPORTED YET\n //socket.on(SOCKET_EVENTS.INCOMING.SEND_OFFER, this.sendOfferHandler);\n //socket.on(SOCKET_EVENTS.INCOMING.JOIN_RESPONSE, this.joinResponseHandler);\n //socket.on(SOCKET_EVENTS.INCOMING.PEER_DISCONNECTED, this.peerDisconnectedHandler);\n\n socket.on(SOCKET_EVENTS.INCOMING.SDP_OFFER, this.sdpOfferHandler);\n socket.on(SOCKET_EVENTS.INCOMING.PUBLISHER_RECONNECT, this.publisherReconnectHandler);\n\n socket.on(SOCKET_EVENTS.INCOMING.ICE_CANDIDATE, this.iceCandidateReceivedHandler);\n }\n });\n }\n\n //#endregion\n\n //#region Publisher\n\n // Received by publisher, causing him to emit SDP_OFFER\n sendOfferHandler({uid, peerId}) {\n trace('sendOfferHandler');\n\n const peerConnection = this._createPeerConnection(peerId, CLIENT_TYPES.SUBSCRIBER);\n const offerParams = {offerToReceiveAudio: true, offerToReceiveVideo: true};\n\n this._localStreamFactory(this._constraints)\n .then((localStream) => {\n trace('sendOfferHandler stream and peer created');\n\n const peerConnectionStream = new TsWebRTCStream(this, localStream.clone(), DEFAULT_STREAM_NAMES.MOBILE_CLIENT_VIDEO_STREAM, false);\n\n peerConnectionStream.peerConnection = peerConnection;\n\n localStream.getTracks().forEach((track) => {\n trace('Adding local tracks to peer connection');\n peerConnection.addTrack(track, peerConnectionStream._mediaStream);\n });\n\n this.registerStream(peerConnectionStream.id, peerConnectionStream);\n })\n .then(() => peerConnection.createOffer(offerParams))\n .then((offerDesc) => {\n trace('Publisher has created sdp offer', {offerDesc});\n\n this._socket.emit(SOCKET_EVENTS.OUTGOING.SDP_OFFER, {\n uid,\n peerId,\n sessionId: this._credentials.sessionId,\n sdpOffer: offerDesc.sdp\n });\n\n return peerConnection.setLocalDescription(offerDesc)\n .then(() => {\n trace('Local description was set on');\n });\n })\n .catch((e) => {\n trace('Error', e);\n });\n }\n\n // Received by the publisher: Indicates that publish should be started\n joinResponseHandler({sdpAnswer, uid, peerId}) {\n trace('joinResponse Received', sdpAnswer);\n\n this._withPeerConnection(peerId, (peerConnection) => {\n const answer = new RTCSessionDescription({\n type: 'answer',\n sdp: sdpAnswer\n });\n\n peerConnection.setRemoteDescription(answer)\n .then(() => {\n trace('Remote description was set', answer);\n\n this._processQueuedIceCandidates(peerId);\n })\n .catch((e) => {\n trace('Error', e);\n });\n });\n }\n\n // Received by publisher after a subscriber's socket has been disconnected\n peerDisconnectedHandler({peerId}) {\n trace('peerDisconnectedHandler');\n }\n\n //#endregion Publisher\n\n //#region Subscriber\n\n // Received by subscriber, causing him to emit SDP_ANSWER\n sdpOfferHandler({sdpOffer, peerId, uid}) {\n trace('sdpOffer Received', sdpOffer);\n\n const peerConnection = this._createPeerConnection(peerId, CLIENT_TYPES.PUBLISHER);\n\n const remoteDesc = new RTCSessionDescription({type: 'offer', sdp: sdpOffer});\n\n peerConnection.setRemoteDescription(remoteDesc)\n .then(() => {\n trace('Remote description was set', remoteDesc);\n\n return peerConnection.createAnswer()\n .then((sdpAnswer) => {\n trace('sdpOfferHandler answer created', sdpAnswer);\n\n this._socket.emit(SOCKET_EVENTS.OUTGOING.SDP_ANSWER, {\n uid,\n peerId,\n sessionId: this._credentials.sessionId,\n sdpAnswer: sdpAnswer.sdp\n });\n\n return peerConnection.setLocalDescription(sdpAnswer)\n .then(() => {\n trace('sdpOfferHandler local desc was set');\n\n this._processQueuedIceCandidates(peerId);\n });\n });\n })\n .catch((e) => {\n trace('Error in sdpOfferHandler', e);\n });\n }\n\n // Received by subscriber after a publisher reconnects to room\n publisherReconnectHandler() {\n trace('publisherReconnectHandler');\n\n const publisherPeer = this._getPublisherPeer();\n\n if (publisherPeer) {\n this._destroyPeerConnection(publisherPeer);\n }\n\n this.emit(SESSION_EVENTS.RECONNECT_TURN_SERVER);\n }\n\n _getPublisherPeer() {\n const publisherPeer = this._getPeerConnectionsByType(CLIENT_TYPES.PUBLISHER);\n\n\n return publisherPeer.length > 0 ? publisherPeer[0] : null;\n }\n\n //#endregion Subscriber\n\n //#region Peer Connection\n\n _createPeerConnection(peerId, peerConnectionType) {\n if (this._peerConnections.get(peerId)) {\n throw new Error(`${this._selfClientType} peer connection for ${peerId} already exists`);\n }\n\n const peerConnection = new RTCPeerConnection(this._configuration);\n\n peerConnection.peerId = peerId;\n peerConnection.peerType = peerConnectionType;\n\n peerConnection.oniceconnectionstatechange = (state) => {\n trace(`ICE Connection state for peer ${peerId} was changed to: ${state.currentTarget.iceConnectionState}`, state);\n if (state.currentTarget.iceConnectionState === 'disconnected') {\n this._iceStateDisconnected(peerConnection);\n }\n };\n\n peerConnection.onicecandidate = (event) => {\n if (event.candidate) {\n trace(`${this._selfClientType} peerConn.onicecandidate`, event.candidate);\n this._socket.emit(SOCKET_EVENTS.OUTGOING.ICE_CANDIDATE, {\n sessionId: this._credentials.sessionId,\n peerId: peerId,\n candidate: event.candidate,\n clientType: this._selfClientType\n });\n } else {\n trace('ICE Candidate is null in peerConnection', event);\n }\n };\n\n if (this._selfClientType === CLIENT_TYPES.SUBSCRIBER) {\n peerConnection.ontrack = (track) => {\n const stream = track.streams[0];\n\n trace(`Stream created from peer connection track: ${track.kind}`, stream);\n\n const tsStream = new TsWebRTCStream(this, stream);\n\n tsStream.peerConnection = peerConnection;\n tsStream.remote = true;\n\n this.registerStream(tsStream.id, tsStream);\n\n this.emit(SESSION_EVENTS.STREAM_CREATED, tsStream);\n };\n }\n\n this._peerConnections.set(peerId, peerConnection);\n\n trace(`${this._selfClientType} peerConnection created`);\n\n return peerConnection;\n }\n\n _destroyPeerConnection(peerConnection) {\n if (this._selfClientType === CLIENT_TYPES.SUBSCRIBER) {\n this._getRemoteStreams(peerConnection).forEach((stream) => {\n this.unregisterStream(stream.id);\n this.emit(SESSION_EVENTS.STREAM_DESTROYED, {stream});\n });\n }\n\n if (this._selfClientType === CLIENT_TYPES.PUBLISHER && this._peerConnections.size === 0) {\n //TODO - ALEX: When publisher will be implemented, here we need to destroy local stream (or better raise, event).\n }\n\n this._peerConnections.delete(peerConnection.peerId);\n peerConnection.close();\n }\n\n _getRemoteStreams(peerConnection) {\n const result = [];\n\n this.streams.forEach((stream) => {\n if (stream.peerConnection === peerConnection && stream.remote) {\n result.push(stream);\n }\n });\n\n return result;\n }\n\n _getPeerConnectionsByType(peerType) {\n const result = [];\n\n this._peerConnections.forEach((peerConnection) => {\n if (peerConnection.peerType === peerType) {\n result.push(peerConnection);\n }\n });\n\n return result;\n }\n\n _withPeerConnection(peerId, callback) {\n if (this._peerConnections.get(peerId)) {\n return callback(this._peerConnections.get(peerId));\n }\n\n return null;\n }\n\n _extendPeerConnection() {\n //TODO - Alex: Need to modify IE shim, and add these methods inside shim itself\n\n if (!RTCPeerConnection.prototype.peerId) {\n RTCPeerConnection.prototype.peerId = '';\n }\n\n if (!RTCPeerConnection.prototype.peerType) {\n RTCPeerConnection.prototype.peerType = null;\n }\n }\n\n //#endregion\n\n //#region ICE Candidates\n\n iceCandidateReceivedHandler({candidate, peerId}) {\n trace('iceCandidateReceivedHandler', candidate);\n if (!candidate) {\n trace('NO iceCandidate');\n\n return;\n }\n\n const peerConnection = this._peerConnections.get(peerId);\n\n if (!peerConnection) {\n trace('Queueing iceCandidate', candidate);\n this._queueIceCandidate(candidate, peerId);\n\n return;\n }\n\n trace('Going to add iceCandidate', candidate);\n this._addIceCandidateToPeer(candidate, peerConnection);\n }\n\n _addIceCandidateToPeer(iceCandidate, peerConnection) {\n return peerConnection.addIceCandidate(iceCandidate)\n .then(() => {\n trace('ICE Candidate add to peer connection');\n })\n .catch((e) => {\n trace('Error adding ICE Candidate to peer connection', e);\n });\n }\n\n _processQueuedIceCandidates(peerId) {\n this._withPeerConnection(peerId, (peerConnection) => {\n const pendingIces = this._pendingPeersIce[peerId];\n\n if (pendingIces) {\n pendingIces.forEach((pendingIce) => {\n trace('Adding pending ICE to peer connections');\n this._addIceCandidateToPeer(pendingIce, peerConnection);\n });\n } else {\n trace('No pending ICE found for peer', peerId);\n }\n });\n }\n\n _queueIceCandidate(iceCandidate, peerId) {\n if (!this._pendingPeersIce[peerId]) {\n this._pendingPeersIce[peerId] = [];\n }\n\n this._pendingPeersIce[peerId].push(iceCandidate);\n }\n\n _iceStateDisconnected(peerConnection) {\n if (peerConnection.peerType === CLIENT_TYPES.PUBLISHER) {\n this._destroyPeerConnection(peerConnection);\n }\n }\n\n //#endregion\n}\n"]}
1
+ {"version":3,"sources":["webrtc/session-turn.v2.js"],"names":["io","trace","window","TurnSessionDebugV2","TurnWebRtcSessionV2","_credentials","sessionId","credentials","constraints","clientType","streamFactory","_socket","_localPeer","_pendingPeersIce","_peerConnections","Map","_constraints","_selfClientType","_localStreamFactory","iceServers","ice","map","item","urls","url","username","login","credential","password","_configuration","iceTransportPolicy","_joinResponseHandler","bind","_iceCandidateReceivedHandler","_sendOfferHandler","_sdpOfferHandler","_initiatorReconnectHandler","_peerDisconnectedHandler","_extendPeerConnection","connect","connectOnly","_connectSocket","then","emit","SOCKET_EVENTS","OUTGOING","JOIN_ROOM","catch","error","SESSION_EVENTS","EXCEPTION","source","disconnect","forEach","peerConnection","_destroyPeerConnection","DISCONNECTED","reason","off","Promise","resolve","reject","socket","SOCKET_RECONNECTION_DELAY","SOCKET_RECONNECTION_DELAY_MAX","SOCKET_RECONNECTION_ATTEMPTS","SOCKET_PATH","done","_","once","err","on","INCOMING","ERROR","SDP_OFFER","PUBLISHER_RECONNECT","ICE_CANDIDATE","uid","peerId","_createPeerConnection","CLIENT_TYPES","GUEST","offerParams","offerToReceiveAudio","offerToReceiveVideo","localStream","peerConnectionStream","TsWebRTCStream","clone","DEFAULT_STREAM_NAMES","MOBILE_CLIENT_VIDEO_STREAM","getTracks","track","addTrack","_mediaStream","registerStream","id","createOffer","offerDesc","sdpOffer","sdp","setLocalDescription","e","sdpAnswer","_withPeerConnection","answer","RTCSessionDescription","type","setRemoteDescription","_processQueuedIceCandidates","INITIATOR","subscriberInitChain","audio","kind","stream","MediaStream","streamName","DASHBOARD_AUDIO_STREAM","agentAudioStream","peerLogicalStream","remoteDesc","createAnswer","SDP_ANSWER","initiatorPeer","_getInitiatorPeer","RECONNECT_TURN_SERVER","peer","_getPeerConnectionsByType","length","peerConnectionType","get","Error","RTCPeerConnection","peerType","oniceconnectionstatechange","state","currentTarget","iceConnectionState","_iceStateDisconnected","onicecandidate","event","candidate","ontrack","trackEvent","streams","tsStream","remote","STREAM_CREATED","set","_getRemoteStreams","unregisterStream","STREAM_DESTROYED","size","delete","close","result","push","callback","prototype","_queueIceCandidate","_addIceCandidateToPeer","iceCandidate","addIceCandidate","pendingIces","pendingIce","TsMediaSession"],"mappings":"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","file":"session-turn.v2.js","sourcesContent":["import {SESSION_EVENTS, TsMediaSession} from '../session';\nimport * as io from 'socket.io-client';\nimport {\n CLIENT_TYPES, DEFAULT_STREAM_NAMES,\n SOCKET_EVENTS,\n SOCKET_PATH,\n SOCKET_RECONNECTION_ATTEMPTS,\n SOCKET_RECONNECTION_DELAY,\n SOCKET_RECONNECTION_DELAY_MAX\n} from './constants';\nimport {TsWebRTCStream} from './stream';\n\nimport {getTracer} from '../tracer';\n\nconst trace = getTracer('TurnWebRtcSessionV2', () => window.TurnSessionDebugV2 === true);\n\n//Currently this version supports subscribing only. Publishing will be implemented as needed.\nexport class TurnWebRtcSessionV2 extends TsMediaSession {\n get id() {\n return this._credentials.sessionId;\n }\n\n constructor({credentials, constraints, clientType, streamFactory}) {\n super();\n\n this._socket = null;\n this._localPeer = null;\n this._pendingPeersIce = {};\n this._peerConnections = new Map();\n\n this._credentials = credentials;\n this._constraints = constraints;\n this._selfClientType = clientType;\n this._localStreamFactory = streamFactory;\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 iceTransportPolicy: 'relay'\n };\n\n this._joinResponseHandler = this._joinResponseHandler.bind(this);\n this._iceCandidateReceivedHandler = this._iceCandidateReceivedHandler.bind(this);\n this._sendOfferHandler = this._sendOfferHandler.bind(this);\n this._sdpOfferHandler = this._sdpOfferHandler.bind(this);\n this._initiatorReconnectHandler = this._initiatorReconnectHandler.bind(this);\n this._peerDisconnectedHandler = this._peerDisconnectedHandler.bind(this);\n\n this._extendPeerConnection();\n }\n\n //#region Socket Connectivity\n\n connect(connectOnly = false) {\n trace('connect');\n\n return this._connectSocket(this._credentials.url, connectOnly)\n .then(() => {\n trace('Joining SessionId: ' + this._credentials.sessionId);\n\n this._socket.emit(SOCKET_EVENTS.OUTGOING.JOIN_ROOM, {\n clientType: this._selfClientType,\n sessionId: this._credentials.sessionId\n });\n })\n .catch((error) => {\n this.emit(SESSION_EVENTS.EXCEPTION, {source: 'connect', error});\n throw error;\n });\n }\n\n disconnect() {\n this._peerConnections.forEach((peerConnection) => {\n this._destroyPeerConnection(peerConnection);\n });\n\n this.emit(SESSION_EVENTS.DISCONNECTED, {reason: 'disconnected'});\n\n this._socket.off();\n this._socket.disconnect();\n }\n\n _connectSocket(url, connectOnly) {\n return new Promise((resolve, reject) => {\n const socket = this._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 err ? reject(err) : resolve();\n });\n\n socket.once('connect', () => done());\n socket.on(SOCKET_EVENTS.INCOMING.ERROR, done);\n socket.on('connect_error', done);\n socket.on('connect_timeout', done);\n\n if (!connectOnly) {\n //PUBLISHING NOT SUPPORTED YET\n //socket.on(SOCKET_EVENTS.INCOMING.SEND_OFFER, this._sendOfferHandler);\n //socket.on(SOCKET_EVENTS.INCOMING.JOIN_RESPONSE, this._joinResponseHandler);\n //socket.on(SOCKET_EVENTS.INCOMING.PEER_DISCONNECTED, this._peerDisconnectedHandler);\n\n socket.on(SOCKET_EVENTS.INCOMING.SDP_OFFER, this._sdpOfferHandler);\n socket.on(SOCKET_EVENTS.INCOMING.PUBLISHER_RECONNECT, this._initiatorReconnectHandler);\n\n socket.on(SOCKET_EVENTS.INCOMING.ICE_CANDIDATE, this._iceCandidateReceivedHandler);\n }\n });\n }\n\n //#endregion\n\n //#region WebRTC Initiator - session Initiator (User on mobile device)\n\n // Received by Initiator, causing him to emit SDP_OFFER\n _sendOfferHandler({uid, peerId}) {\n trace('_sendOfferHandler');\n\n const peerConnection = this._createPeerConnection(peerId, CLIENT_TYPES.GUEST);\n const offerParams = {offerToReceiveAudio: true, offerToReceiveVideo: true};\n\n this._localStreamFactory(this._constraints)\n .then((localStream) => {\n trace('_sendOfferHandler stream and peer created');\n\n const peerConnectionStream = new TsWebRTCStream(this, localStream.clone(), DEFAULT_STREAM_NAMES.MOBILE_CLIENT_VIDEO_STREAM, false);\n\n peerConnectionStream.peerConnection = peerConnection;\n\n localStream.getTracks().forEach((track) => {\n trace('Adding local tracks to peer connection');\n peerConnection.addTrack(track, peerConnectionStream._mediaStream);\n });\n\n this.registerStream(peerConnectionStream.id, peerConnectionStream);\n })\n .then(() => peerConnection.createOffer(offerParams))\n .then((offerDesc) => {\n trace('Initiator has created sdp offer', {offerDesc});\n\n this._socket.emit(SOCKET_EVENTS.OUTGOING.SDP_OFFER, {\n uid,\n peerId,\n sessionId: this._credentials.sessionId,\n sdpOffer: offerDesc.sdp\n });\n\n return peerConnection.setLocalDescription(offerDesc)\n .then(() => {\n trace('Local description was set on');\n });\n })\n .catch((e) => {\n trace('Error', e);\n });\n }\n\n // Received by the Initiator: Indicates that publish should be started\n _joinResponseHandler({sdpAnswer, uid, peerId}) {\n trace('joinResponse Received', sdpAnswer);\n\n this._withPeerConnection(peerId, (peerConnection) => {\n const answer = new RTCSessionDescription({\n type: 'answer',\n sdp: sdpAnswer\n });\n\n peerConnection.setRemoteDescription(answer)\n .then(() => {\n trace('Remote description was set', answer);\n\n this._processQueuedIceCandidates(peerId);\n })\n .catch((e) => {\n trace('Error', e);\n });\n });\n }\n\n // Received by Initiator after a guests socket has been disconnected\n _peerDisconnectedHandler({peerId}) {\n trace('_peerDisconnectedHandler');\n }\n\n //#endregion WebRTC Initiator - session Initiator (User on mobile device)\n\n //#region WebRTC Guest - session Guest (Agent on dashboard platform)\n\n // Received by Guest, causing him to emit SDP_ANSWER\n _sdpOfferHandler({sdpOffer, peerId, uid}) {\n trace('sdpOffer Received', {sdpOffer});\n\n const peerConnection = this._createPeerConnection(peerId, CLIENT_TYPES.INITIATOR);\n\n let subscriberInitChain = Promise.resolve();\n\n if (this._constraints.audio) {\n subscriberInitChain = subscriberInitChain.then(() => {\n trace('Creating agent local streams');\n\n return this._localStreamFactory(this._constraints)\n .then((localStream) => {\n localStream.getTracks().forEach((track) => {\n trace('Adding local tracks to peer connection');\n\n if (track.kind === 'audio') {\n\n const stream = new MediaStream([track]);\n const streamName = DEFAULT_STREAM_NAMES.DASHBOARD_AUDIO_STREAM;\n const agentAudioStream = new TsWebRTCStream(this, stream, streamName, false);\n\n this.registerStream(agentAudioStream.id, agentAudioStream);\n peerConnection.addTrack(track, peerConnection.peerLogicalStream);\n\n trace('Agent audio stream added to peerConnection');\n }\n });\n });\n });\n }\n\n subscriberInitChain.then(() => {\n const remoteDesc = new RTCSessionDescription({type: 'offer', sdp: sdpOffer});\n\n return peerConnection.setRemoteDescription(remoteDesc)\n .then(() => {\n trace('Remote description was set', remoteDesc);\n\n return peerConnection.createAnswer()\n .then((sdpAnswer) => {\n trace('_sdpOfferHandler answer created', sdpAnswer);\n\n this._socket.emit(SOCKET_EVENTS.OUTGOING.SDP_ANSWER, {\n uid,\n peerId,\n sessionId: this._credentials.sessionId,\n sdpAnswer: sdpAnswer.sdp\n });\n\n return peerConnection.setLocalDescription(sdpAnswer)\n .then(() => {\n trace('_sdpOfferHandler local desc was set');\n\n this._processQueuedIceCandidates(peerId);\n });\n });\n });\n\n });\n\n return subscriberInitChain.catch((e) => {\n trace('Error in _sdpOfferHandler', e);\n throw e;\n });\n }\n\n // Received by Guest after an Initiator reconnects to room\n _initiatorReconnectHandler() {\n trace('_initiatorReconnectHandler');\n\n const initiatorPeer = this._getInitiatorPeer();\n\n if (initiatorPeer) {\n this._destroyPeerConnection(initiatorPeer);\n }\n\n this.emit(SESSION_EVENTS.RECONNECT_TURN_SERVER);\n }\n\n _getInitiatorPeer() {\n const peer = this._getPeerConnectionsByType(CLIENT_TYPES.INITIATOR);\n\n return peer.length > 0 ? peer[0] : null;\n }\n\n //#endregion WebRTC Guest - session Guest (Agent on dashboard platform)\n\n //#region Peer Connection\n\n _createPeerConnection(peerId, peerConnectionType) {\n if (this._peerConnections.get(peerId)) {\n throw new Error(`${this._selfClientType} peer connection for ${peerId} already exists`);\n }\n\n const peerConnection = new RTCPeerConnection(this._configuration);\n\n peerConnection.peerId = peerId;\n peerConnection.peerType = peerConnectionType;\n peerConnection.peerLogicalStream = new MediaStream();\n\n peerConnection.oniceconnectionstatechange = (state) => {\n trace(`ICE Connection state for peer ${peerId} was changed to: ${state.currentTarget.iceConnectionState}`, state);\n if (state.currentTarget.iceConnectionState === 'disconnected') {\n this._iceStateDisconnected(peerConnection);\n }\n };\n\n peerConnection.onicecandidate = (event) => {\n if (event.candidate) {\n trace(`${this._selfClientType} peerConn.onicecandidate`, event.candidate);\n this._socket.emit(SOCKET_EVENTS.OUTGOING.ICE_CANDIDATE, {\n sessionId: this._credentials.sessionId,\n peerId: peerId,\n candidate: event.candidate,\n clientType: this._selfClientType\n });\n } else {\n trace('ICE Candidate is null in peerConnection', event);\n }\n };\n\n if (this._selfClientType === CLIENT_TYPES.GUEST) {\n peerConnection.ontrack = (trackEvent) => {\n const {track, streams} = trackEvent;\n\n trace(`Stream created from peer connection track: ${track.kind}`, track, streams.length > 0 ? streams[0] : 'NO STREAM');\n\n const tsStream = new TsWebRTCStream(this, streams[0]);\n\n tsStream.peerConnection = peerConnection;\n tsStream.remote = true;\n\n this.registerStream(tsStream.id, tsStream);\n\n this.emit(SESSION_EVENTS.STREAM_CREATED, tsStream);\n };\n }\n\n this._peerConnections.set(peerId, peerConnection);\n\n trace(`${this._selfClientType} peerConnection created`);\n\n return peerConnection;\n }\n\n _destroyPeerConnection(peerConnection) {\n if (this._selfClientType === CLIENT_TYPES.GUEST) {\n this._getRemoteStreams(peerConnection).forEach((stream) => {\n this.unregisterStream(stream.id);\n this.emit(SESSION_EVENTS.STREAM_DESTROYED, {stream});\n });\n }\n\n if (this._selfClientType === CLIENT_TYPES.INITIATOR && this._peerConnections.size === 0) {\n //TODO - ALEX: When initiator will be implemented, here we need to destroy local stream (or better raise, event).\n }\n\n this._peerConnections.delete(peerConnection.peerId);\n peerConnection.close();\n }\n\n _getRemoteStreams(peerConnection) {\n const result = [];\n\n this.streams.forEach((stream) => {\n if (stream.peerConnection === peerConnection && stream.remote) {\n result.push(stream);\n }\n });\n\n return result;\n }\n\n _getPeerConnectionsByType(peerType) {\n const result = [];\n\n this._peerConnections.forEach((peerConnection) => {\n if (peerConnection.peerType === peerType) {\n result.push(peerConnection);\n }\n });\n\n return result;\n }\n\n _withPeerConnection(peerId, callback) {\n if (this._peerConnections.get(peerId)) {\n return callback(this._peerConnections.get(peerId));\n }\n\n return null;\n }\n\n _extendPeerConnection() {\n //TODO - Alex: Need to modify IE shim, and add these methods inside shim itself\n\n if (!RTCPeerConnection.prototype.peerId) {\n RTCPeerConnection.prototype.peerId = '';\n }\n\n if (!RTCPeerConnection.prototype.peerType) {\n RTCPeerConnection.prototype.peerType = null;\n }\n\n if (!RTCPeerConnection.prototype.peerLogicalStream) {\n RTCPeerConnection.prototype.peerLogicalStream = null;\n }\n }\n\n //#endregion\n\n //#region ICE Candidates\n\n _iceCandidateReceivedHandler({candidate, peerId}) {\n trace('_iceCandidateReceivedHandler', candidate);\n if (!candidate) {\n trace('NO iceCandidate');\n\n return;\n }\n\n const peerConnection = this._peerConnections.get(peerId);\n\n if (!peerConnection) {\n trace('Queueing iceCandidate', candidate);\n this._queueIceCandidate(candidate, peerId);\n\n return;\n }\n\n trace('Going to add iceCandidate', candidate);\n this._addIceCandidateToPeer(candidate, peerConnection);\n }\n\n _addIceCandidateToPeer(iceCandidate, peerConnection) {\n return peerConnection.addIceCandidate(iceCandidate)\n .then(() => {\n trace('ICE Candidate add to peer connection');\n })\n .catch((e) => {\n trace('Error adding ICE Candidate to peer connection', e);\n });\n }\n\n _processQueuedIceCandidates(peerId) {\n this._withPeerConnection(peerId, (peerConnection) => {\n const pendingIces = this._pendingPeersIce[peerId];\n\n if (pendingIces) {\n pendingIces.forEach((pendingIce) => {\n trace('Adding pending ICE to peer connections');\n this._addIceCandidateToPeer(pendingIce, peerConnection);\n });\n } else {\n trace('No pending ICE found for peer', peerId);\n }\n });\n }\n\n _queueIceCandidate(iceCandidate, peerId) {\n if (!this._pendingPeersIce[peerId]) {\n this._pendingPeersIce[peerId] = [];\n }\n\n this._pendingPeersIce[peerId].push(iceCandidate);\n }\n\n _iceStateDisconnected(peerConnection) {\n if (peerConnection.peerType === CLIENT_TYPES.INITIATOR) {\n this._destroyPeerConnection(peerConnection);\n }\n }\n\n //#endregion\n}\n"]}