@techsee/techsee-media-service 0.4.0-alpha.15 → 0.4.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.
package/lib/service.js CHANGED
@@ -3,30 +3,18 @@
3
3
  exports.__esModule = true;
4
4
  exports.TsMediaService = exports.EVENTS = undefined;
5
5
 
6
- var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
7
-
8
- var _tsEnvironmentDetect = require('@techsee/techsee-common/lib/helpers/ts-environment-detect');
9
-
10
6
  var _eventEmitter = require('./event-emitter');
11
7
 
12
- var _session = require('./session');
8
+ var _session = require('./webrtc/session');
13
9
 
14
- var _session2 = require('./opentok/session');
10
+ var _tsEnvironmentDetect = require('@techsee/techsee-common/lib/helpers/ts-environment-detect');
15
11
 
16
- var _session3 = require('./webrtc/session');
12
+ var _session2 = require('./opentok/session');
17
13
 
18
14
  var _helper = require('./webrtc/helper');
19
15
 
20
16
  var _constants = require('./constants');
21
17
 
22
- var _constants2 = require('./webrtc/constants');
23
-
24
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
25
-
26
- function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
27
-
28
- 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
-
30
18
  var environmentDetect = new _tsEnvironmentDetect.TsEnvironmentDetect();
31
19
  var isIE11 = environmentDetect.isIE11();
32
20
 
@@ -86,17 +74,20 @@ var userMediaPromise = null;
86
74
  * @class
87
75
  * @extends EventEmitter
88
76
  */
