@techsee/techsee-media-service 0.7.0-alpha.2 → 0.7.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.
Files changed (149) hide show
  1. package/lib/LocalStreamManager.d.ts +21 -0
  2. package/lib/LocalStreamManager.d.ts.map +1 -0
  3. package/lib/LocalStreamManager.js +268 -0
  4. package/lib/LocalStreamManager.js.map +1 -0
  5. package/lib/MediaConstants.d.ts +52 -0
  6. package/lib/MediaConstants.d.ts.map +1 -0
  7. package/lib/MediaConstants.js +68 -0
  8. package/lib/MediaConstants.js.map +1 -0
  9. package/lib/MediaContracts.d.ts +122 -0
  10. package/lib/MediaContracts.d.ts.map +1 -0
  11. package/lib/MediaContracts.js +6 -0
  12. package/lib/MediaContracts.js.map +1 -0
  13. package/lib/MediaPublisher.d.ts +14 -0
  14. package/lib/MediaPublisher.d.ts.map +1 -0
  15. package/lib/MediaPublisher.js +43 -0
  16. package/lib/MediaPublisher.js.map +1 -0
  17. package/lib/MediaServiceBase.d.ts +64 -0
  18. package/lib/MediaServiceBase.d.ts.map +1 -0
  19. package/lib/MediaServiceBase.js +591 -0
  20. package/lib/MediaServiceBase.js.map +1 -0
  21. package/lib/MediaSession/MediaSessionBase.d.ts +23 -0
  22. package/lib/MediaSession/MediaSessionBase.d.ts.map +1 -0
  23. package/lib/MediaSession/MediaSessionBase.js +63 -0
  24. package/lib/MediaSession/MediaSessionBase.js.map +1 -0
  25. package/lib/MediaSession/SessionOpentok.d.ts +49 -0
  26. package/lib/MediaSession/SessionOpentok.d.ts.map +1 -0
  27. package/lib/MediaSession/SessionOpentok.js +379 -0
  28. package/lib/MediaSession/SessionOpentok.js.map +1 -0
  29. package/lib/MediaSession/SessionTurn.d.ts +32 -0
  30. package/lib/MediaSession/SessionTurn.d.ts.map +1 -0
  31. package/lib/MediaSession/SessionTurn.js +439 -0
  32. package/lib/MediaSession/SessionTurn.js.map +1 -0
  33. package/lib/MediaSession/TurnConstants.d.ts +18 -0
  34. package/lib/MediaSession/TurnConstants.d.ts.map +1 -0
  35. package/lib/MediaSession/TurnConstants.js +36 -0
  36. package/lib/MediaSession/TurnConstants.js.map +1 -0
  37. package/lib/MediaSubscriber.d.ts +36 -0
  38. package/lib/MediaSubscriber.d.ts.map +1 -0
  39. package/lib/MediaSubscriber.js +208 -0
  40. package/lib/MediaSubscriber.js.map +1 -0
  41. package/lib/MediaUtils/Compatibility.d.ts +11 -0
  42. package/lib/MediaUtils/Compatibility.d.ts.map +1 -0
  43. package/lib/MediaUtils/Compatibility.js +71 -0
  44. package/lib/MediaUtils/Compatibility.js.map +1 -0
  45. package/lib/MediaUtils/MediaDomUtils.d.ts +4 -0
  46. package/lib/MediaUtils/MediaDomUtils.d.ts.map +1 -0
  47. package/lib/MediaUtils/MediaDomUtils.js +200 -0
  48. package/lib/MediaUtils/MediaDomUtils.js.map +1 -0
  49. package/lib/MediaUtils/MediaTracer.d.ts +3 -0
  50. package/lib/MediaUtils/MediaTracer.d.ts.map +1 -0
  51. package/lib/MediaUtils/MediaTracer.js +12 -0
  52. package/lib/MediaUtils/MediaTracer.js.map +1 -0
  53. package/lib/TechseeMediaStream.d.ts +14 -0
  54. package/lib/TechseeMediaStream.d.ts.map +1 -0
  55. package/lib/TechseeMediaStream.js +58 -0
  56. package/lib/TechseeMediaStream.js.map +1 -0
  57. package/lib/oldCode/constants.js.map +1 -0
  58. package/lib/oldCode/event-emitter.js.map +1 -0
  59. package/lib/{index.js → oldCode/index.js} +1 -1
  60. package/lib/oldCode/index.js.map +1 -0
  61. package/lib/{opentok → oldCode/opentok}/session.js +6 -0
  62. package/lib/oldCode/opentok/session.js.map +1 -0
  63. package/lib/oldCode/opentok/stream.js.map +1 -0
  64. package/lib/oldCode/publisher.js.map +1 -0
  65. package/lib/{service.js → oldCode/service.js} +4 -6
  66. package/lib/oldCode/service.js.map +1 -0
  67. package/lib/oldCode/session.js.map +1 -0
  68. package/lib/oldCode/stream.js.map +1 -0
  69. package/lib/oldCode/subscriber.js.map +1 -0
  70. package/lib/oldCode/tracer.d.ts +35 -0
  71. package/lib/oldCode/tracer.d.ts.map +1 -0
  72. package/lib/oldCode/tracer.js +151 -0
  73. package/lib/oldCode/tracer.js.map +1 -0
  74. package/lib/oldCode/utils/ImageFixer.d.ts +1 -0
  75. package/lib/oldCode/utils/ImageFixer.d.ts.map +1 -0
  76. package/lib/oldCode/utils/ImageFixer.js +58 -0
  77. package/lib/oldCode/utils/ImageFixer.js.map +1 -0
  78. package/lib/oldCode/webrtc/constants.js.map +1 -0
  79. package/lib/{webrtc → oldCode/webrtc}/helper.js +2 -4
  80. package/lib/oldCode/webrtc/helper.js.map +1 -0
  81. package/lib/oldCode/webrtc/session-kms.js.map +1 -0
  82. package/lib/oldCode/webrtc/session-loopback.js.map +1 -0
  83. package/lib/{webrtc → oldCode/webrtc}/session-turn.js +47 -41
  84. package/lib/oldCode/webrtc/session-turn.js.map +1 -0
  85. package/lib/{webrtc → oldCode/webrtc}/session-turn.v2.js +85 -48
  86. package/lib/oldCode/webrtc/session-turn.v2.js.map +1 -0
  87. package/lib/oldCode/webrtc/session.js.map +1 -0
  88. package/lib/{webrtc → oldCode/webrtc}/stream.js +7 -9
  89. package/lib/oldCode/webrtc/stream.js.map +1 -0
  90. package/lib/oldCode/webrtc/temasys/adapter-loader.js.map +1 -0
  91. package/lib/oldCode/webrtc/temasys/adapter.js.map +1 -0
  92. package/lib/oldCode/webrtc/webrtc-ie-shim.js.map +1 -0
  93. package/lib/qos/raw-qos.js.map +1 -1
  94. package/lib/webrtc-ie-shim.js +3218 -0
  95. package/lib/webrtc-ie-shim.js.map +1 -0
  96. package/package.json +7 -5
  97. package/lib/constants.js.map +0 -1
  98. package/lib/event-emitter.js.map +0 -1
  99. package/lib/index.js.map +0 -1
  100. package/lib/opentok/session.js.map +0 -1
  101. package/lib/opentok/stream.js.map +0 -1
  102. package/lib/publisher.js.map +0 -1
  103. package/lib/service.js.map +0 -1
  104. package/lib/session.js.map +0 -1
  105. package/lib/stream.js.map +0 -1
  106. package/lib/subscriber.js.map +0 -1
  107. package/lib/tracer.js +0 -22
  108. package/lib/tracer.js.map +0 -1
  109. package/lib/v2/Contracts.d.ts +0 -41
  110. package/lib/v2/Contracts.d.ts.map +0 -1
  111. package/lib/v2/Contracts.js +0 -31
  112. package/lib/v2/Contracts.js.map +0 -1
  113. package/lib/v2/LocalStreamManager.d.ts +0 -8
  114. package/lib/v2/LocalStreamManager.d.ts.map +0 -1
  115. package/lib/v2/LocalStreamManager.js +0 -94
  116. package/lib/v2/LocalStreamManager.js.map +0 -1
  117. package/lib/v2/MediaServiceBase.d.ts +0 -24
  118. package/lib/v2/MediaServiceBase.d.ts.map +0 -1
  119. package/lib/v2/MediaServiceBase.js +0 -85
  120. package/lib/v2/MediaServiceBase.js.map +0 -1
  121. package/lib/v2/MediaSubscriber.d.ts +0 -8
  122. package/lib/v2/MediaSubscriber.d.ts.map +0 -1
  123. package/lib/v2/MediaSubscriber.js +0 -17
  124. package/lib/v2/MediaSubscriber.js.map +0 -1
  125. package/lib/webrtc/constants.js.map +0 -1
  126. package/lib/webrtc/helper.js.map +0 -1
  127. package/lib/webrtc/session-kms.js.map +0 -1
  128. package/lib/webrtc/session-loopback.js.map +0 -1
  129. package/lib/webrtc/session-turn.js.map +0 -1
  130. package/lib/webrtc/session-turn.v2.js.map +0 -1
  131. package/lib/webrtc/session.js.map +0 -1
  132. package/lib/webrtc/stream.js.map +0 -1
  133. package/lib/webrtc/temasys/adapter-loader.js.map +0 -1
  134. package/lib/webrtc/temasys/adapter.js.map +0 -1
  135. package/lib/webrtc/webrtc-ie-shim.js.map +0 -1
  136. /package/lib/{constants.js → oldCode/constants.js} +0 -0
  137. /package/lib/{event-emitter.js → oldCode/event-emitter.js} +0 -0
  138. /package/lib/{opentok → oldCode/opentok}/stream.js +0 -0
  139. /package/lib/{publisher.js → oldCode/publisher.js} +0 -0
  140. /package/lib/{session.js → oldCode/session.js} +0 -0
  141. /package/lib/{stream.js → oldCode/stream.js} +0 -0
  142. /package/lib/{subscriber.js → oldCode/subscriber.js} +0 -0
  143. /package/lib/{webrtc → oldCode/webrtc}/constants.js +0 -0
  144. /package/lib/{webrtc → oldCode/webrtc}/session-kms.js +0 -0
  145. /package/lib/{webrtc → oldCode/webrtc}/session-loopback.js +0 -0
  146. /package/lib/{webrtc → oldCode/webrtc}/session.js +0 -0
  147. /package/lib/{webrtc → oldCode/webrtc}/temasys/adapter-loader.js +0 -0
  148. /package/lib/{webrtc → oldCode/webrtc}/temasys/adapter.js +0 -0
  149. /package/lib/{webrtc → oldCode/webrtc}/webrtc-ie-shim.js +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/MediaSubscriber.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,QAAQ,EAAC,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAC,gBAAgB,EAAE,qBAAqB,EAAC,MAAM,kBAAkB,CAAC;AACzE,OAAO,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AAExD,OAAO,EAAC,gBAAgB,EAAuB,MAAM,kBAAkB,CAAC;AAWxE,qBAAa,sBAAuB,YAAW,gBAAgB;IAC3D,OAAO,CAAC,QAAQ,CAAe;IAC/B,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,aAAa,CAAoC;IAEzD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAwB;gBAE9C,gBAAgB,EAAE,qBAAqB;aAW/C,UAAU,EAAI,gBAAgB;aAI9B,SAAS,EAAI,cAAc;aAI3B,SAAS,EAAI,OAAO;aAIpB,YAAY,EAAI,OAAO;aAQvB,QAAQ,EAAI,OAAO;aAInB,QAAQ,EAAI,OAAO;aAInB,YAAY,EAAI,QAAQ,CAAC,gBAAgB,CAAC;aAI1C,UAAU,EAAI,MAAM;aAIpB,WAAW,EAAI,MAAM;aAIrB,WAAW,EAAI,MAAM;aAIrB,YAAY,EAAI,MAAM;IAI1B,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IASjC,cAAc,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI;IAK1C,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI;IASrC,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI;IAc9C,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAI9B,OAAO,IAAI,IAAI;IAgBf,OAAO,CAAC,eAAe;IA4BvB,OAAO,CAAC,kBAAkB;IAK1B,OAAO,CAAC,kBAAkB;IAQ1B,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,eAAe;CAK1B","file":"MediaSubscriber.d.ts","sourcesContent":["import {EventEmitter} from 'events';\nimport {Nullable} from '@techsee/techsee-common';\nimport {IMediaSubscriber, MediaSubscriberParams} from './MediaContracts';\nimport {TechseeMediaStream} from './TechseeMediaStream';\nimport {removeVideoElementFromDom, renderMediaStreamToVideoEl} from './MediaUtils/MediaDomUtils';\nimport {KnownMediaStream, KnownMediaStreamKind} from './MediaConstants';\n\nimport {getMediaTracer} from './MediaUtils/MediaTracer';\n\nconst trace = getMediaTracer('MediaSubscriber');\n\nenum privateEvents {\n STREAM_STATE_CHANGE = 'STREAM_STATE_CHANGE',\n SUBSCRIBER_DISPOSE = 'SUBSCRIBER_DISPOSE'\n}\n\nexport class TechseeMediaSubscriber implements IMediaSubscriber {\n private _emitter: EventEmitter;\n private _isDisposed: boolean = false;\n private _isPlaying: boolean = false;\n private _hasVideo: boolean = false;\n private _hasAudio: boolean = false;\n private _mediaElement: Nullable<HTMLVideoElement> = null;\n\n private readonly _subscriberParams: MediaSubscriberParams;\n\n constructor(subscriberParams: MediaSubscriberParams) {\n trace.info('Subscriber created');\n\n this.videoResizeHandler = this.videoResizeHandler.bind(this);\n\n this._emitter = new EventEmitter();\n this._subscriberParams = subscriberParams;\n }\n\n //#region IMediaSubscriber\n\n get streamType(): KnownMediaStream {\n return this._subscriberParams.streamType;\n }\n\n get container(): HTMLDivElement {\n return this._subscriberParams.container;\n }\n\n get isPlaying(): boolean {\n return this._isPlaying;\n }\n\n get isSoundMuted(): boolean {\n if (!this._mediaElement) {\n return true;\n }\n\n return this._mediaElement.muted;\n }\n\n get hasAudio(): boolean {\n return this._hasAudio;\n }\n\n get hasVideo(): boolean {\n return this._hasVideo;\n }\n\n get mediaElement(): Nullable<HTMLVideoElement> {\n return this._mediaElement;\n }\n\n get videoWidth(): number {\n return this.mediaElement ? this.mediaElement.videoWidth : 0;\n }\n\n get videoHeight(): number {\n return this.mediaElement ? this.mediaElement.videoHeight : 0;\n }\n\n get renderWidth(): number {\n return this.container.offsetWidth;\n }\n\n get renderHeight(): number {\n return this.container.offsetHeight;\n }\n\n muteSound(isMuted: boolean): void {\n this.throwIfDisposed();\n trace.info('Subscriber mute change - isMuted =', isMuted);\n if (this._mediaElement && this._mediaElement.muted !== isMuted) {\n this._mediaElement.muted = isMuted;\n this.emitEvent(privateEvents.STREAM_STATE_CHANGE);\n }\n }\n\n onStateChanged(callback: () => void): void {\n this.throwIfDisposed();\n this._emitter.on(privateEvents.STREAM_STATE_CHANGE, callback);\n }\n\n onDispose(callback: () => void): void {\n this.throwIfDisposed();\n this._emitter.on(privateEvents.SUBSCRIBER_DISPOSE, callback);\n }\n\n //#endregion\n\n //#region Non Interface Methods\n\n renderStream(stream: TechseeMediaStream): void {\n this.throwIfDisposed();\n this.stopRenderInternal().then(() => renderMediaStreamToVideoEl(this.container, stream.mediaStream))\n .then((videoEl) => {\n this._hasAudio = stream.mediaStream.getAudioTracks().length > 0;\n this._hasVideo = stream.mediaStream.getVideoTracks().length > 0;\n\n this.setPlayingState(videoEl, stream.streamKind);\n })\n .catch((error) => {\n trace.warn('Error while rendering stream on video element', error);\n });\n }\n\n stopRendering(): Promise<void> {\n return this.stopRenderInternal().then(() => this.setPlayingState());\n }\n\n dispose(): void {\n if (this._isDisposed) {\n return;\n }\n\n this.stopRendering().catch(() => undefined);\n\n\n this._isDisposed = true;\n this._emitter.removeAllListeners();\n trace.info('Subscriber disposed');\n this.emitEvent(privateEvents.SUBSCRIBER_DISPOSE);\n }\n\n //#endregion\n\n private setPlayingState(mediaElement?: HTMLVideoElement, streamKind?: KnownMediaStreamKind): void {\n this._isPlaying = !!mediaElement;\n this._mediaElement = mediaElement || null;\n\n const finalize = (): void => {\n this.emitEvent(privateEvents.STREAM_STATE_CHANGE);\n trace.info(`Video element ${streamKind || ''} ${this.isPlaying ? 'play' : 'stop'} success`);\n };\n\n if (this._mediaElement && streamKind === KnownMediaStreamKind.Video) {\n if (this._mediaElement.videoHeight === 0) {\n const resizeHandler = (): void => {\n finalize();\n this._mediaElement && this._mediaElement.removeEventListener('resize', resizeHandler);\n this._mediaElement && this._mediaElement.addEventListener('resize', this.videoResizeHandler);\n };\n\n //Todo actually, from here we can know on dimensions changes\n this._mediaElement.addEventListener('resize', resizeHandler, false);\n } else {\n this._mediaElement.addEventListener('resize', this.videoResizeHandler);\n finalize();\n }\n } else {\n finalize();\n }\n }\n\n private videoResizeHandler(): void {\n trace.info(`Video resize, new size = w: ${this.videoWidth} h:${this.videoHeight}`);\n this.emitEvent(privateEvents.STREAM_STATE_CHANGE);\n }\n\n private stopRenderInternal() {\n if (this._mediaElement && document.body.contains(this._mediaElement)) {\n return removeVideoElementFromDom(this._mediaElement);\n }\n\n return Promise.resolve();\n }\n\n private emitEvent(event: string, eventArgs?: any): void {\n setTimeout(() => {\n this._emitter.emit(event, eventArgs);\n });\n }\n\n private throwIfDisposed(): void {\n if (this._isDisposed) {\n throw new Error('Subscriber is already disposed');\n }\n }\n}\n"]}
@@ -0,0 +1,208 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ var events_1 = require("events");
5
+ var MediaDomUtils_1 = require("./MediaUtils/MediaDomUtils");
6
+ var MediaConstants_1 = require("./MediaConstants");
7
+ var MediaTracer_1 = require("./MediaUtils/MediaTracer");
8
+ var trace = MediaTracer_1.getMediaTracer('MediaSubscriber');
9
+ var privateEvents;
10
+ (function (privateEvents) {
11
+ privateEvents["STREAM_STATE_CHANGE"] = "STREAM_STATE_CHANGE";
12
+ privateEvents["SUBSCRIBER_DISPOSE"] = "SUBSCRIBER_DISPOSE";
13
+ })(privateEvents || (privateEvents = {}));
14
+ var TechseeMediaSubscriber = /** @class */function () {
15
+ function TechseeMediaSubscriber(subscriberParams) {
16
+ this._isDisposed = false;
17
+ this._isPlaying = false;
18
+ this._hasVideo = false;
19
+ this._hasAudio = false;
20
+ this._mediaElement = null;
21
+ trace.info('Subscriber created');
22
+ this.videoResizeHandler = this.videoResizeHandler.bind(this);
23
+ this._emitter = new events_1.EventEmitter();
24
+ this._subscriberParams = subscriberParams;
25
+ }
26
+ Object.defineProperty(TechseeMediaSubscriber.prototype, "streamType", {
27
+ //#region IMediaSubscriber
28
+ get: function get() {
29
+ return this._subscriberParams.streamType;
30
+ },
31
+ enumerable: true,
32
+ configurable: true
33
+ });
34
+ Object.defineProperty(TechseeMediaSubscriber.prototype, "container", {
35
+ get: function get() {
36
+ return this._subscriberParams.container;
37
+ },
38
+ enumerable: true,
39
+ configurable: true
40
+ });
41
+ Object.defineProperty(TechseeMediaSubscriber.prototype, "isPlaying", {
42
+ get: function get() {
43
+ return this._isPlaying;
44
+ },
45
+ enumerable: true,
46
+ configurable: true
47
+ });
48
+ Object.defineProperty(TechseeMediaSubscriber.prototype, "isSoundMuted", {
49
+ get: function get() {
50
+ if (!this._mediaElement) {
51
+ return true;
52
+ }
53
+ return this._mediaElement.muted;
54
+ },
55
+ enumerable: true,
56
+ configurable: true
57
+ });
58
+ Object.defineProperty(TechseeMediaSubscriber.prototype, "hasAudio", {
59
+ get: function get() {
60
+ return this._hasAudio;
61
+ },
62
+ enumerable: true,
63
+ configurable: true
64
+ });
65
+ Object.defineProperty(TechseeMediaSubscriber.prototype, "hasVideo", {
66
+ get: function get() {
67
+ return this._hasVideo;
68
+ },
69
+ enumerable: true,
70
+ configurable: true
71
+ });
72
+ Object.defineProperty(TechseeMediaSubscriber.prototype, "mediaElement", {
73
+ get: function get() {
74
+ return this._mediaElement;
75
+ },
76
+ enumerable: true,
77
+ configurable: true
78
+ });
79
+ Object.defineProperty(TechseeMediaSubscriber.prototype, "videoWidth", {
80
+ get: function get() {
81
+ return this.mediaElement ? this.mediaElement.videoWidth : 0;
82
+ },
83
+ enumerable: true,
84
+ configurable: true
85
+ });
86
+ Object.defineProperty(TechseeMediaSubscriber.prototype, "videoHeight", {
87
+ get: function get() {
88
+ return this.mediaElement ? this.mediaElement.videoHeight : 0;
89
+ },
90
+ enumerable: true,
91
+ configurable: true
92
+ });
93
+ Object.defineProperty(TechseeMediaSubscriber.prototype, "renderWidth", {
94
+ get: function get() {
95
+ return this.container.offsetWidth;
96
+ },
97
+ enumerable: true,
98
+ configurable: true
99
+ });
100
+ Object.defineProperty(TechseeMediaSubscriber.prototype, "renderHeight", {
101
+ get: function get() {
102
+ return this.container.offsetHeight;
103
+ },
104
+ enumerable: true,
105
+ configurable: true
106
+ });
107
+ TechseeMediaSubscriber.prototype.muteSound = function (isMuted) {
108
+ this.throwIfDisposed();
109
+ trace.info('Subscriber mute change - isMuted =', isMuted);
110
+ if (this._mediaElement && this._mediaElement.muted !== isMuted) {
111
+ this._mediaElement.muted = isMuted;
112
+ this.emitEvent(privateEvents.STREAM_STATE_CHANGE);
113
+ }
114
+ };
115
+ TechseeMediaSubscriber.prototype.onStateChanged = function (callback) {
116
+ this.throwIfDisposed();
117
+ this._emitter.on(privateEvents.STREAM_STATE_CHANGE, callback);
118
+ };
119
+ TechseeMediaSubscriber.prototype.onDispose = function (callback) {
120
+ this.throwIfDisposed();
121
+ this._emitter.on(privateEvents.SUBSCRIBER_DISPOSE, callback);
122
+ };
123
+ //#endregion
124
+ //#region Non Interface Methods
125
+ TechseeMediaSubscriber.prototype.renderStream = function (stream) {
126
+ var _this = this;
127
+ this.throwIfDisposed();
128
+ this.stopRenderInternal().then(function () {
129
+ return MediaDomUtils_1.renderMediaStreamToVideoEl(_this.container, stream.mediaStream);
130
+ }).then(function (videoEl) {
131
+ _this._hasAudio = stream.mediaStream.getAudioTracks().length > 0;
132
+ _this._hasVideo = stream.mediaStream.getVideoTracks().length > 0;
133
+ _this.setPlayingState(videoEl, stream.streamKind);
134
+ }).catch(function (error) {
135
+ trace.warn('Error while rendering stream on video element', error);
136
+ });
137
+ };
138
+ TechseeMediaSubscriber.prototype.stopRendering = function () {
139
+ var _this = this;
140
+ return this.stopRenderInternal().then(function () {
141
+ return _this.setPlayingState();
142
+ });
143
+ };
144
+ TechseeMediaSubscriber.prototype.dispose = function () {
145
+ if (this._isDisposed) {
146
+ return;
147
+ }
148
+ this.stopRendering().catch(function () {
149
+ return undefined;
150
+ });
151
+ this._isDisposed = true;
152
+ this._emitter.removeAllListeners();
153
+ trace.info('Subscriber disposed');
154
+ this.emitEvent(privateEvents.SUBSCRIBER_DISPOSE);
155
+ };
156
+ //#endregion
157
+ TechseeMediaSubscriber.prototype.setPlayingState = function (mediaElement, streamKind) {
158
+ var _this = this;
159
+ this._isPlaying = !!mediaElement;
160
+ this._mediaElement = mediaElement || null;
161
+ var finalize = function finalize() {
162
+ _this.emitEvent(privateEvents.STREAM_STATE_CHANGE);
163
+ trace.info("Video element " + (streamKind || '') + " " + (_this.isPlaying ? 'play' : 'stop') + " success");
164
+ };
165
+ if (this._mediaElement && streamKind === MediaConstants_1.KnownMediaStreamKind.Video) {
166
+ if (this._mediaElement.videoHeight === 0) {
167
+ var resizeHandler_1 = function resizeHandler_1() {
168
+ finalize();
169
+ _this._mediaElement && _this._mediaElement.removeEventListener('resize', resizeHandler_1);
170
+ _this._mediaElement && _this._mediaElement.addEventListener('resize', _this.videoResizeHandler);
171
+ };
172
+ //Todo actually, from here we can know on dimensions changes
173
+ this._mediaElement.addEventListener('resize', resizeHandler_1, false);
174
+ } else {
175
+ this._mediaElement.addEventListener('resize', this.videoResizeHandler);
176
+ finalize();
177
+ }
178
+ } else {
179
+ finalize();
180
+ }
181
+ };
182
+ TechseeMediaSubscriber.prototype.videoResizeHandler = function () {
183
+ trace.info("Video resize, new size = w: " + this.videoWidth + " h:" + this.videoHeight);
184
+ this.emitEvent(privateEvents.STREAM_STATE_CHANGE);
185
+ };
186
+ TechseeMediaSubscriber.prototype.stopRenderInternal = function () {
187
+ if (this._mediaElement && document.body.contains(this._mediaElement)) {
188
+ return MediaDomUtils_1.removeVideoElementFromDom(this._mediaElement);
189
+ }
190
+ return Promise.resolve();
191
+ };
192
+ TechseeMediaSubscriber.prototype.emitEvent = function (event, eventArgs) {
193
+ var _this = this;
194
+ setTimeout(function () {
195
+ _this._emitter.emit(event, eventArgs);
196
+ });
197
+ };
198
+ TechseeMediaSubscriber.prototype.throwIfDisposed = function () {
199
+ if (this._isDisposed) {
200
+ throw new Error('Subscriber is already disposed');
201
+ }
202
+ };
203
+ return TechseeMediaSubscriber;
204
+ }();
205
+ exports.TechseeMediaSubscriber = TechseeMediaSubscriber;
206
+
207
+ //# sourceMappingURL=MediaSubscriber.js.map
208
+ //# sourceMappingURL=MediaSubscriber.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["MediaSubscriber.js","../src/MediaSubscriber.ts"],"names":["Object","defineProperty","exports","value","events_1","require","MediaDomUtils_1","MediaConstants_1","MediaTracer_1","trace","getMediaTracer","privateEvents","TechseeMediaSubscriber","subscriberParams","_isDisposed","_isPlaying","_hasVideo","_hasAudio","_mediaElement","info","videoResizeHandler","bind","_emitter","EventEmitter","_subscriberParams","prototype","get","streamType","enumerable","configurable","container","muted","mediaElement","videoWidth","videoHeight","offsetWidth","offsetHeight","muteSound","isMuted","throwIfDisposed","emitEvent","STREAM_STATE_CHANGE","onStateChanged","callback","on","onDispose","SUBSCRIBER_DISPOSE","renderStream","stream","_this","stopRenderInternal","then","renderMediaStreamToVideoEl","mediaStream","videoEl","getAudioTracks","length","getVideoTracks","setPlayingState","streamKind","catch","error","warn","stopRendering","dispose","undefined","removeAllListeners","finalize","isPlaying","KnownMediaStreamKind","Video","resizeHandler_1","removeEventListener","addEventListener","document","body","contains","removeVideoElementFromDom","Promise","resolve","event","eventArgs","setTimeout","emit","Error"],"mappings":"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","file":"MediaSubscriber.js","sourcesContent":["\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar events_1 = require(\"events\");\nvar MediaDomUtils_1 = require(\"./MediaUtils/MediaDomUtils\");\nvar MediaConstants_1 = require(\"./MediaConstants\");\nvar MediaTracer_1 = require(\"./MediaUtils/MediaTracer\");\nvar trace = MediaTracer_1.getMediaTracer('MediaSubscriber');\nvar privateEvents;\n(function (privateEvents) {\n privateEvents[\"STREAM_STATE_CHANGE\"] = \"STREAM_STATE_CHANGE\";\n privateEvents[\"SUBSCRIBER_DISPOSE\"] = \"SUBSCRIBER_DISPOSE\";\n})(privateEvents || (privateEvents = {}));\nvar TechseeMediaSubscriber = /** @class */ (function () {\n function TechseeMediaSubscriber(subscriberParams) {\n this._isDisposed = false;\n this._isPlaying = false;\n this._hasVideo = false;\n this._hasAudio = false;\n this._mediaElement = null;\n trace.info('Subscriber created');\n this.videoResizeHandler = this.videoResizeHandler.bind(this);\n this._emitter = new events_1.EventEmitter();\n this._subscriberParams = subscriberParams;\n }\n Object.defineProperty(TechseeMediaSubscriber.prototype, \"streamType\", {\n //#region IMediaSubscriber\n get: function () {\n return this._subscriberParams.streamType;\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(TechseeMediaSubscriber.prototype, \"container\", {\n get: function () {\n return this._subscriberParams.container;\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(TechseeMediaSubscriber.prototype, \"isPlaying\", {\n get: function () {\n return this._isPlaying;\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(TechseeMediaSubscriber.prototype, \"isSoundMuted\", {\n get: function () {\n if (!this._mediaElement) {\n return true;\n }\n return this._mediaElement.muted;\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(TechseeMediaSubscriber.prototype, \"hasAudio\", {\n get: function () {\n return this._hasAudio;\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(TechseeMediaSubscriber.prototype, \"hasVideo\", {\n get: function () {\n return this._hasVideo;\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(TechseeMediaSubscriber.prototype, \"mediaElement\", {\n get: function () {\n return this._mediaElement;\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(TechseeMediaSubscriber.prototype, \"videoWidth\", {\n get: function () {\n return this.mediaElement ? this.mediaElement.videoWidth : 0;\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(TechseeMediaSubscriber.prototype, \"videoHeight\", {\n get: function () {\n return this.mediaElement ? this.mediaElement.videoHeight : 0;\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(TechseeMediaSubscriber.prototype, \"renderWidth\", {\n get: function () {\n return this.container.offsetWidth;\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(TechseeMediaSubscriber.prototype, \"renderHeight\", {\n get: function () {\n return this.container.offsetHeight;\n },\n enumerable: true,\n configurable: true\n });\n TechseeMediaSubscriber.prototype.muteSound = function (isMuted) {\n this.throwIfDisposed();\n trace.info('Subscriber mute change - isMuted =', isMuted);\n if (this._mediaElement && this._mediaElement.muted !== isMuted) {\n this._mediaElement.muted = isMuted;\n this.emitEvent(privateEvents.STREAM_STATE_CHANGE);\n }\n };\n TechseeMediaSubscriber.prototype.onStateChanged = function (callback) {\n this.throwIfDisposed();\n this._emitter.on(privateEvents.STREAM_STATE_CHANGE, callback);\n };\n TechseeMediaSubscriber.prototype.onDispose = function (callback) {\n this.throwIfDisposed();\n this._emitter.on(privateEvents.SUBSCRIBER_DISPOSE, callback);\n };\n //#endregion\n //#region Non Interface Methods\n TechseeMediaSubscriber.prototype.renderStream = function (stream) {\n var _this = this;\n this.throwIfDisposed();\n this.stopRenderInternal().then(function () { return MediaDomUtils_1.renderMediaStreamToVideoEl(_this.container, stream.mediaStream); })\n .then(function (videoEl) {\n _this._hasAudio = stream.mediaStream.getAudioTracks().length > 0;\n _this._hasVideo = stream.mediaStream.getVideoTracks().length > 0;\n _this.setPlayingState(videoEl, stream.streamKind);\n })\n .catch(function (error) {\n trace.warn('Error while rendering stream on video element', error);\n });\n };\n TechseeMediaSubscriber.prototype.stopRendering = function () {\n var _this = this;\n return this.stopRenderInternal().then(function () { return _this.setPlayingState(); });\n };\n TechseeMediaSubscriber.prototype.dispose = function () {\n if (this._isDisposed) {\n return;\n }\n this.stopRendering().catch(function () { return undefined; });\n this._isDisposed = true;\n this._emitter.removeAllListeners();\n trace.info('Subscriber disposed');\n this.emitEvent(privateEvents.SUBSCRIBER_DISPOSE);\n };\n //#endregion\n TechseeMediaSubscriber.prototype.setPlayingState = function (mediaElement, streamKind) {\n var _this = this;\n this._isPlaying = !!mediaElement;\n this._mediaElement = mediaElement || null;\n var finalize = function () {\n _this.emitEvent(privateEvents.STREAM_STATE_CHANGE);\n trace.info(\"Video element \" + (streamKind || '') + \" \" + (_this.isPlaying ? 'play' : 'stop') + \" success\");\n };\n if (this._mediaElement && streamKind === MediaConstants_1.KnownMediaStreamKind.Video) {\n if (this._mediaElement.videoHeight === 0) {\n var resizeHandler_1 = function () {\n finalize();\n _this._mediaElement && _this._mediaElement.removeEventListener('resize', resizeHandler_1);\n _this._mediaElement && _this._mediaElement.addEventListener('resize', _this.videoResizeHandler);\n };\n //Todo actually, from here we can know on dimensions changes\n this._mediaElement.addEventListener('resize', resizeHandler_1, false);\n }\n else {\n this._mediaElement.addEventListener('resize', this.videoResizeHandler);\n finalize();\n }\n }\n else {\n finalize();\n }\n };\n TechseeMediaSubscriber.prototype.videoResizeHandler = function () {\n trace.info(\"Video resize, new size = w: \" + this.videoWidth + \" h:\" + this.videoHeight);\n this.emitEvent(privateEvents.STREAM_STATE_CHANGE);\n };\n TechseeMediaSubscriber.prototype.stopRenderInternal = function () {\n if (this._mediaElement && document.body.contains(this._mediaElement)) {\n return MediaDomUtils_1.removeVideoElementFromDom(this._mediaElement);\n }\n return Promise.resolve();\n };\n TechseeMediaSubscriber.prototype.emitEvent = function (event, eventArgs) {\n var _this = this;\n setTimeout(function () {\n _this._emitter.emit(event, eventArgs);\n });\n };\n TechseeMediaSubscriber.prototype.throwIfDisposed = function () {\n if (this._isDisposed) {\n throw new Error('Subscriber is already disposed');\n }\n };\n return TechseeMediaSubscriber;\n}());\nexports.TechseeMediaSubscriber = TechseeMediaSubscriber;\n\n//# sourceMappingURL=MediaSubscriber.js.map\n","import {EventEmitter} from 'events';\nimport {Nullable} from '@techsee/techsee-common';\nimport {IMediaSubscriber, MediaSubscriberParams} from './MediaContracts';\nimport {TechseeMediaStream} from './TechseeMediaStream';\nimport {removeVideoElementFromDom, renderMediaStreamToVideoEl} from './MediaUtils/MediaDomUtils';\nimport {KnownMediaStream, KnownMediaStreamKind} from './MediaConstants';\n\nimport {getMediaTracer} from './MediaUtils/MediaTracer';\n\nconst trace = getMediaTracer('MediaSubscriber');\n\nenum privateEvents {\n STREAM_STATE_CHANGE = 'STREAM_STATE_CHANGE',\n SUBSCRIBER_DISPOSE = 'SUBSCRIBER_DISPOSE'\n}\n\nexport class TechseeMediaSubscriber implements IMediaSubscriber {\n private _emitter: EventEmitter;\n private _isDisposed: boolean = false;\n private _isPlaying: boolean = false;\n private _hasVideo: boolean = false;\n private _hasAudio: boolean = false;\n private _mediaElement: Nullable<HTMLVideoElement> = null;\n\n private readonly _subscriberParams: MediaSubscriberParams;\n\n constructor(subscriberParams: MediaSubscriberParams) {\n trace.info('Subscriber created');\n\n this.videoResizeHandler = this.videoResizeHandler.bind(this);\n\n this._emitter = new EventEmitter();\n this._subscriberParams = subscriberParams;\n }\n\n //#region IMediaSubscriber\n\n get streamType(): KnownMediaStream {\n return this._subscriberParams.streamType;\n }\n\n get container(): HTMLDivElement {\n return this._subscriberParams.container;\n }\n\n get isPlaying(): boolean {\n return this._isPlaying;\n }\n\n get isSoundMuted(): boolean {\n if (!this._mediaElement) {\n return true;\n }\n\n return this._mediaElement.muted;\n }\n\n get hasAudio(): boolean {\n return this._hasAudio;\n }\n\n get hasVideo(): boolean {\n return this._hasVideo;\n }\n\n get mediaElement(): Nullable<HTMLVideoElement> {\n return this._mediaElement;\n }\n\n get videoWidth(): number {\n return this.mediaElement ? this.mediaElement.videoWidth : 0;\n }\n\n get videoHeight(): number {\n return this.mediaElement ? this.mediaElement.videoHeight : 0;\n }\n\n get renderWidth(): number {\n return this.container.offsetWidth;\n }\n\n get renderHeight(): number {\n return this.container.offsetHeight;\n }\n\n muteSound(isMuted: boolean): void {\n this.throwIfDisposed();\n trace.info('Subscriber mute change - isMuted =', isMuted);\n if (this._mediaElement && this._mediaElement.muted !== isMuted) {\n this._mediaElement.muted = isMuted;\n this.emitEvent(privateEvents.STREAM_STATE_CHANGE);\n }\n }\n\n onStateChanged(callback: () => void): void {\n this.throwIfDisposed();\n this._emitter.on(privateEvents.STREAM_STATE_CHANGE, callback);\n }\n\n onDispose(callback: () => void): void {\n this.throwIfDisposed();\n this._emitter.on(privateEvents.SUBSCRIBER_DISPOSE, callback);\n }\n\n //#endregion\n\n //#region Non Interface Methods\n\n renderStream(stream: TechseeMediaStream): void {\n this.throwIfDisposed();\n this.stopRenderInternal().then(() => renderMediaStreamToVideoEl(this.container, stream.mediaStream))\n .then((videoEl) => {\n this._hasAudio = stream.mediaStream.getAudioTracks().length > 0;\n this._hasVideo = stream.mediaStream.getVideoTracks().length > 0;\n\n this.setPlayingState(videoEl, stream.streamKind);\n })\n .catch((error) => {\n trace.warn('Error while rendering stream on video element', error);\n });\n }\n\n stopRendering(): Promise<void> {\n return this.stopRenderInternal().then(() => this.setPlayingState());\n }\n\n dispose(): void {\n if (this._isDisposed) {\n return;\n }\n\n this.stopRendering().catch(() => undefined);\n\n\n this._isDisposed = true;\n this._emitter.removeAllListeners();\n trace.info('Subscriber disposed');\n this.emitEvent(privateEvents.SUBSCRIBER_DISPOSE);\n }\n\n //#endregion\n\n private setPlayingState(mediaElement?: HTMLVideoElement, streamKind?: KnownMediaStreamKind): void {\n this._isPlaying = !!mediaElement;\n this._mediaElement = mediaElement || null;\n\n const finalize = (): void => {\n this.emitEvent(privateEvents.STREAM_STATE_CHANGE);\n trace.info(`Video element ${streamKind || ''} ${this.isPlaying ? 'play' : 'stop'} success`);\n };\n\n if (this._mediaElement && streamKind === KnownMediaStreamKind.Video) {\n if (this._mediaElement.videoHeight === 0) {\n const resizeHandler = (): void => {\n finalize();\n this._mediaElement && this._mediaElement.removeEventListener('resize', resizeHandler);\n this._mediaElement && this._mediaElement.addEventListener('resize', this.videoResizeHandler);\n };\n\n //Todo actually, from here we can know on dimensions changes\n this._mediaElement.addEventListener('resize', resizeHandler, false);\n } else {\n this._mediaElement.addEventListener('resize', this.videoResizeHandler);\n finalize();\n }\n } else {\n finalize();\n }\n }\n\n private videoResizeHandler(): void {\n trace.info(`Video resize, new size = w: ${this.videoWidth} h:${this.videoHeight}`);\n this.emitEvent(privateEvents.STREAM_STATE_CHANGE);\n }\n\n private stopRenderInternal() {\n if (this._mediaElement && document.body.contains(this._mediaElement)) {\n return removeVideoElementFromDom(this._mediaElement);\n }\n\n return Promise.resolve();\n }\n\n private emitEvent(event: string, eventArgs?: any): void {\n setTimeout(() => {\n this._emitter.emit(event, eventArgs);\n });\n }\n\n private throwIfDisposed(): void {\n if (this._isDisposed) {\n throw new Error('Subscriber is already disposed');\n }\n }\n}\n"]}
@@ -0,0 +1,11 @@
1
+ declare global {
2
+ interface Window {
3
+ OT: any;
4
+ OTPlugin: any;
5
+ }
6
+ }
7
+ export declare const WAIT_FOR_OPENTOK_INITIALIZATION_MAX_ATTEMPTS = 10;
8
+ export declare const WAIT_FOR_OPENTOK_INITIALIZATION_INTERVAL = 500;
9
+ export declare function waitForOpenTokIsLoaded(): Promise<void>;
10
+ export declare function enumerateMediaDevices(): Promise<MediaDeviceInfo[]>;
11
+ export declare function isVideoPlaySupportedOnDevice(isOpenTokService: boolean): Promise<boolean>;
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/MediaUtils/Compatibility.ts"],"names":[],"mappings":"AAEA,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,MAAM;QACZ,EAAE,EAAE,GAAG,CAAC;QACR,QAAQ,EAAE,GAAG,CAAC;KACjB;CACJ;AAOD,eAAO,MAAM,4CAA4C,KAAK,CAAC;AAC/D,eAAO,MAAM,wCAAwC,MAAM,CAAC;AAmB5D,wBAAgB,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CAmBtD;AAED,wBAAgB,qBAAqB,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC,CAUlE;AAED,wBAAgB,4BAA4B,CAAC,gBAAgB,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAcxF","file":"Compatibility.d.ts","sourcesContent":["declare const require: any;\n\ndeclare global {\n interface Window {\n OT: any;\n OTPlugin: any;\n }\n}\n\n//@ts-ignore\nimport {TsEnvironmentDetect} from '@techsee/techsee-common/lib/helpers/ts-environment-detect';\n\n// Grace period to wait in the unlikely case that Opentok has not finished initializing,\n// and a session initialization was requested\nexport const WAIT_FOR_OPENTOK_INITIALIZATION_MAX_ATTEMPTS = 10;\nexport const WAIT_FOR_OPENTOK_INITIALIZATION_INTERVAL = 500;\n\nconst environmentDetect = new TsEnvironmentDetect();\nconst isIE11 = environmentDetect.isIE11();\n\nif (isIE11) {\n require('../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(): boolean {\n try {\n return !!window.OT;\n } catch (e) {\n return false;\n }\n}\n\nexport function waitForOpenTokIsLoaded(): Promise<void> {\n if (_isOTDefined()) {\n return Promise.resolve();\n }\n\n let isDefined = false;\n\n return (Promise as any).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 as any).delay(WAIT_FOR_OPENTOK_INITIALIZATION_INTERVAL);\n }, 0)\n .then(() => isDefined || Promise.reject(new Error('OT is undefined')));\n}\n\nexport function enumerateMediaDevices(): Promise<MediaDeviceInfo[]> {\n return new Promise((resolve, reject) => {\n if ((typeof window.OT !== 'undefined') && window.OT && window.OT.getDevices) {\n window.OT.getDevices((error: any, devices: any) => (error ? reject(error) : resolve(devices)));\n } else if (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) {\n navigator.mediaDevices.enumerateDevices().then(resolve).catch(reject);\n } else {\n reject(new Error('Enumerating media devices is not supported'));\n }\n });\n}\n\nexport function isVideoPlaySupportedOnDevice(isOpenTokService: boolean): Promise<boolean> {\n if (!isIE11) {\n return Promise.resolve(true);\n }\n\n if (isOpenTokService) {\n return waitForOpenTokIsLoaded().then(() => window.OT && window.OTPlugin && window.OTPlugin.isInstalled && window.OTPlugin.isInstalled());\n }\n\n if ((window as any).WebRTCAdapter) {\n return Promise.resolve(true);\n }\n\n return Promise.resolve(false);\n}\n"]}
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ //@ts-ignore
5
+ var ts_environment_detect_1 = require("@techsee/techsee-common/lib/helpers/ts-environment-detect");
6
+ // Grace period to wait in the unlikely case that Opentok has not finished initializing,
7
+ // and a session initialization was requested
8
+ exports.WAIT_FOR_OPENTOK_INITIALIZATION_MAX_ATTEMPTS = 10;
9
+ exports.WAIT_FOR_OPENTOK_INITIALIZATION_INTERVAL = 500;
10
+ var environmentDetect = new ts_environment_detect_1.TsEnvironmentDetect();
11
+ var isIE11 = environmentDetect.isIE11();
12
+ if (isIE11) {
13
+ require('../webrtc-ie-shim.js');
14
+ } else if (!(environmentDetect.isChrome() && environmentDetect.majorVersion() < 49)) {
15
+ require('webrtc-adapter/src/js/adapter_core'); // eslint-disable-line global-require
16
+ }
17
+ function _isOTDefined() {
18
+ try {
19
+ return !!window.OT;
20
+ } catch (e) {
21
+ return false;
22
+ }
23
+ }
24
+ function waitForOpenTokIsLoaded() {
25
+ if (_isOTDefined()) {
26
+ return Promise.resolve();
27
+ }
28
+ var isDefined = false;
29
+ return Promise.reduce(new Array(exports.WAIT_FOR_OPENTOK_INITIALIZATION_MAX_ATTEMPTS), function () {
30
+ if (isDefined || _isOTDefined()) {
31
+ isDefined = true;
32
+ return Promise.resolve();
33
+ }
34
+ return Promise.delay(exports.WAIT_FOR_OPENTOK_INITIALIZATION_INTERVAL);
35
+ }, 0).then(function () {
36
+ return isDefined || Promise.reject(new Error('OT is undefined'));
37
+ });
38
+ }
39
+ exports.waitForOpenTokIsLoaded = waitForOpenTokIsLoaded;
40
+ function enumerateMediaDevices() {
41
+ return new Promise(function (resolve, reject) {
42
+ if (typeof window.OT !== 'undefined' && window.OT && window.OT.getDevices) {
43
+ window.OT.getDevices(function (error, devices) {
44
+ return error ? reject(error) : resolve(devices);
45
+ });
46
+ } else if (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) {
47
+ navigator.mediaDevices.enumerateDevices().then(resolve).catch(reject);
48
+ } else {
49
+ reject(new Error('Enumerating media devices is not supported'));
50
+ }
51
+ });
52
+ }
53
+ exports.enumerateMediaDevices = enumerateMediaDevices;
54
+ function isVideoPlaySupportedOnDevice(isOpenTokService) {
55
+ if (!isIE11) {
56
+ return Promise.resolve(true);
57
+ }
58
+ if (isOpenTokService) {
59
+ return waitForOpenTokIsLoaded().then(function () {
60
+ return window.OT && window.OTPlugin && window.OTPlugin.isInstalled && window.OTPlugin.isInstalled();
61
+ });
62
+ }
63
+ if (window.WebRTCAdapter) {
64
+ return Promise.resolve(true);
65
+ }
66
+ return Promise.resolve(false);
67
+ }
68
+ exports.isVideoPlaySupportedOnDevice = isVideoPlaySupportedOnDevice;
69
+
70
+ //# sourceMappingURL=Compatibility.js.map
71
+ //# sourceMappingURL=Compatibility.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["MediaUtils/Compatibility.js"],"names":["Object","defineProperty","exports","value","ts_environment_detect_1","require","WAIT_FOR_OPENTOK_INITIALIZATION_MAX_ATTEMPTS","WAIT_FOR_OPENTOK_INITIALIZATION_INTERVAL","environmentDetect","TsEnvironmentDetect","isIE11","isChrome","majorVersion","_isOTDefined","window","OT","e","waitForOpenTokIsLoaded","Promise","resolve","isDefined","reduce","Array","delay","then","reject","Error","enumerateMediaDevices","getDevices","error","devices","navigator","mediaDevices","enumerateDevices","catch","isVideoPlaySupportedOnDevice","isOpenTokService","OTPlugin","isInstalled","WebRTCAdapter"],"mappings":"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","file":"Compatibility.js","sourcesContent":["\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n//@ts-ignore\nvar ts_environment_detect_1 = require(\"@techsee/techsee-common/lib/helpers/ts-environment-detect\");\n// Grace period to wait in the unlikely case that Opentok has not finished initializing,\n// and a session initialization was requested\nexports.WAIT_FOR_OPENTOK_INITIALIZATION_MAX_ATTEMPTS = 10;\nexports.WAIT_FOR_OPENTOK_INITIALIZATION_INTERVAL = 500;\nvar environmentDetect = new ts_environment_detect_1.TsEnvironmentDetect();\nvar isIE11 = environmentDetect.isIE11();\nif (isIE11) {\n require('../webrtc-ie-shim.js');\n}\nelse if (!(environmentDetect.isChrome() && (environmentDetect.majorVersion() < 49))) {\n require('webrtc-adapter/src/js/adapter_core'); // eslint-disable-line global-require\n}\nfunction _isOTDefined() {\n try {\n return !!window.OT;\n }\n catch (e) {\n return false;\n }\n}\nfunction waitForOpenTokIsLoaded() {\n if (_isOTDefined()) {\n return Promise.resolve();\n }\n var isDefined = false;\n return Promise.reduce(new Array(exports.WAIT_FOR_OPENTOK_INITIALIZATION_MAX_ATTEMPTS), function () {\n if (isDefined || _isOTDefined()) {\n isDefined = true;\n return Promise.resolve();\n }\n return Promise.delay(exports.WAIT_FOR_OPENTOK_INITIALIZATION_INTERVAL);\n }, 0)\n .then(function () { return isDefined || Promise.reject(new Error('OT is undefined')); });\n}\nexports.waitForOpenTokIsLoaded = waitForOpenTokIsLoaded;\nfunction enumerateMediaDevices() {\n return new Promise(function (resolve, reject) {\n if ((typeof window.OT !== 'undefined') && window.OT && window.OT.getDevices) {\n window.OT.getDevices(function (error, devices) { return (error ? reject(error) : resolve(devices)); });\n }\n else if (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) {\n navigator.mediaDevices.enumerateDevices().then(resolve).catch(reject);\n }\n else {\n reject(new Error('Enumerating media devices is not supported'));\n }\n });\n}\nexports.enumerateMediaDevices = enumerateMediaDevices;\nfunction isVideoPlaySupportedOnDevice(isOpenTokService) {\n if (!isIE11) {\n return Promise.resolve(true);\n }\n if (isOpenTokService) {\n return waitForOpenTokIsLoaded().then(function () { return window.OT && window.OTPlugin && window.OTPlugin.isInstalled && window.OTPlugin.isInstalled(); });\n }\n if (window.WebRTCAdapter) {\n return Promise.resolve(true);\n }\n return Promise.resolve(false);\n}\nexports.isVideoPlaySupportedOnDevice = isVideoPlaySupportedOnDevice;\n\n//# sourceMappingURL=Compatibility.js.map\n"]}
@@ -0,0 +1,4 @@
1
+ import { SnapshotOptions } from '../MediaContracts';
2
+ export declare function renderMediaStreamToVideoEl(container: HTMLDivElement, mediaStream: MediaStream): Promise<HTMLVideoElement>;
3
+ export declare function removeVideoElementFromDom(videoEl: HTMLVideoElement): Promise<void>;
4
+ export declare function getSnapshotFromMediaStream(mediaStream: MediaStream, snapshotOptions?: SnapshotOptions): Promise<string>;
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/MediaUtils/MediaDomUtils.ts"],"names":[],"mappings":"AAKA,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAOlD,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,cAAc,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA8EzH;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBlF;AAOD,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,WAAW,EAAE,eAAe,GAAE,eAAiC,GAAG,OAAO,CAAC,MAAM,CAAC,CAqGxI","file":"MediaDomUtils.d.ts","sourcesContent":["import isUndefined from 'lodash/isUndefined';\n\n//@ts-ignore\nimport {TsEnvironmentDetect} from '@techsee/techsee-common/lib/helpers/ts-environment-detect';\nimport {repeatWithTimeout} from '@techsee/techsee-common/lib/core/retry-with-timeout';\nimport {SnapshotOptions} from '../MediaContracts';\nimport {getMediaTracer} from './MediaTracer';\n\nconst trace = getMediaTracer('DomUtils');\n\nconst isIE11 = (new TsEnvironmentDetect()).isIE11();\n\nexport function renderMediaStreamToVideoEl(container: HTMLDivElement, mediaStream: MediaStream): Promise<HTMLVideoElement> {\n return new Promise((resolve, reject) => {\n if (!document.body.contains(container)) {\n reject(new Error('Cannot render to container that is not attached to dom'));\n\n return;\n }\n\n const doResolve = (videoEl: HTMLVideoElement): void => {\n trace.info('Video element created successfully', {videoEl});\n resolve(videoEl);\n };\n\n const videoEl = document.createElement('video') as any;\n\n videoEl.muted = true;\n videoEl.playsInline = true;\n\n if (isIE11 && (window as any).WebRTCAdapter) {\n container.appendChild(videoEl);\n (window as any).WebRTCAdapter.bindVideoElement(videoEl);\n }\n\n videoEl.srcObject = mediaStream;\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\n if (playRes && playRes.then) {\n playRes.then(() => {\n trace.info('Video element play success');\n if (!isIE11) {\n doResolve(videoEl);\n }\n });\n } else {\n doResolve(videoEl);\n }\n\n if (playRes && playRes.catch) {\n playRes.catch((error: any) => {\n trace.error('Reject while executing play method on video element', error);\n reject(error);\n });\n }\n } catch (error) {\n reject(error);\n trace.error('Error while executing play method on video element', error);\n\n return;\n }\n\n\n if (isIE11) {\n const handleComplete = (): boolean => videoEl.parentElement.tagName !== 'OBJECT';\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 = (): boolean => videoEl.videoHeight <= 0 || videoEl.videoWidth <= 0;\n const waitForVideoSettings = {intervalInMs: 50, timeoutInMs: 10000};\n\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 container.appendChild(videoEl);\n //doResolve(videoEl);\n }\n });\n}\n\nexport function removeVideoElementFromDom(videoEl: HTMLVideoElement): Promise<void> {\n return new Promise((resolve) => {\n if (isIE11 && (window as any).WebRTCAdapter) {\n (window as any).WebRTCAdapter.unBindVideoElement(videoEl);\n if (videoEl && videoEl.parentNode && videoEl.parentNode.removeChild) {\n videoEl.parentNode.removeChild(videoEl);\n trace.info('Video element removed successfully');\n } else {\n trace.warn('Video element not removed', videoEl, videoEl.parentNode);\n }\n } else {\n videoEl.remove();\n }\n\n resolve();\n });\n}\n\nconst defaultSnapshot: SnapshotOptions = {\n format: 'image/png',\n quality: 0.92\n};\n\nexport function getSnapshotFromMediaStream(mediaStream: MediaStream, snapshotOptions: SnapshotOptions = defaultSnapshot): Promise<string> {\n const {format, quality, x, y, w, h} = snapshotOptions;\n const crop = !isUndefined(x) && !isUndefined(y) && !isUndefined(w) && !isUndefined(h);\n const resize = !crop && (!isUndefined(w) || !isUndefined(h));\n\n return new Promise((resolve, reject) => {\n\n const tempContainer = document.createElement('div');\n\n tempContainer.style.cssText = 'position:absolute;left: -10000px;';\n document.body.appendChild(tempContainer);\n\n const doneFn = (err: any, image?: any): void => {\n if (err) {\n reject(err);\n\n return;\n }\n\n setTimeout(() => {\n document.body.removeChild(tempContainer);\n if (!err) {\n resolve(image);\n }\n }, 50);\n };\n\n renderMediaStreamToVideoEl(tempContainer, mediaStream)\n .then((videoElement) => Promise.resolve(isIE11 ? getImgDataIE11(videoElement) : getImgData(videoElement))\n .then((imgData: any) => {\n if (!imgData || imgData.length < 10) {\n throw new Error('Failed to create a snapshot - imgData is null or empty');\n }\n\n doneFn(null, imgData);\n }))\n .catch((error) => {\n doneFn(error || new Error('Failed to create a snapshot - can\\'t render MediaStream To VideoEl '));\n });\n });\n\n //Gets image in all browsers except of IE\n function getImgData(videoElement: HTMLVideoElement): string {\n const {videoWidth, videoHeight} = videoElement;\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 //Gets image in IE browser. There should be TechSee IE11 plugin or OpenTok plugin installed.\n function getImgDataIE11(videoElement: any): Promise<string> {\n return new Promise((resolve) => {\n const {videoWidth, videoHeight} = videoElement;\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: any): string {\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"]}
@@ -0,0 +1,200 @@
1
+ "use strict";
2
+
3
+ var __importDefault = undefined && undefined.__importDefault || function (mod) {
4
+ return mod && mod.__esModule ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ var isUndefined_1 = __importDefault(require("lodash/isUndefined"));
8
+ //@ts-ignore
9
+ var ts_environment_detect_1 = require("@techsee/techsee-common/lib/helpers/ts-environment-detect");
10
+ var retry_with_timeout_1 = require("@techsee/techsee-common/lib/core/retry-with-timeout");
11
+ var MediaTracer_1 = require("./MediaTracer");
12
+ var trace = MediaTracer_1.getMediaTracer('DomUtils');
13
+ var isIE11 = new ts_environment_detect_1.TsEnvironmentDetect().isIE11();
14
+ function renderMediaStreamToVideoEl(container, mediaStream) {
15
+ return new Promise(function (resolve, reject) {
16
+ if (!document.body.contains(container)) {
17
+ reject(new Error('Cannot render to container that is not attached to dom'));
18
+ return;
19
+ }
20
+ var doResolve = function doResolve(videoEl) {
21
+ trace.info('Video element created successfully', { videoEl: videoEl });
22
+ resolve(videoEl);
23
+ };
24
+ var videoEl = document.createElement('video');
25
+ videoEl.muted = true;
26
+ videoEl.playsInline = true;
27
+ if (isIE11 && window.WebRTCAdapter) {
28
+ container.appendChild(videoEl);
29
+ window.WebRTCAdapter.bindVideoElement(videoEl);
30
+ }
31
+ videoEl.srcObject = mediaStream;
32
+ if (!isIE11) {
33
+ // Hack to override behavior introduced by Chrome/FF that unmuted video elements can't auto play
34
+ videoEl.setAttribute('muted', '');
35
+ }
36
+ try {
37
+ var playRes = videoEl.play();
38
+ if (playRes && playRes.then) {
39
+ playRes.then(function () {
40
+ trace.info('Video element play success');
41
+ if (!isIE11) {
42
+ doResolve(videoEl);
43
+ }
44
+ });
45
+ } else {
46
+ doResolve(videoEl);
47
+ }
48
+ if (playRes && playRes.catch) {
49
+ playRes.catch(function (error) {
50
+ trace.error('Reject while executing play method on video element', error);
51
+ reject(error);
52
+ });
53
+ }
54
+ } catch (error) {
55
+ reject(error);
56
+ trace.error('Error while executing play method on video element', error);
57
+ return;
58
+ }
59
+ if (isIE11) {
60
+ var handleComplete = function handleComplete() {
61
+ return videoEl.parentElement.tagName !== 'OBJECT';
62
+ };
63
+ var waitForObjectSettings = { intervalInMs: 30, timeoutInMs: 200 };
64
+ retry_with_timeout_1.repeatWithTimeout(handleComplete, waitForObjectSettings).then(function () {
65
+ //We will wait, until video is played, then we resolve
66
+ var isVideoPlaying = function isVideoPlaying() {
67
+ return videoEl.videoHeight <= 0 || videoEl.videoWidth <= 0;
68
+ };
69
+ var waitForVideoSettings = { intervalInMs: 50, timeoutInMs: 10000 };
70
+ retry_with_timeout_1.repeatWithTimeout(isVideoPlaying, waitForVideoSettings).then(function () {
71
+ return doResolve(videoEl.parentElement);
72
+ }).catch(function () {
73
+ return reject(new Error('Timeout while waiting for video to play'));
74
+ });
75
+ });
76
+ } else {
77
+ container.appendChild(videoEl);
78
+ //doResolve(videoEl);
79
+ }
80
+ });
81
+ }
82
+ exports.renderMediaStreamToVideoEl = renderMediaStreamToVideoEl;
83
+ function removeVideoElementFromDom(videoEl) {
84
+ return new Promise(function (resolve) {
85
+ if (isIE11 && window.WebRTCAdapter) {
86
+ window.WebRTCAdapter.unBindVideoElement(videoEl);
87
+ if (videoEl && videoEl.parentNode && videoEl.parentNode.removeChild) {
88
+ videoEl.parentNode.removeChild(videoEl);
89
+ trace.info('Video element removed successfully');
90
+ } else {
91
+ trace.warn('Video element not removed', videoEl, videoEl.parentNode);
92
+ }
93
+ } else {
94
+ videoEl.remove();
95
+ }
96
+ resolve();
97
+ });
98
+ }
99
+ exports.removeVideoElementFromDom = removeVideoElementFromDom;
100
+ var defaultSnapshot = {
101
+ format: 'image/png',
102
+ quality: 0.92
103
+ };
104
+ function getSnapshotFromMediaStream(mediaStream, snapshotOptions) {
105
+ if (snapshotOptions === void 0) {
106
+ snapshotOptions = defaultSnapshot;
107
+ }
108
+ var format = snapshotOptions.format,
109
+ quality = snapshotOptions.quality,
110
+ x = snapshotOptions.x,
111
+ y = snapshotOptions.y,
112
+ w = snapshotOptions.w,
113
+ h = snapshotOptions.h;
114
+ var crop = !isUndefined_1.default(x) && !isUndefined_1.default(y) && !isUndefined_1.default(w) && !isUndefined_1.default(h);
115
+ var resize = !crop && (!isUndefined_1.default(w) || !isUndefined_1.default(h));
116
+ return new Promise(function (resolve, reject) {
117
+ var tempContainer = document.createElement('div');
118
+ tempContainer.style.cssText = 'position:absolute;left: -10000px;';
119
+ document.body.appendChild(tempContainer);
120
+ var doneFn = function doneFn(err, image) {
121
+ if (err) {
122
+ reject(err);
123
+ return;
124
+ }
125
+ setTimeout(function () {
126
+ document.body.removeChild(tempContainer);
127
+ if (!err) {
128
+ resolve(image);
129
+ }
130
+ }, 50);
131
+ };
132
+ renderMediaStreamToVideoEl(tempContainer, mediaStream).then(function (videoElement) {
133
+ return Promise.resolve(isIE11 ? getImgDataIE11(videoElement) : getImgData(videoElement)).then(function (imgData) {
134
+ if (!imgData || imgData.length < 10) {
135
+ throw new Error('Failed to create a snapshot - imgData is null or empty');
136
+ }
137
+ doneFn(null, imgData);
138
+ });
139
+ }).catch(function (error) {
140
+ doneFn(error || new Error('Failed to create a snapshot - can\'t render MediaStream To VideoEl '));
141
+ });
142
+ });
143
+ //Gets image in all browsers except of IE
144
+ function getImgData(videoElement) {
145
+ var videoWidth = videoElement.videoWidth,
146
+ videoHeight = videoElement.videoHeight;
147
+ var canvas = document.createElement('canvas');
148
+ var ctx = canvas.getContext('2d');
149
+ if (crop) {
150
+ canvas.width = w;
151
+ canvas.height = h;
152
+ ctx.drawImage(videoElement, x, y, w, h, 0, 0, w, h);
153
+ } else if (resize) {
154
+ canvas.width = w;
155
+ canvas.height = h;
156
+ ctx.drawImage(videoElement, 0, 0, w, h);
157
+ } else {
158
+ canvas.height = videoHeight;
159
+ canvas.width = videoWidth;
160
+ ctx.drawImage(videoElement, 0, 0);
161
+ }
162
+ return canvas.toDataURL(format, quality);
163
+ }
164
+ //Gets image in IE browser. There should be TechSee IE11 plugin or OpenTok plugin installed.
165
+ function getImgDataIE11(videoElement) {
166
+ return new Promise(function (resolve) {
167
+ var videoWidth = videoElement.videoWidth,
168
+ videoHeight = videoElement.videoHeight;
169
+ var canvas = document.createElement('canvas');
170
+ var ctx = canvas.getContext('2d');
171
+ if (crop || resize) {
172
+ canvas.width = w;
173
+ canvas.height = h;
174
+ } else {
175
+ canvas.height = videoHeight;
176
+ canvas.width = videoWidth;
177
+ }
178
+ function _drawAndRemove(image) {
179
+ if (crop) {
180
+ ctx.drawImage(image, x, y, w, h, 0, 0, w, h);
181
+ } else if (resize) {
182
+ ctx.drawImage(image, 0, 0, w, h);
183
+ } else {
184
+ ctx.drawImage(image, 0, 0, videoWidth, videoHeight);
185
+ }
186
+ return canvas.toDataURL(format, quality);
187
+ }
188
+ var base64 = videoElement.getFrame();
189
+ var image = new Image();
190
+ image.onload = function () {
191
+ return resolve(_drawAndRemove(image));
192
+ };
193
+ image.setAttribute('src', 'data:image/bmp;base64,' + base64);
194
+ });
195
+ }
196
+ }
197
+ exports.getSnapshotFromMediaStream = getSnapshotFromMediaStream;
198
+
199
+ //# sourceMappingURL=MediaDomUtils.js.map
200
+ //# sourceMappingURL=MediaDomUtils.js.map