@techsee/techsee-media-service 0.1.3

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.
Files changed (44) hide show
  1. package/README.md +1 -0
  2. package/lib/constants.js +20 -0
  3. package/lib/constants.js.map +1 -0
  4. package/lib/event-emitter.js +39 -0
  5. package/lib/event-emitter.js.map +1 -0
  6. package/lib/index.js +64 -0
  7. package/lib/index.js.map +1 -0
  8. package/lib/opentok/session.js +304 -0
  9. package/lib/opentok/session.js.map +1 -0
  10. package/lib/opentok/stream.js +310 -0
  11. package/lib/opentok/stream.js.map +1 -0
  12. package/lib/publisher.js +143 -0
  13. package/lib/publisher.js.map +1 -0
  14. package/lib/qos/raw-qos.js +319 -0
  15. package/lib/qos/raw-qos.js.map +1 -0
  16. package/lib/service.js +316 -0
  17. package/lib/service.js.map +1 -0
  18. package/lib/session.js +104 -0
  19. package/lib/session.js.map +1 -0
  20. package/lib/stream.js +195 -0
  21. package/lib/stream.js.map +1 -0
  22. package/lib/subscriber.js +90 -0
  23. package/lib/subscriber.js.map +1 -0
  24. package/lib/webrtc/constants.js +112 -0
  25. package/lib/webrtc/constants.js.map +1 -0
  26. package/lib/webrtc/helper.js +169 -0
  27. package/lib/webrtc/helper.js.map +1 -0
  28. package/lib/webrtc/session-kms.js +558 -0
  29. package/lib/webrtc/session-kms.js.map +1 -0
  30. package/lib/webrtc/session-loopback.js +340 -0
  31. package/lib/webrtc/session-loopback.js.map +1 -0
  32. package/lib/webrtc/session-turn.js +807 -0
  33. package/lib/webrtc/session-turn.js.map +1 -0
  34. package/lib/webrtc/session-turn.v2.js +2 -0
  35. package/lib/webrtc/session-turn.v2.js.map +1 -0
  36. package/lib/webrtc/session.js +40 -0
  37. package/lib/webrtc/session.js.map +1 -0
  38. package/lib/webrtc/stream.js +631 -0
  39. package/lib/webrtc/stream.js.map +1 -0
  40. package/lib/webrtc/temasys/adapter-loader.js +12 -0
  41. package/lib/webrtc/temasys/adapter-loader.js.map +1 -0
  42. package/lib/webrtc/temasys/adapter.js +5861 -0
  43. package/lib/webrtc/temasys/adapter.js.map +1 -0
  44. package/package.json +53 -0
