@techsee/techsee-media-service 0.4.0-alpha.14 → 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 +37 -122
- package/lib/service.js.map +1 -1
- package/lib/webrtc/constants.js +1 -3
- package/lib/webrtc/constants.js.map +1 -1
- package/lib/webrtc/session-turn.js +1 -5
- package/lib/webrtc/session-turn.js.map +1 -1
- package/lib/webrtc/session-turn.v2.js +102 -117
- package/lib/webrtc/session-turn.v2.js.map +1 -1
- package/package.json +1 -1
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
|
|
10
|
+
var _tsEnvironmentDetect = require('@techsee/techsee-common/lib/helpers/ts-environment-detect');
|
|
15
11
|
|
|
16
|
-
var
|
|
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
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,20 +127,8 @@ var TsMediaServiceFacade = function (_EventEmitter) {
|
|
|
137
127
|
}
|
|
138
128
|
|
|
139
129
|
latestLocalStream = null;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
TsMediaServiceFacade.prototype.toggleMicrophone = function toggleMicrophone() {
|
|
143
|
-
var mute = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
144
|
-
|
|
145
|
-
if (!latestLocalStream) {
|
|
146
|
-
return Promise.resolve();
|
|
147
|
-
}
|
|
130
|
+
},
|
|
148
131
|
|
|
149
|
-
var audioTracks = latestLocalStream.getAudioTracks();
|
|
150
|
-
if (audioTracks.length > 0) {
|
|
151
|
-
audioTracks[0].enabled = mute;
|
|
152
|
-
}
|
|
153
|
-
};
|
|
154
132
|
|
|
155
133
|
/**
|
|
156
134
|
* Enumerate available media devices
|
|
@@ -161,9 +139,7 @@ var TsMediaServiceFacade = function (_EventEmitter) {
|
|
|
161
139
|
*
|
|
162
140
|
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/MediaDeviceInfo | MediaDeviceInfo documentation}
|
|
163
141
|
*/
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
TsMediaServiceFacade.prototype.getDevices = function getDevices() {
|
|
142
|
+
getDevices: function getDevices() {
|
|
167
143
|
if (typeof OT !== 'undefined' && OT && OT.getDevices) {
|
|
168
144
|
return new Promise(function (resolve, reject) {
|
|
169
145
|
OT.getDevices(function (error, devices) {
|
|
@@ -181,7 +157,8 @@ var TsMediaServiceFacade = function (_EventEmitter) {
|
|
|
181
157
|
}
|
|
182
158
|
|
|
183
159
|
return Promise.reject('getDevices is not supported');
|
|
184
|
-
}
|
|
160
|
+
},
|
|
161
|
+
|
|
185
162
|
|
|
186
163
|
/**
|
|
187
164
|
* Verifies camera access
|
|
@@ -192,13 +169,10 @@ var TsMediaServiceFacade = function (_EventEmitter) {
|
|
|
192
169
|
*
|
|
193
170
|
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/MediaDeviceInfo | MediaDeviceInfo documentation}
|
|
194
171
|
*/
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
TsMediaServiceFacade.prototype.verifyCameraAccess = function verifyCameraAccess(deviceOpts) {
|
|
172
|
+
verifyCameraAccess: function verifyCameraAccess(deviceOpts) {
|
|
198
173
|
return (0, _helper.getHighestResolutionStream)(deviceOpts);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
TsMediaServiceFacade.prototype.isVideoPlaySupportedOnDevice = function isVideoPlaySupportedOnDevice() {
|
|
174
|
+
},
|
|
175
|
+
isVideoPlaySupportedOnDevice: function isVideoPlaySupportedOnDevice() {
|
|
202
176
|
if (!isIE11) {
|
|
203
177
|
return Promise.resolve(true);
|
|
204
178
|
}
|
|
@@ -212,7 +186,8 @@ var TsMediaServiceFacade = function (_EventEmitter) {
|
|
|
212
186
|
}
|
|
213
187
|
|
|
214
188
|
return Promise.resolve(false);
|
|
215
|
-
}
|
|
189
|
+
},
|
|
190
|
+
|
|
216
191
|
|
|
217
192
|
/**
|
|
218
193
|
* Init WebRTC or OpenTok session depends on required type.
|
|
@@ -233,10 +208,8 @@ var TsMediaServiceFacade = function (_EventEmitter) {
|
|
|
233
208
|
*
|
|
234
209
|
* @returns { Promise<TsMediaSession> }
|
|
235
210
|
*/
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
TsMediaServiceFacade.prototype.initSession = function initSession() {
|
|
239
|
-
var _this2 = this;
|
|
211
|
+
initSession: function initSession() {
|
|
212
|
+
var _this = this;
|
|
240
213
|
|
|
241
214
|
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
|
|
242
215
|
isMobile: false,
|
|
@@ -263,7 +236,7 @@ var TsMediaServiceFacade = function (_EventEmitter) {
|
|
|
263
236
|
deviceOpts: deviceOpts || { audio: true, video: true }
|
|
264
237
|
};
|
|
265
238
|
|
|
266
|
-
return new
|
|
239
|
+
return new _session.KMSWebRTCSession(sessionOptions);
|
|
267
240
|
});
|
|
268
241
|
} else if (mediaServiceType === _constants.MEDIA_SERVICE_TYPES.TURNSERVER || isLoopback) {
|
|
269
242
|
//
|
|
@@ -279,19 +252,17 @@ var TsMediaServiceFacade = function (_EventEmitter) {
|
|
|
279
252
|
var sessionOptions = {
|
|
280
253
|
isMobile: isMobile,
|
|
281
254
|
resolution: resolution,
|
|
255
|
+
|
|
282
256
|
credentials: creds,
|
|
283
257
|
deviceOpts: deviceOpts || { audio: true, video: true }
|
|
284
258
|
};
|
|
285
259
|
|
|
286
260
|
if (isLoopback) {
|
|
287
|
-
return new
|
|
261
|
+
return new _session.LoopbackWebRTCSession(sessionOptions);
|
|
288
262
|
} else if (isMobile) {
|
|
289
|
-
return new
|
|
263
|
+
return new _session.TurnWebRTCSession(sessionOptions, _this.createLocalMediaStream);
|
|
290
264
|
} else {
|
|
291
|
-
return
|
|
292
|
-
_this2.subscribeTurnSessionEvents(mediaSession);
|
|
293
|
-
return mediaSession;
|
|
294
|
-
});
|
|
265
|
+
return new _session.TurnWebRtcSessionV2(sessionOptions, _this.createLocalMediaStream);
|
|
295
266
|
}
|
|
296
267
|
});
|
|
297
268
|
}
|
|
@@ -312,68 +283,12 @@ var TsMediaServiceFacade = function (_EventEmitter) {
|
|
|
312
283
|
return new _session2.TsOpenTokSession(sessionOptions);
|
|
313
284
|
});
|
|
314
285
|
}).then(function (session) {
|
|
315
|
-
|
|
286
|
+
_this.emit(SERVICE_EVENTS.SESSION_CREATED, session);
|
|
316
287
|
|
|
317
288
|
sessions.push(session);
|
|
318
289
|
|
|
319
290
|
return session;
|
|
320
291
|
});
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
TsMediaServiceFacade.prototype.getTurnMediaSessionV2 = function getTurnMediaSessionV2(sessionOptions) {
|
|
324
|
-
var _this3 = this;
|
|
325
|
-
|
|
326
|
-
return (0, _helper.getMediaConstraints)({
|
|
327
|
-
resolution: sessionOptions.resolution,
|
|
328
|
-
deviceOpts: sessionOptions.deviceOpts
|
|
329
|
-
}).then(function (constraints) {
|
|
330
|
-
var clientType = sessionOptions.isMobile ? _constants2.CLIENT_TYPES.INITIATOR : _constants2.CLIENT_TYPES.GUEST;
|
|
331
|
-
|
|
332
|
-
// streaming from dashboard is not supported and we
|
|
333
|
-
// don't want to access the camera without a reason
|
|
334
|
-
if (clientType === _constants2.CLIENT_TYPES.GUEST) {
|
|
335
|
-
delete constraints.video;
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
var sessionParams = {
|
|
339
|
-
constraints: constraints,
|
|
340
|
-
clientType: clientType,
|
|
341
|
-
credentials: sessionOptions.credentials,
|
|
342
|
-
streamFactory: _this3.createLocalMediaStream.bind(_this3)
|
|
343
|
-
};
|
|
344
|
-
|
|
345
|
-
return new _session3.TurnWebRtcSessionV2(sessionParams);
|
|
346
|
-
});
|
|
347
|
-
};
|
|
348
|
-
|
|
349
|
-
TsMediaServiceFacade.prototype.subscribeTurnSessionEvents = function subscribeTurnSessionEvents(mediaSession) {
|
|
350
|
-
var _this4 = this;
|
|
351
|
-
|
|
352
|
-
var disconnectHandler = function disconnectHandler() {
|
|
353
|
-
_this4.destroyLocalMediaStream();
|
|
354
|
-
mediaSession.off(_session.SESSION_EVENTS.DISCONNECTED, disconnectHandler);
|
|
355
|
-
};
|
|
356
|
-
|
|
357
|
-
mediaSession.on(_session.SESSION_EVENTS.DISCONNECTED, disconnectHandler);
|
|
358
|
-
};
|
|
359
|
-
|
|
360
|
-
_createClass(TsMediaServiceFacade, [{
|
|
361
|
-
key: 'sessions',
|
|
362
|
-
|
|
363
|
-
/**
|
|
364
|
-
* All created sessoins
|
|
365
|
-
*
|
|
366
|
-
* @member { Object }
|
|
367
|
-
* @memberof TsMediaService
|
|
368
|
-
* @type { Array<TsMediaSession> }
|
|
369
|
-
*/
|
|
370
|
-
get: function get() {
|
|
371
|
-
return sessions;
|
|
372
|
-
}
|
|
373
|
-
}]);
|
|
374
|
-
|
|
375
|
-
return TsMediaServiceFacade;
|
|
376
|
-
}(_eventEmitter.EventEmitter);
|
|
377
|
-
|
|
378
|
-
var TsMediaService = exports.TsMediaService = new TsMediaServiceFacade();
|
|
292
|
+
}
|
|
293
|
+
});
|
|
379
294
|
//# sourceMappingURL=service.js.map
|
package/lib/service.js.map
CHANGED
|
@@ -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","mute","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(mute = false) {\n if (!latestLocalStream) {\n return Promise.resolve();\n }\n\n const audioTracks = latestLocalStream.getAudioTracks();\n if (audioTracks.length > 0) {\n audioTracks[0].enabled = mute;\n }\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"]}
|
package/lib/webrtc/constants.js
CHANGED
|
@@ -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","
|
|
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.
|
|
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
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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.
|
|
61
|
-
|
|
62
|
-
_this.
|
|
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.
|
|
78
|
-
_this.
|
|
79
|
-
_this.
|
|
80
|
-
_this.
|
|
81
|
-
_this.
|
|
82
|
-
_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('
|
|
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:
|
|
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.
|
|
149
|
-
//socket.on(SOCKET_EVENTS.INCOMING.JOIN_RESPONSE, this.
|
|
150
|
-
//socket.on(SOCKET_EVENTS.INCOMING.PEER_DISCONNECTED, this.
|
|
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.
|
|
153
|
-
socket.on(_constants.SOCKET_EVENTS.INCOMING.PUBLISHER_RECONNECT, _this4.
|
|
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.
|
|
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
|
|
185
|
+
//#region Publisher
|
|
163
186
|
|
|
164
|
-
// Received by
|
|
187
|
+
// Received by publisher, causing him to emit SDP_OFFER
|
|
165
188
|
|
|
166
189
|
|
|
167
|
-
TurnWebRtcSessionV2.prototype.
|
|
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('
|
|
196
|
+
trace('sendOfferHandler');
|
|
174
197
|
|
|
175
|
-
var peerConnection = this._createPeerConnection(peerId, _constants.CLIENT_TYPES.
|
|
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('
|
|
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('
|
|
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
|
|
234
|
+
// Received by the publisher: Indicates that publish should be started
|
|
212
235
|
|
|
213
236
|
|
|
214
|
-
TurnWebRtcSessionV2.prototype.
|
|
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
|
|
262
|
+
// Received by publisher after a subscriber's socket has been disconnected
|
|
240
263
|
|
|
241
264
|
|
|
242
|
-
TurnWebRtcSessionV2.prototype.
|
|
265
|
+
TurnWebRtcSessionV2.prototype.peerDisconnectedHandler = function peerDisconnectedHandler(_ref4) {
|
|
243
266
|
var peerId = _ref4.peerId;
|
|
244
267
|
|
|
245
|
-
trace('
|
|
268
|
+
trace('peerDisconnectedHandler');
|
|
246
269
|
};
|
|
247
270
|
|
|
248
|
-
//#endregion
|
|
271
|
+
//#endregion Publisher
|
|
249
272
|
|
|
250
|
-
//#region
|
|
273
|
+
//#region Subscriber
|
|
251
274
|
|
|
252
|
-
// Received by
|
|
275
|
+
// Received by subscriber, causing him to emit SDP_ANSWER
|
|
253
276
|
|
|
254
277
|
|
|
255
|
-
TurnWebRtcSessionV2.prototype.
|
|
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',
|
|
263
|
-
|
|
264
|
-
var peerConnection = this._createPeerConnection(peerId, _constants.CLIENT_TYPES.INITIATOR);
|
|
285
|
+
trace('sdpOffer Received', sdpOffer);
|
|
265
286
|
|
|
266
|
-
var
|
|
287
|
+
var peerConnection = this._createPeerConnection(peerId, _constants.CLIENT_TYPES.PUBLISHER);
|
|
267
288
|
|
|
268
|
-
|
|
269
|
-
subscriberInitChain = subscriberInitChain.then(function () {
|
|
270
|
-
trace('Creating agent local streams');
|
|
289
|
+
var remoteDesc = new RTCSessionDescription({ type: 'offer', sdp: sdpOffer });
|
|
271
290
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
trace('Adding local tracks to peer connection');
|
|
291
|
+
peerConnection.setRemoteDescription(remoteDesc).then(function () {
|
|
292
|
+
trace('Remote description was set', remoteDesc);
|
|
275
293
|
|
|
276
|
-
|
|
294
|
+
return peerConnection.createAnswer().then(function (sdpAnswer) {
|
|
295
|
+
trace('sdpOfferHandler answer created', sdpAnswer);
|
|
277
296
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
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
|
-
|
|
302
|
-
|
|
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
|
-
|
|
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
|
|
315
|
+
// Received by subscriber after a publisher reconnects to room
|
|
324
316
|
|
|
325
317
|
|
|
326
|
-
TurnWebRtcSessionV2.prototype.
|
|
327
|
-
trace('
|
|
318
|
+
TurnWebRtcSessionV2.prototype.publisherReconnectHandler = function publisherReconnectHandler() {
|
|
319
|
+
trace('publisherReconnectHandler');
|
|
328
320
|
|
|
329
|
-
var
|
|
321
|
+
var publisherPeer = this._getPublisherPeer();
|
|
330
322
|
|
|
331
|
-
if (
|
|
332
|
-
this._destroyPeerConnection(
|
|
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.
|
|
339
|
-
var
|
|
330
|
+
TurnWebRtcSessionV2.prototype._getPublisherPeer = function _getPublisherPeer() {
|
|
331
|
+
var publisherPeer = this._getPeerConnectionsByType(_constants.CLIENT_TYPES.PUBLISHER);
|
|
340
332
|
|
|
341
|
-
return
|
|
333
|
+
return publisherPeer.length > 0 ? publisherPeer[0] : null;
|
|
342
334
|
};
|
|
343
335
|
|
|
344
|
-
//#endregion
|
|
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.
|
|
383
|
-
peerConnection.ontrack = function (
|
|
384
|
-
var
|
|
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
|
-
|
|
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.
|
|
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.
|
|
419
|
-
//TODO - ALEX: When
|
|
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.
|
|
463
|
+
TurnWebRtcSessionV2.prototype.iceCandidateReceivedHandler = function iceCandidateReceivedHandler(_ref6) {
|
|
479
464
|
var candidate = _ref6.candidate,
|
|
480
465
|
peerId = _ref6.peerId;
|
|
481
466
|
|
|
482
|
-
trace('
|
|
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.
|
|
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"]}
|