77
+ var TsMediaService = exports.TsMediaService = _.assign(new _eventEmitter.EventEmitter(), {
89
78
 
90
- var TsMediaServiceFacade = function (_EventEmitter) {
91
- _inherits(TsMediaServiceFacade, _EventEmitter);
92
-
93
- function TsMediaServiceFacade() {
94
- _classCallCheck(this, TsMediaServiceFacade);
95
-
96
- return _possibleConstructorReturn(this, _EventEmitter.apply(this, arguments));
97
- }
79
+ /**
80
+ * All created sessoins
81
+ *
82
+ * @member { Object }
83
+ * @memberof TsMediaService
84
+ * @type { Array<TsMediaSession> }
85
+ */
86
+ get sessions() {
87
+ return sessions;
88
+ },
98
89
 
99
- TsMediaServiceFacade.prototype.createLocalMediaStream = function createLocalMediaStream(constraints) {
90
+ createLocalMediaStream: function createLocalMediaStream(constraints) {
100
91
  if (userMediaPromise) {
101
92
  return userMediaPromise;
102
93
  }
@@ -106,7 +97,7 @@ var TsMediaServiceFacade = function (_EventEmitter) {
106
97
  if (videoTrack.length > 0 && videoTrack[0].readyState === 'live') {
107
98
  return Promise.resolve(latestLocalStream);
108
99
  } else {
109
- TsMediaService.destroyLocalMediaStream();
100
+ this.destroyLocalMediaStream();
110
101
  }
111
102
  }
112
103
 
@@ -127,9 +118,8 @@ var TsMediaServiceFacade = function (_EventEmitter) {
127
118
  });
128
119
 
129
120
  return userMediaPromise;
130
- };
131
-
132
- TsMediaServiceFacade.prototype.destroyLocalMediaStream = function destroyLocalMediaStream() {
121
+ },
122
+ destroyLocalMediaStream: function destroyLocalMediaStream() {
133
123
  if (latestLocalStream) {
134
124
  latestLocalStream.getTracks().forEach(function (track) {
135
125
  track.stop();
@@ -137,22 +127,8 @@ var TsMediaServiceFacade = function (_EventEmitter) {
137
127
  }
138
128
 
139
129
  latestLocalStream = null;
140
- };
141
-
142
- TsMediaServiceFacade.prototype.toggleMicrophone = function toggleMicrophone() {
143
- var enableMic = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
144
-
145
- if (!latestLocalStream) {
146
- return Promise.resolve();
147
- }
148
-
149
- var audioTracks = latestLocalStream.getAudioTracks();
150
- if (audioTracks.length > 0) {
151
- audioTracks[0].enabled = enableMic;
152
- }
130
+ },
153
131
 
154
- return Promise.resolve();
155
- };
156
132
 
157
133
  /**
158
134
  * Enumerate available media devices
@@ -163,9 +139,7 @@ var TsMediaServiceFacade = function (_EventEmitter) {
163
139
  *
164
140
  * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/MediaDeviceInfo | MediaDeviceInfo documentation}
165
141
  */
166
-
167
-
168
- TsMediaServiceFacade.prototype.getDevices = function getDevices() {
142
+ getDevices: function getDevices() {
169
143
  if (typeof OT !== 'undefined' && OT && OT.getDevices) {
170
144
  return new Promise(function (resolve, reject) {
171
145
  OT.getDevices(function (error, devices) {
@@ -183,7 +157,8 @@ var TsMediaServiceFacade = function (_EventEmitter) {
183
157
  }
184
158
 
185
159
  return Promise.reject('getDevices is not supported');
186
- };
160
+ },
161
+
187
162
 
188
163
  /**
189
164
  * Verifies camera access
@@ -194,13 +169,10 @@ var TsMediaServiceFacade = function (_EventEmitter) {
194
169
  *
195
170
  * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/MediaDeviceInfo | MediaDeviceInfo documentation}
196
171
  */
197
-
198
-
199
- TsMediaServiceFacade.prototype.verifyCameraAccess = function verifyCameraAccess(deviceOpts) {
172
+ verifyCameraAccess: function verifyCameraAccess(deviceOpts) {
200
173
  return (0, _helper.getHighestResolutionStream)(deviceOpts);
201
- };
202
-
203
- TsMediaServiceFacade.prototype.isVideoPlaySupportedOnDevice = function isVideoPlaySupportedOnDevice() {
174
+ },
175
+ isVideoPlaySupportedOnDevice: function isVideoPlaySupportedOnDevice() {
204
176
  if (!isIE11) {
205
177
  return Promise.resolve(true);
206
178
  }
@@ -214,7 +186,8 @@ var TsMediaServiceFacade = function (_EventEmitter) {
214
186
  }
215
187
 
216
188
  return Promise.resolve(false);
217
- };
189
+ },
190
+
218
191
 
219
192
  /**
220
193
  * Init WebRTC or OpenTok session depends on required type.
@@ -235,10 +208,8 @@ var TsMediaServiceFacade = function (_EventEmitter) {
235
208
  *
236
209
  * @returns { Promise<TsMediaSession> }
237
210
  */
238
-
239
-
240
- TsMediaServiceFacade.prototype.initSession = function initSession() {
241
- var _this2 = this;
211
+ initSession: function initSession() {
212
+ var _this = this;
242
213
 
243
214
  var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
244
215
  isMobile: false,
@@ -265,7 +236,7 @@ var TsMediaServiceFacade = function (_EventEmitter) {
265
236
  deviceOpts: deviceOpts || { audio: true, video: true }
266
237
  };
267
238
 
268
- return new _session3.KMSWebRTCSession(sessionOptions);
239
+ return new _session.KMSWebRTCSession(sessionOptions);
269
240
  });
270
241
  } else if (mediaServiceType === _constants.MEDIA_SERVICE_TYPES.TURNSERVER || isLoopback) {
271
242
  //
@@ -281,19 +252,17 @@ var TsMediaServiceFacade = function (_EventEmitter) {
281
252
  var sessionOptions = {
282
253
  isMobile: isMobile,
283
254
  resolution: resolution,
255
+
284
256
  credentials: creds,
285
257
  deviceOpts: deviceOpts || { audio: true, video: true }
286
258
  };
287
259
 
288
260
  if (isLoopback) {
289
- return new _session3.LoopbackWebRTCSession(sessionOptions);
261
+ return new _session.LoopbackWebRTCSession(sessionOptions);
290
262
  } else if (isMobile) {
291
- return new _session3.TurnWebRTCSession(sessionOptions, _this2.createLocalMediaStream.bind(_this2));
263
+ return new _session.TurnWebRTCSession(sessionOptions, _this.createLocalMediaStream);
292
264
  } else {
293
- return _this2.getTurnMediaSessionV2(sessionOptions).then(function (mediaSession) {
294
- _this2.subscribeTurnSessionEvents(mediaSession);
295
- return mediaSession;
296
- });
265
+ return new _session.TurnWebRtcSessionV2(sessionOptions, _this.createLocalMediaStream);
297
266
  }
298
267
  });
299
268
  }
@@ -314,68 +283,12 @@ var TsMediaServiceFacade = function (_EventEmitter) {
314
283
  return new _session2.TsOpenTokSession(sessionOptions);
315
284
  });
316
285
  }).then(function (session) {
317
- _this2.emit(SERVICE_EVENTS.SESSION_CREATED, session);
286
+ _this.emit(SERVICE_EVENTS.SESSION_CREATED, session);
318
287
 
319
288
  sessions.push(session);
320
289
 
321
290
  return session;
322
291
  });
323
- };
324
-
325
- TsMediaServiceFacade.prototype.getTurnMediaSessionV2 = function getTurnMediaSessionV2(sessionOptions) {
326
- var _this3 = this;
327
-
328
- return (0, _helper.getMediaConstraints)({
329
- resolution: sessionOptions.resolution,
330
- deviceOpts: sessionOptions.deviceOpts
331
- }).then(function (constraints) {
332
- var clientType = sessionOptions.isMobile ? _constants2.CLIENT_TYPES.INITIATOR : _constants2.CLIENT_TYPES.GUEST;
333
-
334
- // streaming from dashboard is not supported and we
335
- // don't want to access the camera without a reason
336
- if (clientType === _constants2.CLIENT_TYPES.GUEST) {
337
- delete constraints.video;
338
- }
339
-
340
- var sessionParams = {
341
- constraints: constraints,
342
- clientType: clientType,
343
- credentials: sessionOptions.credentials,
344
- streamFactory: _this3.createLocalMediaStream.bind(_this3)
345
- };
346
-
347
- return new _session3.TurnWebRtcSessionV2(sessionParams);
348
- });
349
- };
350
-
351
- TsMediaServiceFacade.prototype.subscribeTurnSessionEvents = function subscribeTurnSessionEvents(mediaSession) {
352
- var _this4 = this;
353
-
354
- var disconnectHandler = function disconnectHandler() {
355
- _this4.destroyLocalMediaStream();
356
- mediaSession.off(_session.SESSION_EVENTS.DISCONNECTED, disconnectHandler);
357
- };
358
-
359
- mediaSession.on(_session.SESSION_EVENTS.DISCONNECTED, disconnectHandler);
360
- };
361
-
362
- _createClass(TsMediaServiceFacade, [{
363
- key: 'sessions',
364
-
365
- /**
366
- * All created sessoins
367
- *
368
- * @member { Object }
369
- * @memberof TsMediaService
370
- * @type { Array<TsMediaSession> }
371
- */
372
- get: function get() {
373
- return sessions;
374
- }
375
- }]);
376
-
377
- return TsMediaServiceFacade;
378
- }(_eventEmitter.EventEmitter);
379
-
380
- var TsMediaService = exports.TsMediaService = new TsMediaServiceFacade();
292
+ }
293
+ });
381
294
  //# sourceMappingURL=service.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["service.js"],"names":["environmentDetect","TsEnvironmentDetect","isIE11","require","isChrome","majorVersion","_isOTDefined","OT","e","_waitForOT","Promise","resolve","isDefined","reduce","Array","WAIT_FOR_OPENTOK_INITIALIZATION_MAX_ATTEMPTS","delay","WAIT_FOR_OPENTOK_INITIALIZATION_INTERVAL","then","reject","SERVICE_EVENTS","SESSION_CREATED","EXCEPTION","EVENTS","sessions","latestLocalStream","userMediaPromise","TsMediaServiceFacade","createLocalMediaStream","constraints","videoTrack","getVideoTracks","length","readyState","TsMediaService","destroyLocalMediaStream","navigator","mediaDevices","getUserMedia","stream","catch","err","getTracks","forEach","track","stop","toggleMicrophone","enableMic","audioTracks","getAudioTracks","enabled","getDevices","error","devices","enumerateDevices","verifyCameraAccess","deviceOpts","isVideoPlaySupportedOnDevice","window","WebRTCAdapter","OTPlugin","isInstalled","initSession","isMobile","resolution","mediaServiceType","credentials","isLoopback","MEDIA_SERVICE_TYPES","MEDIASERVER","sessionOptions","tsMediaServer","audio","video","KMSWebRTCSession","TURNSERVER","creds","turnServer","opentok","LoopbackWebRTCSession","TurnWebRTCSession","bind","getTurnMediaSessionV2","mediaSession","subscribeTurnSessionEvents","TsOpenTokSession","session","emit","push","clientType","CLIENT_TYPES","INITIATOR","GUEST","sessionParams","streamFactory","TurnWebRtcSessionV2","disconnectHandler","off","SESSION_EVENTS","DISCONNECTED","on","EventEmitter"],"mappings":"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","file":"service.js","sourcesContent":["import {TsEnvironmentDetect} from '@techsee/techsee-common/lib/helpers/ts-environment-detect';\nimport {EventEmitter} from './event-emitter';\nimport {SESSION_EVENTS} from './session';\nimport {TsOpenTokSession} from './opentok/session';\nimport {KMSWebRTCSession, LoopbackWebRTCSession, TurnWebRTCSession, TurnWebRtcSessionV2} from './webrtc/session';\nimport {getHighestResolutionStream, getMediaConstraints} from './webrtc/helper';\n\nimport {\n MEDIA_SERVICE_TYPES,\n WAIT_FOR_OPENTOK_INITIALIZATION_INTERVAL,\n WAIT_FOR_OPENTOK_INITIALIZATION_MAX_ATTEMPTS\n} from './constants';\nimport {CLIENT_TYPES} from './webrtc/constants';\n\nconst environmentDetect = new TsEnvironmentDetect();\nconst isIE11 = environmentDetect.isIE11();\n\nif (isIE11) {\n require('./webrtc/webrtc-ie-shim.js');\n} else if (!(environmentDetect.isChrome() && (environmentDetect.majorVersion() < 49))) {\n require('webrtc-adapter/src/js/adapter_core'); // eslint-disable-line global-require\n}\n\nfunction _isOTDefined() {\n try {\n return !!OT;\n } catch (e) {\n return false;\n }\n}\n\nfunction _waitForOT() {\n if (_isOTDefined()) {\n return Promise.resolve();\n }\n\n let isDefined = false;\n\n return Promise.reduce(\n new Array(WAIT_FOR_OPENTOK_INITIALIZATION_MAX_ATTEMPTS),\n () => {\n if (isDefined || _isOTDefined()) {\n isDefined = true;\n\n return Promise.resolve();\n }\n\n return Promise.delay(WAIT_FOR_OPENTOK_INITIALIZATION_INTERVAL);\n }, 0)\n .then(() => isDefined || Promise.reject('OT is undefined'));\n}\n\n/**\n * @enum SERVICE_EVENTS\n */\nconst SERVICE_EVENTS = {\n SESSION_CREATED: 'SESSION_CREATED',\n EXCEPTION: 'EXCEPTION'\n};\n\nexport {SERVICE_EVENTS as EVENTS};\n\nconst sessions = [];\nlet latestLocalStream = null;\nlet userMediaPromise = null;\n\n/**\n * The top of hierarchy and the entry point of the TsMedia Service.\n *\n * @static\n * @class\n * @extends EventEmitter\n */\nclass TsMediaServiceFacade extends EventEmitter {\n /**\n * All created sessoins\n *\n * @member { Object }\n * @memberof TsMediaService\n * @type { Array<TsMediaSession> }\n */\n get sessions() {\n return sessions;\n }\n\n createLocalMediaStream(constraints) {\n if (userMediaPromise) {\n return userMediaPromise;\n }\n\n if (latestLocalStream) {\n const videoTrack = latestLocalStream.getVideoTracks();\n if (videoTrack.length > 0 && videoTrack[0].readyState === 'live') {\n return Promise.resolve(latestLocalStream);\n } else {\n TsMediaService.destroyLocalMediaStream();\n }\n }\n\n userMediaPromise = new Promise((resolve, reject) => {\n try {\n navigator.mediaDevices.getUserMedia(constraints)\n .then((stream) => {\n latestLocalStream = stream;\n userMediaPromise = null;\n resolve(stream);\n })\n .catch((err) => {\n userMediaPromise = null;\n reject(err);\n });\n } catch (e) {\n userMediaPromise = null;\n reject(e);\n }\n });\n\n return userMediaPromise;\n }\n\n destroyLocalMediaStream() {\n if (latestLocalStream) {\n latestLocalStream.getTracks().forEach((track) => {\n track.stop();\n });\n }\n\n latestLocalStream = null;\n }\n\n toggleMicrophone(enableMic = true) {\n if (!latestLocalStream) {\n return Promise.resolve();\n }\n\n const audioTracks = latestLocalStream.getAudioTracks();\n if (audioTracks.length > 0) {\n audioTracks[0].enabled = enableMic;\n }\n\n return Promise.resolve();\n }\n\n /**\n * Enumerate available media devices\n *\n * @method\n * @memberof TsMediaService\n * @returns { Promise<Array<MediaDeviceInfo>> } devices list\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/MediaDeviceInfo | MediaDeviceInfo documentation}\n */\n getDevices() {\n if ((typeof OT !== 'undefined') && OT && OT.getDevices) {\n return new Promise((resolve, reject) => {\n OT.getDevices((error, devices) => {\n if (error) {\n return reject(error);\n }\n\n return resolve(devices);\n });\n });\n }\n\n if (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) {\n return navigator.mediaDevices.enumerateDevices();\n }\n\n return Promise.reject('getDevices is not supported');\n }\n\n /**\n * Verifies camera access\n *\n * @method\n * @memberof TsMediaService\n * @returns { Promise<Object> } returns {stream,constraints} if successful, or rejected promise if failed\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/MediaDeviceInfo | MediaDeviceInfo documentation}\n */\n verifyCameraAccess(deviceOpts) {\n return getHighestResolutionStream(deviceOpts);\n }\n\n isVideoPlaySupportedOnDevice() {\n if (!isIE11) {\n return Promise.resolve(true);\n }\n\n if (!!window.WebRTCAdapter) {\n return Promise.resolve(true);\n }\n\n if (window.OT && window.OTPlugin && window.OTPlugin.isInstalled && window.OTPlugin.isInstalled()) {\n return Promise.resolve(true);\n }\n\n return Promise.resolve(false);\n }\n\n /**\n * Init WebRTC or OpenTok session depends on required type.\n *\n * Returns an initialized specific implementation of TsMediaSession interface.\n *\n * Assuming mobile will be a publisher and not mobile will be a subscriber.\n *\n * @method\n * @memberof TsMediaService\n *\n * @param { OPENTOK|MEDIASERVER|TURNSERVER } mediaServiceType required implementation\n * @param { Boolean } isMobile Whether techsee-mobile or not calls this method.\n * @param { Object } resolution constraint to use for video stream\n * @param { opentok|tsMediaServer|turnServer } credentials server/service credentials\n * @param { Object } deviceOpts requested devices (mainly audio/video device ids)\n * @param { Boolean } isLoopback Whether to use loopback webrtc\n *\n * @returns { Promise<TsMediaSession> }\n */\n initSession({\n mediaServiceType,\n isMobile,\n resolution,\n credentials,\n deviceOpts,\n isLoopback\n } = {\n isMobile: false,\n resolution: '640x480'\n }) {\n return Promise.resolve()\n .then(() => {\n if (mediaServiceType === MEDIA_SERVICE_TYPES.MEDIASERVER) {\n //\n // KMS CONNECTION\n //\n return Promise.resolve()\n .then(() => {\n const sessionOptions = {\n isMobile,\n resolution,\n\n credentials: credentials.tsMediaServer,\n deviceOpts: deviceOpts || {audio: true, video: true}\n };\n\n return new KMSWebRTCSession(sessionOptions);\n });\n } else if (mediaServiceType === MEDIA_SERVICE_TYPES.TURNSERVER || isLoopback) {\n //\n // TURN-based connection or loopback (no connection)\n //\n return Promise.resolve()\n .then(() => {\n let creds = null;\n\n if (!isLoopback) {\n creds = (mediaServiceType === MEDIA_SERVICE_TYPES.TURNSERVER) ? credentials.turnServer : credentials.opentok;\n }\n\n const sessionOptions = {\n isMobile,\n resolution,\n credentials: creds,\n deviceOpts: deviceOpts || {audio: true, video: true}\n };\n\n if (isLoopback) {\n return new LoopbackWebRTCSession(sessionOptions);\n } else if (isMobile) {\n return new TurnWebRTCSession(sessionOptions, this.createLocalMediaStream.bind(this));\n } else {\n return this.getTurnMediaSessionV2(sessionOptions)\n .then((mediaSession) => {\n this.subscribeTurnSessionEvents(mediaSession);\n return mediaSession;\n });\n }\n });\n }\n\n //\n // OT CONNECTION (default mediaServiceType)\n //\n return Promise.resolve()\n .then(() => _waitForOT())\n .then(() => {\n const sessionOptions = {\n isMobile,\n resolution,\n\n credentials: credentials.opentok\n };\n\n return new TsOpenTokSession(sessionOptions);\n });\n })\n .then((session) => {\n this.emit(SERVICE_EVENTS.SESSION_CREATED, session);\n\n sessions.push(session);\n\n return session;\n });\n }\n\n getTurnMediaSessionV2(sessionOptions) {\n return getMediaConstraints({\n resolution: sessionOptions.resolution,\n deviceOpts: sessionOptions.deviceOpts\n }).then((constraints) => {\n const clientType = sessionOptions.isMobile ? CLIENT_TYPES.INITIATOR : CLIENT_TYPES.GUEST;\n\n // streaming from dashboard is not supported and we\n // don't want to access the camera without a reason\n if (clientType === CLIENT_TYPES.GUEST) {\n delete constraints.video;\n }\n\n const sessionParams = {\n constraints,\n clientType,\n credentials: sessionOptions.credentials,\n streamFactory: this.createLocalMediaStream.bind(this)\n };\n\n return new TurnWebRtcSessionV2(sessionParams);\n });\n }\n\n subscribeTurnSessionEvents(mediaSession) {\n const disconnectHandler = () => {\n this.destroyLocalMediaStream();\n mediaSession.off(SESSION_EVENTS.DISCONNECTED, disconnectHandler);\n };\n\n mediaSession.on(SESSION_EVENTS.DISCONNECTED, disconnectHandler);\n }\n}\n\nexport const TsMediaService = new TsMediaServiceFacade();\n"]}
