@techsee/techsee-media-service 0.2.0 → 0.4.0-alpha.13

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.
@@ -15,6 +15,10 @@ var _constants = require('./constants');
15
15
 
16
16
  var _tsEnvironmentDetect = require('@techsee/techsee-common/lib/helpers/ts-environment-detect');
17
17
 
18
+ var _retryWithTimeout = require('@techsee/techsee-common/lib/core/retry-with-timeout');
19
+
20
+ var _tracer = require('../tracer');
21
+
18
22
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
19
23
 
20
24
  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,11 +31,9 @@ exports.EVENTS = _stream.EVENTS;
27
31
  var TORCH_DELAY = 1500;
28
32
  var isIE11 = new _tsEnvironmentDetect.TsEnvironmentDetect().isIE11();
29
33
 
30
- var AdapterJS = void 0;
31
-
32
- if (isIE11) {
33
- AdapterJS = require('./temasys/adapter-loader')(); // eslint-disable-line global-require
34
- }
34
+ var trace = (0, _tracer.getTracer)('TsWebRTCStream', function () {
35
+ return window.TsWebRTCStreamDebug === true;
36
+ });
35
37
 
36
38
  /**
37
39
  * WebRTC-specific implementation of TsMediaStream.
@@ -51,15 +53,18 @@ var TsWebRTCStream = exports.TsWebRTCStream = function (_TsMediaStream) {
51
53
  function TsWebRTCStream(session, mediaStream, name, isRemote, videoTrackSettings) {
52
54
  _classCallCheck(this, TsWebRTCStream);
53
55
 
56
+ //In TurnWebRtcSessionV2, we keep connection on instance of stream.
54
57
  var _this = _possibleConstructorReturn(this, _TsMediaStream.call(this, mediaStream.id, session, isRemote, videoTrackSettings));
55
58
 
59
+ _this.peerConnection = null;
60
+
56
61
  _this._torchDelayTimeOut = null;
57
62
  _this._torchOffTimeOut = null;
58
63
 
59
64
  /**
60
65
  * Browser's native media stream
61
66
  *
62
- * @private
67
+ * @public
63
68
  * @member { Object }
64
69
  *
65
70
  * {@link https://developer.mozilla.org/en-US/docs/Web/API/MediaStream MediaStream API}
@@ -120,7 +125,7 @@ var TsWebRTCStream = exports.TsWebRTCStream = function (_TsMediaStream) {
120
125
 
121
126
  TsWebRTCStream.prototype._getPeerConnection = function _getPeerConnection() {
122
127
  // KMS store the peer connection as _pc, TURN store it as _lastPc
123
- return _.get(this._session, '_lastPc.peerConnection') || _.get(this._session, '_pc.peerConnection');
128
+ return this.peerConnection || _.get(this._session, '_lastPc.peerConnection') || _.get(this._session, '_pc.peerConnection');
124
129
  };
125
130
 
126
131
  /**
@@ -228,60 +233,91 @@ var TsWebRTCStream = exports.TsWebRTCStream = function (_TsMediaStream) {
228
233
  target = null;
229
234
  }
230
235
 
231
- return Promise.resolve().then(function () {
232
- //
233
- // New video element where publishing video stream will be rendered
234
- //
235
- var video = document.createElement('video');
236
+ var elementHeight = typeof params.height === 'string' ? params.height : params.height + 'px';
237
+ var elementWidth = typeof params.width === 'string' ? params.width : params.width + 'px';
236
238
 
237
- video.muted = true;
238
- video.playsInline = true;
239
+ var bindVideoStreamToElement = function bindVideoStreamToElement(stream, target) {
240
+ return new Promise(function (resolve, reject) {
241
+ var doResolve = function doResolve(videoEl) {
242
+ trace('Video element created successfully');
243
+ resolve(videoEl);
244
+ };
239
245
 
240
- var attachedVideo = void 0;
246
+ var videoEl = document.createElement('video');
247
+ videoEl.muted = true;
248
+ videoEl.playsInline = true;
241
249
 
242
- if (!isIE11) {
243
- video.srcObject = _this2._mediaStream;
250
+ if (isIE11 && window.WebRTCAdapter) {
251
+ target.appendChild(videoEl);
252
+ window.WebRTCAdapter.bindVideoElement(videoEl);
253
+ }
244
254
 
245
- // Hack to override behavior introduced by Chrome/FF that unmuted video elements can't auto play
246
- video.setAttribute('muted', '');
255
+ videoEl.srcObject = stream;
247
256
 
248
- video.play();
249
- } else {
250
- target.appendChild(video);
257
+ if (!isIE11) {
258
+ // Hack to override behavior introduced by Chrome/FF that unmuted video elements can't auto play
259
+ videoEl.setAttribute('muted', '');
260
+ }
251
261
 
252
- attachedVideo = AdapterJS.attachMediaStream(video, _this2._mediaStream);
262
+ try {
263
+ var playRes = videoEl.play();
264
+ if (playRes && playRes.then) {
265
+ playRes.then(function () {
266
+ trace('Video element play success');
267
+ });
268
+ }
253
269
 
254
- if (attachedVideo && attachedVideo.play) {
255
- attachedVideo.play();
270
+ if (playRes && playRes.catch) {
271
+ playRes.catch(function (error) {
272
+ trace('Reject while executing play method on video element', error);
273
+ });
274
+ }
275
+ } catch (error) {
276
+ trace('Error while executing play method on video element', error);
256
277
  }
257
- }
258
278
 
259
- //
260
- // If height and width are numbers then add 'px' ending.
261
- // Else use it as is (suppose that it's already 'px' or '%')
262
- //
263
- var elementHeight = typeof params.height === 'string' ? params.height : params.height + 'px';
264
- var elementWidth = typeof params.width === 'string' ? params.width : params.width + 'px';
279
+ if (isIE11) {
280
+ var handleComplete = function handleComplete() {
281
+ return videoEl.parentElement.tagName !== 'OBJECT';
282
+ };
283
+
284
+ var waitForObjectSettings = { intervalInMs: 30, timeoutInMs: 200 };
285
+
286
+ (0, _retryWithTimeout.repeatWithTimeout)(handleComplete, waitForObjectSettings).then(function () {
287
+ //We will wait, until video is played, then we resolve
288
+ var isVideoPlaying = function isVideoPlaying() {
289
+ return videoEl.videoHeight <= 0 || videoEl.videoWidth <= 0;
290
+ };
291
+ var waitForVideoSettings = { intervalInMs: 50, timeoutInMs: 10000 };
292
+ (0, _retryWithTimeout.repeatWithTimeout)(isVideoPlaying, waitForVideoSettings).then(function () {
293
+ return doResolve(videoEl.parentElement);
294
+ }).catch(function () {
295
+ return reject(new Error('Timeout while waiting for video to play'));
296
+ });
297
+ });
298
+ } else {
299
+ target.appendChild(videoEl);
300
+ doResolve(videoEl);
301
+ }
302
+ });
303
+ };
265
304
 
266
- _.assign((isIE11 ? attachedVideo : video).style, {
305
+ return bindVideoStreamToElement(this._mediaStream, target).then(function (videoEl) {
306
+ _.assign(videoEl.style, {
267
307
  height: elementHeight,
268
308
  width: elementWidth,
269
309
 
270
310
  'object-fit': params.fitMode
271
311
  });
272
312
 
273
- if (!isIE11) {
274
- target.appendChild(video);
275
- }
276
-
277
313
  var subscriber = new _subscriber.TsMediaSubscriber({
278
314
  target: target,
279
315
  _session: _this2._session,
280
316
  stream: _this2,
281
- _element: isIE11 ? attachedVideo : video
317
+ _element: videoEl
282
318
  });
283
319
 
284
- _this2.setupDimensionsListener(isIE11 ? attachedVideo : video, subscriber);
320
+ _this2.setupDimensionsListener(videoEl, subscriber);
285
321
 
286
322
  _this2.subscriber = subscriber;
287
323
 
@@ -307,14 +343,26 @@ var TsWebRTCStream = exports.TsWebRTCStream = function (_TsMediaStream) {
307
343
 
308
344
 
309
345
  TsWebRTCStream.prototype.destroySubscriber = function destroySubscriber(subscriber) {
310
- return Promise.resolve().then(function () {
311
- if (!isIE11) {
312
- subscriber._element.remove();
346
+ return new Promise(function (resolve) {
347
+ var doResolve = function doResolve() {
348
+ subscriber.emit(_subscriber.EVENTS.DESTROYED);
349
+ resolve();
350
+ };
351
+
352
+ if (isIE11 && window.WebRTCAdapter) {
353
+ var videoEl = subscriber._element.firstChild;
354
+ window.WebRTCAdapter.unBindVideoElement(videoEl);
355
+ if (videoEl && videoEl.parentNode && videoEl.parentNode.removeChild) {
356
+ videoEl.parentNode.removeChild(videoEl);
357
+ trace('Video element removed successfully');
358
+ } else {
359
+ trace('Video element not removed', videoEl, videoEl.parentNode);
360
+ }
361
+ doResolve();
313
362
  } else {
314
- subscriber._element.parentNode.removeChild(subscriber._element);
363
+ subscriber._element.remove();
364
+ doResolve();
315
365
  }
316
-
317
- subscriber.emit(_subscriber.EVENTS.DESTROYED);
318
366
  });
319
367
  };
320
368
 
@@ -398,10 +446,6 @@ var TsWebRTCStream = exports.TsWebRTCStream = function (_TsMediaStream) {
398
446
  return canvas.toDataURL(format, quality);
399
447
  }
400
448
 
401
- if (!_.get(AdapterJS, 'WebRTCPlugin.plugin.valid')) {
402
- return resolve(_drawAndRemove(videoElement));
403
- }
404
-
405
449
  var base64 = videoElement.getFrame();
406
450
  var image = new Image();
407
451
 
@@ -443,7 +487,7 @@ var TsWebRTCStream = exports.TsWebRTCStream = function (_TsMediaStream) {
443
487
  try {
444
488
  var pc = _this3._getPeerConnection();
445
489
 
446
- if (!pc) {
490
+ if (isIE11 || !pc) {
447
491
  return resolve();
448
492
  }
449
493
 
@@ -467,6 +511,7 @@ var TsWebRTCStream = exports.TsWebRTCStream = function (_TsMediaStream) {
467
511
  }
468
512
  });
469
513
  };
514
+
470
515
  /* eslint-enable no-unused-vars */