@@ -0,0 +1,340 @@
1
+ 'use strict';
2
+
3
+ exports.__esModule = true;
4
+ exports.LoopbackWebRTCSession = undefined;
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 _session = require('../session');
9
+
10
+ var _publisher = require('../publisher');
11
+
12
+ var _tsEnvironmentDetect = require('techsee-common/lib/helpers/ts-environment-detect');
13
+
14
+ var _stream = require('./stream');
15
+
16
+ var _helper = require('./helper');
17
+
18
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
19
+
20
+ 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; }
21
+
22
+ 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; }
23
+
24
+ var isIE11 = new _tsEnvironmentDetect.TsEnvironmentDetect().isIE11();
25
+
26
+ if (isIE11) {
27
+ require('./temasys/adapter-loader')(); // eslint-disable-line global-require
28
+ }
29
+
30
+ /**
31
+ * WebRTC-specific implementation of TsMediaSession.
32
+ *
33
+ * Instance of this class is returned by TsMediaService.initSession call
34
+ * with 'LOOPBACK' as desired mediaType.
35
+ *
36
+ * @class
37
+ * @extends TsMediaSession
38
+ *
39
+ * @see TsMediaSession
40
+ */
41
+ var LoopbackWebRTCSession = exports.LoopbackWebRTCSession = function (_TsMediaSession) {
42
+ _inherits(LoopbackWebRTCSession, _TsMediaSession);
43
+
44
+ function LoopbackWebRTCSession(_ref) {
45
+ var credentials = _ref.credentials,
46
+ deviceOpts = _ref.deviceOpts;
47
+
48
+ _classCallCheck(this, LoopbackWebRTCSession);
49
+
50
+ var _this = _possibleConstructorReturn(this, _TsMediaSession.call(this));
51
+
52
+ _this._credentials = credentials;
53
+ _this._deviceOpts = deviceOpts;
54
+ _this._constraints = null;
55
+ return _this;
56
+ }
57
+
58
+ /**
59
+ * Id of the session.
60
+ *
61
+ * @member { String }
62
+ *
63
+ * @type { String }
64
+ */
65
+
66
+
67
+ LoopbackWebRTCSession.prototype._setTrackStateTo = function _setTrackStateTo(state) {
68
+ return function (track) {
69
+ if (track.setEnabled) {
70
+ track.setEnabled(state);
71
+ } else {
72
+ track.enabled = state;
73
+ }
74
+ };
75
+ };
76
+
77
+ /**
78
+ * Loopback does not connect, but still need to provide an implementation.
79
+ *
80
+ * @method
81
+ * @returns { Promise }
82
+ *
83
+ */
84
+
85
+
86
+ LoopbackWebRTCSession.prototype.connect = function connect() {
87
+ return Promise.resolve();
88
+ };
89
+
90
+ LoopbackWebRTCSession.prototype._toggleAllStreams = function _toggleAllStreams(state) {
91
+ var _this2 = this;
92
+
93
+ if (!_.isEmpty(this._streams)) {
94
+ this._streams.forEach(function (stream) {
95
+ return stream._mediaStream.getTracks().forEach(_this2._setTrackStateTo(state));
96
+ });
97
+ }
98
+ };
99
+
100
+ LoopbackWebRTCSession.prototype._stopAllStreams = function _stopAllStreams() {
101
+ if (!_.isEmpty(this._streams)) {
102
+ this._streams.forEach(function (stream) {
103
+ return stream._mediaStream.getTracks().forEach(function (track) {
104
+ return track.stop();
105
+ });
106
+ });
107
+ }
108
+ };
109
+
110
+ /**
111
+ * Cleanup
112
+ *
113
+ * @method
114
+ * @returns { Promise }
115
+ *
116
+ */
117
+
118
+
119
+ LoopbackWebRTCSession.prototype.disconnect = function disconnect() {
120
+ return Promise.resolve();
121
+ };
122
+
123
+ /**
124
+ * Create new TsMediaPublisher instance
125
+ *
126
+ * @method
127
+ *
128
+ * @param { DOMElement } [target] Video element
129
+ * that will be used to render publishing video stream
130
+ * @param { Object } params
131
+ * @param { String } [params.videoDevice] Video device id
132
+ * @param { String } [params.videoParams] Video device id
133
+ * @param { String } [params.videoParams.fitMode] Video fit mode
134
+ * @param { Number|String } [params.videoParams.width] Video element width
135
+ * @param { Number|String } [params.videoParams.height] Video element height
136
+ * @param { String } [params.audioDevice] Video device id
137
+ *
138
+ * @returns { Promise<TsMediaPublisher> } publisher
139
+ *
140
+ * @see TsMediaPublisher
141
+ */
142
+
143
+
144
+ LoopbackWebRTCSession.prototype.createPublisher = function createPublisher(t, p) {
145
+ var _this3 = this;
146
+
147
+ var target = t,
148
+ params = p;
149
+
150
+ if (!params) {
151
+ params = target;
152
+ target = null;
153
+ }
154
+
155
+ return new Promise(function (resolve, reject) {
156
+ (0, _helper.getHighestResolutionStream)(_this3._deviceOpts, _this3._constraints).then(function (result) {
157
+ _this3._constraints = result.constraints;
158
+
159
+ return resolve(result.stream);
160
+ }).catch(function (error) {
161
+ return reject(error);
162
+ });
163
+ }).then(function (mediaStream) {
164
+ // Clear previous streams
165
+ _this3._streams.clear();
166
+
167
+ //
168
+ // Get tracks that are related to the publisher (audio or video)
169
+ //
170
+ var tracks = mediaStream.getTracks().filter(function (track) {
171
+ return track.kind === 'video' && params.videoDevice || track.kind === 'audio' && params.audioDevice;
172
+ });
173
+
174
+ var videoTrackSettings = (0, _helper.getVideoTrackSettings)(mediaStream);
175
+
176
+ var tsstream = new _stream.TsWebRTCStream(_this3, mediaStream, params.name, false, videoTrackSettings);
177
+
178
+ var publisher = new _publisher.TsMediaPublisher(_this3, {
179
+ stream: tsstream,
180
+ tracks: tracks,
181
+ videoParams: params.videoParams,
182
+
183
+ videoHeight: tsstream.videoDimensions.height,
184
+ videoWidth: tsstream.videoDimensions.width,
185
+
186
+ _target: target
187
+ });
188
+
189
+ tsstream.publisher = publisher;
190
+ _this3.publisher = publisher;
191
+
192
+ return publisher;
193
+ });
194
+ };
195
+
196
+ /**
197
+ * Publish stream from previously create TsMediaPublisher instance.
198
+ *
199
+ * Used internally by TsMediaPublisher.publish
200
+ *
201
+ * @method
202
+ *
203
+ * @param { TsMediaPublisher } publisher
204
+ *
205
+ * @returns { Promise }
206
+ *
207
+ * @fires PUBLISHER_EVENTS#STREAM_CREATED
208
+ * @fires SESSION_EVENTS#STREAM_PROPERTY_CHANGED
209
+ * @fires STREAM_EVENTS#PROPERTY_CHANGED
210
+ *
211
+ * @see TsMediaPublisher#publish
212
+ */
213
+
214
+
215
+ LoopbackWebRTCSession.prototype.publish = function publish(publisher) {
216
+ var _this4 = this;
217
+
218
+ return Promise.resolve().then(function () {
219
+ publisher.emit(_publisher.EVENTS.STREAM_CREATED, publisher.stream);
220
+ _this4.emit(_session.EVENTS.STREAM_PROPERTY_CHANGED, {
221
+ stream: publisher.stream,
222
+ property: 'hasVideo',
223
+ value: publisher.stream.hasVideo
224
+ });
225
+ _this4.emit(_session.EVENTS.STREAM_PROPERTY_CHANGED, {
226
+ stream: publisher.stream,
227
+ property: 'hasAudio',
228
+ value: publisher.stream.hasAudio
229
+ });
230
+
231
+ if (_this4.publisher._element) {
232
+ return;
233
+ }
234
+
235
+ if (publisher._target) {
236
+ //
237
+ // New video element where publishing video stream will be rendered
238
+ //
239
+ var video = document.createElement('video');
240
+
241
+ if (!isIE11) {
242
+ video.src = URL.createObjectURL(publisher.stream._mediaStream);
243
+ }
244
+
245
+ video.playsInline = true;
246
+ video.autoplay = true;
247
+
248
+ if (isIE11) {
249
+ publisher._target.appendChild(video);
250
+ publisher._element = attachMediaStream(video, publisher.stream._mediaStream);
251
+ }
252
+
253
+ var streamDimensions = publisher.stream.videoDimensions;
254
+
255
+ var params = _.assign({}, {
256
+ fitMode: 'contain',
257
+ insertMode: 'append',
258
+ mirror: false,
259
+ resolution: streamDimensions.width + 'x' + streamDimensions.height,
260
+ width: '100%',
261
+ height: '100%'
262
+ }, publisher.videoParams);
263
+
264
+ var elementHeight = typeof params.height === 'string' ? params.height : params.height + 'px';
265
+ var elementWidth = typeof params.width === 'string' ? params.width : params.width + 'px';
266
+
267
+ _.assign((isIE11 ? publisher._element : video).style, {
268
+ height: elementHeight,
269
+ width: elementWidth,
270
+
271
+ position: 'relative',
272
+ 'object-fit': params.fitMode
273
+ });
274
+
275
+ if (!isIE11) {
276
+ publisher._target.appendChild(video);
277
+ publisher._element = video;
278
+ }
279
+
280
+ publisher.stream.setupDimensionsListener(video);
281
+ }
282
+
283
+ //
284
+ // Enable (unpause) all media tracks related to publisher.
285
+ // They are sending data to the server from this moment.
286
+ //
287
+ _this4._toggleAllStreams(true);
288
+ });
289
+ };
290
+
291
+ /**
292
+ * Unpublish stream and destroy publisher's view.
293
+ *
294
+ * Used internally by TsMediaPublisher.destroy
295
+ *
296
+ * @method
297
+ *
298
+ * @param { TsMediaPublisher } publisher
299
+ *
300
+ * @returns { Promise }
301
+ *
302
+ * @fires PUBLISHER_EVENTS#DESTROYED
303
+ *
304
+ * @see TsMediaPublisher#destroy
305
+ */
306
+
307
+
308
+ LoopbackWebRTCSession.prototype.destroyPublisher = function destroyPublisher(publisher) {
309
+ var _this5 = this;
310
+
311
+ return new Promise(function (resolve) {
312
+ _this5._toggleAllStreams(false);
313
+ _this5._stopAllStreams();
314
+
315
+ if (publisher._element) {
316
+ publisher._element.remove();
317
+ }
318
+
319
+ _this5.publisher = null;
320
+ publisher.emit(_publisher.EVENTS.DESTROYED);
321
+
322
+ return resolve();
323
+ });
324
+ };
325
+
326
+ _createClass(LoopbackWebRTCSession, [{
327
+ key: 'id',
328
+ get: function get() {
329
+ return _.get(this._credentials, 'sessionId');
330
+ }
331
+ }, {
332
+ key: 'isLoopback',
333
+ get: function get() {
334
+ return true;
335
+ }
336
+ }]);
337
+
338
+ return LoopbackWebRTCSession;
339
+ }(_session.TsMediaSession);
340
+ //# sourceMappingURL=session-loopback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["webrtc/session-loopback.js"],"names":["isIE11","TsEnvironmentDetect","require","LoopbackWebRTCSession","credentials","deviceOpts","_credentials","_deviceOpts","_constraints","_setTrackStateTo","state","track","setEnabled","enabled","connect","Promise","resolve","_toggleAllStreams","_","isEmpty","_streams","forEach","stream","_mediaStream","getTracks","_stopAllStreams","stop","disconnect","createPublisher","t","p","target","params","reject","then","result","constraints","catch","error","mediaStream","clear","tracks","filter","kind","videoDevice","audioDevice","videoTrackSettings","tsstream","TsWebRTCStream","name","publisher","TsMediaPublisher","videoParams","videoHeight","videoDimensions","height","videoWidth","width","_target","publish","emit","PUBLISHER_EVENTS","STREAM_CREATED","EVENTS","STREAM_PROPERTY_CHANGED","property","value","hasVideo","hasAudio","_element","video","document","createElement","src","URL","createObjectURL","playsInline","autoplay","appendChild","attachMediaStream","streamDimensions","assign","fitMode","insertMode","mirror","resolution","elementHeight","elementWidth","style","position","setupDimensionsListener","destroyPublisher","remove","DESTROYED","get","TsMediaSession"],"mappings":"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","file":"session-loopback.js","sourcesContent":["import {\n EVENTS,\n TsMediaSession\n} from '../session';\n\nimport {\n EVENTS as PUBLISHER_EVENTS,\n TsMediaPublisher\n} from '../publisher';\n\nimport { TsEnvironmentDetect } from 'techsee-common/lib/helpers/ts-environment-detect';\n\nimport {\n TsWebRTCStream,\n} from './stream';\n\nconst isIE11 = (new TsEnvironmentDetect()).isIE11();\n\nif (isIE11) {\n require('./temasys/adapter-loader')(); // eslint-disable-line global-require\n}\n\nimport {\n getVideoTrackSettings,\n getHighestResolutionStream\n} from './helper';\n\n/**\n * WebRTC-specific implementation of TsMediaSession.\n *\n * Instance of this class is returned by TsMediaService.initSession call\n * with 'LOOPBACK' as desired mediaType.\n *\n * @class\n * @extends TsMediaSession\n *\n * @see TsMediaSession\n */\nexport class LoopbackWebRTCSession extends TsMediaSession {\n constructor({ credentials, deviceOpts }) {\n super();\n\n this._credentials = credentials;\n this._deviceOpts = deviceOpts;\n this._constraints = null;\n }\n\n /**\n * Id of the session.\n *\n * @member { String }\n *\n * @type { String }\n */\n get id() {\n return _.get(this._credentials, 'sessionId');\n }\n\n get isLoopback() {\n return true;\n }\n\n _setTrackStateTo(state) {\n return function (track) {\n if (track.setEnabled) {\n track.setEnabled(state);\n } else {\n track.enabled = state;\n }\n };\n }\n\n /**\n * Loopback does not connect, but still need to provide an implementation.\n *\n * @method\n * @returns { Promise }\n *\n */\n connect() {\n return Promise.resolve();\n }\n\n _toggleAllStreams(state) {\n if (!_.isEmpty(this._streams)) {\n this._streams.forEach((stream) => stream._mediaStream.getTracks().forEach(this._setTrackStateTo(state)));\n }\n }\n\n _stopAllStreams() {\n if (!_.isEmpty(this._streams)) {\n this._streams.forEach((stream) => stream._mediaStream.getTracks().forEach((track) => track.stop()));\n }\n }\n\n /**\n * Cleanup\n *\n * @method\n * @returns { Promise }\n *\n */\n disconnect() {\n return Promise.resolve();\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(t, p) {\n let target = t,\n params = p;\n\n if (!params) {\n params = target;\n target = null;\n }\n\n return new Promise((resolve, reject) => {\n getHighestResolutionStream(this._deviceOpts, this._constraints)\n .then((result) => {\n this._constraints = result.constraints;\n\n return resolve(result.stream);\n })\n .catch((error) => reject(error));\n })\n .then((mediaStream) => {\n // Clear previous streams\n this._streams.clear();\n\n //\n // Get tracks that are related to the publisher (audio or video)\n //\n const tracks = mediaStream.getTracks()\n .filter((track) => (\n (track.kind === 'video' && params.videoDevice) ||\n (track.kind === 'audio' && params.audioDevice)));\n\n const videoTrackSettings = getVideoTrackSettings(mediaStream);\n\n const tsstream = new TsWebRTCStream(this, mediaStream, params.name, false, videoTrackSettings);\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 return Promise.resolve()\n .then(() => {\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 (isIE11) {\n publisher._target.appendChild(video);\n publisher._element = attachMediaStream(video, publisher.stream._mediaStream);\n }\n\n const streamDimensions = publisher.stream.videoDimensions;\n\n const params = _.assign({}, {\n fitMode: 'contain',\n insertMode: 'append',\n mirror: false,\n resolution: `${streamDimensions.width}x${streamDimensions.height}`,\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 return new Promise((resolve) => {\n this._toggleAllStreams(false);\n this._stopAllStreams();\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"]}