1
+ {"version":3,"sources":["service.js"],"names":["environmentDetect","TsEnvironmentDetect","isIE11","require","isChrome","majorVersion","_isOTDefined","OT","e","_waitForOT","Promise","resolve","isDefined","reduce","Array","WAIT_FOR_OPENTOK_INITIALIZATION_MAX_ATTEMPTS","delay","WAIT_FOR_OPENTOK_INITIALIZATION_INTERVAL","then","reject","SERVICE_EVENTS","SESSION_CREATED","EXCEPTION","EVENTS","sessions","latestLocalStream","userMediaPromise","TsMediaService","_","assign","EventEmitter","createLocalMediaStream","constraints","videoTrack","getVideoTracks","length","readyState","destroyLocalMediaStream","navigator","mediaDevices","getUserMedia","stream","catch","err","getTracks","forEach","track","stop","getDevices","error","devices","enumerateDevices","verifyCameraAccess","deviceOpts","isVideoPlaySupportedOnDevice","window","WebRTCAdapter","OTPlugin","isInstalled","initSession","isMobile","resolution","mediaServiceType","credentials","isLoopback","MEDIA_SERVICE_TYPES","MEDIASERVER","sessionOptions","tsMediaServer","audio","video","KMSWebRTCSession","TURNSERVER","creds","turnServer","opentok","LoopbackWebRTCSession","TurnWebRTCSession","TurnWebRtcSessionV2","TsOpenTokSession","session","emit","push"],"mappings":"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","file":"service.js","sourcesContent":["import {EventEmitter} from './event-emitter';\nimport {KMSWebRTCSession, LoopbackWebRTCSession, TurnWebRTCSession, TurnWebRtcSessionV2} from './webrtc/session';\nimport {TsEnvironmentDetect} from '@techsee/techsee-common/lib/helpers/ts-environment-detect';\nimport {TsOpenTokSession} from './opentok/session';\nimport {getHighestResolutionStream} from './webrtc/helper';\n\nimport {\n MEDIA_SERVICE_TYPES,\n WAIT_FOR_OPENTOK_INITIALIZATION_INTERVAL,\n WAIT_FOR_OPENTOK_INITIALIZATION_MAX_ATTEMPTS\n} from './constants';\n\nconst environmentDetect = new TsEnvironmentDetect();\nconst isIE11 = environmentDetect.isIE11();\n\nif (isIE11) {\n require('./webrtc/webrtc-ie-shim.js');\n} else if (!(environmentDetect.isChrome() && (environmentDetect.majorVersion() < 49))) {\n require('webrtc-adapter/src/js/adapter_core'); // eslint-disable-line global-require\n}\n\nfunction _isOTDefined() {\n try {\n return !!OT;\n } catch (e) {\n return false;\n }\n}\n\nfunction _waitForOT() {\n if (_isOTDefined()) {\n return Promise.resolve();\n }\n\n let isDefined = false;\n\n return Promise.reduce(\n new Array(WAIT_FOR_OPENTOK_INITIALIZATION_MAX_ATTEMPTS),\n () => {\n if (isDefined || _isOTDefined()) {\n isDefined = true;\n\n return Promise.resolve();\n }\n\n return Promise.delay(WAIT_FOR_OPENTOK_INITIALIZATION_INTERVAL);\n }, 0)\n .then(() => isDefined || Promise.reject('OT is undefined'));\n}\n\n/**\n * @enum SERVICE_EVENTS\n */\nconst SERVICE_EVENTS = {\n SESSION_CREATED: 'SESSION_CREATED',\n EXCEPTION: 'EXCEPTION'\n};\n\nexport {SERVICE_EVENTS as EVENTS};\n\nconst sessions = [];\nlet latestLocalStream = null;\nlet userMediaPromise = null;\n\n/**\n * The top of hierarchy and the entry point of the TsMedia Service.\n *\n * @static\n * @class\n * @extends EventEmitter\n */\nexport const TsMediaService = _.assign(new EventEmitter(), {\n\n /**\n * All created sessoins\n *\n * @member { Object }\n * @memberof TsMediaService\n * @type { Array<TsMediaSession> }\n */\n get sessions() {\n return sessions;\n },\n\n createLocalMediaStream(constraints) {\n if (userMediaPromise) {\n return userMediaPromise;\n }\n\n if (latestLocalStream) {\n const videoTrack = latestLocalStream.getVideoTracks();\n if (videoTrack.length > 0 && videoTrack[0].readyState === 'live') {\n return Promise.resolve(latestLocalStream);\n } else {\n this.destroyLocalMediaStream();\n }\n }\n\n userMediaPromise = new Promise((resolve, reject) => {\n try {\n navigator.mediaDevices.getUserMedia(constraints)\n .then((stream) => {\n latestLocalStream = stream;\n userMediaPromise = null;\n resolve(stream);\n })\n .catch((err) => {\n userMediaPromise = null;\n reject(err);\n });\n } catch (e) {\n userMediaPromise = null;\n reject(e);\n }\n });\n\n return userMediaPromise;\n },\n\n destroyLocalMediaStream() {\n if (latestLocalStream) {\n latestLocalStream.getTracks().forEach((track) => {\n track.stop();\n });\n }\n\n latestLocalStream = null;\n },\n\n /**\n * Enumerate available media devices\n *\n * @method\n * @memberof TsMediaService\n * @returns { Promise<Array<MediaDeviceInfo>> } devices list\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/MediaDeviceInfo | MediaDeviceInfo documentation}\n */\n getDevices() {\n if ((typeof OT !== 'undefined') && OT && OT.getDevices) {\n return new Promise((resolve, reject) => {\n OT.getDevices((error, devices) => {\n if (error) {\n return reject(error);\n }\n\n return resolve(devices);\n });\n });\n }\n\n if (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) {\n return navigator.mediaDevices.enumerateDevices();\n }\n\n return Promise.reject('getDevices is not supported');\n },\n\n /**\n * Verifies camera access\n *\n * @method\n * @memberof TsMediaService\n * @returns { Promise<Object> } returns {stream,constraints} if successful, or rejected promise if failed\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/MediaDeviceInfo | MediaDeviceInfo documentation}\n */\n verifyCameraAccess(deviceOpts) {\n return getHighestResolutionStream(deviceOpts);\n },\n\n isVideoPlaySupportedOnDevice() {\n if (!isIE11) {\n return Promise.resolve(true);\n }\n\n if (!!window.WebRTCAdapter) {\n return Promise.resolve(true);\n }\n\n if (window.OT && window.OTPlugin && window.OTPlugin.isInstalled && window.OTPlugin.isInstalled()) {\n return Promise.resolve(true);\n }\n\n return Promise.resolve(false);\n },\n\n /**\n * Init WebRTC or OpenTok session depends on required type.\n *\n * Returns an initialized specific implementation of TsMediaSession interface.\n *\n * Assuming mobile will be a publisher and not mobile will be a subscriber.\n *\n * @method\n * @memberof TsMediaService\n *\n * @param { OPENTOK|MEDIASERVER|TURNSERVER } mediaServiceType required implementation\n * @param { Boolean } isMobile Whether techsee-mobile or not calls this method.\n * @param { Object } resolution constraint to use for video stream\n * @param { opentok|tsMediaServer|turnServer } credentials server/service credentials\n * @param { Object } deviceOpts requested devices (mainly audio/video device ids)\n * @param { Boolean } isLoopback Whether to use loopback webrtc\n *\n * @returns { Promise<TsMediaSession> }\n */\n initSession({\n mediaServiceType,\n isMobile,\n resolution,\n credentials,\n deviceOpts,\n isLoopback\n } = {\n isMobile: false,\n resolution: '640x480'\n }) {\n return Promise.resolve()\n .then(() => {\n if (mediaServiceType === MEDIA_SERVICE_TYPES.MEDIASERVER) {\n //\n // KMS CONNECTION\n //\n return Promise.resolve()\n .then(() => {\n const sessionOptions = {\n isMobile,\n resolution,\n\n credentials: credentials.tsMediaServer,\n deviceOpts: deviceOpts || {audio: true, video: true}\n };\n\n return new KMSWebRTCSession(sessionOptions);\n });\n } else if (mediaServiceType === MEDIA_SERVICE_TYPES.TURNSERVER || isLoopback) {\n //\n // TURN-based connection or loopback (no connection)\n //\n return Promise.resolve()\n .then(() => {\n let creds = null;\n\n if (!isLoopback) {\n creds = (mediaServiceType === MEDIA_SERVICE_TYPES.TURNSERVER) ? credentials.turnServer : credentials.opentok;\n }\n\n const sessionOptions = {\n isMobile,\n resolution,\n\n credentials: creds,\n deviceOpts: deviceOpts || {audio: true, video: true}\n };\n\n if (isLoopback) {\n return new LoopbackWebRTCSession(sessionOptions);\n } else if (isMobile) {\n return new TurnWebRTCSession(sessionOptions, this.createLocalMediaStream);\n } else {\n return new TurnWebRtcSessionV2(sessionOptions, this.createLocalMediaStream);\n }\n });\n }\n\n //\n // OT CONNECTION (default mediaServiceType)\n //\n return Promise.resolve()\n .then(() => _waitForOT())\n .then(() => {\n const sessionOptions = {\n isMobile,\n resolution,\n\n credentials: credentials.opentok\n };\n\n return new TsOpenTokSession(sessionOptions);\n });\n })\n .then((session) => {\n this.emit(SERVICE_EVENTS.SESSION_CREATED, session);\n\n sessions.push(session);\n\n return session;\n });\n }\n});\n\n"]}
@@ -73,9 +73,7 @@ var PIPELINE_TYPES = exports.PIPELINE_TYPES = {
73
73
 
74
74
  var CLIENT_TYPES = exports.CLIENT_TYPES = {
75
75
  PUBLISHER: 'publisher',
76
- SUBSCRIBER: 'subscriber',
77
- INITIATOR: 'publisher',
78
- GUEST: 'subscriber'
76
+ SUBSCRIBER: 'subscriber'
79
77
  };
80
78
 
81
79
  var PEER_CONNECTION_TYPES = exports.PEER_CONNECTION_TYPES = {
@@ -1 +1 @@
1
- {"version":3,"sources":["webrtc/constants.js"],"names":["SOCKET_EVENTS","OUTGOING","ICE_CANDIDATE","JOIN_PIPELINE","DESTROY_PIPELINE","JOIN_ROOM","SDP_OFFER","SDP_ANSWER","INCOMING","JOIN_RESPONSE","ERROR","PIPELINE_DESTROYED","SEND_OFFER","PUBLISHER_RECONNECT","PEER_DISCONNECTED","PIPELINE_TYPES","AUDIO_VIDEO_TO_SUBSCRIBERS","AUDIO_VIDEO_TO_SUBSCRIBERS_WITH_SMART","CLIENT_TYPES","PUBLISHER","SUBSCRIBER","INITIATOR","GUEST","PEER_CONNECTION_TYPES","SEND_ONLY","RECV_ONLY","SEND_RECV","COOKIES","UID","DEFAULT_STREAM_NAMES","MOBILE_CLIENT_VIDEO_STREAM","MOBILE_CLIENT_AUDIO_STREAM","DASHBOARD_AUDIO_STREAM","RECONNECT_TURN_SERVER_INTERVAL","FAILED_CONNECTING_TURN_SERVER_INTERVAL","WAIT_FOR_PC_INTERVAL","PUBLISH_APPROVAL_CHECK_INTERVAL","SOCKET_RECONNECTION_DELAY","SOCKET_RECONNECTION_DELAY_MAX","SOCKET_RECONNECTION_ATTEMPTS","SOCKET_PATH"],"mappings":";;;AAAO,IAAMA,wCAAgB;AACzBC,cAAU;AACN;AACAC,uBAAe,gBAFT;;AAIN;AACA;AACA;;AAEA;AACAC,uBAAe,cATT;;AAWN;AACAC,0BAAkB,iBAZZ;;AAcN;AACA;AACA;;AAEA;AACAC,mBAAW,UAnBL;;AAqBN;AACAC,mBAAW,cAtBL;;AAwBN;AACAC,oBAAY;AAzBN,KADe;AA4BzBC,cAAU;AACN;AACA;AACAC,uBAAe,cAHT,EAGyB;;AAE/B;AACAP,uBAAe,cANT;;AAQN;AACAQ,eAAO,cATD;;AAWN;AACA;AACA;;AAEA;AACAC,4BAAoB,mBAhBd;;AAkBN;AACA;AACA;;AAEA;AACAC,oBAAY,WAvBN;;AAyBN;AACAN,mBAAW,cA1BL;;AA4BN;AACAO,6BAAqB,oBA7Bf;;AA+BN;AACAC,2BAAmB;AAhCb;AA5Be,CAAtB;;AAgEP;AACO,IAAMC,0CAAiB;AAC1BC,gCAA4B,iBADF;AAE1BC,2CAAuC;AAFb,CAAvB;;AAKA,IAAMC,sCAAe;AACxBC,eAAW,WADa;AAExBC,gBAAY,YAFY;AAGxBC,eAAW,WAHa;AAIxBC,WAAO;AAJiB,CAArB;;AAOA,IAAMC,wDAAwB;AACjCC,eAAW,oBADsB;AAEjCC,eAAW,oBAFsB;AAGjCC,eAAW;AAHsB,CAA9B;;AAMP;AACO,IAAMC,4BAAU;AACnBC,SAAK;AADc,CAAhB;;AAIA,IAAMC,sDAAuB;AAChCC,gCAA4B,4BADI;AAEhCC,gCAA4B,4BAFI;AAGhCC,4BAAwB;AAHQ,CAA7B;;AAMP;AACO,IAAMC,0EAAiC,IAAvC;;AAEP;AACO,IAAMC,0FAAyC,KAA/C;;AAEP;AACO,IAAMC,sDAAuB,IAA7B;;AAEP;AACO,IAAMC,4EAAkC,IAAxC;;AAEA,IAAMC,gEAA4B,IAAlC;AAAA,IACHC,wEAAgC,IAD7B;AAAA,IAEHC,sEAA+B,GAF5B;AAAA,IAGHC,oCAAc,aAHX","file":"constants.js","sourcesContent":["export const SOCKET_EVENTS = {\n OUTGOING: {\n // Emitted to a peer, offering an ICE candidate\n ICE_CANDIDATE: 'onIceCandidate',\n\n //\n // KMS Events\n //\n\n // Initial event, sent by pub/sub as a request to create/join a pipeline\n JOIN_PIPELINE: 'joinPipeline',\n\n // Final event, sent by pub/sub as a request to destroy a pipeline, or response to PIPELINE_DESTROYED event\n DESTROY_PIPELINE: 'destroyPipeline',\n\n //\n // TURN Events\n //\n\n // Initial event, sent by pub/sub as a request to create/join a room\n JOIN_ROOM: 'joinRoom',\n\n // Sent by publisher, as a response to an SDP offer request (SEND_OFFER)\n SDP_OFFER: 'sdpOfferSend',\n\n // An SDP response (emitted after receiving an SDP offer)\n SDP_ANSWER: 'sdpAnswerSend'\n },\n INCOMING: {\n // In TURN - Received by a publisher, as a response to an SDP_ANSWER sent by a subscriber\n // In KMS - Received after JOIN_PIPELINE is processed\n JOIN_RESPONSE: 'joinResponse', // This event is received by a publisher, when the sig server receive an SDP answer from subscriber\n\n // An incoming ICE candidate sent by a peer\n ICE_CANDIDATE: 'iceCandidate',\n\n // An error occured in the signaling server\n ERROR: 'errorOccured',\n\n //\n // KMS Events\n //\n\n // KMS pipeline was destroyed, in response we do a cleanup\n PIPELINE_DESTROYED: 'pipelineDestroyed',\n\n //\n // TURN Events\n //\n\n // Received by a publisher (sent by signaling server when a peer joining a room)\n SEND_OFFER: 'sendOffer',\n\n // Recieved by a subscriber when publisher sent an SDP offer\n SDP_OFFER: 'sdpOfferRecv',\n\n // Recieved by all subscribers, when the publisher has reconnected\n PUBLISHER_RECONNECT: 'publisherReconnect',\n\n // Recieved by the publisher, when a subscriber has disconnected\n PEER_DISCONNECTED: 'peerDisconnected'\n }\n};\n\n// KMS - Pipeline types\nexport const PIPELINE_TYPES = {\n AUDIO_VIDEO_TO_SUBSCRIBERS: 'AudioVideoToSub',\n AUDIO_VIDEO_TO_SUBSCRIBERS_WITH_SMART: 'AudioVideoToSubWithSmart'\n};\n\nexport const CLIENT_TYPES = {\n PUBLISHER: 'publisher',\n SUBSCRIBER: 'subscriber',\n INITIATOR: 'publisher',\n GUEST: 'subscriber'\n};\n\nexport const PEER_CONNECTION_TYPES = {\n SEND_ONLY: 'WebRtcPeerSendonly',\n RECV_ONLY: 'WebRtcPeerRecvonly',\n SEND_RECV: 'WebRtcPeerSendrecv'\n};\n\n// Used to store the peer unique identifier (UID)\nexport const COOKIES = {\n UID: 'media-client.uid'\n};\n\nexport const DEFAULT_STREAM_NAMES = {\n MOBILE_CLIENT_VIDEO_STREAM: 'MOBILE_CLIENT_VIDEO_STREAM',\n MOBILE_CLIENT_AUDIO_STREAM: 'MOBILE_CLIENT_AUDIO_STREAM',\n DASHBOARD_AUDIO_STREAM: 'DASHBOARD_AUDIO_STREAM'\n};\n\n// When ICE exchange fail, an interval between reconnection attempts\nexport const RECONNECT_TURN_SERVER_INTERVAL = 1000;\n\n// When ICE exchange start, this is the timeout until the connection is deemed failed\nexport const FAILED_CONNECTING_TURN_SERVER_INTERVAL = 15000;\n\n// Grace to to wait before creating a publisher, if peer connection has not been created yet\nexport const WAIT_FOR_PC_INTERVAL = 2000;\n\n// Interval between checks of video publishing ability attempts\nexport const PUBLISH_APPROVAL_CHECK_INTERVAL = 1000;\n\nexport const SOCKET_RECONNECTION_DELAY = 3000,\n SOCKET_RECONNECTION_DELAY_MAX = 6000,\n SOCKET_RECONNECTION_ATTEMPTS = 100,\n SOCKET_PATH = '/socket2.io';\n"]}
1
+ {"version":3,"sources":["webrtc/constants.js"],"names":["SOCKET_EVENTS","OUTGOING","ICE_CANDIDATE","JOIN_PIPELINE","DESTROY_PIPELINE","JOIN_ROOM","SDP_OFFER","SDP_ANSWER","INCOMING","JOIN_RESPONSE","ERROR","PIPELINE_DESTROYED","SEND_OFFER","PUBLISHER_RECONNECT","PEER_DISCONNECTED","PIPELINE_TYPES","AUDIO_VIDEO_TO_SUBSCRIBERS","AUDIO_VIDEO_TO_SUBSCRIBERS_WITH_SMART","CLIENT_TYPES","PUBLISHER","SUBSCRIBER","PEER_CONNECTION_TYPES","SEND_ONLY","RECV_ONLY","SEND_RECV","COOKIES","UID","DEFAULT_STREAM_NAMES","MOBILE_CLIENT_VIDEO_STREAM","MOBILE_CLIENT_AUDIO_STREAM","DASHBOARD_AUDIO_STREAM","RECONNECT_TURN_SERVER_INTERVAL","FAILED_CONNECTING_TURN_SERVER_INTERVAL","WAIT_FOR_PC_INTERVAL","PUBLISH_APPROVAL_CHECK_INTERVAL","SOCKET_RECONNECTION_DELAY","SOCKET_RECONNECTION_DELAY_MAX","SOCKET_RECONNECTION_ATTEMPTS","SOCKET_PATH"],"mappings":";;;AAAO,IAAMA,wCAAgB;AACzBC,cAAU;AACN;AACAC,uBAAe,gBAFT;;AAIN;AACA;AACA;;AAEA;AACAC,uBAAe,cATT;;AAWN;AACAC,0BAAkB,iBAZZ;;AAcN;AACA;AACA;;AAEA;AACAC,mBAAW,UAnBL;;AAqBN;AACAC,mBAAW,cAtBL;;AAwBN;AACAC,oBAAY;AAzBN,KADe;AA4BzBC,cAAU;AACN;AACA;AACAC,uBAAe,cAHT,EAGyB;;AAE/B;AACAP,uBAAe,cANT;;AAQN;AACAQ,eAAO,cATD;;AAWN;AACA;AACA;;AAEA;AACAC,4BAAoB,mBAhBd;;AAkBN;AACA;AACA;;AAEA;AACAC,oBAAY,WAvBN;;AAyBN;AACAN,mBAAW,cA1BL;;AA4BN;AACAO,6BAAqB,oBA7Bf;;AA+BN;AACAC,2BAAmB;AAhCb;AA5Be,CAAtB;;AAgEP;AACO,IAAMC,0CAAiB;AAC1BC,gCAA4B,iBADF;AAE1BC,2CAAuC;AAFb,CAAvB;;AAKA,IAAMC,sCAAe;AACxBC,eAAW,WADa;AAExBC,gBAAY;AAFY,CAArB;;AAKA,IAAMC,wDAAwB;AACjCC,eAAW,oBADsB;AAEjCC,eAAW,oBAFsB;AAGjCC,eAAW;AAHsB,CAA9B;;AAMP;AACO,IAAMC,4BAAU;AACnBC,SAAK;AADc,CAAhB;;AAIA,IAAMC,sDAAuB;AAChCC,gCAA4B,4BADI;AAEhCC,gCAA4B,4BAFI;AAGhCC,4BAAwB;AAHQ,CAA7B;;AAMP;AACO,IAAMC,0EAAiC,IAAvC;;AAEP;AACO,IAAMC,0FAAyC,KAA/C;;AAEP;AACO,IAAMC,sDAAuB,IAA7B;;AAEP;AACO,IAAMC,4EAAkC,IAAxC;;AAEA,IAAMC,gEAA4B,IAAlC;AAAA,IACHC,wEAAgC,IAD7B;AAAA,IAEHC,sEAA+B,GAF5B;AAAA,IAGHC,oCAAc,aAHX","file":"constants.js","sourcesContent":["export const SOCKET_EVENTS = {\n OUTGOING: {\n // Emitted to a peer, offering an ICE candidate\n ICE_CANDIDATE: 'onIceCandidate',\n\n //\n // KMS Events\n //\n\n // Initial event, sent by pub/sub as a request to create/join a pipeline\n JOIN_PIPELINE: 'joinPipeline',\n\n // Final event, sent by pub/sub as a request to destroy a pipeline, or response to PIPELINE_DESTROYED event\n DESTROY_PIPELINE: 'destroyPipeline',\n\n //\n // TURN Events\n //\n\n // Initial event, sent by pub/sub as a request to create/join a room\n JOIN_ROOM: 'joinRoom',\n\n // Sent by publisher, as a response to an SDP offer request (SEND_OFFER)\n SDP_OFFER: 'sdpOfferSend',\n\n // An SDP response (emitted after receiving an SDP offer)\n SDP_ANSWER: 'sdpAnswerSend',\n },\n INCOMING: {\n // In TURN - Received by a publisher, as a response to an SDP_ANSWER sent by a subscriber\n // In KMS - Received after JOIN_PIPELINE is processed\n JOIN_RESPONSE: 'joinResponse', // This event is received by a publisher, when the sig server receive an SDP answer from subscriber\n\n // An incoming ICE candidate sent by a peer\n ICE_CANDIDATE: 'iceCandidate',\n\n // An error occured in the signaling server\n ERROR: 'errorOccured',\n\n //\n // KMS Events\n //\n\n // KMS pipeline was destroyed, in response we do a cleanup\n PIPELINE_DESTROYED: 'pipelineDestroyed',\n\n //\n // TURN Events\n //\n\n // Received by a publisher (sent by signaling server when a peer joining a room)\n SEND_OFFER: 'sendOffer',\n\n // Recieved by a subscriber when publisher sent an SDP offer\n SDP_OFFER: 'sdpOfferRecv',\n\n // Recieved by all subscribers, when the publisher has reconnected\n PUBLISHER_RECONNECT: 'publisherReconnect',\n\n // Recieved by the publisher, when a subscriber has disconnected\n PEER_DISCONNECTED: 'peerDisconnected'\n },\n};\n\n// KMS - Pipeline types\nexport const PIPELINE_TYPES = {\n AUDIO_VIDEO_TO_SUBSCRIBERS: 'AudioVideoToSub',\n AUDIO_VIDEO_TO_SUBSCRIBERS_WITH_SMART: 'AudioVideoToSubWithSmart',\n};\n\nexport const CLIENT_TYPES = {\n PUBLISHER: 'publisher',\n SUBSCRIBER: 'subscriber',\n};\n\nexport const PEER_CONNECTION_TYPES = {\n SEND_ONLY: 'WebRtcPeerSendonly',\n RECV_ONLY: 'WebRtcPeerRecvonly',\n SEND_RECV: 'WebRtcPeerSendrecv'\n};\n\n// Used to store the peer unique identifier (UID)\nexport const COOKIES = {\n UID: 'media-client.uid',\n};\n\nexport const DEFAULT_STREAM_NAMES = {\n MOBILE_CLIENT_VIDEO_STREAM: 'MOBILE_CLIENT_VIDEO_STREAM',\n MOBILE_CLIENT_AUDIO_STREAM: 'MOBILE_CLIENT_AUDIO_STREAM',\n DASHBOARD_AUDIO_STREAM: 'DASHBOARD_AUDIO_STREAM'\n};\n\n// When ICE exchange fail, an interval between reconnection attempts\nexport const RECONNECT_TURN_SERVER_INTERVAL = 1000;\n\n// When ICE exchange start, this is the timeout until the connection is deemed failed\nexport const FAILED_CONNECTING_TURN_SERVER_INTERVAL = 15000;\n\n// Grace to to wait before creating a publisher, if peer connection has not been created yet\nexport const WAIT_FOR_PC_INTERVAL = 2000;\n\n// Interval between checks of video publishing ability attempts\nexport const PUBLISH_APPROVAL_CHECK_INTERVAL = 1000;\n\nexport const SOCKET_RECONNECTION_DELAY = 3000,\n SOCKET_RECONNECTION_DELAY_MAX = 6000,\n SOCKET_RECONNECTION_ATTEMPTS = 100,\n SOCKET_PATH = '/socket2.io';\n"]}
@@ -771,12 +771,8 @@ var TurnWebRTCSession = exports.TurnWebRTCSession = function (_TsMediaSession) {
771
771
  //
772
772
  var video = document.createElement('video');
773
773
 
774
- //Currently this code is used only in mobile, so when publishing, then we always need only video track
775
- //to set to video element. Othenwise, when VOIP enabled, technician side will here himself through this video element.
776
- var videoTracks = publisher.stream._mediaStream.getVideoTracks();
777
-
778
774
  if (!isIE11) {
779
- video.srcObject = new MediaStream(videoTracks);
775
+ video.src = URL.createObjectURL(publisher.stream._mediaStream);
780
776
  }
781
777
 
782
778
  video.playsInline = true;
@@ -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);\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');\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');\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 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. Othenwise, when VOIP enabled, technician side will here 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","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","src","URL","createObjectURL","_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);\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');\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');\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 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 if (!isIE11) {\n video.src = URL.createObjectURL(publisher.stream._mediaStream);\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"]}
@@ -13,6 +13,8 @@ var io = _interopRequireWildcard(_socket);
13
13
 
14
14
  var _constants = require('./constants');
15
15
 
16
+ var _helper = require('./helper');
17
+
16
18
  var _stream = require('./stream');
17
19
 
18
20
  var _tracer = require('../tracer');
@@ -26,7 +28,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
26
28
  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; }