471
516
 
472
517
  TsWebRTCStream.prototype.getFullVideoStats = function getFullVideoStats() {
@@ -1 +1 @@
1
- {"version":3,"sources":["webrtc/stream.js"],"names":["EVENTS","TORCH_DELAY","isIE11","TsEnvironmentDetect","AdapterJS","require","TsWebRTCStream","session","mediaStream","name","isRemote","videoTrackSettings","id","_torchDelayTimeOut","_torchOffTimeOut","_mediaStream","_session","_name","hasVideo","_isMobile","DEFAULT_STREAM_NAMES","MOBILE_CLIENT_VIDEO_STREAM","hasAudio","remote","DASHBOARD_AUDIO_STREAM","MOBILE_CLIENT_AUDIO_STREAM","Math","random","toString","on","SESSION_EVENTS","DISCONNECTED","publisher","destroy","subscriber","_getPeerConnection","_","get","publishAudio","publish","getTracks","forEach","track","kind","setEnabled","enabled","emit","STREAM_PROPERTY_CHANGED","stream","property","value","PROPERTY_CHANGED","publishVideo","subscribe","target","params","height","width","fitMode","insertMode","Promise","resolve","then","video","document","createElement","muted","playsInline","attachedVideo","srcObject","setAttribute","play","appendChild","attachMediaStream","elementHeight","elementWidth","assign","style","TsMediaSubscriber","_element","setupDimensionsListener","destroySubscriber","remove","parentNode","removeChild","SUBSCRIBER_EVENTS","DESTROYED","getSnapshot","tsMediaElement","timeout","format","quality","x","y","w","h","videoElement","videoWidth","videoHeight","crop","isUndefined","resize","getImgData","canvas","ctx","getContext","drawImage","toDataURL","getImgDataIE11","_drawAndRemove","image","base64","getFrame","Image","onload","imgData","length","reject","getStats","pc","getVideoTracks","reports","matches","report","includes","type","push","head","e","getFullVideoStats","turnFlashlight","isTorchOn","navigator","mediaDevices","clearInterval","setTimeout","capatibilitiesAfter","getCapabilities","torch","applyConstraints","advanced","catch","console","error","setAutoLightOffTimer","flashlightTimeout","enabledVideoTracks","filter","enabledAudioTracks","getAudioTracks","TsMediaStream"],"mappings":"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","file":"stream.js","sourcesContent":["import {\n EVENTS,\n TsMediaStream,\n} from '../stream';\n\nimport {\n EVENTS as SESSION_EVENTS,\n} from '../session';\n\nimport {\n EVENTS as SUBSCRIBER_EVENTS,\n TsMediaSubscriber,\n} from '../subscriber';\n\nimport {\n DEFAULT_STREAM_NAMES,\n} from './constants';\n\nexport { EVENTS };\n\nimport { TsEnvironmentDetect } from '@techsee/techsee-common/lib/helpers/ts-environment-detect';\n\nconst TORCH_DELAY = 1500;\nconst isIE11 = (new TsEnvironmentDetect()).isIE11();\n\nlet AdapterJS;\n\nif (isIE11) {\n AdapterJS = require('./temasys/adapter-loader')(); // eslint-disable-line global-require\n}\n\n/**\n * WebRTC-specific implementation of TsMediaStream.\n *\n * Instances of this class are mostly used internally by TsMediaPublisher\n * and for subscribers creating.\n *\n * @class\n * @extends TsMediaStream\n *\n * @see TsMediaStream\n */\nexport class TsWebRTCStream extends TsMediaStream {\n constructor(session, mediaStream, name, isRemote, videoTrackSettings) {\n super(mediaStream.id, session, isRemote, videoTrackSettings);\n\n this._torchDelayTimeOut = null;\n this._torchOffTimeOut = null;\n\n /**\n * Browser's native media stream\n *\n * @private\n * @member { Object }\n *\n * {@link https://developer.mozilla.org/en-US/docs/Web/API/MediaStream MediaStream API}\n */\n this._mediaStream = mediaStream;\n\n /**\n * Instance of TsWebRTCSession\n *\n * @private\n * @member { Object }\n *\n * @see TsWebRTCSession\n */\n this._session = session;\n\n this._name = name;\n\n if (!this._name) {\n if (this.hasVideo) {\n if (!this._session._isMobile) {\n this._name = DEFAULT_STREAM_NAMES.MOBILE_CLIENT_VIDEO_STREAM;\n }\n } else if (this.hasAudio) {\n if (this._session._isMobile) {\n this._name = this.remote ? DEFAULT_STREAM_NAMES.DASHBOARD_AUDIO_STREAM : DEFAULT_STREAM_NAMES.MOBILE_CLIENT_AUDIO_STREAM;\n } else {\n this._name = this.remote ? DEFAULT_STREAM_NAMES.MOBILE_CLIENT_AUDIO_STREAM : DEFAULT_STREAM_NAMES.DASHBOARD_AUDIO_STREAM;\n }\n }\n }\n\n if (!this._name) {\n this._name = Math.random().toString();\n }\n\n // TODO I think this will never be emitted, as both app/mobile call session.off() before they call session.disconnect(). And we call the destroy elsewhere\n // TODO Need to make sure that it's always the case, especially for IOS\n session.on(SESSION_EVENTS.DISCONNECTED, () => {\n if (this.publisher) {\n this.publisher.destroy();\n }\n\n if (this.subscriber) {\n this.subscriber.destroy();\n }\n });\n }\n\n /**\n * Unique id of the stream\n *\n * @member { String }\n * @type { String }\n */\n get id() {\n return this._mediaStream.id;\n }\n\n /**\n * Unique name of the stream\n *\n * @member { String }\n * @type { String }\n */\n get name() {\n return this._name;\n }\n\n /**\n * Whether or not stream has enabled video tracks\n *\n * @member { Boolean }\n * @type { Boolean }\n */\n get hasVideo() {\n const enabledVideoTracks = this._mediaStream.getVideoTracks()\n .filter((track) => track.enabled);\n\n return enabledVideoTracks.length > 0;\n }\n\n /**\n * Whether or not stream has enabled audio tracks\n *\n * @member { Boolean }\n * @type { Boolean }\n */\n get hasAudio() {\n const enabledAudioTracks = this._mediaStream.getAudioTracks()\n .filter((track) => track.enabled);\n\n return enabledAudioTracks.length > 0;\n }\n\n _getPeerConnection() {\n // KMS store the peer connection as _pc, TURN store it as _lastPc\n return _.get(this._session, '_lastPc.peerConnection') || _.get(this._session, '_pc.peerConnection');\n }\n\n /**\n * Publish or unpublish audio tracks.\n *\n * Used internally by TsMediaPublisher.publishAudio\n *\n * @method\n *\n * @param { Boolean } publish\n *\n * @fires SESSION_EVENTS.STREAM_PROPERTY_CHANGED\n * @fires STREAM_EVENTS.PROPERTY_CHANGED\n */\n publishAudio(publish) {\n this._mediaStream.getTracks().forEach((track) => {\n if (track.kind === 'audio') {\n if (track.setEnabled) {\n track.setEnabled(publish);\n } else {\n track.enabled = publish;\n }\n }\n });\n\n this._session.emit(SESSION_EVENTS.STREAM_PROPERTY_CHANGED, {\n stream: this,\n property: 'hasAudio',\n value: publish\n });\n\n this.emit(EVENTS.PROPERTY_CHANGED, {\n stream: this,\n property: 'hasAudio',\n value: publish\n });\n }\n\n /**\n * Publish or unpublish video tracks.\n *\n * Used internally by TsMediaPublisher.publishVideo\n *\n * @method\n *\n * @param { Boolean } publish\n *\n * @fires SESSION_EVENTS.STREAM_PROPERTY_CHANGED\n */\n publishVideo(publish) {\n this._mediaStream.getTracks().forEach((track) => {\n if (track.kind === 'video') {\n if (track.setEnabled) {\n track.setEnabled(publish);\n } else {\n track.enabled = publish;\n }\n }\n });\n\n this._session.emit(SESSION_EVENTS.STREAM_PROPERTY_CHANGED, {\n stream: this,\n property: 'hasVideo',\n value: publish,\n });\n }\n\n /**\n * Subscribe to a remote stream.\n *\n * Used internally by TsMediaStream.subscribe\n *\n * @method\n *\n * @param { TsMediaStream } stream\n * @param { DOMElement } target\n * @param { Object } params\n * @param { String|Number } params.height Subscriber's view height\n * @param { String|Number } params.width Subscriber's view width\n * @param { String } params.fitMode Subscriber's view fit mode\n * @param { String } params.insertMode Subscriber's view insert mode (Is not in use yet)\n *\n * @returns { Promise<TsMediaSubscriber> } subsriber instance\n *\n * @see TsMediaStream\n */\n subscribe(target, params = {\n height: '100%',\n width: '100%',\n fitMode: 'contain',\n insertMode: 'append',\n }) {\n if (!params) {\n params = target;\n target = null;\n }\n\n return Promise.resolve()\n .then(() => {\n //\n // New video element where publishing video stream will be rendered\n //\n const video = document.createElement('video');\n\n video.muted = true;\n video.playsInline = true;\n\n let attachedVideo;\n\n if (!isIE11) {\n video.srcObject = this._mediaStream;\n\n // Hack to override behavior introduced by Chrome/FF that unmuted video elements can't auto play\n video.setAttribute('muted', '');\n\n video.play();\n } else {\n target.appendChild(video);\n\n attachedVideo = AdapterJS.attachMediaStream(video, this._mediaStream);\n\n if (attachedVideo && attachedVideo.play) {\n attachedVideo.play();\n }\n }\n\n //\n // If height and width are numbers then add 'px' ending.\n // Else use it as is (suppose that it's already 'px' or '%')\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 ? attachedVideo : video).style, {\n height: elementHeight,\n width: elementWidth,\n\n 'object-fit': params.fitMode,\n });\n\n if (!isIE11) {\n target.appendChild(video);\n }\n\n const subscriber = new TsMediaSubscriber({\n target,\n _session: this._session,\n stream: this,\n _element: (isIE11 ? attachedVideo : video),\n });\n\n this.setupDimensionsListener((isIE11 ? attachedVideo : video), subscriber);\n\n this.subscriber = subscriber;\n\n return subscriber;\n });\n }\n\n /**\n * Unsubscribe from the stream and destroy subscriber's view.\n *\n * Used internally by TsMediaSubscriber.destroy.\n *\n * @method\n *\n * @param { TsMediaSubscriber } subscriber\n *\n * @returns { Promise }\n *\n * @fires SUBSCRIBER_EVENTS#DESTROYED\n *\n * @see TsMediaSubscriber#destroy\n */\n destroySubscriber(subscriber) {\n return Promise.resolve()\n .then(() => {\n if (!isIE11) {\n subscriber._element.remove();\n } else {\n subscriber._element.parentNode.removeChild(subscriber._element);\n }\n\n subscriber.emit(SUBSCRIBER_EVENTS.DESTROYED);\n });\n }\n\n /* eslint-disable no-unused-vars */\n getSnapshot(tsMediaElement, timeout = 0, {format = 'image/png', quality = 0.92, x, y, w, h} = {}) {\n const videoElement = tsMediaElement._element;\n const {videoWidth, videoHeight} = videoElement;\n const crop = !_.isUndefined(x) && !_.isUndefined(y) && !_.isUndefined(w) && !_.isUndefined(h);\n const resize = !crop && (!_.isUndefined(w) || !_.isUndefined(h));\n\n if (resize) {\n if (!h) {\n h = w * (videoHeight / videoWidth);\n } else if (!w) {\n w = h * (videoWidth / videoHeight);\n }\n }\n\n function getImgData() {\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n\n if (crop) {\n canvas.width = w;\n canvas.height = h;\n\n ctx.drawImage(videoElement, x, y, w, h, 0, 0, w, h);\n } else if (resize) {\n canvas.width = w;\n canvas.height = h;\n\n ctx.drawImage(videoElement, 0, 0, w, h);\n } else {\n canvas.height = videoHeight;\n canvas.width = videoWidth;\n\n ctx.drawImage(videoElement, 0, 0);\n }\n\n return canvas.toDataURL(format, quality);\n }\n\n function getImgDataIE11() {\n return new Promise((resolve) => {\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n\n if (crop || resize) {\n canvas.width = w;\n canvas.height = h;\n } else {\n canvas.height = videoHeight;\n canvas.width = videoWidth;\n }\n\n function _drawAndRemove(image) {\n if (crop) {\n ctx.drawImage(image, x, y, w, h, 0, 0, w, h);\n } else if (resize) {\n ctx.drawImage(image, 0, 0, w, h);\n } else {\n ctx.drawImage(image, 0, 0, videoWidth, videoHeight);\n }\n\n return canvas.toDataURL(format, quality);\n }\n\n if (!_.get(AdapterJS, 'WebRTCPlugin.plugin.valid')) {\n return resolve(_drawAndRemove(videoElement));\n }\n\n const base64 = videoElement.getFrame();\n const image = new Image();\n\n image.onload = () => resolve(_drawAndRemove(image));\n image.setAttribute('src', 'data:image/bmp;base64,' + base64);\n });\n }\n\n return Promise.resolve(isIE11 ? getImgDataIE11() : getImgData())\n .then((imgData) => {\n if (!imgData || imgData.length < 10) {\n return Promise.reject('Failed to get a snapshot');\n }\n\n return imgData;\n });\n }\n\n /**\n * Get statistics of the media subscription like bytes received.\n *\n * Used internally by TsMediaSubscriber.getStats\n *\n * @method\n *\n * @param { TsMediaSubscriber } subscriber\n *\n * @returns { Promise<ToBeDefined> } stats\n *\n * @see TsMediaSubscriber#getStats\n */\n getStats(subscriber) {\n return new Promise((resolve) => {\n try {\n const pc = this._getPeerConnection();\n\n if (!pc) {\n return resolve();\n }\n\n pc.getStats(this._mediaStream.getVideoTracks()[0])\n .then((reports) => {\n const matches = [];\n\n reports.forEach((report) => {\n if (_.includes(['inbound-rtp', 'ssrc'], report.type)) {\n matches.push(report);\n }\n });\n\n return resolve({\n video: _.head(matches)\n });\n });\n } catch (e) {\n // when this fails, it's most likely due ot no support for the getStats\n // functionality, so we don't want to log this as a recurring error\n resolve();\n }\n });\n }\n /* eslint-enable no-unused-vars */\n\n getFullVideoStats() {\n return new Promise((resolve, reject) => {\n try {\n const pc = this._getPeerConnection();\n\n if (!pc) {\n return reject('NO_PEER_CONNECTION');\n }\n\n return resolve(pc.getStats(this._mediaStream.getVideoTracks()[0]));\n\n } catch (e) {\n reject(e);\n }\n });\n }\n\n turnFlashlight(isTorchOn = true) {\n return new Promise((resolve, reject) => {\n if (this._torchDelayTimeOut) {\n return reject('No tourch delay');\n }\n\n if (!navigator || !navigator.mediaDevices) {\n return reject('No mediaDevices');\n }\n\n const track = this._mediaStream.getVideoTracks()[0];\n\n if (!track) {\n return reject('No track');\n }\n if (this._torchOffTimeOut) {\n clearInterval(this._torchOffTimeOut);\n this._torchOffTimeOut = null;\n }\n\n this._torchDelayTimeOut = setTimeout(() => {\n let capatibilitiesAfter = {};\n\n try {\n capatibilitiesAfter = track.getCapabilities();\n } catch (e) {\n return reject('No capabilities');\n }\n\n if (!capatibilitiesAfter.torch) {\n return reject('No tourch capabilities');\n }\n\n return track.applyConstraints({\n advanced: [{\n torch: isTorchOn\n }]\n }).then(() => {\n this._torchDelayTimeOut = null;\n resolve(true);\n }).catch((e) => {\n this._torchDelayTimeOut = null;\n console.error(e);\n reject('Can\\'t turn on the light, please try later!');\n });\n }, TORCH_DELAY);\n });\n }\n\n setAutoLightOffTimer(flashlightTimeout) {\n return new Promise((resolve) => {\n if (!flashlightTimeout) {\n return reject('No timeout');\n }\n\n const track = this._mediaStream.getVideoTracks()[0];\n\n if (!track) {\n return reject('No track');\n }\n\n this._torchOffTimeOut = setTimeout(() => {\n\n if (!track) {\n return reject('No track');\n }\n\n track.applyConstraints({\n advanced: [{\n torch: false\n }]\n }).then(() => {\n this._torchOffTimeOut = null;\n resolve();\n });\n }, flashlightTimeout);\n });\n }\n}\n"]}
1
+ {"version":3,"sources":["webrtc/stream.js"],"names":["EVENTS","TORCH_DELAY","isIE11","TsEnvironmentDetect","trace","window","TsWebRTCStreamDebug","TsWebRTCStream","session","mediaStream","name","isRemote","videoTrackSettings","id","peerConnection","_torchDelayTimeOut","_torchOffTimeOut","_mediaStream","_session","_name","hasVideo","_isMobile","DEFAULT_STREAM_NAMES","MOBILE_CLIENT_VIDEO_STREAM","hasAudio","remote","DASHBOARD_AUDIO_STREAM","MOBILE_CLIENT_AUDIO_STREAM","Math","random","toString","on","SESSION_EVENTS","DISCONNECTED","publisher","destroy","subscriber","_getPeerConnection","_","get","publishAudio","publish","getTracks","forEach","track","kind","setEnabled","enabled","emit","STREAM_PROPERTY_CHANGED","stream","property","value","PROPERTY_CHANGED","publishVideo","subscribe","target","params","height","width","fitMode","insertMode","elementHeight","elementWidth","bindVideoStreamToElement","Promise","resolve","reject","doResolve","videoEl","document","createElement","muted","playsInline","WebRTCAdapter","appendChild","bindVideoElement","srcObject","setAttribute","playRes","play","then","catch","error","handleComplete","parentElement","tagName","waitForObjectSettings","intervalInMs","timeoutInMs","isVideoPlaying","videoHeight","videoWidth","waitForVideoSettings","Error","assign","style","TsMediaSubscriber","_element","setupDimensionsListener","destroySubscriber","SUBSCRIBER_EVENTS","DESTROYED","firstChild","unBindVideoElement","parentNode","removeChild","remove","getSnapshot","tsMediaElement","timeout","format","quality","x","y","w","h","videoElement","crop","isUndefined","resize","getImgData","canvas","ctx","getContext","drawImage","toDataURL","getImgDataIE11","_drawAndRemove","image","base64","getFrame","Image","onload","imgData","length","getStats","pc","getVideoTracks","reports","matches","report","includes","type","push","video","head","e","getFullVideoStats","turnFlashlight","isTorchOn","navigator","mediaDevices","clearInterval","setTimeout","capatibilitiesAfter","getCapabilities","torch","applyConstraints","advanced","console","setAutoLightOffTimer","flashlightTimeout","enabledVideoTracks","filter","enabledAudioTracks","getAudioTracks","TsMediaStream"],"mappings":"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","file":"stream.js","sourcesContent":["import {\n EVENTS,\n TsMediaStream\n} from '../stream';\n\nimport {\n EVENTS as SESSION_EVENTS\n} from '../session';\n\nimport {\n EVENTS as SUBSCRIBER_EVENTS,\n TsMediaSubscriber\n} from '../subscriber';\n\nimport {\n DEFAULT_STREAM_NAMES\n} from './constants';\n\nexport {EVENTS};\n\nimport {TsEnvironmentDetect} from '@techsee/techsee-common/lib/helpers/ts-environment-detect';\nimport {repeatWithTimeout} from '@techsee/techsee-common/lib/core/retry-with-timeout';\n\nconst TORCH_DELAY = 1500;\nconst isIE11 = (new TsEnvironmentDetect()).isIE11();\n\nimport {getTracer} from '../tracer';\n\nconst trace = getTracer('TsWebRTCStream', () => window.TsWebRTCStreamDebug === true);\n\n/**\n * WebRTC-specific implementation of TsMediaStream.\n *\n * Instances of this class are mostly used internally by TsMediaPublisher\n * and for subscribers creating.\n *\n * @class\n * @extends TsMediaStream\n *\n * @see TsMediaStream\n */\nexport class TsWebRTCStream extends TsMediaStream {\n constructor(session, mediaStream, name, isRemote, videoTrackSettings) {\n super(mediaStream.id, session, isRemote, videoTrackSettings);\n\n //In TurnWebRtcSessionV2, we keep connection on instance of stream.\n this.peerConnection = null;\n\n this._torchDelayTimeOut = null;\n this._torchOffTimeOut = null;\n\n /**\n * Browser's native media stream\n *\n * @public\n * @member { Object }\n *\n * {@link https://developer.mozilla.org/en-US/docs/Web/API/MediaStream MediaStream API}\n */\n this._mediaStream = mediaStream;\n\n /**\n * Instance of TsWebRTCSession\n *\n * @private\n * @member { Object }\n *\n * @see TsWebRTCSession\n */\n this._session = session;\n\n this._name = name;\n\n if (!this._name) {\n if (this.hasVideo) {\n if (!this._session._isMobile) {\n this._name = DEFAULT_STREAM_NAMES.MOBILE_CLIENT_VIDEO_STREAM;\n }\n } else if (this.hasAudio) {\n if (this._session._isMobile) {\n this._name = this.remote ? DEFAULT_STREAM_NAMES.DASHBOARD_AUDIO_STREAM : DEFAULT_STREAM_NAMES.MOBILE_CLIENT_AUDIO_STREAM;\n } else {\n this._name = this.remote ? DEFAULT_STREAM_NAMES.MOBILE_CLIENT_AUDIO_STREAM : DEFAULT_STREAM_NAMES.DASHBOARD_AUDIO_STREAM;\n }\n }\n }\n\n if (!this._name) {\n this._name = Math.random().toString();\n }\n\n // TODO I think this will never be emitted, as both app/mobile call session.off() before they call session.disconnect(). And we call the destroy elsewhere\n // TODO Need to make sure that it's always the case, especially for IOS\n session.on(SESSION_EVENTS.DISCONNECTED, () => {\n if (this.publisher) {\n this.publisher.destroy();\n }\n\n if (this.subscriber) {\n this.subscriber.destroy();\n }\n });\n }\n\n /**\n * Unique id of the stream\n *\n * @member { String }\n * @type { String }\n */\n get id() {\n return this._mediaStream.id;\n }\n\n /**\n * Unique name of the stream\n *\n * @member { String }\n * @type { String }\n */\n get name() {\n return this._name;\n }\n\n /**\n * Whether or not stream has enabled video tracks\n *\n * @member { Boolean }\n * @type { Boolean }\n */\n get hasVideo() {\n const enabledVideoTracks = this._mediaStream.getVideoTracks()\n .filter((track) => track.enabled);\n\n return enabledVideoTracks.length > 0;\n }\n\n /**\n * Whether or not stream has enabled audio tracks\n *\n * @member { Boolean }\n * @type { Boolean }\n */\n get hasAudio() {\n const enabledAudioTracks = this._mediaStream.getAudioTracks()\n .filter((track) => track.enabled);\n\n return enabledAudioTracks.length > 0;\n }\n\n _getPeerConnection() {\n // KMS store the peer connection as _pc, TURN store it as _lastPc\n return this.peerConnection\n || _.get(this._session, '_lastPc.peerConnection')\n || _.get(this._session, '_pc.peerConnection');\n }\n\n /**\n * Publish or unpublish audio tracks.\n *\n * Used internally by TsMediaPublisher.publishAudio\n *\n * @method\n *\n * @param { Boolean } publish\n *\n * @fires SESSION_EVENTS.STREAM_PROPERTY_CHANGED\n * @fires STREAM_EVENTS.PROPERTY_CHANGED\n */\n publishAudio(publish) {\n this._mediaStream.getTracks().forEach((track) => {\n if (track.kind === 'audio') {\n if (track.setEnabled) {\n track.setEnabled(publish);\n } else {\n track.enabled = publish;\n }\n }\n });\n\n this._session.emit(SESSION_EVENTS.STREAM_PROPERTY_CHANGED, {\n stream: this,\n property: 'hasAudio',\n value: publish\n });\n\n this.emit(EVENTS.PROPERTY_CHANGED, {\n stream: this,\n property: 'hasAudio',\n value: publish\n });\n }\n\n /**\n * Publish or unpublish video tracks.\n *\n * Used internally by TsMediaPublisher.publishVideo\n *\n * @method\n *\n * @param { Boolean } publish\n *\n * @fires SESSION_EVENTS.STREAM_PROPERTY_CHANGED\n */\n publishVideo(publish) {\n this._mediaStream.getTracks().forEach((track) => {\n if (track.kind === 'video') {\n if (track.setEnabled) {\n track.setEnabled(publish);\n } else {\n track.enabled = publish;\n }\n }\n });\n\n this._session.emit(SESSION_EVENTS.STREAM_PROPERTY_CHANGED, {\n stream: this,\n property: 'hasVideo',\n value: publish\n });\n }\n\n /**\n * Subscribe to a remote stream.\n *\n * Used internally by TsMediaStream.subscribe\n *\n * @method\n *\n * @param { TsMediaStream } stream\n * @param { DOMElement } target\n * @param { Object } params\n * @param { String|Number } params.height Subscriber's view height\n * @param { String|Number } params.width Subscriber's view width\n * @param { String } params.fitMode Subscriber's view fit mode\n * @param { String } params.insertMode Subscriber's view insert mode (Is not in use yet)\n *\n * @returns { Promise<TsMediaSubscriber> } subsriber instance\n *\n * @see TsMediaStream\n */\n subscribe(target, params = {\n height: '100%',\n width: '100%',\n fitMode: 'contain',\n insertMode: 'append'\n }) {\n if (!params) {\n params = target;\n target = null;\n }\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 const bindVideoStreamToElement = (stream, target) => {\n return new Promise((resolve, reject) => {\n const doResolve = (videoEl) => {\n trace('Video element created successfully');\n resolve(videoEl);\n };\n\n const videoEl = document.createElement('video');\n videoEl.muted = true;\n videoEl.playsInline = true;\n\n if (isIE11 && window.WebRTCAdapter) {\n target.appendChild(videoEl);\n window.WebRTCAdapter.bindVideoElement(videoEl);\n }\n\n videoEl.srcObject = stream;\n\n if (!isIE11) {\n // Hack to override behavior introduced by Chrome/FF that unmuted video elements can't auto play\n videoEl.setAttribute('muted', '');\n }\n\n try {\n const playRes = videoEl.play();\n if (playRes && playRes.then) {\n playRes.then(() => {\n trace('Video element play success');\n });\n }\n\n if (playRes && playRes.catch) {\n playRes.catch((error) => {\n trace('Reject while executing play method on video element', error);\n });\n }\n } catch (error) {\n trace('Error while executing play method on video element', error);\n }\n\n\n if (isIE11) {\n const handleComplete = () => {\n return videoEl.parentElement.tagName !== 'OBJECT';\n };\n\n const waitForObjectSettings = {intervalInMs: 30, timeoutInMs: 200};\n\n repeatWithTimeout(handleComplete, waitForObjectSettings)\n .then(() => {\n //We will wait, until video is played, then we resolve\n const isVideoPlaying = () => videoEl.videoHeight <= 0 || videoEl.videoWidth <= 0;\n const waitForVideoSettings = {intervalInMs: 50, timeoutInMs: 10000};\n repeatWithTimeout(isVideoPlaying, waitForVideoSettings)\n .then(() => doResolve(videoEl.parentElement))\n .catch(() => reject(new Error('Timeout while waiting for video to play')));\n });\n } else {\n target.appendChild(videoEl);\n doResolve(videoEl);\n }\n\n });\n };\n\n return bindVideoStreamToElement(this._mediaStream, target)\n .then((videoEl) => {\n _.assign(videoEl.style, {\n height: elementHeight,\n width: elementWidth,\n\n 'object-fit': params.fitMode\n });\n\n const subscriber = new TsMediaSubscriber({\n target,\n _session: this._session,\n stream: this,\n _element: videoEl\n });\n\n this.setupDimensionsListener(videoEl, subscriber);\n\n this.subscriber = subscriber;\n\n return subscriber;\n });\n }\n\n /**\n * Unsubscribe from the stream and destroy subscriber's view.\n *\n * Used internally by TsMediaSubscriber.destroy.\n *\n * @method\n *\n * @param { TsMediaSubscriber } subscriber\n *\n * @returns { Promise }\n *\n * @fires SUBSCRIBER_EVENTS#DESTROYED\n *\n * @see TsMediaSubscriber#destroy\n */\n destroySubscriber(subscriber) {\n return new Promise((resolve) => {\n const doResolve = () => {\n subscriber.emit(SUBSCRIBER_EVENTS.DESTROYED);\n resolve();\n };\n\n if (isIE11 && window.WebRTCAdapter) {\n const videoEl = subscriber._element.firstChild;\n window.WebRTCAdapter.unBindVideoElement(videoEl);\n if (videoEl && videoEl.parentNode && videoEl.parentNode.removeChild) {\n videoEl.parentNode.removeChild(videoEl);\n trace('Video element removed successfully');\n } else {\n trace('Video element not removed', videoEl, videoEl.parentNode);\n }\n doResolve();\n } else {\n subscriber._element.remove();\n doResolve();\n }\n });\n }\n\n /* eslint-disable no-unused-vars */\n getSnapshot(tsMediaElement, timeout = 0, {format = 'image/png', quality = 0.92, x, y, w, h} = {}) {\n const videoElement = tsMediaElement._element;\n const {videoWidth, videoHeight} = videoElement;\n const crop = !_.isUndefined(x) && !_.isUndefined(y) && !_.isUndefined(w) && !_.isUndefined(h);\n const resize = !crop && (!_.isUndefined(w) || !_.isUndefined(h));\n\n if (resize) {\n if (!h) {\n h = w * (videoHeight / videoWidth);\n } else if (!w) {\n w = h * (videoWidth / videoHeight);\n }\n }\n\n function getImgData() {\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n\n if (crop) {\n canvas.width = w;\n canvas.height = h;\n\n ctx.drawImage(videoElement, x, y, w, h, 0, 0, w, h);\n } else if (resize) {\n canvas.width = w;\n canvas.height = h;\n\n ctx.drawImage(videoElement, 0, 0, w, h);\n } else {\n canvas.height = videoHeight;\n canvas.width = videoWidth;\n\n ctx.drawImage(videoElement, 0, 0);\n }\n\n return canvas.toDataURL(format, quality);\n }\n\n function getImgDataIE11() {\n return new Promise((resolve) => {\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n\n if (crop || resize) {\n canvas.width = w;\n canvas.height = h;\n } else {\n canvas.height = videoHeight;\n canvas.width = videoWidth;\n }\n\n function _drawAndRemove(image) {\n if (crop) {\n ctx.drawImage(image, x, y, w, h, 0, 0, w, h);\n } else if (resize) {\n ctx.drawImage(image, 0, 0, w, h);\n } else {\n ctx.drawImage(image, 0, 0, videoWidth, videoHeight);\n }\n\n return canvas.toDataURL(format, quality);\n }\n\n const base64 = videoElement.getFrame();\n const image = new Image();\n\n image.onload = () => resolve(_drawAndRemove(image));\n image.setAttribute('src', 'data:image/bmp;base64,' + base64);\n });\n }\n\n return Promise.resolve(isIE11 ? getImgDataIE11() : getImgData())\n .then((imgData) => {\n if (!imgData || imgData.length < 10) {\n return Promise.reject('Failed to get a snapshot');\n }\n\n return imgData;\n });\n }\n\n /**\n * Get statistics of the media subscription like bytes received.\n *\n * Used internally by TsMediaSubscriber.getStats\n *\n * @method\n *\n * @param { TsMediaSubscriber } subscriber\n *\n * @returns { Promise<ToBeDefined> } stats\n *\n * @see TsMediaSubscriber#getStats\n */\n getStats(subscriber) {\n return new Promise((resolve) => {\n try {\n const pc = this._getPeerConnection();\n\n if (isIE11 || !pc) {\n return resolve();\n }\n\n pc.getStats(this._mediaStream.getVideoTracks()[0])\n .then((reports) => {\n const matches = [];\n\n reports.forEach((report) => {\n if (_.includes(['inbound-rtp', 'ssrc'], report.type)) {\n matches.push(report);\n }\n });\n\n return resolve({\n video: _.head(matches)\n });\n });\n } catch (e) {\n // when this fails, it's most likely due ot no support for the getStats\n // functionality, so we don't want to log this as a recurring error\n resolve();\n }\n });\n }\n\n /* eslint-enable no-unused-vars */\n\n getFullVideoStats() {\n return new Promise((resolve, reject) => {\n try {\n const pc = this._getPeerConnection();\n\n if (!pc) {\n return reject('NO_PEER_CONNECTION');\n }\n\n return resolve(pc.getStats(this._mediaStream.getVideoTracks()[0]));\n\n } catch (e) {\n reject(e);\n }\n });\n }\n\n turnFlashlight(isTorchOn = true) {\n return new Promise((resolve, reject) => {\n if (this._torchDelayTimeOut) {\n return reject('No tourch delay');\n }\n\n if (!navigator || !navigator.mediaDevices) {\n return reject('No mediaDevices');\n }\n\n const track = this._mediaStream.getVideoTracks()[0];\n\n if (!track) {\n return reject('No track');\n }\n if (this._torchOffTimeOut) {\n clearInterval(this._torchOffTimeOut);\n this._torchOffTimeOut = null;\n }\n\n this._torchDelayTimeOut = setTimeout(() => {\n let capatibilitiesAfter = {};\n\n try {\n capatibilitiesAfter = track.getCapabilities();\n } catch (e) {\n return reject('No capabilities');\n }\n\n if (!capatibilitiesAfter.torch) {\n return reject('No tourch capabilities');\n }\n\n return track.applyConstraints({\n advanced: [{\n torch: isTorchOn\n }]\n }).then(() => {\n this._torchDelayTimeOut = null;\n resolve(true);\n }).catch((e) => {\n this._torchDelayTimeOut = null;\n console.error(e);\n reject('Can\\'t turn on the light, please try later!');\n });\n }, TORCH_DELAY);\n });\n }\n\n setAutoLightOffTimer(flashlightTimeout) {\n return new Promise((resolve) => {\n if (!flashlightTimeout) {\n return reject('No timeout');\n }\n\n const track = this._mediaStream.getVideoTracks()[0];\n\n if (!track) {\n return reject('No track');\n }\n\n this._torchOffTimeOut = setTimeout(() => {\n\n if (!track) {\n return reject('No track');\n }\n\n track.applyConstraints({\n advanced: [{\n torch: false\n }]\n }).then(() => {\n this._torchOffTimeOut = null;\n resolve();\n });\n }, flashlightTimeout);\n });\n }\n}\n"]}