27
29
 
28
30
  var trace = (0, _tracer.getTracer)('TurnWebRtcSessionV2', function () {
29
- return window.TurnSessionDebugV2 === true;
31
+ return window.TurnSessionDebugV2 === true || true;
30
32
  });
31
33
 
32
34
  //Currently this version supports subscribing only. Publishing will be implemented as needed.
@@ -41,11 +43,11 @@ var TurnWebRtcSessionV2 = exports.TurnWebRtcSessionV2 = function (_TsMediaSessio
41
43
  }
42
44
  }]);
43
45
 
44
- function TurnWebRtcSessionV2(_ref) {
46
+ function TurnWebRtcSessionV2(_ref, localStreamFactory) {
45
47
  var credentials = _ref.credentials,
46
- constraints = _ref.constraints,
47
- clientType = _ref.clientType,
48
- streamFactory = _ref.streamFactory;
48
+ isMobile = _ref.isMobile,
49
+ resolution = _ref.resolution,
50
+ deviceOpts = _ref.deviceOpts;
49
51
 
50
52
  _classCallCheck(this, TurnWebRtcSessionV2);
51
53
 
@@ -53,13 +55,17 @@ var TurnWebRtcSessionV2 = exports.TurnWebRtcSessionV2 = function (_TsMediaSessio
53
55
 
54
56
  _this._socket = null;
55
57
  _this._localPeer = null;
56
- _this._pendingPeersIce = {};
57
58
  _this._peerConnections = new Map();
58
59
 
59
60
  _this._credentials = credentials;
60
- _this._constraints = constraints;
61
- _this._selfClientType = clientType;
62
- _this._localStreamFactory = streamFactory;
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;
63
69
 
64
70
  var iceServers = credentials.ice.map(function (item) {
65
71
  return {
@@ -74,12 +80,12 @@ var TurnWebRtcSessionV2 = exports.TurnWebRtcSessionV2 = function (_TsMediaSessio
74
80
  iceTransportPolicy: 'relay'
75
81
  };
76
82
 
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);
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);
83
89
 
84
90
  _this._extendPeerConnection();
85
91
  return _this;
@@ -95,10 +101,29 @@ var TurnWebRtcSessionV2 = exports.TurnWebRtcSessionV2 = function (_TsMediaSessio
95
101
  trace('connect');
96
102
 
97
103
  return this._connectSocket(this._credentials.url, connectOnly).then(function () {
98
- trace('Joining SessionId: ' + _this2._credentials.sessionId);
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
+ }
99
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
+ trace('Joining SessionId: ' + _this2._credentials.sessionId);
100
125
  _this2._socket.emit(_constants.SOCKET_EVENTS.OUTGOING.JOIN_ROOM, {
101
- clientType: _this2._selfClientType,
126
+ clientType: clientType,
102
127
  sessionId: _this2._credentials.sessionId
103
128
  });
104
129
  }).catch(function (error) {
@@ -114,8 +139,6 @@ var TurnWebRtcSessionV2 = exports.TurnWebRtcSessionV2 = function (_TsMediaSessio
114
139
  _this3._destroyPeerConnection(peerConnection);
115
140
  });
116
141
 
117
- this.emit(_session.SESSION_EVENTS.DISCONNECTED, { reason: 'disconnected' });
118
-
119
142
  this._socket.off();
120
143
  this._socket.disconnect();
121
144
  };
@@ -145,38 +168,38 @@ var TurnWebRtcSessionV2 = exports.TurnWebRtcSessionV2 = function (_TsMediaSessio
145
168
 
146
169
  if (!connectOnly) {
147
170
  //PUBLISHING NOT SUPPORTED YET
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);
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);
151
174
 
152
- socket.on(_constants.SOCKET_EVENTS.INCOMING.SDP_OFFER, _this4._sdpOfferHandler);
153
- socket.on(_constants.SOCKET_EVENTS.INCOMING.PUBLISHER_RECONNECT, _this4._initiatorReconnectHandler);
175
+ socket.on(_constants.SOCKET_EVENTS.INCOMING.SDP_OFFER, _this4.sdpOfferHandler);
176
+ socket.on(_constants.SOCKET_EVENTS.INCOMING.PUBLISHER_RECONNECT, _this4.publisherReconnectHandler);
154
177
 
155
- socket.on(_constants.SOCKET_EVENTS.INCOMING.ICE_CANDIDATE, _this4._iceCandidateReceivedHandler);
178
+ socket.on(_constants.SOCKET_EVENTS.INCOMING.ICE_CANDIDATE, _this4.iceCandidateReceivedHandler);
156
179
  }
157
180
  });
158
181
  };
159
182
 
160
183
  //#endregion
161
184
 
162
- //#region WebRTC Initiator - session Initiator (User on mobile device)
185
+ //#region Publisher
163
186
 
164
- // Received by Initiator, causing him to emit SDP_OFFER
187
+ // Received by publisher, causing him to emit SDP_OFFER
165
188
 
166
189
 
167
- TurnWebRtcSessionV2.prototype._sendOfferHandler = function _sendOfferHandler(_ref2) {
190
+ TurnWebRtcSessionV2.prototype.sendOfferHandler = function sendOfferHandler(_ref2) {
168
191
  var _this5 = this;
169
192
 
170
193
  var uid = _ref2.uid,
171
194
  peerId = _ref2.peerId;
172
195
 
173
- trace('_sendOfferHandler');
196
+ trace('sendOfferHandler');
174
197
 
175
- var peerConnection = this._createPeerConnection(peerId, _constants.CLIENT_TYPES.GUEST);
198
+ var peerConnection = this._createPeerConnection(peerId, _constants.CLIENT_TYPES.SUBSCRIBER);
176
199
  var offerParams = { offerToReceiveAudio: true, offerToReceiveVideo: true };
177
200
 
178
201
  this._localStreamFactory(this._constraints).then(function (localStream) {
179
- trace('_sendOfferHandler stream and peer created');
202
+ trace('sendOfferHandler stream and peer created');
180
203
 
181
204
  var peerConnectionStream = new _stream.TsWebRTCStream(_this5, localStream.clone(), _constants.DEFAULT_STREAM_NAMES.MOBILE_CLIENT_VIDEO_STREAM, false);
182
205
 
@@ -191,7 +214,7 @@ var TurnWebRtcSessionV2 = exports.TurnWebRtcSessionV2 = function (_TsMediaSessio
191
214
  }).then(function () {
192
215
  return peerConnection.createOffer(offerParams);
193
216
  }).then(function (offerDesc) {
194
- trace('Initiator has created sdp offer', { offerDesc: offerDesc });
217
+ trace('Publisher has created sdp offer', { offerDesc: offerDesc });
195
218
 
196
219
  _this5._socket.emit(_constants.SOCKET_EVENTS.OUTGOING.SDP_OFFER, {
197
220
  uid: uid,
@@ -208,10 +231,10 @@ var TurnWebRtcSessionV2 = exports.TurnWebRtcSessionV2 = function (_TsMediaSessio
208
231
  });
209
232
  };
210
233
 
211
- // Received by the Initiator: Indicates that publish should be started
234
+ // Received by the publisher: Indicates that publish should be started
212
235
 
213
236
 
214
- TurnWebRtcSessionV2.prototype._joinResponseHandler = function _joinResponseHandler(_ref3) {
237
+ TurnWebRtcSessionV2.prototype.joinResponseHandler = function joinResponseHandler(_ref3) {
215
238
  var _this6 = this;
216
239
 
217
240
  var sdpAnswer = _ref3.sdpAnswer,
@@ -236,112 +259,81 @@ var TurnWebRtcSessionV2 = exports.TurnWebRtcSessionV2 = function (_TsMediaSessio
236
259
  });
237
260
  };
238
261
 
239
- // Received by Initiator after a guests socket has been disconnected
262
+ // Received by publisher after a subscriber's socket has been disconnected
240
263
 
241
264
 
242
- TurnWebRtcSessionV2.prototype._peerDisconnectedHandler = function _peerDisconnectedHandler(_ref4) {
265
+ TurnWebRtcSessionV2.prototype.peerDisconnectedHandler = function peerDisconnectedHandler(_ref4) {
243
266
  var peerId = _ref4.peerId;
244
267
 
245
- trace('_peerDisconnectedHandler');
268
+ trace('peerDisconnectedHandler');
246
269
  };
247
270
 
248
- //#endregion WebRTC Initiator - session Initiator (User on mobile device)
271
+ //#endregion Publisher
249
272
 
250
- //#region WebRTC Guest - session Guest (Agent on dashboard platform)
273
+ //#region Subscriber
251
274
 
252
- // Received by Guest, causing him to emit SDP_ANSWER
275
+ // Received by subscriber, causing him to emit SDP_ANSWER
253
276
 
254
277
 
255
- TurnWebRtcSessionV2.prototype._sdpOfferHandler = function _sdpOfferHandler(_ref5) {
278
+ TurnWebRtcSessionV2.prototype.sdpOfferHandler = function sdpOfferHandler(_ref5) {
256
279
  var _this7 = this;
257
280
 
258
281
  var sdpOffer = _ref5.sdpOffer,
259
282
  peerId = _ref5.peerId,
260
283
  uid = _ref5.uid;
261
284
 
262
- trace('sdpOffer Received', { sdpOffer: sdpOffer });
263
-
264
- var peerConnection = this._createPeerConnection(peerId, _constants.CLIENT_TYPES.INITIATOR);
285
+ trace('sdpOffer Received', sdpOffer);
265
286
 
266
- var subscriberInitChain = Promise.resolve();
287
+ var peerConnection = this._createPeerConnection(peerId, _constants.CLIENT_TYPES.PUBLISHER);
267
288
 
268
- if (this._constraints.audio) {
269
- subscriberInitChain = subscriberInitChain.then(function () {
270
- trace('Creating agent local streams');
289
+ var remoteDesc = new RTCSessionDescription({ type: 'offer', sdp: sdpOffer });
271
290
 
272
- return _this7._localStreamFactory(_this7._constraints).then(function (localStream) {
273
- localStream.getTracks().forEach(function (track) {
274
- trace('Adding local tracks to peer connection');
291
+ peerConnection.setRemoteDescription(remoteDesc).then(function () {
292
+ trace('Remote description was set', remoteDesc);
275
293
 
276
- if (track.kind === 'audio') {
294
+ return peerConnection.createAnswer().then(function (sdpAnswer) {
295
+ trace('sdpOfferHandler answer created', sdpAnswer);
277
296
 
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
- });
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
288
302
  });
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);
300
303
 
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
- });
304
+ return peerConnection.setLocalDescription(sdpAnswer).then(function () {
305
+ trace('sdpOfferHandler local desc was set');
307
306
 
308
- return peerConnection.setLocalDescription(sdpAnswer).then(function () {
309
- trace('_sdpOfferHandler local desc was set');
310
-
311
- _this7._processQueuedIceCandidates(peerId);
312
- });
307
+ _this7._processQueuedIceCandidates(peerId);
313
308
  });
314
309
  });
315
- });
316
-
317
- return subscriberInitChain.catch(function (e) {
318
- trace('Error in _sdpOfferHandler', e);
319
- throw e;
310
+ }).catch(function (e) {
311
+ trace('Error in sdpOfferHandler', e);
320
312
  });
321
313
  };
322
314
 
323
- // Received by Guest after an Initiator reconnects to room
315
+ // Received by subscriber after a publisher reconnects to room
324
316
 
325
317
 
326
- TurnWebRtcSessionV2.prototype._initiatorReconnectHandler = function _initiatorReconnectHandler() {
327
- trace('_initiatorReconnectHandler');
318
+ TurnWebRtcSessionV2.prototype.publisherReconnectHandler = function publisherReconnectHandler() {
319
+ trace('publisherReconnectHandler');
328
320
 
329
- var initiatorPeer = this._getInitiatorPeer();
321
+ var publisherPeer = this._getPublisherPeer();
330
322
 
331
- if (initiatorPeer) {
332
- this._destroyPeerConnection(initiatorPeer);
323
+ if (publisherPeer) {
324
+ this._destroyPeerConnection(publisherPeer);
333
325
  }
334
326
 
335
327
  this.emit(_session.SESSION_EVENTS.RECONNECT_TURN_SERVER);
336
328
  };
337
329
 
338
- TurnWebRtcSessionV2.prototype._getInitiatorPeer = function _getInitiatorPeer() {
339
- var peer = this._getPeerConnectionsByType(_constants.CLIENT_TYPES.INITIATOR);
330
+ TurnWebRtcSessionV2.prototype._getPublisherPeer = function _getPublisherPeer() {
331
+ var publisherPeer = this._getPeerConnectionsByType(_constants.CLIENT_TYPES.PUBLISHER);
340
332
 
341
- return peer.length > 0 ? peer[0] : null;
333
+ return publisherPeer.length > 0 ? publisherPeer[0] : null;
342
334
  };
343
335
 
344
- //#endregion WebRTC Guest - session Guest (Agent on dashboard platform)
336
+ //#endregion Subscriber
345
337
 
346
338
  //#region Peer Connection
347
339
 
@@ -356,7 +348,6 @@ var TurnWebRtcSessionV2 = exports.TurnWebRtcSessionV2 = function (_TsMediaSessio
356
348
 
357
349
  peerConnection.peerId = peerId;
358
350
  peerConnection.peerType = peerConnectionType;
359
- peerConnection.peerLogicalStream = new MediaStream();
360
351
 
361
352
  peerConnection.oniceconnectionstatechange = function (state) {
362
353
  trace('ICE Connection state for peer ' + peerId + ' was changed to: ' + state.currentTarget.iceConnectionState, state);
@@ -379,15 +370,13 @@ var TurnWebRtcSessionV2 = exports.TurnWebRtcSessionV2 = function (_TsMediaSessio
379
370
  }
380
371
  };
381
372
 
382
- if (this._selfClientType === _constants.CLIENT_TYPES.GUEST) {
383
- peerConnection.ontrack = function (trackEvent) {
384
- var track = trackEvent.track,
385
- streams = trackEvent.streams;
373
+ if (this._selfClientType === _constants.CLIENT_TYPES.SUBSCRIBER) {
374
+ peerConnection.ontrack = function (track) {
375
+ var stream = track.streams[0];
386
376
 
377
+ trace('Stream created from peer connection track: ' + track.kind, stream);
387
378
 
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]);
379
+ var tsStream = new _stream.TsWebRTCStream(_this8, stream);
391
380
 
392
381
  tsStream.peerConnection = peerConnection;
393
382
  tsStream.remote = true;
@@ -408,15 +397,15 @@ var TurnWebRtcSessionV2 = exports.TurnWebRtcSessionV2 = function (_TsMediaSessio
408
397
  TurnWebRtcSessionV2.prototype._destroyPeerConnection = function _destroyPeerConnection(peerConnection) {
409
398
  var _this9 = this;
410
399
 
411
- if (this._selfClientType === _constants.CLIENT_TYPES.GUEST) {
400
+ if (this._selfClientType === _constants.CLIENT_TYPES.SUBSCRIBER) {
412
401
  this._getRemoteStreams(peerConnection).forEach(function (stream) {
413
402
  _this9.unregisterStream(stream.id);
414
403
  _this9.emit(_session.SESSION_EVENTS.STREAM_DESTROYED, { stream: stream });
415
404
  });
416
405
  }
417
406
 
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).
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).
420
409
  }
421
410
 
422
411
  this._peerConnections.delete(peerConnection.peerId);
@@ -465,21 +454,17 @@ var TurnWebRtcSessionV2 = exports.TurnWebRtcSessionV2 = function (_TsMediaSessio
465
454
  if (!RTCPeerConnection.prototype.peerType) {
466
455
  RTCPeerConnection.prototype.peerType = null;
467
456
  }
468
-
469
- if (!RTCPeerConnection.prototype.peerLogicalStream) {
470
- RTCPeerConnection.prototype.peerLogicalStream = null;
471
- }
472
457
  };
473
458
 
474
459
  //#endregion
475
460
 
476
461
  //#region ICE Candidates
477
462
 
478
- TurnWebRtcSessionV2.prototype._iceCandidateReceivedHandler = function _iceCandidateReceivedHandler(_ref6) {
463
+ TurnWebRtcSessionV2.prototype.iceCandidateReceivedHandler = function iceCandidateReceivedHandler(_ref6) {
479
464
  var candidate = _ref6.candidate,
480
465
  peerId = _ref6.peerId;
481
466
 
482
- trace('_iceCandidateReceivedHandler', candidate);
467
+ trace('iceCandidateReceivedHandler', candidate);
483
468
  if (!candidate) {
484
469
  trace('NO iceCandidate');
485
470
 
@@ -533,7 +518,7 @@ var TurnWebRtcSessionV2 = exports.TurnWebRtcSessionV2 = function (_TsMediaSessio
533
518
  };
534
519
 
535
520
  TurnWebRtcSessionV2.prototype._iceStateDisconnected = function _iceStateDisconnected(peerConnection) {
536
- if (peerConnection.peerType === _constants.CLIENT_TYPES.INITIATOR) {
521
+ if (peerConnection.peerType === _constants.CLIENT_TYPES.PUBLISHER) {
537
522
  this._destroyPeerConnection(peerConnection);
538
523
  }
539
524
  };
@@ -1 +1 @@
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"]}
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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@techsee/techsee-media-service",
3
- "version": "0.4.0-alpha.15",
3
+ "version": "0.4.0",
4
4
  "description": "Techsee Media Service Client",
5
5
  "author": "TechSee - Alex Danilov",
6
6
  "main": "lib/index.js",