@techsee/techsee-media-service 0.6.1-alpha.3 → 0.6.1-alpha.5

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.
@@ -0,0 +1,23 @@
1
+ import { IMediaSessionPeer } from './MediaSessionBase';
2
+ import { SessionClientRole, SessionClientType } from '../MediaConstants';
3
+ import { ISessionStreamsManager, MediaSessionParams, RemoteMediaTrack } from '../MediaContracts';
4
+ import { Nullable } from '@techsee/techsee-common';
5
+ export interface IMediaSessionPeer {
6
+ peerId: string;
7
+ peerType: SessionClientType;
8
+ peerRole: SessionClientRole;
9
+ remoteMediaTracks: RemoteMediaTrack[];
10
+ }
11
+ declare global {
12
+ interface RTCPeerConnection extends IMediaSessionPeer {
13
+ }
14
+ }
15
+ export declare abstract class MediaSessionBase<PeerType extends IMediaSessionPeer> {
16
+ protected readonly _peerConnections: Map<string, PeerType>;
17
+ protected readonly _sessionStreamsManager: ISessionStreamsManager;
18
+ protected readonly _sessionParams: MediaSessionParams;
19
+ protected constructor(sessionParams: MediaSessionParams, streamFactory: ISessionStreamsManager);
20
+ protected registerMediaTrackFromPeer(sourcePeerConnection: IMediaSessionPeer, mediaTrack: MediaStreamTrack): void;
21
+ unregisterPeersRemoteMediaTracks(peerConnection: PeerType): void;
22
+ protected getPeerConnectionByMediaTrack(mediaTrack: MediaStreamTrack): Nullable<PeerType>;
23
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/MediaSession/MediaSessionBase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,iBAAiB,EAAC,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAyC,iBAAiB,EAAE,iBAAiB,EAAC,MAAM,mBAAmB,CAAC;AAC/G,OAAO,EAAC,sBAAsB,EAAE,kBAAkB,EAAE,gBAAgB,EAAC,MAAM,mBAAmB,CAAC;AAG/F,OAAO,EAAC,QAAQ,EAAC,MAAM,yBAAyB,CAAC;AAEjD,MAAM,WAAW,iBAAiB;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;CACzC;AAED,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,iBAAkB,SAAQ,iBAAiB;KAEpD;CACJ;AAID,8BAAsB,gBAAgB,CAAC,QAAQ,SAAS,iBAAiB;IACrE,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAa;IACvE,SAAS,CAAC,QAAQ,CAAC,sBAAsB,EAAE,sBAAsB,CAAC;IAClE,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,kBAAkB,CAAC;IAEtD,SAAS,aAAa,aAAa,EAAE,kBAAkB,EAAE,aAAa,EAAE,sBAAsB;IAO9F,SAAS,CAAC,0BAA0B,CAAC,oBAAoB,EAAE,iBAAiB,EAAE,UAAU,EAAE,gBAAgB;IA0B1G,gCAAgC,CAAC,cAAc,EAAE,QAAQ;IASzD,SAAS,CAAC,6BAA6B,CAAC,UAAU,EAAE,gBAAgB,GAAG,QAAQ,CAAC,QAAQ,CAAC;CAiB5F","file":"MediaSessionBase.d.ts","sourcesContent":["import {IMediaSessionPeer} from './MediaSessionBase';\nimport {KnownMediaStream, KnownMediaStreamKind, SessionClientRole, SessionClientType} from '../MediaConstants';\nimport {ISessionStreamsManager, MediaSessionParams, RemoteMediaTrack} from '../MediaContracts';\n\nimport {getMediaTracer} from '../MediaUtils/MediaTracer';\nimport {Nullable} from '@techsee/techsee-common';\n\nexport interface IMediaSessionPeer {\n peerId: string;\n peerType: SessionClientType;\n peerRole: SessionClientRole;\n remoteMediaTracks: RemoteMediaTrack[];\n}\n\ndeclare global {\n interface RTCPeerConnection extends IMediaSessionPeer {\n\n }\n}\n\nconst trace = getMediaTracer('MediaSessionBase');\n\nexport abstract class MediaSessionBase<PeerType extends IMediaSessionPeer> {\n protected readonly _peerConnections: Map<string, PeerType> = new Map();\n protected readonly _sessionStreamsManager: ISessionStreamsManager;\n protected readonly _sessionParams: MediaSessionParams;\n\n protected constructor(sessionParams: MediaSessionParams, streamFactory: ISessionStreamsManager) {\n this._sessionParams = sessionParams;\n this._sessionStreamsManager = streamFactory;\n\n this._peerConnections = new Map();\n }\n\n protected registerMediaTrackFromPeer(sourcePeerConnection: IMediaSessionPeer, mediaTrack: MediaStreamTrack) {\n if (mediaTrack.kind === KnownMediaStreamKind.Video &&\n sourcePeerConnection.peerRole === SessionClientRole.AGENT) {\n //Currently We don't support video streams from Agent side\n return;\n }\n\n let trackType: Nullable<KnownMediaStream> = null;\n\n if (mediaTrack.kind.toLowerCase() === KnownMediaStreamKind.Audio) {\n trackType = sourcePeerConnection.peerRole === SessionClientRole.AGENT\n ? KnownMediaStream.AGENT_AUDIO_STREAM : KnownMediaStream.USER_AUDIO_STREAM;\n\n } else {\n trackType = KnownMediaStream.USER_VIDEO_STREAM;\n }\n\n const remoteMediaTrack = {mediaTrack, trackType};\n\n sourcePeerConnection.remoteMediaTracks.push(remoteMediaTrack);\n this._sessionStreamsManager.addRemoteMediaTrack(remoteMediaTrack)\n .catch((error: any) => {\n trace.warn('Error adding remote media track to available streams', error);\n });\n }\n\n unregisterPeersRemoteMediaTracks(peerConnection: PeerType) {\n peerConnection.remoteMediaTracks.forEach((remoteMediaTrack) => {\n this._sessionStreamsManager.removeMediaTrack(remoteMediaTrack.mediaTrack)\n .catch(() => {\n trace.warn('Error while removing remote media track', remoteMediaTrack);\n });\n });\n }\n\n protected getPeerConnectionByMediaTrack(mediaTrack: MediaStreamTrack): Nullable<PeerType> {\n let peerConnectionOfTrack: Nullable<PeerType> = null;\n\n this._peerConnections.forEach((peerConnection: PeerType) => {\n if (peerConnectionOfTrack !== null) {\n return;\n }\n\n const remoteTrack = peerConnection.remoteMediaTracks.filter((track) => track.mediaTrack.id === mediaTrack.id);\n\n if (remoteTrack.length === 1) {\n peerConnectionOfTrack = peerConnection;\n }\n });\n\n return peerConnectionOfTrack;\n }\n}\n"]}
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ var MediaConstants_1 = require("../MediaConstants");
5
+ var MediaTracer_1 = require("../MediaUtils/MediaTracer");
6
+ var trace = MediaTracer_1.getMediaTracer('MediaSessionBase');
7
+ var MediaSessionBase = /** @class */function () {
8
+ function MediaSessionBase(sessionParams, streamFactory) {
9
+ this._peerConnections = new Map();
10
+ this._sessionParams = sessionParams;
11
+ this._sessionStreamsManager = streamFactory;
12
+ this._peerConnections = new Map();
13
+ }
14
+ MediaSessionBase.prototype.registerMediaTrackFromPeer = function (sourcePeerConnection, mediaTrack) {
15
+ if (mediaTrack.kind === MediaConstants_1.KnownMediaStreamKind.Video && sourcePeerConnection.peerRole === MediaConstants_1.SessionClientRole.AGENT) {
16
+ //Currently We don't support video streams from Agent side
17
+ return;
18
+ }
19
+ var trackType = null;
20
+ if (mediaTrack.kind.toLowerCase() === MediaConstants_1.KnownMediaStreamKind.Audio) {
21
+ trackType = sourcePeerConnection.peerRole === MediaConstants_1.SessionClientRole.AGENT ? MediaConstants_1.KnownMediaStream.AGENT_AUDIO_STREAM : MediaConstants_1.KnownMediaStream.USER_AUDIO_STREAM;
22
+ } else {
23
+ trackType = MediaConstants_1.KnownMediaStream.USER_VIDEO_STREAM;
24
+ }
25
+ var remoteMediaTrack = { mediaTrack: mediaTrack, trackType: trackType };
26
+ sourcePeerConnection.remoteMediaTracks.push(remoteMediaTrack);
27
+ this._sessionStreamsManager.addRemoteMediaTrack(remoteMediaTrack).catch(function (error) {
28
+ trace.warn('Error adding remote media track to available streams', error);
29
+ });
30
+ };
31
+ MediaSessionBase.prototype.unregisterPeersRemoteMediaTracks = function (peerConnection) {
32
+ var _this = this;
33
+ peerConnection.remoteMediaTracks.forEach(function (remoteMediaTrack) {
34
+ _this._sessionStreamsManager.removeMediaTrack(remoteMediaTrack.mediaTrack).catch(function () {
35
+ trace.warn('Error while removing remote media track', remoteMediaTrack);
36
+ });
37
+ });
38
+ };
39
+ MediaSessionBase.prototype.getPeerConnectionByMediaTrack = function (mediaTrack) {
40
+ var peerConnectionOfTrack = null;
41
+ this._peerConnections.forEach(function (peerConnection) {
42
+ if (peerConnectionOfTrack !== null) {
43
+ return;
44
+ }
45
+ var remoteTrack = peerConnection.remoteMediaTracks.filter(function (track) {
46
+ return track.mediaTrack.id === mediaTrack.id;
47
+ });
48
+ if (remoteTrack.length === 1) {
49
+ peerConnectionOfTrack = peerConnection;
50
+ }
51
+ });
52
+ return peerConnectionOfTrack;
53
+ };
54
+ return MediaSessionBase;
55
+ }();
56
+ exports.MediaSessionBase = MediaSessionBase;
57
+
58
+ //# sourceMappingURL=MediaSessionBase.js.map
59
+ //# sourceMappingURL=MediaSessionBase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["MediaSession/MediaSessionBase.js"],"names":["Object","defineProperty","exports","value","MediaConstants_1","require","MediaTracer_1","trace","getMediaTracer","MediaSessionBase","sessionParams","streamFactory","_peerConnections","Map","_sessionParams","_sessionStreamsManager","prototype","registerMediaTrackFromPeer","sourcePeerConnection","mediaTrack","kind","KnownMediaStreamKind","Video","peerRole","SessionClientRole","AGENT","trackType","toLowerCase","Audio","KnownMediaStream","AGENT_AUDIO_STREAM","USER_AUDIO_STREAM","USER_VIDEO_STREAM","remoteMediaTrack","remoteMediaTracks","push","addRemoteMediaTrack","catch","error","warn","unregisterPeersRemoteMediaTracks","peerConnection","_this","forEach","removeMediaTrack","getPeerConnectionByMediaTrack","peerConnectionOfTrack","remoteTrack","filter","track","id","length"],"mappings":"AAAA;;AACAA,OAAOC,cAAP,CAAsBC,OAAtB,EAA+B,YAA/B,EAA6C,EAAEC,OAAO,IAAT,EAA7C;AACA,IAAIC,mBAAmBC,QAAQ,mBAAR,CAAvB;AACA,IAAIC,gBAAgBD,QAAQ,2BAAR,CAApB;AACA,IAAIE,QAAQD,cAAcE,cAAd,CAA6B,kBAA7B,CAAZ;AACA,IAAIC,mBAAmB,aAAe,YAAY;AAC9C,aAASA,gBAAT,CAA0BC,aAA1B,EAAyCC,aAAzC,EAAwD;AACpD,aAAKC,gBAAL,GAAwB,IAAIC,GAAJ,EAAxB;AACA,aAAKC,cAAL,GAAsBJ,aAAtB;AACA,aAAKK,sBAAL,GAA8BJ,aAA9B;AACA,aAAKC,gBAAL,GAAwB,IAAIC,GAAJ,EAAxB;AACH;AACDJ,qBAAiBO,SAAjB,CAA2BC,0BAA3B,GAAwD,UAAUC,oBAAV,EAAgCC,UAAhC,EAA4C;AAChG,YAAIA,WAAWC,IAAX,KAAoBhB,iBAAiBiB,oBAAjB,CAAsCC,KAA1D,IACAJ,qBAAqBK,QAArB,KAAkCnB,iBAAiBoB,iBAAjB,CAAmCC,KADzE,EACgF;AAC5E;AACA;AACH;AACD,YAAIC,YAAY,IAAhB;AACA,YAAIP,WAAWC,IAAX,CAAgBO,WAAhB,OAAkCvB,iBAAiBiB,oBAAjB,CAAsCO,KAA5E,EAAmF;AAC/EF,wBAAYR,qBAAqBK,QAArB,KAAkCnB,iBAAiBoB,iBAAjB,CAAmCC,KAArE,GACNrB,iBAAiByB,gBAAjB,CAAkCC,kBAD5B,GACiD1B,iBAAiByB,gBAAjB,CAAkCE,iBAD/F;AAEH,SAHD,MAIK;AACDL,wBAAYtB,iBAAiByB,gBAAjB,CAAkCG,iBAA9C;AACH;AACD,YAAIC,mBAAmB,EAAEd,YAAYA,UAAd,EAA0BO,WAAWA,SAArC,EAAvB;AACAR,6BAAqBgB,iBAArB,CAAuCC,IAAvC,CAA4CF,gBAA5C;AACA,aAAKlB,sBAAL,CAA4BqB,mBAA5B,CAAgDH,gBAAhD,EACKI,KADL,CACW,UAAUC,KAAV,EAAiB;AACxB/B,kBAAMgC,IAAN,CAAW,sDAAX,EAAmED,KAAnE;AACH,SAHD;AAIH,KApBD;AAqBA7B,qBAAiBO,SAAjB,CAA2BwB,gCAA3B,GAA8D,UAAUC,cAAV,EAA0B;AACpF,YAAIC,QAAQ,IAAZ;AACAD,uBAAeP,iBAAf,CAAiCS,OAAjC,CAAyC,UAAUV,gBAAV,EAA4B;AACjES,kBAAM3B,sBAAN,CAA6B6B,gBAA7B,CAA8CX,iBAAiBd,UAA/D,EACKkB,KADL,CACW,YAAY;AACnB9B,sBAAMgC,IAAN,CAAW,yCAAX,EAAsDN,gBAAtD;AACH,aAHD;AAIH,SALD;AAMH,KARD;AASAxB,qBAAiBO,SAAjB,CAA2B6B,6BAA3B,GAA2D,UAAU1B,UAAV,EAAsB;AAC7E,YAAI2B,wBAAwB,IAA5B;AACA,aAAKlC,gBAAL,CAAsB+B,OAAtB,CAA8B,UAAUF,cAAV,EAA0B;AACpD,gBAAIK,0BAA0B,IAA9B,EAAoC;AAChC;AACH;AACD,gBAAIC,cAAcN,eAAeP,iBAAf,CAAiCc,MAAjC,CAAwC,UAAUC,KAAV,EAAiB;AAAE,uBAAOA,MAAM9B,UAAN,CAAiB+B,EAAjB,KAAwB/B,WAAW+B,EAA1C;AAA+C,aAA1G,CAAlB;AACA,gBAAIH,YAAYI,MAAZ,KAAuB,CAA3B,EAA8B;AAC1BL,wCAAwBL,cAAxB;AACH;AACJ,SARD;AASA,eAAOK,qBAAP;AACH,KAZD;AAaA,WAAOrC,gBAAP;AACH,CAnDqC,EAAtC;AAoDAP,QAAQO,gBAAR,GAA2BA,gBAA3B;;AAEA","file":"MediaSessionBase.js","sourcesContent":["\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar MediaConstants_1 = require(\"../MediaConstants\");\nvar MediaTracer_1 = require(\"../MediaUtils/MediaTracer\");\nvar trace = MediaTracer_1.getMediaTracer('MediaSessionBase');\nvar MediaSessionBase = /** @class */ (function () {\n function MediaSessionBase(sessionParams, streamFactory) {\n this._peerConnections = new Map();\n this._sessionParams = sessionParams;\n this._sessionStreamsManager = streamFactory;\n this._peerConnections = new Map();\n }\n MediaSessionBase.prototype.registerMediaTrackFromPeer = function (sourcePeerConnection, mediaTrack) {\n if (mediaTrack.kind === MediaConstants_1.KnownMediaStreamKind.Video &&\n sourcePeerConnection.peerRole === MediaConstants_1.SessionClientRole.AGENT) {\n //Currently We don't support video streams from Agent side\n return;\n }\n var trackType = null;\n if (mediaTrack.kind.toLowerCase() === MediaConstants_1.KnownMediaStreamKind.Audio) {\n trackType = sourcePeerConnection.peerRole === MediaConstants_1.SessionClientRole.AGENT\n ? MediaConstants_1.KnownMediaStream.AGENT_AUDIO_STREAM : MediaConstants_1.KnownMediaStream.USER_AUDIO_STREAM;\n }\n else {\n trackType = MediaConstants_1.KnownMediaStream.USER_VIDEO_STREAM;\n }\n var remoteMediaTrack = { mediaTrack: mediaTrack, trackType: trackType };\n sourcePeerConnection.remoteMediaTracks.push(remoteMediaTrack);\n this._sessionStreamsManager.addRemoteMediaTrack(remoteMediaTrack)\n .catch(function (error) {\n trace.warn('Error adding remote media track to available streams', error);\n });\n };\n MediaSessionBase.prototype.unregisterPeersRemoteMediaTracks = function (peerConnection) {\n var _this = this;\n peerConnection.remoteMediaTracks.forEach(function (remoteMediaTrack) {\n _this._sessionStreamsManager.removeMediaTrack(remoteMediaTrack.mediaTrack)\n .catch(function () {\n trace.warn('Error while removing remote media track', remoteMediaTrack);\n });\n });\n };\n MediaSessionBase.prototype.getPeerConnectionByMediaTrack = function (mediaTrack) {\n var peerConnectionOfTrack = null;\n this._peerConnections.forEach(function (peerConnection) {\n if (peerConnectionOfTrack !== null) {\n return;\n }\n var remoteTrack = peerConnection.remoteMediaTracks.filter(function (track) { return track.mediaTrack.id === mediaTrack.id; });\n if (remoteTrack.length === 1) {\n peerConnectionOfTrack = peerConnection;\n }\n });\n return peerConnectionOfTrack;\n };\n return MediaSessionBase;\n}());\nexports.MediaSessionBase = MediaSessionBase;\n\n//# sourceMappingURL=MediaSessionBase.js.map\n"]}
@@ -1,14 +1,28 @@
1
+ import { Nullable } from '@techsee/techsee-common';
1
2
  import { IMediaSession, ISessionStreamsManager, MediaSessionParams, RemoteTrackStats } from '../MediaContracts';
2
3
  import { SessionClientRole } from '../MediaConstants';
4
+ import { IMediaSessionPeer, MediaSessionBase } from './MediaSessionBase';
3
5
  declare global {
4
6
  interface Window {
5
7
  OT: any;
6
8
  }
7
9
  }
8
- export declare class OpentokSessionV3 implements IMediaSession {
9
- private readonly _sessionStreamsManager;
10
- private readonly _sessionParams;
11
- private readonly _peerConnections;
10
+ declare type OTPublisher = any;
11
+ declare type OTSubscriber = any;
12
+ interface OTConnection {
13
+ connectionId: string;
14
+ }
15
+ interface OTPeerConnection extends IMediaSessionPeer {
16
+ localStream: Nullable<OTStreamSource>;
17
+ connection: OTConnection;
18
+ publisher: Nullable<OTPublisher>;
19
+ subscriber: Nullable<OTSubscriber>;
20
+ }
21
+ interface OTStreamSource {
22
+ videoSource: any;
23
+ audioSource: any;
24
+ }
25
+ export declare class OpentokSessionV3 extends MediaSessionBase<OTPeerConnection> implements IMediaSession {
12
26
  private readonly _credentials;
13
27
  private _session;
14
28
  readonly id: string;
@@ -16,18 +30,19 @@ export declare class OpentokSessionV3 implements IMediaSession {
16
30
  constructor(sessionParams: MediaSessionParams, streamFactory: ISessionStreamsManager);
17
31
  connect(): Promise<void>;
18
32
  disconnect(): Promise<void>;
19
- onMediaStreamDestroyed(clientRole: SessionClientRole): Promise<void>;
20
- onMediaStreamRenewed(clientRole: SessionClientRole, mediaStream: MediaStream): Promise<void>;
21
- getRemoteTrackStats(mediaTrack: MediaStreamTrack): Promise<RemoteTrackStats>;
22
33
  private connectionCreatedHandler;
23
34
  private connectionDestroyedHandler;
24
35
  private streamCreatedHandler;
25
36
  private streamDestroyedHandler;
37
+ onMediaStreamDestroyed(clientRole: SessionClientRole): Promise<void>;
38
+ onMediaStreamRenewed(clientRole: SessionClientRole, mediaStream: MediaStream): Promise<void>;
39
+ getRemoteTrackStats(mediaTrack: MediaStreamTrack): Promise<RemoteTrackStats>;
26
40
  private createStreamForPublishing;
27
41
  private calculateDestinationRole;
28
42
  private createMediaPublisher;
29
- private clearPeerConnections;
30
- private sessionExistsGuard;
31
43
  private destroyPeerConnection;
32
44
  private destroyPublisherOnPeerConnection;
45
+ private destroySubscriberOnPeerConnection;
46
+ private sessionExistsGuard;
33
47
  }
48
+ export {};
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/MediaSession/SessionOpentok.v3.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,aAAa,EACb,sBAAsB,EACtB,kBAAkB,EACA,gBAAgB,EACrC,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAEH,iBAAiB,EAEpB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,MAAM;QACZ,EAAE,EAAE,GAAG,CAAC;KACX;CACJ;AAoDD,qBAAa,gBAAiB,YAAW,aAAa;IAClD,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAyB;IAChE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA8C;IAC/E,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAM;IAEnC,OAAO,CAAC,QAAQ,CAA8B;aAE1C,EAAE,EAAI,MAAM;qBAIJ,SAAS;gBAIT,aAAa,EAAE,kBAAkB,EAAE,aAAa,EAAE,sBAAsB;IAmBpF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAwCxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAwB3B,sBAAsB,CAAC,UAAU,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAUpE,oBAAoB,CAAC,UAAU,EAAE,iBAAiB,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAK5F,mBAAmB,CAAC,UAAU,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAO5E,OAAO,CAAC,wBAAwB;IAyEhC,OAAO,CAAC,0BAA0B;IAalC,OAAO,CAAC,oBAAoB;IA4B5B,OAAO,CAAC,sBAAsB;IAc9B,OAAO,CAAC,yBAAyB;IAyBjC,OAAO,CAAC,wBAAwB;IAWhC,OAAO,CAAC,oBAAoB;IAsB5B,OAAO,CAAC,oBAAoB;IAI5B,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,qBAAqB;IAW7B,OAAO,CAAC,gCAAgC;CAY3C","file":"SessionOpentok.v3.d.ts","sourcesContent":["import {Nullable} from '@techsee/techsee-common';\n\nimport {\n IMediaSession,\n ISessionStreamsManager,\n MediaSessionParams,\n RemoteMediaTrack, RemoteTrackStats\n} from '../MediaContracts';\n\nimport {\n KnownMediaStream,\n SessionClientRole,\n SessionClientType\n} from '../MediaConstants';\n\ndeclare global {\n interface Window {\n OT: any;\n }\n}\n\nimport {getMediaTracer} from '../MediaUtils/MediaTracer';\nimport {throwableGuard} from '@techsee/techsee-common/lib/core/guards';\n\nconst trace = getMediaTracer('OpenTokSession');\n\ninterface IOTSession {\n\n sessionId: string;\n\n connection: Nullable<OTConnection>;\n\n isConnected(): boolean;\n\n connect(token: string, cb: any): void;\n\n disconnect(): void;\n\n publish(publisher: any, cb: any): void;\n\n off(): void;\n\n on(param: string, cb: any): void;\n\n once(param: string, cb: any): void;\n}\n\ntype OTPublisher = any\n\ntype OTPeerId = any\n\ninterface OTConnection {\n connectionId: string;\n}\n\ninterface OTPeerConnection {\n peerId: OTPeerId;\n peerType: SessionClientType;\n peerRole: SessionClientRole;\n remoteMediaTracks: RemoteMediaTrack[];\n localStream: Nullable<OTStreamSource>;\n connection: OTConnection;\n publisher: Nullable<OTPublisher>;\n}\n\ninterface OTStreamSource {\n videoSource: any;\n audioSource: any;\n}\n\n//Currently this version supports subscribing only. Publishing will be implemented as needed.\nexport class OpentokSessionV3 implements IMediaSession {\n private readonly _sessionStreamsManager: ISessionStreamsManager;\n private readonly _sessionParams: MediaSessionParams;\n private readonly _peerConnections: Map<OTPeerId, OTPeerConnection> = new Map();\n private readonly _credentials: any;\n\n private _session: Nullable<IOTSession> = null;\n\n get id(): string {\n return this._session && this._session.sessionId ? this._session.sessionId : '';\n }\n\n private get ownPeerId(): string {\n return this._session && this._session.connection ? this._session.connection.connectionId : '';\n }\n\n constructor(sessionParams: MediaSessionParams, streamFactory: ISessionStreamsManager) {\n this._sessionParams = sessionParams;\n this._sessionStreamsManager = streamFactory;\n this._credentials = sessionParams.credentials;\n\n this.connect = this.connect.bind(this);\n this.disconnect = this.disconnect.bind(this);\n this.onMediaStreamDestroyed = this.onMediaStreamDestroyed.bind(this);\n this.onMediaStreamRenewed = this.onMediaStreamRenewed.bind(this);\n\n this.createStreamForPublishing = this.createStreamForPublishing.bind(this);\n this.createMediaPublisher = this.createMediaPublisher.bind(this);\n this.clearPeerConnections = this.clearPeerConnections.bind(this);\n this.connectionCreatedHandler = this.connectionCreatedHandler.bind(this);\n this.connectionDestroyedHandler = this.connectionDestroyedHandler.bind(this);\n this.streamCreatedHandler = this.streamCreatedHandler.bind(this);\n this.streamDestroyedHandler = this.streamDestroyedHandler.bind(this);\n }\n\n connect(): Promise<void> {\n trace.info('Connect to session');\n\n if (this._session) {\n trace.error('Session already exists');\n\n return Promise.reject('Cannot connect to session while another session is active');\n }\n\n return new Promise((resolve, reject) => {\n const handleError = (error: any): void => {\n this._session && this._session!.off();\n this._session = null;\n trace.error('handleConnect error:', error);\n reject(error);\n };\n\n const {apiKey, sessionId} = this._sessionParams.credentials;\n\n this._session = (window as any).OTSESSION = window.OT.initSession(apiKey, sessionId);\n\n this._session!.on('connectionCreated', this.connectionCreatedHandler);\n this._session!.on('connectionDestroyed', this.connectionDestroyedHandler);\n this._session!.on('streamCreated', this.streamCreatedHandler);\n this._session!.on('streamDestroyed', this.streamDestroyedHandler);\n\n const connectHandler = (error: any): void => {\n if (error) {\n handleError(error);\n\n return;\n }\n\n resolve();\n };\n\n this._session!.connect(this._credentials.token, connectHandler);\n });\n }\n\n disconnect(): Promise<void> {\n //TODO - Alex: Implement destroying all publishers (by opentok docs)\n //Create a method destroy publisher (or publishers can treated the same as \"peerConnections\"?\n return new Promise((resolve) => {\n const currentSession = this._session;\n\n this._session = null;\n\n this._peerConnections.forEach((peerConnection) => {\n this.destroyPeerConnection(peerConnection);\n });\n\n if (!currentSession) {\n trace.info('No active session - resolving');\n resolve();\n\n return;\n }\n currentSession.off();\n currentSession.disconnect();\n resolve();\n });\n }\n\n onMediaStreamDestroyed(clientRole: SessionClientRole): Promise<void> {\n this._peerConnections.forEach((peerConnection) => {\n if (peerConnection.peerRole === clientRole) {\n this.destroyPublisherOnPeerConnection(peerConnection);\n }\n });\n\n return Promise.resolve();\n }\n\n onMediaStreamRenewed(clientRole: SessionClientRole, mediaStream: MediaStream): Promise<void> {\n //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation (in OT API)\n return Promise.resolve();\n }\n\n getRemoteTrackStats(mediaTrack: MediaStreamTrack): Promise<RemoteTrackStats> {\n //https://tokbox.com/developer/sdks/js/reference/Subscriber.html (getStats)\n return Promise.reject(new Error('Not implemented yet'));\n }\n\n //#region OpenTok Events Handlers\n\n private connectionCreatedHandler(event: any): void {\n trace.info('connectionCreatedHandler', event);\n const {connection} = event;\n\n if (!this.sessionExistsGuard(false) || !connection) {\n return;\n }\n\n //In case we got our own connection, we have nothing to do with it\n if (connection.connectionId === this.ownPeerId) {\n return;\n }\n\n const destinationRole = this.calculateDestinationRole();\n\n this.createStreamForPublishing(destinationRole)\n .then((streams: OTStreamSource) => {\n const peerConnection: OTPeerConnection = {\n peerId: connection.connectionId,\n peerRole: destinationRole,\n peerType: this._sessionParams.clientType === SessionClientType.INITIATOR\n ? SessionClientType.GUEST : SessionClientType.INITIATOR,\n connection: connection,\n publisher: null,\n remoteMediaTracks: [],\n localStream: streams\n };\n\n if (!streams.videoSource && !streams.audioSource) {\n trace.info('Peer connection without publisher was created', peerConnection);\n\n return peerConnection;\n }\n\n const streamName = destinationRole === SessionClientRole.USER\n ? KnownMediaStream.AGENT_AUDIO_STREAM : KnownMediaStream.USER_VIDEO_STREAM;\n\n\n return this.createMediaPublisher(streams, streamName)\n .then((publisher: OTPublisher) => {\n peerConnection.publisher = publisher;\n trace.info('Peer connection with publisher was created', peerConnection);\n\n return peerConnection;\n });\n })\n .then((peerConnection: OTPeerConnection) => {\n this._peerConnections.set(peerConnection.peerId, peerConnection);\n\n if (peerConnection.publisher) {\n return new Promise<void>((resolve, reject) => {\n trace.info('Starting publish to peerConnection.publisher');\n this._session!.publish(peerConnection.publisher, (error: any) => {\n if (error) {\n trace.error('Publish to peerConnection error', error);\n\n return reject(error);\n }\n trace.info('Publish to peerConnection success');\n\n return resolve();\n });\n });\n }\n\n return Promise.resolve();\n })\n .catch((error: any) => {\n //Need to handle fail cases during reliability\n trace.error('Error handling new peer connection', error);\n });\n }\n\n private connectionDestroyedHandler(event: any): void {\n trace.info('connectionDestroyedHandler', event);\n const {connection} = event;\n\n if (!this.sessionExistsGuard(false) || !connection) {\n return;\n }\n\n if (this._peerConnections.has(connection.connectionId)) {\n this.destroyPeerConnection(this._peerConnections.get(connection.connectionId)!);\n }\n }\n\n private streamCreatedHandler(event: any): void {\n trace.info('streamCreatedHandler', event.stream);\n const {stream} = event;\n const {connection} = stream || {connection: null};\n\n if (!this.sessionExistsGuard(false) || !stream) {\n return;\n }\n\n if (!this._peerConnections.has(connection.connectionId)) {\n trace.warn('Unexpected case, connection should exist on this stage');\n\n return;\n }\n\n const peerConnection = this._peerConnections.get(connection.connectionId);\n\n if (!peerConnection) {\n trace.warn('Unexpected PeerConnection not found');\n\n return;\n }\n\n //Find peerConnection by connectionId, add all tracks to remoteTracks (check if it exists before)\n //We cannot have to tracks with the same id or with the same meaning\n //Register each track using addRemoteTrack\n }\n\n private streamDestroyedHandler(event: any): void {\n trace.info('streamDestroyedHandler', event);\n const {stream} = event;\n\n if (!this.sessionExistsGuard(false) || !stream) {\n return;\n }\n\n //Find peerConnection by connectionId, add remove tracks from stream\n //Register each track using addRemoteTrack\n }\n\n //#endregion\n\n private createStreamForPublishing(destinationRole: SessionClientRole): Promise<OTStreamSource> {\n trace.info('createStreamForPublishing');\n\n return this._sessionStreamsManager.getMediaStreamForRole(destinationRole)\n .then((mediaStream: Nullable<MediaStream>) => {\n\n const stream: OTStreamSource = {videoSource: null, audioSource: null};\n\n if (mediaStream) {\n trace.info('Media stream found for publishing', mediaStream);\n mediaStream.getTracks().forEach((track) => {\n if (track.kind === 'video') {\n stream.videoSource = track;\n } else if (track.kind === 'audio') {\n stream.audioSource = track;\n }\n });\n } else if (this._sessionParams.clientRole === SessionClientRole.USER) {\n trace.warn('No local media was found for publishing to destinationRole:', destinationRole);\n }\n\n return stream;\n });\n }\n\n private calculateDestinationRole(): SessionClientRole {\n if (this._sessionParams.clientRole === SessionClientRole.USER) {\n const isAgentConnected = false;\n\n\n return !isAgentConnected ? SessionClientRole.AGENT : SessionClientRole.OBSERVER;\n }\n\n return SessionClientRole.USER;\n }\n\n private createMediaPublisher(stream: OTStreamSource, streamName: string): Promise<OTPublisher> {\n const otParams = {\n videoSource: stream.videoSource ? stream.videoSource : false,\n audioSource: stream.audioSource ? stream.audioSource : false,\n publishAudio: !!stream.audioSource,\n publishVideo: !!stream.videoSource,\n showControls: false,\n name: streamName\n };\n\n return new Promise((resolve, reject) => {\n const otPublisher = window.OT.initPublisher(undefined, otParams, (error: any) => {\n if (error) {\n reject(error);\n \n return;\n }\n resolve(otPublisher);\n });\n });\n }\n\n private clearPeerConnections(): Promise<void> {\n return Promise.resolve();\n }\n\n private sessionExistsGuard(shouldThrow = true): boolean {\n const connected = !!(this._session && this._session.connection && this._session.connection.connectionId);\n\n\n return throwableGuard(connected, 'There no active session', shouldThrow);\n }\n\n private destroyPeerConnection(peerConnection: OTPeerConnection): void {\n this._peerConnections.delete(peerConnection.peerId);\n this.destroyPublisherOnPeerConnection(peerConnection);\n peerConnection.remoteMediaTracks.forEach((mediaTrack) => {\n this._sessionStreamsManager.removeMediaTrack(mediaTrack.mediaTrack)\n .catch((error: any) => {\n trace.warn('Error removing media track', error);\n });\n });\n }\n\n private destroyPublisherOnPeerConnection(peerConnection: OTPeerConnection): void {\n if (peerConnection.publisher) {\n //TODO - Alex: When destroying the publisher, OT closes the stream by himself, without we ask him.\n //So we not destroying the OT publisher right now in order to preserve our stream alive.\n //Later, we can recreate our stream as new, or manually delete \"video\" element that created by OT.\n // or we just can leave it as is :)\n //peerConnection.publisher.destroy();\n peerConnection.publisher = null;\n peerConnection.localStream = null;\n }\n }\n\n}\n\n"]}
1
+ {"version":3,"sources":["../src/MediaSession/SessionOpentok.v3.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,yBAAyB,CAAC;AAEjD,OAAO,EACH,aAAa,EACb,sBAAsB,EACtB,kBAAkB,EAClB,gBAAgB,EACnB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAmB,iBAAiB,EAAoB,MAAM,mBAAmB,CAAC;AAEzF,OAAO,EAAC,iBAAiB,EAAE,gBAAgB,EAAC,MAAM,oBAAoB,CAAC;AAKvE,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,MAAM;QACZ,EAAE,EAAE,GAAG,CAAC;KACX;CACJ;AA6BD,aAAK,WAAW,GAAG,GAAG,CAAA;AAEtB,aAAK,YAAY,GAAG,GAAG,CAAA;AAEvB,UAAU,YAAY;IAClB,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,UAAU,gBAAiB,SAAQ,iBAAiB;IAChD,WAAW,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;IACtC,UAAU,EAAE,YAAY,CAAC;IACzB,SAAS,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;IACjC,UAAU,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;CACtC;AAED,UAAU,cAAc;IACpB,WAAW,EAAE,GAAG,CAAC;IACjB,WAAW,EAAE,GAAG,CAAC;CACpB;AAGD,qBAAa,gBAAiB,SAAQ,gBAAgB,CAAC,gBAAgB,CAAE,YAAW,aAAa;IAC7F,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAM;IAEnC,OAAO,CAAC,QAAQ,CAA8B;aAE1C,EAAE,EAAI,MAAM;qBAIJ,SAAS;gBAIT,aAAa,EAAE,kBAAkB,EAAE,aAAa,EAAE,sBAAsB;IAiBpF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAwCxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAyB3B,OAAO,CAAC,wBAAwB;IA0EhC,OAAO,CAAC,0BAA0B;IAalC,OAAO,CAAC,oBAAoB;IAwD5B,OAAO,CAAC,sBAAsB;IAsB9B,sBAAsB,CAAC,UAAU,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAUpE,oBAAoB,CAAC,UAAU,EAAE,iBAAiB,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAK5F,mBAAmB,CAAC,UAAU,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAqB5E,OAAO,CAAC,yBAAyB;IAyBjC,OAAO,CAAC,wBAAwB;IAWhC,OAAO,CAAC,oBAAoB;IAsB5B,OAAO,CAAC,qBAAqB;IAO7B,OAAO,CAAC,gCAAgC;IAYxC,OAAO,CAAC,iCAAiC;IASzC,OAAO,CAAC,kBAAkB;CAM7B","file":"SessionOpentok.v3.d.ts","sourcesContent":["import {Nullable} from '@techsee/techsee-common';\n\nimport {\n IMediaSession,\n ISessionStreamsManager,\n MediaSessionParams,\n RemoteTrackStats\n} from '../MediaContracts';\n\nimport {KnownMediaStream, SessionClientRole, SessionClientType} from '../MediaConstants';\nimport {throwableGuard} from '@techsee/techsee-common/lib/core/guards';\nimport {IMediaSessionPeer, MediaSessionBase} from './MediaSessionBase';\nimport {getMediaTracer} from '../MediaUtils/MediaTracer';\n\nconst trace = getMediaTracer('OpentokSessionV3');\n\ndeclare global {\n interface Window {\n OT: any;\n }\n}\n\ninterface IOTSession {\n\n sessionId: string;\n\n connection: Nullable<OTConnection>;\n\n isConnected(): boolean;\n\n connect(token: string, cb: any): void;\n\n disconnect(): void;\n\n publish(publisher: any, cb: any): void;\n\n subscribe(stream: any, container: any, uiProps: any, doneCb: any): OTSubscriber;\n\n unsubscribe(subscriber: OTSubscriber): void;\n\n getSubscribersForStream(stream: any): OTSubscriber[];\n\n off(): void;\n\n on(param: string, cb: any): void;\n\n once(param: string, cb: any): void;\n}\n\ntype OTPublisher = any\n\ntype OTSubscriber = any\n\ninterface OTConnection {\n connectionId: string;\n}\n\ninterface OTPeerConnection extends IMediaSessionPeer {\n localStream: Nullable<OTStreamSource>;\n connection: OTConnection;\n publisher: Nullable<OTPublisher>;\n subscriber: Nullable<OTSubscriber>;\n}\n\ninterface OTStreamSource {\n videoSource: any;\n audioSource: any;\n}\n\n//Currently this version supports subscribing only. Publishing will be implemented as needed.\nexport class OpentokSessionV3 extends MediaSessionBase<OTPeerConnection> implements IMediaSession {\n private readonly _credentials: any;\n\n private _session: Nullable<IOTSession> = null;\n\n get id(): string {\n return this._session && this._session.sessionId ? this._session.sessionId : '';\n }\n\n private get ownPeerId(): string {\n return this._session && this._session.connection ? this._session.connection.connectionId : '';\n }\n\n constructor(sessionParams: MediaSessionParams, streamFactory: ISessionStreamsManager) {\n super(sessionParams, streamFactory);\n this._credentials = sessionParams.credentials;\n\n this.connect = this.connect.bind(this);\n this.disconnect = this.disconnect.bind(this);\n this.onMediaStreamDestroyed = this.onMediaStreamDestroyed.bind(this);\n this.onMediaStreamRenewed = this.onMediaStreamRenewed.bind(this);\n\n this.createStreamForPublishing = this.createStreamForPublishing.bind(this);\n this.createMediaPublisher = this.createMediaPublisher.bind(this);\n this.connectionCreatedHandler = this.connectionCreatedHandler.bind(this);\n this.connectionDestroyedHandler = this.connectionDestroyedHandler.bind(this);\n this.streamCreatedHandler = this.streamCreatedHandler.bind(this);\n this.streamDestroyedHandler = this.streamDestroyedHandler.bind(this);\n }\n\n connect(): Promise<void> {\n trace.info('Connect to session');\n\n if (this._session) {\n trace.error('Session already exists');\n\n return Promise.reject('Cannot connect to session while another session is active');\n }\n\n return new Promise((resolve, reject) => {\n const handleError = (error: any): void => {\n this._session && this._session!.off();\n this._session = null;\n trace.error('handleConnect error:', error);\n reject(error);\n };\n\n const {apiKey, sessionId} = this._sessionParams.credentials;\n\n this._session = (window as any).OTSESSION = window.OT.initSession(apiKey, sessionId);\n\n this._session!.on('connectionCreated', this.connectionCreatedHandler);\n this._session!.on('connectionDestroyed', this.connectionDestroyedHandler);\n this._session!.on('streamCreated', this.streamCreatedHandler);\n this._session!.on('streamDestroyed', this.streamDestroyedHandler);\n\n const connectHandler = (error: any): void => {\n if (error) {\n handleError(error);\n\n return;\n }\n\n resolve();\n };\n\n this._session!.connect(this._credentials.token, connectHandler);\n });\n }\n\n disconnect(): Promise<void> {\n return new Promise((resolve) => {\n trace.info('Disconnecting from session');\n const currentSession = this._session;\n\n this._session = null;\n\n this._peerConnections.forEach((peerConnection) => {\n this.destroyPeerConnection(peerConnection);\n });\n\n if (!currentSession) {\n trace.info('No active session - resolving');\n resolve();\n\n return;\n }\n currentSession.off();\n currentSession.disconnect();\n resolve();\n });\n }\n\n //#region OpenTok Events Handlers\n\n private connectionCreatedHandler(event: any): void {\n trace.info('connectionCreatedHandler', event);\n const {connection} = event;\n\n if (!this.sessionExistsGuard(false) || !connection) {\n return;\n }\n\n //In case we got our own connection, we have nothing to do with it\n if (connection.connectionId === this.ownPeerId) {\n return;\n }\n\n const destinationRole = this.calculateDestinationRole();\n\n this.createStreamForPublishing(destinationRole)\n .then((streams: OTStreamSource) => {\n const peerConnection: OTPeerConnection = {\n peerId: connection.connectionId,\n peerRole: destinationRole,\n peerType: this._sessionParams.clientType === SessionClientType.INITIATOR\n ? SessionClientType.GUEST : SessionClientType.INITIATOR,\n connection: connection,\n publisher: null,\n subscriber: null,\n remoteMediaTracks: [],\n localStream: streams\n };\n\n if (!streams.videoSource && !streams.audioSource) {\n trace.info('Peer connection without publisher was created', peerConnection);\n\n return peerConnection;\n }\n\n const streamName = destinationRole === SessionClientRole.USER\n ? KnownMediaStream.AGENT_AUDIO_STREAM : KnownMediaStream.USER_VIDEO_STREAM;\n\n\n return this.createMediaPublisher(streams, streamName)\n .then((publisher: OTPublisher) => {\n peerConnection.publisher = publisher;\n trace.info('Peer connection with publisher was created', peerConnection);\n\n return peerConnection;\n });\n })\n .then((peerConnection: OTPeerConnection) => {\n this._peerConnections.set(peerConnection.peerId, peerConnection);\n\n if (peerConnection.publisher) {\n return new Promise<void>((resolve, reject) => {\n trace.info('Starting publish to peerConnection.publisher');\n this._session!.publish(peerConnection.publisher, (error: any) => {\n if (error) {\n trace.error('Publish to peerConnection error', error);\n\n return reject(error);\n }\n trace.info('Publish to peerConnection success');\n\n return resolve();\n });\n });\n }\n\n return Promise.resolve();\n })\n .catch((error: any) => {\n //Need to handle fail cases during reliability\n trace.error('Error handling new peer connection', error);\n });\n }\n\n private connectionDestroyedHandler(event: any): void {\n trace.info('connectionDestroyedHandler', event);\n const {connection} = event;\n\n if (!this.sessionExistsGuard(false) || !connection) {\n return;\n }\n\n if (this._peerConnections.has(connection.connectionId)) {\n this.destroyPeerConnection(this._peerConnections.get(connection.connectionId)!);\n }\n }\n\n private streamCreatedHandler(event: any): void {\n trace.info('streamCreatedHandler', event.stream);\n const {stream} = event;\n const {connection} = stream || {connection: null};\n\n if (!this.sessionExistsGuard(false) || !stream) {\n return;\n }\n\n if (!this._peerConnections.has(connection.connectionId)) {\n trace.warn('Unexpected case, connection should exist on this stage');\n\n return;\n }\n\n const peerConnection = this._peerConnections.get(connection.connectionId)!;\n\n trace.info('Subscribing the stream');\n\n //TODO - Optimize the code below\n peerConnection.subscriber = this._session!.subscribe(stream, null, null, (err: any) => {\n if (err) {\n peerConnection.subscriber = null;\n trace.warn('Error in subscriber', err);\n\n return;\n }\n\n const videoElQuery = `#${peerConnection.subscriber.id} .OT_video-element`;\n const otVideoEl = document.querySelector(videoElQuery);\n\n if (!otVideoEl) {\n trace.warn('Cannot fined OT video element');\n\n return;\n }\n\n document.getElementById(peerConnection.subscriber.id)!.style.display = 'none';\n const otMediaStream: MediaStream = (otVideoEl as any).srcObject;\n\n if (!otMediaStream) {\n trace.warn('MediaStream not found in OT video element');\n\n return;\n }\n\n trace.info('Registering remote media tracks', peerConnection.subscriber);\n otMediaStream.getTracks().forEach((mediaTrack: MediaStreamTrack) => {\n this.registerMediaTrackFromPeer(peerConnection, mediaTrack);\n });\n });\n peerConnection.subscriber.on('videoElementCreated', (args: any) => {\n trace.info('videoElementCreated - REDO', args);\n });\n }\n\n private streamDestroyedHandler(event: any): void {\n trace.info('streamDestroyedHandler', event);\n const {stream} = event;\n\n if (!this.sessionExistsGuard(false) || !stream) {\n return;\n }\n\n const peerConnection = this._peerConnections.get(stream.connection.connectionId);\n\n if (!peerConnection) {\n trace.warn('Peer connection for remote stream not found');\n\n return;\n }\n\n this.unregisterPeersRemoteMediaTracks(peerConnection);\n this.destroySubscriberOnPeerConnection(peerConnection);\n }\n\n //#endregion\n\n onMediaStreamDestroyed(clientRole: SessionClientRole): Promise<void> {\n this._peerConnections.forEach((peerConnection) => {\n if (peerConnection.peerRole === clientRole) {\n this.destroyPublisherOnPeerConnection(peerConnection);\n }\n });\n\n return Promise.resolve();\n }\n\n onMediaStreamRenewed(clientRole: SessionClientRole, mediaStream: MediaStream): Promise<void> {\n //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation (in OT API)\n return Promise.resolve();\n }\n\n getRemoteTrackStats(mediaTrack: MediaStreamTrack): Promise<RemoteTrackStats> {\n return new Promise((resolve: any, reject: any) => {\n const peerConnectionOfTrack = this.getPeerConnectionByMediaTrack(mediaTrack);\n\n if (!peerConnectionOfTrack || !peerConnectionOfTrack.subscriber) {\n reject(new Error('Cannot find peer or subscriber for getting stats'));\n }\n\n //https://tokbox.com/developer/sdks/js/reference/Subscriber.html#getStats\n peerConnectionOfTrack!.subscriber.getStats((error: any, stats: any) => {\n if (error) {\n trace.warn('Error getting stats', error);\n resolve({trackId: mediaTrack.id, trackStats: {}});\n\n return;\n }\n resolve({trackId: mediaTrack.id, trackStats: stats});\n });\n });\n }\n\n private createStreamForPublishing(destinationRole: SessionClientRole): Promise<OTStreamSource> {\n trace.info('createStreamForPublishing');\n\n return this._sessionStreamsManager.getMediaStreamForRole(destinationRole)\n .then((mediaStream: Nullable<MediaStream>) => {\n\n const stream: OTStreamSource = {videoSource: null, audioSource: null};\n\n if (mediaStream) {\n trace.info('Media stream found for publishing', mediaStream);\n mediaStream.getTracks().forEach((track) => {\n if (track.kind === 'video') {\n stream.videoSource = track;\n } else if (track.kind === 'audio') {\n stream.audioSource = track;\n }\n });\n } else if (this._sessionParams.clientRole === SessionClientRole.USER) {\n trace.warn('No local media was found for publishing to destinationRole:', destinationRole);\n }\n\n return stream;\n });\n }\n\n private calculateDestinationRole(): SessionClientRole {\n if (this._sessionParams.clientRole === SessionClientRole.USER) {\n const isAgentConnected = false;\n\n\n return !isAgentConnected ? SessionClientRole.AGENT : SessionClientRole.OBSERVER;\n }\n\n return SessionClientRole.USER;\n }\n\n private createMediaPublisher(stream: OTStreamSource, streamName: string): Promise<OTPublisher> {\n const otParams = {\n videoSource: stream.videoSource ? stream.videoSource : false,\n audioSource: stream.audioSource ? stream.audioSource : false,\n publishAudio: !!stream.audioSource,\n publishVideo: !!stream.videoSource,\n showControls: false,\n name: streamName\n };\n\n return new Promise((resolve, reject) => {\n const otPublisher = window.OT.initPublisher(undefined, otParams, (error: any) => {\n if (error) {\n reject(error);\n\n return;\n }\n resolve(otPublisher);\n });\n });\n }\n\n private destroyPeerConnection(peerConnection: OTPeerConnection): void {\n this._peerConnections.delete(peerConnection.peerId);\n this.destroyPublisherOnPeerConnection(peerConnection);\n this.unregisterPeersRemoteMediaTracks(peerConnection);\n this.destroySubscriberOnPeerConnection(peerConnection);\n }\n\n private destroyPublisherOnPeerConnection(peerConnection: OTPeerConnection): void {\n if (peerConnection.publisher) {\n //TODO - Alex: When destroying the publisher, OT closes the stream by himself, without we ask him.\n //So we not destroying the OT publisher right now in order to preserve our stream alive.\n //Later, we can recreate our stream as new, or manually delete \"video\" element that created by OT.\n // or we just can leave it as is :)\n //peerConnection.publisher.destroy();\n peerConnection.publisher = null;\n peerConnection.localStream = null;\n }\n }\n\n private destroySubscriberOnPeerConnection(peerConnection: OTPeerConnection): void {\n if (!this.sessionExistsGuard(false) || peerConnection.subscriber) {\n return;\n }\n\n this._session!.unsubscribe(peerConnection.subscriber);\n peerConnection.subscriber = null;\n }\n\n private sessionExistsGuard(shouldThrow = true): boolean {\n const connected = !!(this._session && this._session.connection && this._session.connection.connectionId);\n\n\n return throwableGuard(connected, 'There no active session', shouldThrow);\n }\n}\n\n"]}
@@ -1,29 +1,48 @@
1
1
  "use strict";
2
2
 
3
+ var __extends = undefined && undefined.__extends || function () {
4
+ var _extendStatics = function extendStatics(d, b) {
5
+ _extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function (d, b) {
6
+ d.__proto__ = b;
7
+ } || function (d, b) {
8
+ for (var p in b) {
9
+ if (b.hasOwnProperty(p)) d[p] = b[p];
10
+ }
11
+ };
12
+ return _extendStatics(d, b);
13
+ };
14
+ return function (d, b) {
15
+ _extendStatics(d, b);
16
+ function __() {
17
+ this.constructor = d;
18
+ }
19
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
20
+ };
21
+ }();
3
22
  Object.defineProperty(exports, "__esModule", { value: true });
4
23
  var MediaConstants_1 = require("../MediaConstants");
5
- var MediaTracer_1 = require("../MediaUtils/MediaTracer");
6
24
  var guards_1 = require("@techsee/techsee-common/lib/core/guards");
7
- var trace = MediaTracer_1.getMediaTracer('OpenTokSession');
25
+ var MediaSessionBase_1 = require("./MediaSessionBase");
26
+ var MediaTracer_1 = require("../MediaUtils/MediaTracer");
27
+ var trace = MediaTracer_1.getMediaTracer('OpentokSessionV3');
8
28
  //Currently this version supports subscribing only. Publishing will be implemented as needed.
9
- var OpentokSessionV3 = /** @class */function () {
29
+ var OpentokSessionV3 = /** @class */function (_super) {
30
+ __extends(OpentokSessionV3, _super);
10
31
  function OpentokSessionV3(sessionParams, streamFactory) {
11
- this._peerConnections = new Map();
12
- this._session = null;
13
- this._sessionParams = sessionParams;
14
- this._sessionStreamsManager = streamFactory;
15
- this._credentials = sessionParams.credentials;
16
- this.connect = this.connect.bind(this);
17
- this.disconnect = this.disconnect.bind(this);
18
- this.onMediaStreamDestroyed = this.onMediaStreamDestroyed.bind(this);
19
- this.onMediaStreamRenewed = this.onMediaStreamRenewed.bind(this);
20
- this.createStreamForPublishing = this.createStreamForPublishing.bind(this);
21
- this.createMediaPublisher = this.createMediaPublisher.bind(this);
22
- this.clearPeerConnections = this.clearPeerConnections.bind(this);
23
- this.connectionCreatedHandler = this.connectionCreatedHandler.bind(this);
24
- this.connectionDestroyedHandler = this.connectionDestroyedHandler.bind(this);
25
- this.streamCreatedHandler = this.streamCreatedHandler.bind(this);
26
- this.streamDestroyedHandler = this.streamDestroyedHandler.bind(this);
32
+ var _this = _super.call(this, sessionParams, streamFactory) || this;
33
+ _this._session = null;
34
+ _this._credentials = sessionParams.credentials;
35
+ _this.connect = _this.connect.bind(_this);
36
+ _this.disconnect = _this.disconnect.bind(_this);
37
+ _this.onMediaStreamDestroyed = _this.onMediaStreamDestroyed.bind(_this);
38
+ _this.onMediaStreamRenewed = _this.onMediaStreamRenewed.bind(_this);
39
+ _this.createStreamForPublishing = _this.createStreamForPublishing.bind(_this);
40
+ _this.createMediaPublisher = _this.createMediaPublisher.bind(_this);
41
+ _this.connectionCreatedHandler = _this.connectionCreatedHandler.bind(_this);
42
+ _this.connectionDestroyedHandler = _this.connectionDestroyedHandler.bind(_this);
43
+ _this.streamCreatedHandler = _this.streamCreatedHandler.bind(_this);
44
+ _this.streamDestroyedHandler = _this.streamDestroyedHandler.bind(_this);
45
+ return _this;
27
46
  }
28
47
  Object.defineProperty(OpentokSessionV3.prototype, "id", {
29
48
  get: function get() {
@@ -73,9 +92,8 @@ var OpentokSessionV3 = /** @class */function () {
73
92
  };
74
93
  OpentokSessionV3.prototype.disconnect = function () {
75
94
  var _this = this;
76
- //TODO - Alex: Implement destroying all publishers (by opentok docs)
77
- //Create a method destroy publisher (or publishers can treated the same as "peerConnections"?
78
95
  return new Promise(function (resolve) {
96
+ trace.info('Disconnecting from session');
79
97
  var currentSession = _this._session;
80
98
  _this._session = null;
81
99
  _this._peerConnections.forEach(function (peerConnection) {
@@ -91,23 +109,6 @@ var OpentokSessionV3 = /** @class */function () {
91
109
  resolve();
92
110
  });
93
111
  };
94
- OpentokSessionV3.prototype.onMediaStreamDestroyed = function (clientRole) {
95
- var _this = this;
96
- this._peerConnections.forEach(function (peerConnection) {
97
- if (peerConnection.peerRole === clientRole) {
98
- _this.destroyPublisherOnPeerConnection(peerConnection);
99
- }
100
- });
101
- return Promise.resolve();
102
- };
103
- OpentokSessionV3.prototype.onMediaStreamRenewed = function (clientRole, mediaStream) {
104
- //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation (in OT API)
105
- return Promise.resolve();
106
- };
107
- OpentokSessionV3.prototype.getRemoteTrackStats = function (mediaTrack) {
108
- //https://tokbox.com/developer/sdks/js/reference/Subscriber.html (getStats)
109
- return Promise.reject(new Error('Not implemented yet'));
110
- };
111
112
  //#region OpenTok Events Handlers
112
113
  OpentokSessionV3.prototype.connectionCreatedHandler = function (event) {
113
114
  var _this = this;
@@ -128,6 +129,7 @@ var OpentokSessionV3 = /** @class */function () {
128
129
  peerType: _this._sessionParams.clientType === MediaConstants_1.SessionClientType.INITIATOR ? MediaConstants_1.SessionClientType.GUEST : MediaConstants_1.SessionClientType.INITIATOR,
129
130
  connection: connection,
130
131
  publisher: null,
132
+ subscriber: null,
131
133
  remoteMediaTracks: [],
132
134
  localStream: streams
133
135
  };
@@ -173,6 +175,7 @@ var OpentokSessionV3 = /** @class */function () {
173
175
  }
174
176
  };
175
177
  OpentokSessionV3.prototype.streamCreatedHandler = function (event) {
178
+ var _this = this;
176
179
  trace.info('streamCreatedHandler', event.stream);
177
180
  var stream = event.stream;
178
181
  var connection = (stream || { connection: null }).connection;
@@ -184,13 +187,34 @@ var OpentokSessionV3 = /** @class */function () {
184
187
  return;
185
188
  }
186
189
  var peerConnection = this._peerConnections.get(connection.connectionId);
187
- if (!peerConnection) {
188
- trace.warn('Unexpected PeerConnection not found');
189
- return;
190
- }
191
- //Find peerConnection by connectionId, add all tracks to remoteTracks (check if it exists before)
192
- //We cannot have to tracks with the same id or with the same meaning
193
- //Register each track using addRemoteTrack
190
+ trace.info('Subscribing the stream');
191
+ //TODO - Optimize the code below
192
+ peerConnection.subscriber = this._session.subscribe(stream, null, null, function (err) {
193
+ if (err) {
194
+ peerConnection.subscriber = null;
195
+ trace.warn('Error in subscriber', err);
196
+ return;
197
+ }
198
+ var videoElQuery = "#" + peerConnection.subscriber.id + " .OT_video-element";
199
+ var otVideoEl = document.querySelector(videoElQuery);
200
+ if (!otVideoEl) {
201
+ trace.warn('Cannot fined OT video element');
202
+ return;
203
+ }
204
+ document.getElementById(peerConnection.subscriber.id).style.display = 'none';
205
+ var otMediaStream = otVideoEl.srcObject;
206
+ if (!otMediaStream) {
207
+ trace.warn('MediaStream not found in OT video element');
208
+ return;
209
+ }
210
+ trace.info('Registering remote media tracks', peerConnection.subscriber);
211
+ otMediaStream.getTracks().forEach(function (mediaTrack) {
212
+ _this.registerMediaTrackFromPeer(peerConnection, mediaTrack);
213
+ });
214
+ });
215
+ peerConnection.subscriber.on('videoElementCreated', function (args) {
216
+ trace.info('videoElementCreated - REDO', args);
217
+ });
194
218
  };
195
219
  OpentokSessionV3.prototype.streamDestroyedHandler = function (event) {
196
220
  trace.info('streamDestroyedHandler', event);
@@ -198,10 +222,46 @@ var OpentokSessionV3 = /** @class */function () {
198
222
  if (!this.sessionExistsGuard(false) || !stream) {
199
223
  return;
200
224
  }
201
- //Find peerConnection by connectionId, add remove tracks from stream
202
- //Register each track using addRemoteTrack
225
+ var peerConnection = this._peerConnections.get(stream.connection.connectionId);
226
+ if (!peerConnection) {
227
+ trace.warn('Peer connection for remote stream not found');
228
+ return;
229
+ }
230
+ this.unregisterPeersRemoteMediaTracks(peerConnection);
231
+ this.destroySubscriberOnPeerConnection(peerConnection);
203
232
  };
204
233
  //#endregion
234
+ OpentokSessionV3.prototype.onMediaStreamDestroyed = function (clientRole) {
235
+ var _this = this;
236
+ this._peerConnections.forEach(function (peerConnection) {
237
+ if (peerConnection.peerRole === clientRole) {
238
+ _this.destroyPublisherOnPeerConnection(peerConnection);
239
+ }
240
+ });
241
+ return Promise.resolve();
242
+ };
243
+ OpentokSessionV3.prototype.onMediaStreamRenewed = function (clientRole, mediaStream) {
244
+ //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation (in OT API)
245
+ return Promise.resolve();
246
+ };
247
+ OpentokSessionV3.prototype.getRemoteTrackStats = function (mediaTrack) {
248
+ var _this = this;
249
+ return new Promise(function (resolve, reject) {
250
+ var peerConnectionOfTrack = _this.getPeerConnectionByMediaTrack(mediaTrack);
251
+ if (!peerConnectionOfTrack || !peerConnectionOfTrack.subscriber) {
252
+ reject(new Error('Cannot find peer or subscriber for getting stats'));
253
+ }
254
+ //https://tokbox.com/developer/sdks/js/reference/Subscriber.html#getStats
255
+ peerConnectionOfTrack.subscriber.getStats(function (error, stats) {
256
+ if (error) {
257
+ trace.warn('Error getting stats', error);
258
+ resolve({ trackId: mediaTrack.id, trackStats: {} });
259
+ return;
260
+ }
261
+ resolve({ trackId: mediaTrack.id, trackStats: stats });
262
+ });
263
+ });
264
+ };
205
265
  OpentokSessionV3.prototype.createStreamForPublishing = function (destinationRole) {
206
266
  var _this = this;
207
267
  trace.info('createStreamForPublishing');
@@ -248,25 +308,11 @@ var OpentokSessionV3 = /** @class */function () {
248
308
  });
249
309
  });
250
310
  };
251
- OpentokSessionV3.prototype.clearPeerConnections = function () {
252
- return Promise.resolve();
253
- };
254
- OpentokSessionV3.prototype.sessionExistsGuard = function (shouldThrow) {
255
- if (shouldThrow === void 0) {
256
- shouldThrow = true;
257
- }
258
- var connected = !!(this._session && this._session.connection && this._session.connection.connectionId);
259
- return guards_1.throwableGuard(connected, 'There no active session', shouldThrow);
260
- };
261
311
  OpentokSessionV3.prototype.destroyPeerConnection = function (peerConnection) {
262
- var _this = this;
263
312
  this._peerConnections.delete(peerConnection.peerId);
264
313
  this.destroyPublisherOnPeerConnection(peerConnection);
265
- peerConnection.remoteMediaTracks.forEach(function (mediaTrack) {
266
- _this._sessionStreamsManager.removeMediaTrack(mediaTrack.mediaTrack).catch(function (error) {
267
- trace.warn('Error removing media track', error);
268
- });
269
- });
314
+ this.unregisterPeersRemoteMediaTracks(peerConnection);
315
+ this.destroySubscriberOnPeerConnection(peerConnection);
270
316
  };
271
317
  OpentokSessionV3.prototype.destroyPublisherOnPeerConnection = function (peerConnection) {
272
318
  if (peerConnection.publisher) {
@@ -279,8 +325,22 @@ var OpentokSessionV3 = /** @class */function () {
279
325
  peerConnection.localStream = null;
280
326
  }
281
327
  };
328
+ OpentokSessionV3.prototype.destroySubscriberOnPeerConnection = function (peerConnection) {
329
+ if (!this.sessionExistsGuard(false) || peerConnection.subscriber) {
330
+ return;
331
+ }
332
+ this._session.unsubscribe(peerConnection.subscriber);
333
+ peerConnection.subscriber = null;
334
+ };
335
+ OpentokSessionV3.prototype.sessionExistsGuard = function (shouldThrow) {
336
+ if (shouldThrow === void 0) {
337
+ shouldThrow = true;
338
+ }
339
+ var connected = !!(this._session && this._session.connection && this._session.connection.connectionId);
340
+ return guards_1.throwableGuard(connected, 'There no active session', shouldThrow);
341
+ };
282
342
  return OpentokSessionV3;
283
- }();
343
+ }(MediaSessionBase_1.MediaSessionBase);
284
344
  exports.OpentokSessionV3 = OpentokSessionV3;
285
345
 
286
346
  //# sourceMappingURL=SessionOpentok.v3.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["MediaSession/SessionOpentok.v3.js"],"names":["Object","defineProperty","exports","value","MediaConstants_1","require","MediaTracer_1","guards_1","trace","getMediaTracer","OpentokSessionV3","sessionParams","streamFactory","_peerConnections","Map","_session","_sessionParams","_sessionStreamsManager","_credentials","credentials","connect","bind","disconnect","onMediaStreamDestroyed","onMediaStreamRenewed","createStreamForPublishing","createMediaPublisher","clearPeerConnections","connectionCreatedHandler","connectionDestroyedHandler","streamCreatedHandler","streamDestroyedHandler","prototype","get","sessionId","enumerable","configurable","connection","connectionId","_this","info","error","Promise","reject","resolve","handleError","off","_a","apiKey","window","OTSESSION","OT","initSession","on","connectHandler","token","currentSession","forEach","peerConnection","destroyPeerConnection","clientRole","peerRole","destroyPublisherOnPeerConnection","mediaStream","getRemoteTrackStats","mediaTrack","Error","event","sessionExistsGuard","ownPeerId","destinationRole","calculateDestinationRole","then","streams","peerId","peerType","clientType","SessionClientType","INITIATOR","GUEST","publisher","remoteMediaTracks","localStream","videoSource","audioSource","streamName","SessionClientRole","USER","KnownMediaStream","AGENT_AUDIO_STREAM","USER_VIDEO_STREAM","set","publish","catch","has","stream","warn","getMediaStreamForRole","getTracks","track","kind","isAgentConnected","AGENT","OBSERVER","otParams","publishAudio","publishVideo","showControls","name","otPublisher","initPublisher","undefined","shouldThrow","connected","throwableGuard","delete","removeMediaTrack"],"mappings":"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","file":"SessionOpentok.v3.js","sourcesContent":["\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar MediaConstants_1 = require(\"../MediaConstants\");\nvar MediaTracer_1 = require(\"../MediaUtils/MediaTracer\");\nvar guards_1 = require(\"@techsee/techsee-common/lib/core/guards\");\nvar trace = MediaTracer_1.getMediaTracer('OpenTokSession');\n//Currently this version supports subscribing only. Publishing will be implemented as needed.\nvar OpentokSessionV3 = /** @class */ (function () {\n function OpentokSessionV3(sessionParams, streamFactory) {\n this._peerConnections = new Map();\n this._session = null;\n this._sessionParams = sessionParams;\n this._sessionStreamsManager = streamFactory;\n this._credentials = sessionParams.credentials;\n this.connect = this.connect.bind(this);\n this.disconnect = this.disconnect.bind(this);\n this.onMediaStreamDestroyed = this.onMediaStreamDestroyed.bind(this);\n this.onMediaStreamRenewed = this.onMediaStreamRenewed.bind(this);\n this.createStreamForPublishing = this.createStreamForPublishing.bind(this);\n this.createMediaPublisher = this.createMediaPublisher.bind(this);\n this.clearPeerConnections = this.clearPeerConnections.bind(this);\n this.connectionCreatedHandler = this.connectionCreatedHandler.bind(this);\n this.connectionDestroyedHandler = this.connectionDestroyedHandler.bind(this);\n this.streamCreatedHandler = this.streamCreatedHandler.bind(this);\n this.streamDestroyedHandler = this.streamDestroyedHandler.bind(this);\n }\n Object.defineProperty(OpentokSessionV3.prototype, \"id\", {\n get: function () {\n return this._session && this._session.sessionId ? this._session.sessionId : '';\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(OpentokSessionV3.prototype, \"ownPeerId\", {\n get: function () {\n return this._session && this._session.connection ? this._session.connection.connectionId : '';\n },\n enumerable: true,\n configurable: true\n });\n OpentokSessionV3.prototype.connect = function () {\n var _this = this;\n trace.info('Connect to session');\n if (this._session) {\n trace.error('Session already exists');\n return Promise.reject('Cannot connect to session while another session is active');\n }\n return new Promise(function (resolve, reject) {\n var handleError = function (error) {\n _this._session && _this._session.off();\n _this._session = null;\n trace.error('handleConnect error:', error);\n reject(error);\n };\n var _a = _this._sessionParams.credentials, apiKey = _a.apiKey, sessionId = _a.sessionId;\n _this._session = window.OTSESSION = window.OT.initSession(apiKey, sessionId);\n _this._session.on('connectionCreated', _this.connectionCreatedHandler);\n _this._session.on('connectionDestroyed', _this.connectionDestroyedHandler);\n _this._session.on('streamCreated', _this.streamCreatedHandler);\n _this._session.on('streamDestroyed', _this.streamDestroyedHandler);\n var connectHandler = function (error) {\n if (error) {\n handleError(error);\n return;\n }\n resolve();\n };\n _this._session.connect(_this._credentials.token, connectHandler);\n });\n };\n OpentokSessionV3.prototype.disconnect = function () {\n var _this = this;\n //TODO - Alex: Implement destroying all publishers (by opentok docs)\n //Create a method destroy publisher (or publishers can treated the same as \"peerConnections\"?\n return new Promise(function (resolve) {\n var currentSession = _this._session;\n _this._session = null;\n _this._peerConnections.forEach(function (peerConnection) {\n _this.destroyPeerConnection(peerConnection);\n });\n if (!currentSession) {\n trace.info('No active session - resolving');\n resolve();\n return;\n }\n currentSession.off();\n currentSession.disconnect();\n resolve();\n });\n };\n OpentokSessionV3.prototype.onMediaStreamDestroyed = function (clientRole) {\n var _this = this;\n this._peerConnections.forEach(function (peerConnection) {\n if (peerConnection.peerRole === clientRole) {\n _this.destroyPublisherOnPeerConnection(peerConnection);\n }\n });\n return Promise.resolve();\n };\n OpentokSessionV3.prototype.onMediaStreamRenewed = function (clientRole, mediaStream) {\n //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation (in OT API)\n return Promise.resolve();\n };\n OpentokSessionV3.prototype.getRemoteTrackStats = function (mediaTrack) {\n //https://tokbox.com/developer/sdks/js/reference/Subscriber.html (getStats)\n return Promise.reject(new Error('Not implemented yet'));\n };\n //#region OpenTok Events Handlers\n OpentokSessionV3.prototype.connectionCreatedHandler = function (event) {\n var _this = this;\n trace.info('connectionCreatedHandler', event);\n var connection = event.connection;\n if (!this.sessionExistsGuard(false) || !connection) {\n return;\n }\n //In case we got our own connection, we have nothing to do with it\n if (connection.connectionId === this.ownPeerId) {\n return;\n }\n var destinationRole = this.calculateDestinationRole();\n this.createStreamForPublishing(destinationRole)\n .then(function (streams) {\n var peerConnection = {\n peerId: connection.connectionId,\n peerRole: destinationRole,\n peerType: _this._sessionParams.clientType === MediaConstants_1.SessionClientType.INITIATOR\n ? MediaConstants_1.SessionClientType.GUEST : MediaConstants_1.SessionClientType.INITIATOR,\n connection: connection,\n publisher: null,\n remoteMediaTracks: [],\n localStream: streams\n };\n if (!streams.videoSource && !streams.audioSource) {\n trace.info('Peer connection without publisher was created', peerConnection);\n return peerConnection;\n }\n var streamName = destinationRole === MediaConstants_1.SessionClientRole.USER\n ? MediaConstants_1.KnownMediaStream.AGENT_AUDIO_STREAM : MediaConstants_1.KnownMediaStream.USER_VIDEO_STREAM;\n return _this.createMediaPublisher(streams, streamName)\n .then(function (publisher) {\n peerConnection.publisher = publisher;\n trace.info('Peer connection with publisher was created', peerConnection);\n return peerConnection;\n });\n })\n .then(function (peerConnection) {\n _this._peerConnections.set(peerConnection.peerId, peerConnection);\n if (peerConnection.publisher) {\n return new Promise(function (resolve, reject) {\n trace.info('Starting publish to peerConnection.publisher');\n _this._session.publish(peerConnection.publisher, function (error) {\n if (error) {\n trace.error('Publish to peerConnection error', error);\n return reject(error);\n }\n trace.info('Publish to peerConnection success');\n return resolve();\n });\n });\n }\n return Promise.resolve();\n })\n .catch(function (error) {\n //Need to handle fail cases during reliability\n trace.error('Error handling new peer connection', error);\n });\n };\n OpentokSessionV3.prototype.connectionDestroyedHandler = function (event) {\n trace.info('connectionDestroyedHandler', event);\n var connection = event.connection;\n if (!this.sessionExistsGuard(false) || !connection) {\n return;\n }\n if (this._peerConnections.has(connection.connectionId)) {\n this.destroyPeerConnection(this._peerConnections.get(connection.connectionId));\n }\n };\n OpentokSessionV3.prototype.streamCreatedHandler = function (event) {\n trace.info('streamCreatedHandler', event.stream);\n var stream = event.stream;\n var connection = (stream || { connection: null }).connection;\n if (!this.sessionExistsGuard(false) || !stream) {\n return;\n }\n if (!this._peerConnections.has(connection.connectionId)) {\n trace.warn('Unexpected case, connection should exist on this stage');\n return;\n }\n var peerConnection = this._peerConnections.get(connection.connectionId);\n if (!peerConnection) {\n trace.warn('Unexpected PeerConnection not found');\n return;\n }\n //Find peerConnection by connectionId, add all tracks to remoteTracks (check if it exists before)\n //We cannot have to tracks with the same id or with the same meaning\n //Register each track using addRemoteTrack\n };\n OpentokSessionV3.prototype.streamDestroyedHandler = function (event) {\n trace.info('streamDestroyedHandler', event);\n var stream = event.stream;\n if (!this.sessionExistsGuard(false) || !stream) {\n return;\n }\n //Find peerConnection by connectionId, add remove tracks from stream\n //Register each track using addRemoteTrack\n };\n //#endregion\n OpentokSessionV3.prototype.createStreamForPublishing = function (destinationRole) {\n var _this = this;\n trace.info('createStreamForPublishing');\n return this._sessionStreamsManager.getMediaStreamForRole(destinationRole)\n .then(function (mediaStream) {\n var stream = { videoSource: null, audioSource: null };\n if (mediaStream) {\n trace.info('Media stream found for publishing', mediaStream);\n mediaStream.getTracks().forEach(function (track) {\n if (track.kind === 'video') {\n stream.videoSource = track;\n }\n else if (track.kind === 'audio') {\n stream.audioSource = track;\n }\n });\n }\n else if (_this._sessionParams.clientRole === MediaConstants_1.SessionClientRole.USER) {\n trace.warn('No local media was found for publishing to destinationRole:', destinationRole);\n }\n return stream;\n });\n };\n OpentokSessionV3.prototype.calculateDestinationRole = function () {\n if (this._sessionParams.clientRole === MediaConstants_1.SessionClientRole.USER) {\n var isAgentConnected = false;\n return !isAgentConnected ? MediaConstants_1.SessionClientRole.AGENT : MediaConstants_1.SessionClientRole.OBSERVER;\n }\n return MediaConstants_1.SessionClientRole.USER;\n };\n OpentokSessionV3.prototype.createMediaPublisher = function (stream, streamName) {\n var otParams = {\n videoSource: stream.videoSource ? stream.videoSource : false,\n audioSource: stream.audioSource ? stream.audioSource : false,\n publishAudio: !!stream.audioSource,\n publishVideo: !!stream.videoSource,\n showControls: false,\n name: streamName\n };\n return new Promise(function (resolve, reject) {\n var otPublisher = window.OT.initPublisher(undefined, otParams, function (error) {\n if (error) {\n reject(error);\n return;\n }\n resolve(otPublisher);\n });\n });\n };\n OpentokSessionV3.prototype.clearPeerConnections = function () {\n return Promise.resolve();\n };\n OpentokSessionV3.prototype.sessionExistsGuard = function (shouldThrow) {\n if (shouldThrow === void 0) { shouldThrow = true; }\n var connected = !!(this._session && this._session.connection && this._session.connection.connectionId);\n return guards_1.throwableGuard(connected, 'There no active session', shouldThrow);\n };\n OpentokSessionV3.prototype.destroyPeerConnection = function (peerConnection) {\n var _this = this;\n this._peerConnections.delete(peerConnection.peerId);\n this.destroyPublisherOnPeerConnection(peerConnection);\n peerConnection.remoteMediaTracks.forEach(function (mediaTrack) {\n _this._sessionStreamsManager.removeMediaTrack(mediaTrack.mediaTrack)\n .catch(function (error) {\n trace.warn('Error removing media track', error);\n });\n });\n };\n OpentokSessionV3.prototype.destroyPublisherOnPeerConnection = function (peerConnection) {\n if (peerConnection.publisher) {\n //TODO - Alex: When destroying the publisher, OT closes the stream by himself, without we ask him.\n //So we not destroying the OT publisher right now in order to preserve our stream alive.\n //Later, we can recreate our stream as new, or manually delete \"video\" element that created by OT.\n // or we just can leave it as is :)\n //peerConnection.publisher.destroy();\n peerConnection.publisher = null;\n peerConnection.localStream = null;\n }\n };\n return OpentokSessionV3;\n}());\nexports.OpentokSessionV3 = OpentokSessionV3;\n\n//# sourceMappingURL=SessionOpentok.v3.js.map\n"]}
1
+ {"version":3,"sources":["MediaSession/SessionOpentok.v3.js"],"names":["__extends","extendStatics","d","b","Object","setPrototypeOf","__proto__","Array","p","hasOwnProperty","__","constructor","prototype","create","defineProperty","exports","value","MediaConstants_1","require","guards_1","MediaSessionBase_1","MediaTracer_1","trace","getMediaTracer","OpentokSessionV3","_super","sessionParams","streamFactory","_this","call","_session","_credentials","credentials","connect","bind","disconnect","onMediaStreamDestroyed","onMediaStreamRenewed","createStreamForPublishing","createMediaPublisher","connectionCreatedHandler","connectionDestroyedHandler","streamCreatedHandler","streamDestroyedHandler","get","sessionId","enumerable","configurable","connection","connectionId","info","error","Promise","reject","resolve","handleError","off","_a","_sessionParams","apiKey","window","OTSESSION","OT","initSession","on","connectHandler","token","currentSession","_peerConnections","forEach","peerConnection","destroyPeerConnection","event","sessionExistsGuard","ownPeerId","destinationRole","calculateDestinationRole","then","streams","peerId","peerRole","peerType","clientType","SessionClientType","INITIATOR","GUEST","publisher","subscriber","remoteMediaTracks","localStream","videoSource","audioSource","streamName","SessionClientRole","USER","KnownMediaStream","AGENT_AUDIO_STREAM","USER_VIDEO_STREAM","set","publish","catch","has","stream","warn","subscribe","err","videoElQuery","id","otVideoEl","document","querySelector","getElementById","style","display","otMediaStream","srcObject","getTracks","mediaTrack","registerMediaTrackFromPeer","args","unregisterPeersRemoteMediaTracks","destroySubscriberOnPeerConnection","clientRole","destroyPublisherOnPeerConnection","mediaStream","getRemoteTrackStats","peerConnectionOfTrack","getPeerConnectionByMediaTrack","Error","getStats","stats","trackId","trackStats","_sessionStreamsManager","getMediaStreamForRole","track","kind","isAgentConnected","AGENT","OBSERVER","otParams","publishAudio","publishVideo","showControls","name","otPublisher","initPublisher","undefined","delete","unsubscribe","shouldThrow","connected","throwableGuard","MediaSessionBase"],"mappings":"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","file":"SessionOpentok.v3.js","sourcesContent":["\"use strict\";\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar MediaConstants_1 = require(\"../MediaConstants\");\nvar guards_1 = require(\"@techsee/techsee-common/lib/core/guards\");\nvar MediaSessionBase_1 = require(\"./MediaSessionBase\");\nvar MediaTracer_1 = require(\"../MediaUtils/MediaTracer\");\nvar trace = MediaTracer_1.getMediaTracer('OpentokSessionV3');\n//Currently this version supports subscribing only. Publishing will be implemented as needed.\nvar OpentokSessionV3 = /** @class */ (function (_super) {\n __extends(OpentokSessionV3, _super);\n function OpentokSessionV3(sessionParams, streamFactory) {\n var _this = _super.call(this, sessionParams, streamFactory) || this;\n _this._session = null;\n _this._credentials = sessionParams.credentials;\n _this.connect = _this.connect.bind(_this);\n _this.disconnect = _this.disconnect.bind(_this);\n _this.onMediaStreamDestroyed = _this.onMediaStreamDestroyed.bind(_this);\n _this.onMediaStreamRenewed = _this.onMediaStreamRenewed.bind(_this);\n _this.createStreamForPublishing = _this.createStreamForPublishing.bind(_this);\n _this.createMediaPublisher = _this.createMediaPublisher.bind(_this);\n _this.connectionCreatedHandler = _this.connectionCreatedHandler.bind(_this);\n _this.connectionDestroyedHandler = _this.connectionDestroyedHandler.bind(_this);\n _this.streamCreatedHandler = _this.streamCreatedHandler.bind(_this);\n _this.streamDestroyedHandler = _this.streamDestroyedHandler.bind(_this);\n return _this;\n }\n Object.defineProperty(OpentokSessionV3.prototype, \"id\", {\n get: function () {\n return this._session && this._session.sessionId ? this._session.sessionId : '';\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(OpentokSessionV3.prototype, \"ownPeerId\", {\n get: function () {\n return this._session && this._session.connection ? this._session.connection.connectionId : '';\n },\n enumerable: true,\n configurable: true\n });\n OpentokSessionV3.prototype.connect = function () {\n var _this = this;\n trace.info('Connect to session');\n if (this._session) {\n trace.error('Session already exists');\n return Promise.reject('Cannot connect to session while another session is active');\n }\n return new Promise(function (resolve, reject) {\n var handleError = function (error) {\n _this._session && _this._session.off();\n _this._session = null;\n trace.error('handleConnect error:', error);\n reject(error);\n };\n var _a = _this._sessionParams.credentials, apiKey = _a.apiKey, sessionId = _a.sessionId;\n _this._session = window.OTSESSION = window.OT.initSession(apiKey, sessionId);\n _this._session.on('connectionCreated', _this.connectionCreatedHandler);\n _this._session.on('connectionDestroyed', _this.connectionDestroyedHandler);\n _this._session.on('streamCreated', _this.streamCreatedHandler);\n _this._session.on('streamDestroyed', _this.streamDestroyedHandler);\n var connectHandler = function (error) {\n if (error) {\n handleError(error);\n return;\n }\n resolve();\n };\n _this._session.connect(_this._credentials.token, connectHandler);\n });\n };\n OpentokSessionV3.prototype.disconnect = function () {\n var _this = this;\n return new Promise(function (resolve) {\n trace.info('Disconnecting from session');\n var currentSession = _this._session;\n _this._session = null;\n _this._peerConnections.forEach(function (peerConnection) {\n _this.destroyPeerConnection(peerConnection);\n });\n if (!currentSession) {\n trace.info('No active session - resolving');\n resolve();\n return;\n }\n currentSession.off();\n currentSession.disconnect();\n resolve();\n });\n };\n //#region OpenTok Events Handlers\n OpentokSessionV3.prototype.connectionCreatedHandler = function (event) {\n var _this = this;\n trace.info('connectionCreatedHandler', event);\n var connection = event.connection;\n if (!this.sessionExistsGuard(false) || !connection) {\n return;\n }\n //In case we got our own connection, we have nothing to do with it\n if (connection.connectionId === this.ownPeerId) {\n return;\n }\n var destinationRole = this.calculateDestinationRole();\n this.createStreamForPublishing(destinationRole)\n .then(function (streams) {\n var peerConnection = {\n peerId: connection.connectionId,\n peerRole: destinationRole,\n peerType: _this._sessionParams.clientType === MediaConstants_1.SessionClientType.INITIATOR\n ? MediaConstants_1.SessionClientType.GUEST : MediaConstants_1.SessionClientType.INITIATOR,\n connection: connection,\n publisher: null,\n subscriber: null,\n remoteMediaTracks: [],\n localStream: streams\n };\n if (!streams.videoSource && !streams.audioSource) {\n trace.info('Peer connection without publisher was created', peerConnection);\n return peerConnection;\n }\n var streamName = destinationRole === MediaConstants_1.SessionClientRole.USER\n ? MediaConstants_1.KnownMediaStream.AGENT_AUDIO_STREAM : MediaConstants_1.KnownMediaStream.USER_VIDEO_STREAM;\n return _this.createMediaPublisher(streams, streamName)\n .then(function (publisher) {\n peerConnection.publisher = publisher;\n trace.info('Peer connection with publisher was created', peerConnection);\n return peerConnection;\n });\n })\n .then(function (peerConnection) {\n _this._peerConnections.set(peerConnection.peerId, peerConnection);\n if (peerConnection.publisher) {\n return new Promise(function (resolve, reject) {\n trace.info('Starting publish to peerConnection.publisher');\n _this._session.publish(peerConnection.publisher, function (error) {\n if (error) {\n trace.error('Publish to peerConnection error', error);\n return reject(error);\n }\n trace.info('Publish to peerConnection success');\n return resolve();\n });\n });\n }\n return Promise.resolve();\n })\n .catch(function (error) {\n //Need to handle fail cases during reliability\n trace.error('Error handling new peer connection', error);\n });\n };\n OpentokSessionV3.prototype.connectionDestroyedHandler = function (event) {\n trace.info('connectionDestroyedHandler', event);\n var connection = event.connection;\n if (!this.sessionExistsGuard(false) || !connection) {\n return;\n }\n if (this._peerConnections.has(connection.connectionId)) {\n this.destroyPeerConnection(this._peerConnections.get(connection.connectionId));\n }\n };\n OpentokSessionV3.prototype.streamCreatedHandler = function (event) {\n var _this = this;\n trace.info('streamCreatedHandler', event.stream);\n var stream = event.stream;\n var connection = (stream || { connection: null }).connection;\n if (!this.sessionExistsGuard(false) || !stream) {\n return;\n }\n if (!this._peerConnections.has(connection.connectionId)) {\n trace.warn('Unexpected case, connection should exist on this stage');\n return;\n }\n var peerConnection = this._peerConnections.get(connection.connectionId);\n trace.info('Subscribing the stream');\n //TODO - Optimize the code below\n peerConnection.subscriber = this._session.subscribe(stream, null, null, function (err) {\n if (err) {\n peerConnection.subscriber = null;\n trace.warn('Error in subscriber', err);\n return;\n }\n var videoElQuery = \"#\" + peerConnection.subscriber.id + \" .OT_video-element\";\n var otVideoEl = document.querySelector(videoElQuery);\n if (!otVideoEl) {\n trace.warn('Cannot fined OT video element');\n return;\n }\n document.getElementById(peerConnection.subscriber.id).style.display = 'none';\n var otMediaStream = otVideoEl.srcObject;\n if (!otMediaStream) {\n trace.warn('MediaStream not found in OT video element');\n return;\n }\n trace.info('Registering remote media tracks', peerConnection.subscriber);\n otMediaStream.getTracks().forEach(function (mediaTrack) {\n _this.registerMediaTrackFromPeer(peerConnection, mediaTrack);\n });\n });\n peerConnection.subscriber.on('videoElementCreated', function (args) {\n trace.info('videoElementCreated - REDO', args);\n });\n };\n OpentokSessionV3.prototype.streamDestroyedHandler = function (event) {\n trace.info('streamDestroyedHandler', event);\n var stream = event.stream;\n if (!this.sessionExistsGuard(false) || !stream) {\n return;\n }\n var peerConnection = this._peerConnections.get(stream.connection.connectionId);\n if (!peerConnection) {\n trace.warn('Peer connection for remote stream not found');\n return;\n }\n this.unregisterPeersRemoteMediaTracks(peerConnection);\n this.destroySubscriberOnPeerConnection(peerConnection);\n };\n //#endregion\n OpentokSessionV3.prototype.onMediaStreamDestroyed = function (clientRole) {\n var _this = this;\n this._peerConnections.forEach(function (peerConnection) {\n if (peerConnection.peerRole === clientRole) {\n _this.destroyPublisherOnPeerConnection(peerConnection);\n }\n });\n return Promise.resolve();\n };\n OpentokSessionV3.prototype.onMediaStreamRenewed = function (clientRole, mediaStream) {\n //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation (in OT API)\n return Promise.resolve();\n };\n OpentokSessionV3.prototype.getRemoteTrackStats = function (mediaTrack) {\n var _this = this;\n return new Promise(function (resolve, reject) {\n var peerConnectionOfTrack = _this.getPeerConnectionByMediaTrack(mediaTrack);\n if (!peerConnectionOfTrack || !peerConnectionOfTrack.subscriber) {\n reject(new Error('Cannot find peer or subscriber for getting stats'));\n }\n //https://tokbox.com/developer/sdks/js/reference/Subscriber.html#getStats\n peerConnectionOfTrack.subscriber.getStats(function (error, stats) {\n if (error) {\n trace.warn('Error getting stats', error);\n resolve({ trackId: mediaTrack.id, trackStats: {} });\n return;\n }\n resolve({ trackId: mediaTrack.id, trackStats: stats });\n });\n });\n };\n OpentokSessionV3.prototype.createStreamForPublishing = function (destinationRole) {\n var _this = this;\n trace.info('createStreamForPublishing');\n return this._sessionStreamsManager.getMediaStreamForRole(destinationRole)\n .then(function (mediaStream) {\n var stream = { videoSource: null, audioSource: null };\n if (mediaStream) {\n trace.info('Media stream found for publishing', mediaStream);\n mediaStream.getTracks().forEach(function (track) {\n if (track.kind === 'video') {\n stream.videoSource = track;\n }\n else if (track.kind === 'audio') {\n stream.audioSource = track;\n }\n });\n }\n else if (_this._sessionParams.clientRole === MediaConstants_1.SessionClientRole.USER) {\n trace.warn('No local media was found for publishing to destinationRole:', destinationRole);\n }\n return stream;\n });\n };\n OpentokSessionV3.prototype.calculateDestinationRole = function () {\n if (this._sessionParams.clientRole === MediaConstants_1.SessionClientRole.USER) {\n var isAgentConnected = false;\n return !isAgentConnected ? MediaConstants_1.SessionClientRole.AGENT : MediaConstants_1.SessionClientRole.OBSERVER;\n }\n return MediaConstants_1.SessionClientRole.USER;\n };\n OpentokSessionV3.prototype.createMediaPublisher = function (stream, streamName) {\n var otParams = {\n videoSource: stream.videoSource ? stream.videoSource : false,\n audioSource: stream.audioSource ? stream.audioSource : false,\n publishAudio: !!stream.audioSource,\n publishVideo: !!stream.videoSource,\n showControls: false,\n name: streamName\n };\n return new Promise(function (resolve, reject) {\n var otPublisher = window.OT.initPublisher(undefined, otParams, function (error) {\n if (error) {\n reject(error);\n return;\n }\n resolve(otPublisher);\n });\n });\n };\n OpentokSessionV3.prototype.destroyPeerConnection = function (peerConnection) {\n this._peerConnections.delete(peerConnection.peerId);\n this.destroyPublisherOnPeerConnection(peerConnection);\n this.unregisterPeersRemoteMediaTracks(peerConnection);\n this.destroySubscriberOnPeerConnection(peerConnection);\n };\n OpentokSessionV3.prototype.destroyPublisherOnPeerConnection = function (peerConnection) {\n if (peerConnection.publisher) {\n //TODO - Alex: When destroying the publisher, OT closes the stream by himself, without we ask him.\n //So we not destroying the OT publisher right now in order to preserve our stream alive.\n //Later, we can recreate our stream as new, or manually delete \"video\" element that created by OT.\n // or we just can leave it as is :)\n //peerConnection.publisher.destroy();\n peerConnection.publisher = null;\n peerConnection.localStream = null;\n }\n };\n OpentokSessionV3.prototype.destroySubscriberOnPeerConnection = function (peerConnection) {\n if (!this.sessionExistsGuard(false) || peerConnection.subscriber) {\n return;\n }\n this._session.unsubscribe(peerConnection.subscriber);\n peerConnection.subscriber = null;\n };\n OpentokSessionV3.prototype.sessionExistsGuard = function (shouldThrow) {\n if (shouldThrow === void 0) { shouldThrow = true; }\n var connected = !!(this._session && this._session.connection && this._session.connection.connectionId);\n return guards_1.throwableGuard(connected, 'There no active session', shouldThrow);\n };\n return OpentokSessionV3;\n}(MediaSessionBase_1.MediaSessionBase));\nexports.OpentokSessionV3 = OpentokSessionV3;\n\n//# sourceMappingURL=SessionOpentok.v3.js.map\n"]}
@@ -1,19 +1,9 @@
1
- import { IMediaSession, ISessionStreamsManager, MediaSessionHandlers, MediaSessionParams, RemoteMediaTrack, RemoteTrackStats } from '../MediaContracts';
2
- import { SessionClientRole, SessionClientType } from '../MediaConstants';
3
- declare global {
4
- interface RTCPeerConnection {
5
- peerId: any;
6
- peerType: SessionClientType;
7
- peerRole: SessionClientRole;
8
- remoteMediaTracks: RemoteMediaTrack[];
9
- }
10
- }
11
- export declare class TurnWebRtcSessionV3 implements IMediaSession {
12
- private readonly _sessionStreamsManager;
13
- private readonly _sessionParams;
1
+ import { IMediaSession, ISessionStreamsManager, MediaSessionHandlers, MediaSessionParams, RemoteTrackStats } from '../MediaContracts';
2
+ import { SessionClientRole } from '../MediaConstants';
3
+ import { MediaSessionBase } from './MediaSessionBase';
4
+ export declare class TurnWebRtcSessionV3 extends MediaSessionBase<RTCPeerConnection> implements IMediaSession {
14
5
  private readonly _sessionHandlers;
15
6
  private readonly _pendingPeersIce;
16
- private readonly _peerConnections;
17
7
  private readonly _configuration;
18
8
  private _socket;
19
9
  readonly id: string;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/MediaSession/SessionTurn.v3.ts"],"names":[],"mappings":"AAIA,OAAO,EACH,aAAa,EACb,sBAAsB,EACtB,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAAE,gBAAgB,EACrC,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAGH,iBAAiB,EACjB,iBAAiB,EACpB,MAAM,mBAAmB,CAAC;AAc3B,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,iBAAiB;QACvB,MAAM,EAAE,GAAG,CAAC;QACZ,QAAQ,EAAE,iBAAiB,CAAC;QAC5B,QAAQ,EAAE,iBAAiB,CAAC;QAC5B,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;KACzC;CACJ;AAGD,qBAAa,mBAAoB,YAAW,aAAa;IACrD,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAyB;IAChE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAuB;IACxD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAM;IACvC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAM;IACvC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAM;IACrC,OAAO,CAAC,OAAO,CAAM;aAEjB,EAAE,EAAI,MAAM;gBAIJ,aAAa,EAAE,kBAAkB,EAAE,eAAe,EAAE,oBAAoB,EAAE,aAAa,EAAE,sBAAsB;IA8B3H,OAAO,CAAC,WAAW,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB3C,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAkChE,4BAA4B,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAgBlD,iBAAiB,CAAC,kBAAkB,EAAE,GAAG,GAAG,IAAI;IAmEhD,oBAAoB,CAAC,gBAAgB,EAAE,GAAG,GAAG,IAAI;IAwBjD,wBAAwB,CAAC,qBAAqB,EAAE,GAAG,GAAG,IAAI;IAe1D,gBAAgB,CAAC,aAAa,EAAE,GAAG,GAAG,IAAI;IA2E1C,yBAAyB,IAAI,IAAI;IAcjC,sBAAsB,CAAC,UAAU,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IASpE,oBAAoB,CAAC,UAAU,EAAE,iBAAiB,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAK5F,mBAAmB,CAAC,UAAU,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAoB5E,OAAO,CAAC,mBAAmB;IAkB3B,OAAO,CAAC,qBAAqB;IA8C7B,OAAO,CAAC,sBAAsB;IAmB9B,OAAO,CAAC,mBAAmB;IAY3B,4BAA4B,CAAC,gBAAgB,EAAE,GAAG,GAAG,IAAI;IAuBzD,sBAAsB,CAAC,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAWvG,2BAA2B,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAejD,kBAAkB,CAAC,YAAY,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAQvE,qBAAqB,CAAC,cAAc,EAAE,iBAAiB,GAAG,IAAI;CAKjE","file":"SessionTurn.v3.d.ts","sourcesContent":["import * as io from 'socket.io-client';\nimport once from 'lodash/once';\nimport {Nullable} from '@techsee/techsee-common';\n\nimport {\n IMediaSession,\n ISessionStreamsManager,\n MediaSessionHandlers,\n MediaSessionParams,\n RemoteMediaTrack, RemoteTrackStats\n} from '../MediaContracts';\n\nimport {\n KnownMediaStream,\n MediaSessionDisconnectReason,\n SessionClientRole,\n SessionClientType\n} from '../MediaConstants';\n\nimport {\n SOCKET_EVENTS, SOCKET_PATH,\n SOCKET_RECONNECTION_ATTEMPTS,\n SOCKET_RECONNECTION_DELAY,\n SOCKET_RECONNECTION_DELAY_MAX\n} from './TurnConstants';\n\nimport {getMediaTracer} from '../MediaUtils/MediaTracer';\n\nconst trace = getMediaTracer('TurnSessionV3');\n\n\ndeclare global {\n interface RTCPeerConnection {\n peerId: any;\n peerType: SessionClientType;\n peerRole: SessionClientRole;\n remoteMediaTracks: RemoteMediaTrack[];\n }\n}\n\n//Currently this version supports subscribing only. Publishing will be implemented as needed.\nexport class TurnWebRtcSessionV3 implements IMediaSession {\n private readonly _sessionStreamsManager: ISessionStreamsManager;\n private readonly _sessionParams: MediaSessionParams;\n private readonly _sessionHandlers: MediaSessionHandlers;\n private readonly _pendingPeersIce: any;\n private readonly _peerConnections: any;\n private readonly _configuration: any;\n private _socket: any;\n\n get id(): string {\n return this._sessionParams.sessionId;\n }\n\n constructor(sessionParams: MediaSessionParams, sessionHandlers: MediaSessionHandlers, streamFactory: ISessionStreamsManager) {\n this._sessionParams = sessionParams;\n this._sessionStreamsManager = streamFactory;\n this._sessionHandlers = sessionHandlers;\n this._socket = null;\n this._pendingPeersIce = {};\n this._peerConnections = new Map();\n\n const iceServers = sessionParams.credentials.ice.map((item: any) => ({\n urls: item.url,\n username: item.login,\n credential: item.password\n }));\n\n this._configuration = {\n iceServers,\n iceTransportPolicy: 'relay'\n };\n\n this._joinResponseHandler = this._joinResponseHandler.bind(this);\n this._iceCandidateReceivedHandler = this._iceCandidateReceivedHandler.bind(this);\n this._sendOfferHandler = this._sendOfferHandler.bind(this);\n this._sdpOfferHandler = this._sdpOfferHandler.bind(this);\n this._userPeerReconnectHandler = this._userPeerReconnectHandler.bind(this);\n this._peerDisconnectedHandler = this._peerDisconnectedHandler.bind(this);\n this._onSocketDisconnectedHandler = this._onSocketDisconnectedHandler.bind(this);\n }\n\n //#region Socket Connectivity\n\n connect(connectOnly = false): Promise<void> {\n trace.info('Connect to session');\n\n return this._connectSocket(this._sessionParams.credentials.url, connectOnly)\n .then(() => {\n trace.info('Joining SessionId: ' + this._sessionParams.sessionId);\n\n this._socket.emit(SOCKET_EVENTS.OUTGOING.JOIN_ROOM, {\n clientType: this._sessionParams.clientType,\n sessionId: this._sessionParams.sessionId\n });\n })\n .catch((error) => {\n throw error;\n });\n }\n\n disconnect(): Promise<void> {\n return this._disconnectInternal(MediaSessionDisconnectReason.ForcedByConsumer);\n }\n\n _connectSocket(url: string, connectOnly: boolean): Promise<void> {\n return new Promise((resolve, reject) => {\n const socket = this._socket = io.connect(url, {\n 'forceNew': true,\n 'reconnectionDelay': SOCKET_RECONNECTION_DELAY,\n 'reconnectionDelayMax': SOCKET_RECONNECTION_DELAY_MAX,\n 'reconnectionAttempts': SOCKET_RECONNECTION_ATTEMPTS,\n 'path': SOCKET_PATH\n });\n\n const done = once((err?: any) => {\n err ? reject(err) : resolve();\n });\n\n socket.once('connect', () => done());\n socket.on(SOCKET_EVENTS.INCOMING.ERROR, done);\n socket.on('connect_error', done);\n socket.on('connect_timeout', done);\n socket.on('disconnect', this._onSocketDisconnectedHandler);\n\n if (!connectOnly) {\n trace.info('Subscribing socket events');\n\n //PUBLISHING NOT SUPPORTED YET\n socket.on(SOCKET_EVENTS.INCOMING.SEND_OFFER, this._sendOfferHandler);\n socket.on(SOCKET_EVENTS.INCOMING.JOIN_RESPONSE, this._joinResponseHandler);\n socket.on(SOCKET_EVENTS.INCOMING.PEER_DISCONNECTED, this._peerDisconnectedHandler);\n socket.on(SOCKET_EVENTS.INCOMING.SDP_OFFER, this._sdpOfferHandler);\n socket.on(SOCKET_EVENTS.INCOMING.PUBLISHER_RECONNECT, this._userPeerReconnectHandler);\n socket.on(SOCKET_EVENTS.INCOMING.ICE_CANDIDATE, this._iceCandidateReceivedHandler);\n }\n });\n }\n\n _onSocketDisconnectedHandler(reason: string): void {\n if (this._socket) {\n // The initial example of differentiating between \"forced\" disconnect and \"network\" disconnect is taken from:\n // https://socket.io/docs/client-api/#Event-%E2%80%98disconnect%E2%80%99\n if (reason !== 'io server disconnect' && reason !== 'io client disconnect') {\n // the disconnection was initiated by the server or by client, you need to call (connect) manually\n this._disconnectInternal(MediaSessionDisconnectReason.SignalingChannelDisconnect).catch(() => undefined);\n }\n }\n }\n\n //#endregion\n\n //#region WebRTC Initiator - session Initiator (User on mobile device)\n\n // Received by Initiator, causing him to emit SDP_OFFER\n _sendOfferHandler(sendOfferEventData: any): void {\n const {uid, peerId} = sendOfferEventData;\n\n trace.info('_sendOfferHandler');\n\n //Currently we not support of passing role through signaling, so we assume every connection is \"AGENT\" like\n const peerConnection = this._createPeerConnection(peerId, SessionClientType.GUEST, SessionClientRole.AGENT);\n const offerParams = {offerToReceiveAudio: true, offerToReceiveVideo: true};\n\n peerConnection.ontrack = (trackEvent: any) => {\n const track: MediaStreamTrack = trackEvent.track;\n\n trace.info(`MediaStreamTrack arrived from peerConnection: ${track.kind}`, track);\n\n //We only support to stream audio from dashboard\n if (track.kind.toLowerCase() === 'audio') {\n const remoteMediaTrack: RemoteMediaTrack = {\n mediaTrack: track,\n trackType: KnownMediaStream.AGENT_AUDIO_STREAM\n };\n\n peerConnection.remoteMediaTracks.push(remoteMediaTrack);\n this._sessionStreamsManager.addRemoteMediaTrack(remoteMediaTrack)\n .catch((error: any) => {\n trace.warn('Error adding remote media track to available streams', error);\n });\n }\n };\n\n //TODO - Alex: Currently we not sending \"role\" through signaling, and by default we assume that the one who asks fot offer, is agent.\n //On later stages we can send or the client \"role\" or the list of \"streams\" that peer is interested in.\n this._sessionStreamsManager.getMediaStreamForRole(SessionClientRole.AGENT)\n .then((mediaStream: Nullable<MediaStream>) => {\n trace.info('_sendOfferHandler stream and peer created');\n\n if (mediaStream) {\n trace.info('Adding local tracks to peer connection');\n mediaStream.getTracks().forEach((track) => {\n peerConnection.addTrack(track, mediaStream);\n trace.info(`Local ${track.kind} track added to peer connection`);\n });\n } else {\n trace.info('No media stream was found for publishing');\n }\n })\n .then(() => peerConnection.createOffer(offerParams))\n .then((offerDesc) => {\n trace.info('Initiator has created sdp offer', {offerDesc});\n\n this._socket.emit(SOCKET_EVENTS.OUTGOING.SDP_OFFER, {\n uid,\n peerId,\n sessionId: this._sessionParams.sessionId,\n sdpOffer: offerDesc.sdp\n });\n\n return peerConnection.setLocalDescription(offerDesc)\n .then(() => {\n trace.info('Local description was set on peerConnection', peerConnection);\n });\n })\n .catch((e) => {\n trace.warn('Error', e);\n });\n }\n\n // Received by the Initiator: Indicates that publish should be started\n _joinResponseHandler(joinResponseData: any): void {\n const {sdpAnswer, uid, peerId} = joinResponseData;\n\n trace.info('joinResponse Received', {sdpAnswer});\n\n this._withPeerConnection(peerId, (peerConnection: RTCPeerConnection) => {\n const answer = new RTCSessionDescription({\n type: 'answer',\n sdp: sdpAnswer\n });\n\n peerConnection.setRemoteDescription(answer)\n .then(() => {\n trace.info('Remote description was set', answer);\n\n this._processQueuedIceCandidates(peerId);\n })\n .catch((e) => {\n trace.warn('Error', e);\n });\n });\n }\n\n // Received by Initiator after a guests socket has been disconnected\n _peerDisconnectedHandler(peerDisconnectedEvent: any): void {\n const {peerId} = peerDisconnectedEvent;\n\n trace.info('_peerDisconnectedHandler');\n\n this._withPeerConnection(peerId, (peerConnection: any) => {\n this._disconnectInternal(MediaSessionDisconnectReason.PeerDisconnected).catch(() => undefined);\n });\n }\n\n //#endregion WebRTC Initiator - session Initiator (User on mobile device)\n\n //#region WebRTC Guest - session Guest (Agent on dashboard platform)\n\n // Received by Guest, causing him to emit SDP_ANSWER\n _sdpOfferHandler(sdpOfferEvent: any): void {\n const {sdpOffer, peerId, uid} = sdpOfferEvent;\n\n trace.info('sdpOffer Received', {sdpOffer});\n\n const peerConnection = this._createPeerConnection(peerId, SessionClientType.INITIATOR, SessionClientRole.USER);\n\n peerConnection.ontrack = (trackEvent: any) => {\n const {track} = trackEvent;\n\n trace.info(`MediaStreamTrack arrived from peerConnection: ${track.kind}`, track);\n\n const remoteTrack: RemoteMediaTrack = {\n mediaTrack: track,\n trackType: track.kind === 'video'\n //Although we can have desktop share stream, we still name it USER_VIDEO_STREAM in dashboard.\n //Because currently we support only one video stream to be streamed at the time, it's not an issue.\n //But when we will need to stream more than one stream of a kind from single peer, this will be need to change.\n ? KnownMediaStream.USER_VIDEO_STREAM : KnownMediaStream.USER_AUDIO_STREAM\n };\n\n peerConnection.remoteMediaTracks.push(remoteTrack);\n this._sessionStreamsManager.addRemoteMediaTrack(remoteTrack)\n .catch(() => {\n trace.warn('Error adding remote track to stream manager', remoteTrack);\n });\n };\n\n this._sessionStreamsManager.getMediaStreamForRole(SessionClientRole.USER)\n .then((mediaStream: Nullable<MediaStream>) => {\n if (mediaStream) {\n trace.info('Adding local tracks to peer connection');\n mediaStream.getTracks().forEach((track) => {\n peerConnection.addTrack(track, mediaStream);\n trace.info(`Local ${track.kind} track added to peer connection`);\n });\n } else {\n trace.info('No media stream was found for publishing');\n }\n })\n .then(() => {\n const remoteDesc = new RTCSessionDescription({type: 'offer', sdp: sdpOffer});\n\n return peerConnection.setRemoteDescription(remoteDesc)\n .then(() => {\n trace.info('Remote description was set', remoteDesc);\n\n return peerConnection.createAnswer()\n .then((sdpAnswer) => {\n trace.info('_sdpOfferHandler answer created', sdpAnswer);\n\n this._socket.emit(SOCKET_EVENTS.OUTGOING.SDP_ANSWER, {\n uid,\n peerId,\n sessionId: this._sessionParams.sessionId,\n sdpAnswer: sdpAnswer.sdp\n });\n\n return peerConnection.setLocalDescription(sdpAnswer)\n .then(() => {\n trace.info('_sdpOfferHandler local desc was set');\n\n this._processQueuedIceCandidates(peerId);\n });\n });\n });\n\n })\n .catch((e) => {\n trace.error('Error in _sdpOfferHandler', e);\n throw e;\n });\n }\n\n // Received by Guest after an Initiator reconnects to room\n _userPeerReconnectHandler(): void {\n trace.info('_userPeerReconnectHandler');\n this._disconnectInternal(MediaSessionDisconnectReason.UserPeerReconnected)\n .catch((error: any) => {\n trace.warn('Error while disconnecting during userPeerReconnectHandler.', error);\n });\n }\n\n //#endregion WebRTC Guest - session Guest (Agent on dashboard platform)\n\n //#region Peer Connection\n\n //#region Streams Handling\n\n onMediaStreamDestroyed(clientRole: SessionClientRole): Promise<void> {\n //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation\n this._peerConnections.forEach((peerConnection: RTCPeerConnection) => {\n this._disconnectInternal(MediaSessionDisconnectReason.PublishedStreamDestroyed).catch(() => undefined);\n });\n\n return Promise.resolve();\n }\n\n onMediaStreamRenewed(clientRole: SessionClientRole, mediaStream: MediaStream): Promise<void> {\n //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation\n return Promise.resolve();\n }\n\n getRemoteTrackStats(mediaTrack: MediaStreamTrack): Promise<RemoteTrackStats> {\n let peerConnectionOfTrack: Nullable<RTCPeerConnection> = null;\n\n this._peerConnections.forEach((peerConnection: RTCPeerConnection) => {\n const remoteTrack = peerConnection.remoteMediaTracks.filter((track) => track.mediaTrack.id === mediaTrack.id);\n\n if (remoteTrack.length === 1) {\n peerConnectionOfTrack = peerConnection;\n }\n });\n\n if (peerConnectionOfTrack !== null) {\n return (peerConnectionOfTrack as any).getStats(mediaTrack);\n }\n\n return Promise.reject(new Error('Provided track is not remote track'));\n }\n\n //#endregion\n\n private _disconnectInternal(reason: MediaSessionDisconnectReason): Promise<void> {\n this._peerConnections.forEach((peerConnection: RTCPeerConnection) => {\n this._destroyPeerConnection(peerConnection);\n });\n\n trace.info('Disconnecting from session', reason);\n\n if (this._socket) {\n this._socket.off();\n this._socket.disconnect();\n }\n\n this._socket = null;\n setTimeout(() => this._sessionHandlers.onDisconnectedHandler(reason));\n\n return Promise.resolve();\n }\n\n private _createPeerConnection(peerId: string, peerConnectionType: SessionClientType, peerConnectionRole: SessionClientRole): RTCPeerConnection {\n if (this._peerConnections.get(peerId)) {\n throw new Error(`${this._sessionParams.clientType} peer connection for ${peerId} already exists`);\n }\n\n const peerConnection: any = new RTCPeerConnection(this._configuration);\n\n peerConnection.peerId = peerId;\n peerConnection.peerType = peerConnectionType;\n peerConnection.remoteMediaTracks = [];\n peerConnection.peerRole = peerConnectionRole;\n\n peerConnection.onconnectionstatechange = () => {\n trace.info('onconnectionstatechange', peerConnection);\n };\n\n peerConnection.oniceconnectionstatechange = (state: any) => {\n trace.info(`ICE Connection state for peer ${peerId} was changed to: ${state.currentTarget.iceConnectionState}`, state);\n const cnState = state.currentTarget.iceConnectionState;\n\n if (['closed', 'disconnected', 'failed'].indexOf(cnState) > -1) {\n this._iceStateDisconnected(peerConnection);\n }\n };\n\n peerConnection.onicecandidate = (event: any) => {\n if (event.candidate) {\n trace.info(`${this._sessionParams.clientType} peerConn.onicecandidate`, event.candidate);\n this._socket.emit(SOCKET_EVENTS.OUTGOING.ICE_CANDIDATE, {\n sessionId: this._sessionParams.sessionId,\n peerId: peerId,\n candidate: event.candidate,\n clientType: this._sessionParams.clientType\n });\n } else {\n trace.info('ICE Candidate is null in peerConnection', event);\n }\n };\n\n this._peerConnections.set(peerId, peerConnection);\n\n trace.info(`${peerConnectionType} peerConnection created`);\n\n return peerConnection;\n }\n\n private _destroyPeerConnection(peerConnection: RTCPeerConnection): void {\n trace.info('Destroying PeerConnection', peerConnection.peerType);\n peerConnection.ontrack = null;\n peerConnection.onicecandidate = null;\n peerConnection.onconnectionstatechange = null;\n peerConnection.oniceconnectionstatechange = null;\n peerConnection.onicegatheringstatechange = null;\n\n peerConnection.remoteMediaTracks.forEach((remoteMediaTrack) => {\n this._sessionStreamsManager.removeMediaTrack(remoteMediaTrack.mediaTrack)\n .catch(() => {\n trace.warn('Error while removing remote media track', remoteMediaTrack);\n });\n });\n\n this._peerConnections.delete(peerConnection.peerId);\n peerConnection.close();\n }\n\n private _withPeerConnection(peerId: any, callback: any): void | undefined {\n if (this._peerConnections.get(peerId)) {\n return callback(this._peerConnections.get(peerId));\n }\n\n return undefined;\n }\n\n //#endregion\n\n //#region ICE Candidates\n\n _iceCandidateReceivedHandler(iceCandidateData: any): void {\n const {candidate, peerId} = iceCandidateData;\n\n trace.info('_iceCandidateReceivedHandler', candidate);\n if (!candidate) {\n trace.info('Unexpected case, iceCandidate message arrived without candidate');\n\n return;\n }\n\n const peerConnection = this._peerConnections.get(peerId);\n\n if (!peerConnection || !peerConnection.remoteDescription) {\n trace.info('Queueing iceCandidate', candidate);\n this._queueIceCandidate(candidate, peerId);\n\n return;\n }\n\n trace.info('Going to add iceCandidate', candidate);\n this._addIceCandidateToPeer(candidate, peerConnection).catch(() => undefined);\n }\n\n _addIceCandidateToPeer(iceCandidate: RTCIceCandidate, peerConnection: RTCPeerConnection): Promise<void> {\n return peerConnection.addIceCandidate(iceCandidate)\n .then(() => {\n trace.info('ICE Candidate add to peer connection');\n })\n .catch((e) => {\n trace.warn('Error adding ICE Candidate to peer connection', e);\n throw e;\n });\n }\n\n _processQueuedIceCandidates(peerId: string): void {\n this._withPeerConnection(peerId, (peerConnection: RTCPeerConnection) => {\n const pendingIces = this._pendingPeersIce[peerId];\n\n if (pendingIces) {\n pendingIces.forEach((pendingIce: RTCIceCandidate) => {\n trace.info('Adding pending ICE to peer connections');\n this._addIceCandidateToPeer(pendingIce, peerConnection).catch(() => undefined);\n });\n } else {\n trace.info('No pending ICE found for peer', peerId);\n }\n });\n }\n\n _queueIceCandidate(iceCandidate: RTCIceCandidate, peerId: string): void {\n if (!this._pendingPeersIce[peerId]) {\n this._pendingPeersIce[peerId] = [];\n }\n\n this._pendingPeersIce[peerId].push(iceCandidate);\n }\n\n _iceStateDisconnected(peerConnection: RTCPeerConnection): void {\n this._disconnectInternal(MediaSessionDisconnectReason.PeerConnectionInterrupted).catch(() => undefined);\n }\n\n //#endregion\n}\n"]}
1
+ {"version":3,"sources":["../src/MediaSession/SessionTurn.v3.ts"],"names":[],"mappings":"AAIA,OAAO,EACH,aAAa,EACb,sBAAsB,EACtB,oBAAoB,EACpB,kBAAkB,EACA,gBAAgB,EACrC,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAGH,iBAAiB,EAEpB,MAAM,mBAAmB,CAAC;AAU3B,OAAO,EAAC,gBAAgB,EAAC,MAAM,oBAAoB,CAAC;AAKpD,qBAAa,mBAAoB,SAAQ,gBAAgB,CAAC,iBAAiB,CAAE,YAAW,aAAa;IACjG,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAuB;IACxD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAM;IACvC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAM;IACrC,OAAO,CAAC,OAAO,CAAM;aAEjB,EAAE,EAAI,MAAM;gBAIJ,aAAa,EAAE,kBAAkB,EAAE,eAAe,EAAE,oBAAoB,EAAE,aAAa,EAAE,sBAAsB;IA4B3H,OAAO,CAAC,WAAW,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB3C,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAkChE,4BAA4B,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAgBlD,iBAAiB,CAAC,kBAAkB,EAAE,GAAG,GAAG,IAAI;IAsDhD,oBAAoB,CAAC,gBAAgB,EAAE,GAAG,GAAG,IAAI;IAwBjD,wBAAwB,CAAC,qBAAqB,EAAE,GAAG,GAAG,IAAI;IAe1D,gBAAgB,CAAC,aAAa,EAAE,GAAG,GAAG,IAAI;IA2E1C,yBAAyB,IAAI,IAAI;IAcjC,sBAAsB,CAAC,UAAU,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IASpE,oBAAoB,CAAC,UAAU,EAAE,iBAAiB,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAK5F,mBAAmB,CAAC,UAAU,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAY5E,OAAO,CAAC,mBAAmB;IAkB3B,OAAO,CAAC,qBAAqB;IA8C7B,OAAO,CAAC,sBAAsB;IAc9B,OAAO,CAAC,mBAAmB;IAY3B,4BAA4B,CAAC,gBAAgB,EAAE,GAAG,GAAG,IAAI;IAuBzD,sBAAsB,CAAC,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAWvG,2BAA2B,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAejD,kBAAkB,CAAC,YAAY,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAQvE,qBAAqB,CAAC,cAAc,EAAE,iBAAiB,GAAG,IAAI;CAKjE","file":"SessionTurn.v3.d.ts","sourcesContent":["import * as io from 'socket.io-client';\nimport once from 'lodash/once';\nimport {Nullable} from '@techsee/techsee-common';\n\nimport {\n IMediaSession,\n ISessionStreamsManager,\n MediaSessionHandlers,\n MediaSessionParams,\n RemoteMediaTrack, RemoteTrackStats\n} from '../MediaContracts';\n\nimport {\n KnownMediaStream,\n MediaSessionDisconnectReason,\n SessionClientRole,\n SessionClientType\n} from '../MediaConstants';\n\nimport {\n SOCKET_EVENTS, SOCKET_PATH,\n SOCKET_RECONNECTION_ATTEMPTS,\n SOCKET_RECONNECTION_DELAY,\n SOCKET_RECONNECTION_DELAY_MAX\n} from './TurnConstants';\n\nimport {getMediaTracer} from '../MediaUtils/MediaTracer';\nimport {MediaSessionBase} from './MediaSessionBase';\n\nconst trace = getMediaTracer('TurnSessionV3');\n\n//Currently this version supports subscribing only. Publishing will be implemented as needed.\nexport class TurnWebRtcSessionV3 extends MediaSessionBase<RTCPeerConnection> implements IMediaSession {\n private readonly _sessionHandlers: MediaSessionHandlers;\n private readonly _pendingPeersIce: any;\n private readonly _configuration: any;\n private _socket: any;\n\n get id(): string {\n return this._sessionParams.sessionId;\n }\n\n constructor(sessionParams: MediaSessionParams, sessionHandlers: MediaSessionHandlers, streamFactory: ISessionStreamsManager) {\n super(sessionParams, streamFactory);\n this._sessionHandlers = sessionHandlers;\n this._socket = null;\n this._pendingPeersIce = {};\n\n const iceServers = sessionParams.credentials.ice.map((item: any) => ({\n urls: item.url,\n username: item.login,\n credential: item.password\n }));\n\n this._configuration = {\n iceServers,\n iceTransportPolicy: 'relay'\n };\n\n this._joinResponseHandler = this._joinResponseHandler.bind(this);\n this._iceCandidateReceivedHandler = this._iceCandidateReceivedHandler.bind(this);\n this._sendOfferHandler = this._sendOfferHandler.bind(this);\n this._sdpOfferHandler = this._sdpOfferHandler.bind(this);\n this._userPeerReconnectHandler = this._userPeerReconnectHandler.bind(this);\n this._peerDisconnectedHandler = this._peerDisconnectedHandler.bind(this);\n this._onSocketDisconnectedHandler = this._onSocketDisconnectedHandler.bind(this);\n }\n\n //#region Socket Connectivity\n\n connect(connectOnly = false): Promise<void> {\n trace.info('Connect to session');\n\n return this._connectSocket(this._sessionParams.credentials.url, connectOnly)\n .then(() => {\n trace.info('Joining SessionId: ' + this._sessionParams.sessionId);\n\n this._socket.emit(SOCKET_EVENTS.OUTGOING.JOIN_ROOM, {\n clientType: this._sessionParams.clientType,\n sessionId: this._sessionParams.sessionId\n });\n })\n .catch((error) => {\n throw error;\n });\n }\n\n disconnect(): Promise<void> {\n return this._disconnectInternal(MediaSessionDisconnectReason.ForcedByConsumer);\n }\n\n _connectSocket(url: string, connectOnly: boolean): Promise<void> {\n return new Promise((resolve, reject) => {\n const socket = this._socket = io.connect(url, {\n 'forceNew': true,\n 'reconnectionDelay': SOCKET_RECONNECTION_DELAY,\n 'reconnectionDelayMax': SOCKET_RECONNECTION_DELAY_MAX,\n 'reconnectionAttempts': SOCKET_RECONNECTION_ATTEMPTS,\n 'path': SOCKET_PATH\n });\n\n const done = once((err?: any) => {\n err ? reject(err) : resolve();\n });\n\n socket.once('connect', () => done());\n socket.on(SOCKET_EVENTS.INCOMING.ERROR, done);\n socket.on('connect_error', done);\n socket.on('connect_timeout', done);\n socket.on('disconnect', this._onSocketDisconnectedHandler);\n\n if (!connectOnly) {\n trace.info('Subscribing socket events');\n\n //PUBLISHING NOT SUPPORTED YET\n socket.on(SOCKET_EVENTS.INCOMING.SEND_OFFER, this._sendOfferHandler);\n socket.on(SOCKET_EVENTS.INCOMING.JOIN_RESPONSE, this._joinResponseHandler);\n socket.on(SOCKET_EVENTS.INCOMING.PEER_DISCONNECTED, this._peerDisconnectedHandler);\n socket.on(SOCKET_EVENTS.INCOMING.SDP_OFFER, this._sdpOfferHandler);\n socket.on(SOCKET_EVENTS.INCOMING.PUBLISHER_RECONNECT, this._userPeerReconnectHandler);\n socket.on(SOCKET_EVENTS.INCOMING.ICE_CANDIDATE, this._iceCandidateReceivedHandler);\n }\n });\n }\n\n _onSocketDisconnectedHandler(reason: string): void {\n if (this._socket) {\n // The initial example of differentiating between \"forced\" disconnect and \"network\" disconnect is taken from:\n // https://socket.io/docs/client-api/#Event-%E2%80%98disconnect%E2%80%99\n if (reason !== 'io server disconnect' && reason !== 'io client disconnect') {\n // the disconnection was initiated by the server or by client, you need to call (connect) manually\n this._disconnectInternal(MediaSessionDisconnectReason.SignalingChannelDisconnect).catch(() => undefined);\n }\n }\n }\n\n //#endregion\n\n //#region WebRTC Initiator - session Initiator (User on mobile device)\n\n // Received by Initiator, causing him to emit SDP_OFFER\n _sendOfferHandler(sendOfferEventData: any): void {\n const {uid, peerId} = sendOfferEventData;\n\n trace.info('_sendOfferHandler');\n\n //Currently we not support of passing role through signaling, so we assume every connection is \"AGENT\" like\n const peerConnection = this._createPeerConnection(peerId, SessionClientType.GUEST, SessionClientRole.AGENT);\n const offerParams = {offerToReceiveAudio: true, offerToReceiveVideo: true};\n\n peerConnection.ontrack = (trackEvent: any) => {\n const track: MediaStreamTrack = trackEvent.track;\n\n trace.info(`MediaStreamTrack arrived from peerConnection: ${track.kind}`, track);\n this.registerMediaTrackFromPeer(peerConnection, track);\n };\n\n //TODO - Alex: Currently we not sending \"role\" through signaling, and by default we assume that the one who asks fot offer, is agent.\n //On later stages we can send or the client \"role\" or the list of \"streams\" that peer is interested in.\n this._sessionStreamsManager.getMediaStreamForRole(SessionClientRole.AGENT)\n .then((mediaStream: Nullable<MediaStream>) => {\n trace.info('_sendOfferHandler stream and peer created');\n\n if (mediaStream) {\n trace.info('Adding local tracks to peer connection');\n mediaStream.getTracks().forEach((track) => {\n peerConnection.addTrack(track, mediaStream);\n trace.info(`Local ${track.kind} track added to peer connection`);\n });\n } else {\n trace.info('No media stream was found for publishing');\n }\n })\n .then(() => peerConnection.createOffer(offerParams))\n .then((offerDesc) => {\n trace.info('Initiator has created sdp offer', {offerDesc});\n\n this._socket.emit(SOCKET_EVENTS.OUTGOING.SDP_OFFER, {\n uid,\n peerId,\n sessionId: this._sessionParams.sessionId,\n sdpOffer: offerDesc.sdp\n });\n\n return peerConnection.setLocalDescription(offerDesc)\n .then(() => {\n trace.info('Local description was set on peerConnection', peerConnection);\n });\n })\n .catch((e) => {\n trace.warn('Error', e);\n });\n }\n\n // Received by the Initiator: Indicates that publish should be started\n _joinResponseHandler(joinResponseData: any): void {\n const {sdpAnswer, uid, peerId} = joinResponseData;\n\n trace.info('joinResponse Received', {sdpAnswer});\n\n this._withPeerConnection(peerId, (peerConnection: RTCPeerConnection) => {\n const answer = new RTCSessionDescription({\n type: 'answer',\n sdp: sdpAnswer\n });\n\n peerConnection.setRemoteDescription(answer)\n .then(() => {\n trace.info('Remote description was set', answer);\n\n this._processQueuedIceCandidates(peerId);\n })\n .catch((e) => {\n trace.warn('Error', e);\n });\n });\n }\n\n // Received by Initiator after a guests socket has been disconnected\n _peerDisconnectedHandler(peerDisconnectedEvent: any): void {\n const {peerId} = peerDisconnectedEvent;\n\n trace.info('_peerDisconnectedHandler');\n\n this._withPeerConnection(peerId, (peerConnection: any) => {\n this._disconnectInternal(MediaSessionDisconnectReason.PeerDisconnected).catch(() => undefined);\n });\n }\n\n //#endregion WebRTC Initiator - session Initiator (User on mobile device)\n\n //#region WebRTC Guest - session Guest (Agent on dashboard platform)\n\n // Received by Guest, causing him to emit SDP_ANSWER\n _sdpOfferHandler(sdpOfferEvent: any): void {\n const {sdpOffer, peerId, uid} = sdpOfferEvent;\n\n trace.info('sdpOffer Received', {sdpOffer});\n\n const peerConnection = this._createPeerConnection(peerId, SessionClientType.INITIATOR, SessionClientRole.USER);\n\n peerConnection.ontrack = (trackEvent: any) => {\n const {track} = trackEvent;\n\n trace.info(`MediaStreamTrack arrived from peerConnection: ${track.kind}`, track);\n\n const remoteTrack: RemoteMediaTrack = {\n mediaTrack: track,\n trackType: track.kind === 'video'\n //Although we can have desktop share stream, we still name it USER_VIDEO_STREAM in dashboard.\n //Because currently we support only one video stream to be streamed at the time, it's not an issue.\n //But when we will need to stream more than one stream of a kind from single peer, this will be need to change.\n ? KnownMediaStream.USER_VIDEO_STREAM : KnownMediaStream.USER_AUDIO_STREAM\n };\n\n peerConnection.remoteMediaTracks.push(remoteTrack);\n this._sessionStreamsManager.addRemoteMediaTrack(remoteTrack)\n .catch(() => {\n trace.warn('Error adding remote track to stream manager', remoteTrack);\n });\n };\n\n this._sessionStreamsManager.getMediaStreamForRole(SessionClientRole.USER)\n .then((mediaStream: Nullable<MediaStream>) => {\n if (mediaStream) {\n trace.info('Adding local tracks to peer connection');\n mediaStream.getTracks().forEach((track) => {\n peerConnection.addTrack(track, mediaStream);\n trace.info(`Local ${track.kind} track added to peer connection`);\n });\n } else {\n trace.info('No media stream was found for publishing');\n }\n })\n .then(() => {\n const remoteDesc = new RTCSessionDescription({type: 'offer', sdp: sdpOffer});\n\n return peerConnection.setRemoteDescription(remoteDesc)\n .then(() => {\n trace.info('Remote description was set', remoteDesc);\n\n return peerConnection.createAnswer()\n .then((sdpAnswer) => {\n trace.info('_sdpOfferHandler answer created', sdpAnswer);\n\n this._socket.emit(SOCKET_EVENTS.OUTGOING.SDP_ANSWER, {\n uid,\n peerId,\n sessionId: this._sessionParams.sessionId,\n sdpAnswer: sdpAnswer.sdp\n });\n\n return peerConnection.setLocalDescription(sdpAnswer)\n .then(() => {\n trace.info('_sdpOfferHandler local desc was set');\n\n this._processQueuedIceCandidates(peerId);\n });\n });\n });\n\n })\n .catch((e) => {\n trace.error('Error in _sdpOfferHandler', e);\n throw e;\n });\n }\n\n // Received by Guest after an Initiator reconnects to room\n _userPeerReconnectHandler(): void {\n trace.info('_userPeerReconnectHandler');\n this._disconnectInternal(MediaSessionDisconnectReason.UserPeerReconnected)\n .catch((error: any) => {\n trace.warn('Error while disconnecting during userPeerReconnectHandler.', error);\n });\n }\n\n //#endregion WebRTC Guest - session Guest (Agent on dashboard platform)\n\n //#region Peer Connection\n\n //#region Streams Handling\n\n onMediaStreamDestroyed(clientRole: SessionClientRole): Promise<void> {\n //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation\n this._peerConnections.forEach((peerConnection: RTCPeerConnection) => {\n this._disconnectInternal(MediaSessionDisconnectReason.PublishedStreamDestroyed).catch(() => undefined);\n });\n\n return Promise.resolve();\n }\n\n onMediaStreamRenewed(clientRole: SessionClientRole, mediaStream: MediaStream): Promise<void> {\n //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation\n return Promise.resolve();\n }\n\n getRemoteTrackStats(mediaTrack: MediaStreamTrack): Promise<RemoteTrackStats> {\n const peerConnectionOfTrack = this.getPeerConnectionByMediaTrack(mediaTrack);\n\n if (peerConnectionOfTrack !== null) {\n return (peerConnectionOfTrack as any).getStats(mediaTrack);\n }\n\n return Promise.reject(new Error('Provided track is not remote track'));\n }\n\n //#endregion\n\n private _disconnectInternal(reason: MediaSessionDisconnectReason): Promise<void> {\n this._peerConnections.forEach((peerConnection: RTCPeerConnection) => {\n this._destroyPeerConnection(peerConnection);\n });\n\n trace.info('Disconnecting from session', reason);\n\n if (this._socket) {\n this._socket.off();\n this._socket.disconnect();\n }\n\n this._socket = null;\n setTimeout(() => this._sessionHandlers.onDisconnectedHandler(reason));\n\n return Promise.resolve();\n }\n\n private _createPeerConnection(peerId: string, peerConnectionType: SessionClientType, peerConnectionRole: SessionClientRole): RTCPeerConnection {\n if (this._peerConnections.get(peerId)) {\n throw new Error(`${this._sessionParams.clientType} peer connection for ${peerId} already exists`);\n }\n\n const peerConnection: any = new RTCPeerConnection(this._configuration);\n\n peerConnection.peerId = peerId;\n peerConnection.peerType = peerConnectionType;\n peerConnection.remoteMediaTracks = [];\n peerConnection.peerRole = peerConnectionRole;\n\n peerConnection.onconnectionstatechange = () => {\n trace.info('onconnectionstatechange', peerConnection);\n };\n\n peerConnection.oniceconnectionstatechange = (state: any) => {\n trace.info(`ICE Connection state for peer ${peerId} was changed to: ${state.currentTarget.iceConnectionState}`, state);\n const cnState = state.currentTarget.iceConnectionState;\n\n if (['closed', 'disconnected', 'failed'].indexOf(cnState) > -1) {\n this._iceStateDisconnected(peerConnection);\n }\n };\n\n peerConnection.onicecandidate = (event: any) => {\n if (event.candidate) {\n trace.info(`${this._sessionParams.clientType} peerConn.onicecandidate`, event.candidate);\n this._socket.emit(SOCKET_EVENTS.OUTGOING.ICE_CANDIDATE, {\n sessionId: this._sessionParams.sessionId,\n peerId: peerId,\n candidate: event.candidate,\n clientType: this._sessionParams.clientType\n });\n } else {\n trace.info('ICE Candidate is null in peerConnection', event);\n }\n };\n\n this._peerConnections.set(peerId, peerConnection);\n\n trace.info(`${peerConnectionType} peerConnection created`);\n\n return peerConnection;\n }\n\n private _destroyPeerConnection(peerConnection: RTCPeerConnection): void {\n trace.info('Destroying PeerConnection', peerConnection.peerType);\n peerConnection.ontrack = null;\n peerConnection.onicecandidate = null;\n peerConnection.onconnectionstatechange = null;\n peerConnection.oniceconnectionstatechange = null;\n peerConnection.onicegatheringstatechange = null;\n\n this.unregisterPeersRemoteMediaTracks(peerConnection);\n\n this._peerConnections.delete(peerConnection.peerId);\n peerConnection.close();\n }\n\n private _withPeerConnection(peerId: any, callback: any): void | undefined {\n if (this._peerConnections.get(peerId)) {\n return callback(this._peerConnections.get(peerId));\n }\n\n return undefined;\n }\n\n //#endregion\n\n //#region ICE Candidates\n\n _iceCandidateReceivedHandler(iceCandidateData: any): void {\n const {candidate, peerId} = iceCandidateData;\n\n trace.info('_iceCandidateReceivedHandler', candidate);\n if (!candidate) {\n trace.info('Unexpected case, iceCandidate message arrived without candidate');\n\n return;\n }\n\n const peerConnection = this._peerConnections.get(peerId);\n\n if (!peerConnection || !peerConnection.remoteDescription) {\n trace.info('Queueing iceCandidate', candidate);\n this._queueIceCandidate(candidate, peerId);\n\n return;\n }\n\n trace.info('Going to add iceCandidate', candidate);\n this._addIceCandidateToPeer(candidate, peerConnection).catch(() => undefined);\n }\n\n _addIceCandidateToPeer(iceCandidate: RTCIceCandidate, peerConnection: RTCPeerConnection): Promise<void> {\n return peerConnection.addIceCandidate(iceCandidate)\n .then(() => {\n trace.info('ICE Candidate add to peer connection');\n })\n .catch((e) => {\n trace.warn('Error adding ICE Candidate to peer connection', e);\n throw e;\n });\n }\n\n _processQueuedIceCandidates(peerId: string): void {\n this._withPeerConnection(peerId, (peerConnection: RTCPeerConnection) => {\n const pendingIces = this._pendingPeersIce[peerId];\n\n if (pendingIces) {\n pendingIces.forEach((pendingIce: RTCIceCandidate) => {\n trace.info('Adding pending ICE to peer connections');\n this._addIceCandidateToPeer(pendingIce, peerConnection).catch(() => undefined);\n });\n } else {\n trace.info('No pending ICE found for peer', peerId);\n }\n });\n }\n\n _queueIceCandidate(iceCandidate: RTCIceCandidate, peerId: string): void {\n if (!this._pendingPeersIce[peerId]) {\n this._pendingPeersIce[peerId] = [];\n }\n\n this._pendingPeersIce[peerId].push(iceCandidate);\n }\n\n _iceStateDisconnected(peerConnection: RTCPeerConnection): void {\n this._disconnectInternal(MediaSessionDisconnectReason.PeerConnectionInterrupted).catch(() => undefined);\n }\n\n //#endregion\n}\n"]}
@@ -1,5 +1,24 @@
1
1
  "use strict";
2
2
 
3
+ var __extends = undefined && undefined.__extends || function () {
4
+ var _extendStatics = function extendStatics(d, b) {
5
+ _extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function (d, b) {
6
+ d.__proto__ = b;
7
+ } || function (d, b) {
8
+ for (var p in b) {
9
+ if (b.hasOwnProperty(p)) d[p] = b[p];
10
+ }
11
+ };
12
+ return _extendStatics(d, b);
13
+ };
14
+ return function (d, b) {
15
+ _extendStatics(d, b);
16
+ function __() {
17
+ this.constructor = d;
18
+ }
19
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
20
+ };
21
+ }();
3
22
  var __importStar = undefined && undefined.__importStar || function (mod) {
4
23
  if (mod && mod.__esModule) return mod;
5
24
  var result = {};
@@ -17,16 +36,16 @@ var once_1 = __importDefault(require("lodash/once"));
17
36
  var MediaConstants_1 = require("../MediaConstants");
18
37
  var TurnConstants_1 = require("./TurnConstants");
19
38
  var MediaTracer_1 = require("../MediaUtils/MediaTracer");
39
+ var MediaSessionBase_1 = require("./MediaSessionBase");
20
40
  var trace = MediaTracer_1.getMediaTracer('TurnSessionV3');
21
41
  //Currently this version supports subscribing only. Publishing will be implemented as needed.
22
- var TurnWebRtcSessionV3 = /** @class */function () {
42
+ var TurnWebRtcSessionV3 = /** @class */function (_super) {
43
+ __extends(TurnWebRtcSessionV3, _super);
23
44
  function TurnWebRtcSessionV3(sessionParams, sessionHandlers, streamFactory) {
24
- this._sessionParams = sessionParams;
25
- this._sessionStreamsManager = streamFactory;
26
- this._sessionHandlers = sessionHandlers;
27
- this._socket = null;
28
- this._pendingPeersIce = {};
29
- this._peerConnections = new Map();
45
+ var _this = _super.call(this, sessionParams, streamFactory) || this;
46
+ _this._sessionHandlers = sessionHandlers;
47
+ _this._socket = null;
48
+ _this._pendingPeersIce = {};
30
49
  var iceServers = sessionParams.credentials.ice.map(function (item) {
31
50
  return {
32
51
  urls: item.url,
@@ -34,17 +53,18 @@ var TurnWebRtcSessionV3 = /** @class */function () {
34
53
  credential: item.password
35
54
  };
36
55
  });
37
- this._configuration = {
56
+ _this._configuration = {
38
57
  iceServers: iceServers,
39
58
  iceTransportPolicy: 'relay'
40
59
  };
41
- this._joinResponseHandler = this._joinResponseHandler.bind(this);
42
- this._iceCandidateReceivedHandler = this._iceCandidateReceivedHandler.bind(this);
43
- this._sendOfferHandler = this._sendOfferHandler.bind(this);
44
- this._sdpOfferHandler = this._sdpOfferHandler.bind(this);
45
- this._userPeerReconnectHandler = this._userPeerReconnectHandler.bind(this);
46
- this._peerDisconnectedHandler = this._peerDisconnectedHandler.bind(this);
47
- this._onSocketDisconnectedHandler = this._onSocketDisconnectedHandler.bind(this);
60
+ _this._joinResponseHandler = _this._joinResponseHandler.bind(_this);
61
+ _this._iceCandidateReceivedHandler = _this._iceCandidateReceivedHandler.bind(_this);
62
+ _this._sendOfferHandler = _this._sendOfferHandler.bind(_this);
63
+ _this._sdpOfferHandler = _this._sdpOfferHandler.bind(_this);
64
+ _this._userPeerReconnectHandler = _this._userPeerReconnectHandler.bind(_this);
65
+ _this._peerDisconnectedHandler = _this._peerDisconnectedHandler.bind(_this);
66
+ _this._onSocketDisconnectedHandler = _this._onSocketDisconnectedHandler.bind(_this);
67
+ return _this;
48
68
  }
49
69
  Object.defineProperty(TurnWebRtcSessionV3.prototype, "id", {
50
70
  get: function get() {
@@ -131,17 +151,7 @@ var TurnWebRtcSessionV3 = /** @class */function () {
131
151
  peerConnection.ontrack = function (trackEvent) {
132
152
  var track = trackEvent.track;
133
153
  trace.info("MediaStreamTrack arrived from peerConnection: " + track.kind, track);
134
- //We only support to stream audio from dashboard
135
- if (track.kind.toLowerCase() === 'audio') {
136
- var remoteMediaTrack = {
137
- mediaTrack: track,
138
- trackType: MediaConstants_1.KnownMediaStream.AGENT_AUDIO_STREAM
139
- };
140
- peerConnection.remoteMediaTracks.push(remoteMediaTrack);
141
- _this._sessionStreamsManager.addRemoteMediaTrack(remoteMediaTrack).catch(function (error) {
142
- trace.warn('Error adding remote media track to available streams', error);
143
- });
144
- }
154
+ _this.registerMediaTrackFromPeer(peerConnection, track);
145
155
  };
146
156
  //TODO - Alex: Currently we not sending "role" through signaling, and by default we assume that the one who asks fot offer, is agent.
147
157
  //On later stages we can send or the client "role" or the list of "streams" that peer is interested in.
@@ -288,15 +298,7 @@ var TurnWebRtcSessionV3 = /** @class */function () {
288
298
  return Promise.resolve();
289
299
  };
290
300
  TurnWebRtcSessionV3.prototype.getRemoteTrackStats = function (mediaTrack) {
291
- var peerConnectionOfTrack = null;
292
- this._peerConnections.forEach(function (peerConnection) {
293
- var remoteTrack = peerConnection.remoteMediaTracks.filter(function (track) {
294
- return track.mediaTrack.id === mediaTrack.id;
295
- });
296
- if (remoteTrack.length === 1) {
297
- peerConnectionOfTrack = peerConnection;
298
- }
299
- });
301
+ var peerConnectionOfTrack = this.getPeerConnectionByMediaTrack(mediaTrack);
300
302
  if (peerConnectionOfTrack !== null) {
301
303
  return peerConnectionOfTrack.getStats(mediaTrack);
302
304
  }
@@ -357,18 +359,13 @@ var TurnWebRtcSessionV3 = /** @class */function () {
357
359
  return peerConnection;
358
360
  };
359
361
  TurnWebRtcSessionV3.prototype._destroyPeerConnection = function (peerConnection) {
360
- var _this = this;
361
362
  trace.info('Destroying PeerConnection', peerConnection.peerType);
362
363
  peerConnection.ontrack = null;
363
364
  peerConnection.onicecandidate = null;
364
365
  peerConnection.onconnectionstatechange = null;
365
366
  peerConnection.oniceconnectionstatechange = null;
366
367
  peerConnection.onicegatheringstatechange = null;
367
- peerConnection.remoteMediaTracks.forEach(function (remoteMediaTrack) {
368
- _this._sessionStreamsManager.removeMediaTrack(remoteMediaTrack.mediaTrack).catch(function () {
369
- trace.warn('Error while removing remote media track', remoteMediaTrack);
370
- });
371
- });
368
+ this.unregisterPeersRemoteMediaTracks(peerConnection);
372
369
  this._peerConnections.delete(peerConnection.peerId);
373
370
  peerConnection.close();
374
371
  };
@@ -435,7 +432,7 @@ var TurnWebRtcSessionV3 = /** @class */function () {
435
432
  });
436
433
  };
437
434
  return TurnWebRtcSessionV3;
438
- }();
435
+ }(MediaSessionBase_1.MediaSessionBase);
439
436
  exports.TurnWebRtcSessionV3 = TurnWebRtcSessionV3;
440
437
 
441
438
  //# sourceMappingURL=SessionTurn.v3.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["MediaSession/SessionTurn.v3.js"],"names":["__importStar","mod","__esModule","result","k","Object","hasOwnProperty","call","__importDefault","defineProperty","exports","value","io","require","once_1","MediaConstants_1","TurnConstants_1","MediaTracer_1","trace","getMediaTracer","TurnWebRtcSessionV3","sessionParams","sessionHandlers","streamFactory","_sessionParams","_sessionStreamsManager","_sessionHandlers","_socket","_pendingPeersIce","_peerConnections","Map","iceServers","credentials","ice","map","item","urls","url","username","login","credential","password","_configuration","iceTransportPolicy","_joinResponseHandler","bind","_iceCandidateReceivedHandler","_sendOfferHandler","_sdpOfferHandler","_userPeerReconnectHandler","_peerDisconnectedHandler","_onSocketDisconnectedHandler","prototype","get","sessionId","enumerable","configurable","connect","connectOnly","_this","info","_connectSocket","then","emit","SOCKET_EVENTS","OUTGOING","JOIN_ROOM","clientType","catch","error","disconnect","_disconnectInternal","MediaSessionDisconnectReason","ForcedByConsumer","Promise","resolve","reject","socket","SOCKET_RECONNECTION_DELAY","SOCKET_RECONNECTION_DELAY_MAX","SOCKET_RECONNECTION_ATTEMPTS","SOCKET_PATH","done","default","err","once","on","INCOMING","ERROR","SEND_OFFER","JOIN_RESPONSE","PEER_DISCONNECTED","SDP_OFFER","PUBLISHER_RECONNECT","ICE_CANDIDATE","reason","SignalingChannelDisconnect","undefined","sendOfferEventData","uid","peerId","peerConnection","_createPeerConnection","SessionClientType","GUEST","SessionClientRole","AGENT","offerParams","offerToReceiveAudio","offerToReceiveVideo","ontrack","trackEvent","track","kind","toLowerCase","remoteMediaTrack","mediaTrack","trackType","KnownMediaStream","AGENT_AUDIO_STREAM","remoteMediaTracks","push","addRemoteMediaTrack","warn","getMediaStreamForRole","mediaStream","getTracks","forEach","addTrack","createOffer","offerDesc","sdpOffer","sdp","setLocalDescription","e","joinResponseData","sdpAnswer","_withPeerConnection","answer","RTCSessionDescription","type","setRemoteDescription","_processQueuedIceCandidates","peerDisconnectedEvent","PeerDisconnected","sdpOfferEvent","INITIATOR","USER","remoteTrack","USER_VIDEO_STREAM","USER_AUDIO_STREAM","remoteDesc","createAnswer","SDP_ANSWER","UserPeerReconnected","onMediaStreamDestroyed","clientRole","PublishedStreamDestroyed","onMediaStreamRenewed","getRemoteTrackStats","peerConnectionOfTrack","filter","id","length","getStats","Error","_destroyPeerConnection","off","setTimeout","onDisconnectedHandler","peerConnectionType","peerConnectionRole","RTCPeerConnection","peerType","peerRole","onconnectionstatechange","oniceconnectionstatechange","state","currentTarget","iceConnectionState","cnState","indexOf","_iceStateDisconnected","onicecandidate","event","candidate","set","onicegatheringstatechange","removeMediaTrack","delete","close","callback","iceCandidateData","remoteDescription","_queueIceCandidate","_addIceCandidateToPeer","iceCandidate","addIceCandidate","pendingIces","pendingIce","PeerConnectionInterrupted"],"mappings":"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","file":"SessionTurn.v3.js","sourcesContent":["\"use strict\";\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\n result[\"default\"] = mod;\n return result;\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar io = __importStar(require(\"socket.io-client\"));\nvar once_1 = __importDefault(require(\"lodash/once\"));\nvar MediaConstants_1 = require(\"../MediaConstants\");\nvar TurnConstants_1 = require(\"./TurnConstants\");\nvar MediaTracer_1 = require(\"../MediaUtils/MediaTracer\");\nvar trace = MediaTracer_1.getMediaTracer('TurnSessionV3');\n//Currently this version supports subscribing only. Publishing will be implemented as needed.\nvar TurnWebRtcSessionV3 = /** @class */ (function () {\n function TurnWebRtcSessionV3(sessionParams, sessionHandlers, streamFactory) {\n this._sessionParams = sessionParams;\n this._sessionStreamsManager = streamFactory;\n this._sessionHandlers = sessionHandlers;\n this._socket = null;\n this._pendingPeersIce = {};\n this._peerConnections = new Map();\n var iceServers = sessionParams.credentials.ice.map(function (item) { return ({\n urls: item.url,\n username: item.login,\n credential: item.password\n }); });\n this._configuration = {\n iceServers: iceServers,\n iceTransportPolicy: 'relay'\n };\n this._joinResponseHandler = this._joinResponseHandler.bind(this);\n this._iceCandidateReceivedHandler = this._iceCandidateReceivedHandler.bind(this);\n this._sendOfferHandler = this._sendOfferHandler.bind(this);\n this._sdpOfferHandler = this._sdpOfferHandler.bind(this);\n this._userPeerReconnectHandler = this._userPeerReconnectHandler.bind(this);\n this._peerDisconnectedHandler = this._peerDisconnectedHandler.bind(this);\n this._onSocketDisconnectedHandler = this._onSocketDisconnectedHandler.bind(this);\n }\n Object.defineProperty(TurnWebRtcSessionV3.prototype, \"id\", {\n get: function () {\n return this._sessionParams.sessionId;\n },\n enumerable: true,\n configurable: true\n });\n //#region Socket Connectivity\n TurnWebRtcSessionV3.prototype.connect = function (connectOnly) {\n var _this = this;\n if (connectOnly === void 0) { connectOnly = false; }\n trace.info('Connect to session');\n return this._connectSocket(this._sessionParams.credentials.url, connectOnly)\n .then(function () {\n trace.info('Joining SessionId: ' + _this._sessionParams.sessionId);\n _this._socket.emit(TurnConstants_1.SOCKET_EVENTS.OUTGOING.JOIN_ROOM, {\n clientType: _this._sessionParams.clientType,\n sessionId: _this._sessionParams.sessionId\n });\n })\n .catch(function (error) {\n throw error;\n });\n };\n TurnWebRtcSessionV3.prototype.disconnect = function () {\n return this._disconnectInternal(MediaConstants_1.MediaSessionDisconnectReason.ForcedByConsumer);\n };\n TurnWebRtcSessionV3.prototype._connectSocket = function (url, connectOnly) {\n var _this = this;\n return new Promise(function (resolve, reject) {\n var socket = _this._socket = io.connect(url, {\n 'forceNew': true,\n 'reconnectionDelay': TurnConstants_1.SOCKET_RECONNECTION_DELAY,\n 'reconnectionDelayMax': TurnConstants_1.SOCKET_RECONNECTION_DELAY_MAX,\n 'reconnectionAttempts': TurnConstants_1.SOCKET_RECONNECTION_ATTEMPTS,\n 'path': TurnConstants_1.SOCKET_PATH\n });\n var done = once_1.default(function (err) {\n err ? reject(err) : resolve();\n });\n socket.once('connect', function () { return done(); });\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.ERROR, done);\n socket.on('connect_error', done);\n socket.on('connect_timeout', done);\n socket.on('disconnect', _this._onSocketDisconnectedHandler);\n if (!connectOnly) {\n trace.info('Subscribing socket events');\n //PUBLISHING NOT SUPPORTED YET\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.SEND_OFFER, _this._sendOfferHandler);\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.JOIN_RESPONSE, _this._joinResponseHandler);\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.PEER_DISCONNECTED, _this._peerDisconnectedHandler);\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.SDP_OFFER, _this._sdpOfferHandler);\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.PUBLISHER_RECONNECT, _this._userPeerReconnectHandler);\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.ICE_CANDIDATE, _this._iceCandidateReceivedHandler);\n }\n });\n };\n TurnWebRtcSessionV3.prototype._onSocketDisconnectedHandler = function (reason) {\n if (this._socket) {\n // The initial example of differentiating between \"forced\" disconnect and \"network\" disconnect is taken from:\n // https://socket.io/docs/client-api/#Event-%E2%80%98disconnect%E2%80%99\n if (reason !== 'io server disconnect' && reason !== 'io client disconnect') {\n // the disconnection was initiated by the server or by client, you need to call (connect) manually\n this._disconnectInternal(MediaConstants_1.MediaSessionDisconnectReason.SignalingChannelDisconnect).catch(function () { return undefined; });\n }\n }\n };\n //#endregion\n //#region WebRTC Initiator - session Initiator (User on mobile device)\n // Received by Initiator, causing him to emit SDP_OFFER\n TurnWebRtcSessionV3.prototype._sendOfferHandler = function (sendOfferEventData) {\n var _this = this;\n var uid = sendOfferEventData.uid, peerId = sendOfferEventData.peerId;\n trace.info('_sendOfferHandler');\n //Currently we not support of passing role through signaling, so we assume every connection is \"AGENT\" like\n var peerConnection = this._createPeerConnection(peerId, MediaConstants_1.SessionClientType.GUEST, MediaConstants_1.SessionClientRole.AGENT);\n var offerParams = { offerToReceiveAudio: true, offerToReceiveVideo: true };\n peerConnection.ontrack = function (trackEvent) {\n var track = trackEvent.track;\n trace.info(\"MediaStreamTrack arrived from peerConnection: \" + track.kind, track);\n //We only support to stream audio from dashboard\n if (track.kind.toLowerCase() === 'audio') {\n var remoteMediaTrack = {\n mediaTrack: track,\n trackType: MediaConstants_1.KnownMediaStream.AGENT_AUDIO_STREAM\n };\n peerConnection.remoteMediaTracks.push(remoteMediaTrack);\n _this._sessionStreamsManager.addRemoteMediaTrack(remoteMediaTrack)\n .catch(function (error) {\n trace.warn('Error adding remote media track to available streams', error);\n });\n }\n };\n //TODO - Alex: Currently we not sending \"role\" through signaling, and by default we assume that the one who asks fot offer, is agent.\n //On later stages we can send or the client \"role\" or the list of \"streams\" that peer is interested in.\n this._sessionStreamsManager.getMediaStreamForRole(MediaConstants_1.SessionClientRole.AGENT)\n .then(function (mediaStream) {\n trace.info('_sendOfferHandler stream and peer created');\n if (mediaStream) {\n trace.info('Adding local tracks to peer connection');\n mediaStream.getTracks().forEach(function (track) {\n peerConnection.addTrack(track, mediaStream);\n trace.info(\"Local \" + track.kind + \" track added to peer connection\");\n });\n }\n else {\n trace.info('No media stream was found for publishing');\n }\n })\n .then(function () { return peerConnection.createOffer(offerParams); })\n .then(function (offerDesc) {\n trace.info('Initiator has created sdp offer', { offerDesc: offerDesc });\n _this._socket.emit(TurnConstants_1.SOCKET_EVENTS.OUTGOING.SDP_OFFER, {\n uid: uid,\n peerId: peerId,\n sessionId: _this._sessionParams.sessionId,\n sdpOffer: offerDesc.sdp\n });\n return peerConnection.setLocalDescription(offerDesc)\n .then(function () {\n trace.info('Local description was set on peerConnection', peerConnection);\n });\n })\n .catch(function (e) {\n trace.warn('Error', e);\n });\n };\n // Received by the Initiator: Indicates that publish should be started\n TurnWebRtcSessionV3.prototype._joinResponseHandler = function (joinResponseData) {\n var _this = this;\n var sdpAnswer = joinResponseData.sdpAnswer, uid = joinResponseData.uid, peerId = joinResponseData.peerId;\n trace.info('joinResponse Received', { sdpAnswer: sdpAnswer });\n this._withPeerConnection(peerId, function (peerConnection) {\n var answer = new RTCSessionDescription({\n type: 'answer',\n sdp: sdpAnswer\n });\n peerConnection.setRemoteDescription(answer)\n .then(function () {\n trace.info('Remote description was set', answer);\n _this._processQueuedIceCandidates(peerId);\n })\n .catch(function (e) {\n trace.warn('Error', e);\n });\n });\n };\n // Received by Initiator after a guests socket has been disconnected\n TurnWebRtcSessionV3.prototype._peerDisconnectedHandler = function (peerDisconnectedEvent) {\n var _this = this;\n var peerId = peerDisconnectedEvent.peerId;\n trace.info('_peerDisconnectedHandler');\n this._withPeerConnection(peerId, function (peerConnection) {\n _this._disconnectInternal(MediaConstants_1.MediaSessionDisconnectReason.PeerDisconnected).catch(function () { return undefined; });\n });\n };\n //#endregion WebRTC Initiator - session Initiator (User on mobile device)\n //#region WebRTC Guest - session Guest (Agent on dashboard platform)\n // Received by Guest, causing him to emit SDP_ANSWER\n TurnWebRtcSessionV3.prototype._sdpOfferHandler = function (sdpOfferEvent) {\n var _this = this;\n var sdpOffer = sdpOfferEvent.sdpOffer, peerId = sdpOfferEvent.peerId, uid = sdpOfferEvent.uid;\n trace.info('sdpOffer Received', { sdpOffer: sdpOffer });\n var peerConnection = this._createPeerConnection(peerId, MediaConstants_1.SessionClientType.INITIATOR, MediaConstants_1.SessionClientRole.USER);\n peerConnection.ontrack = function (trackEvent) {\n var track = trackEvent.track;\n trace.info(\"MediaStreamTrack arrived from peerConnection: \" + track.kind, track);\n var remoteTrack = {\n mediaTrack: track,\n trackType: track.kind === 'video'\n //Although we can have desktop share stream, we still name it USER_VIDEO_STREAM in dashboard.\n //Because currently we support only one video stream to be streamed at the time, it's not an issue.\n //But when we will need to stream more than one stream of a kind from single peer, this will be need to change.\n ? MediaConstants_1.KnownMediaStream.USER_VIDEO_STREAM : MediaConstants_1.KnownMediaStream.USER_AUDIO_STREAM\n };\n peerConnection.remoteMediaTracks.push(remoteTrack);\n _this._sessionStreamsManager.addRemoteMediaTrack(remoteTrack)\n .catch(function () {\n trace.warn('Error adding remote track to stream manager', remoteTrack);\n });\n };\n this._sessionStreamsManager.getMediaStreamForRole(MediaConstants_1.SessionClientRole.USER)\n .then(function (mediaStream) {\n if (mediaStream) {\n trace.info('Adding local tracks to peer connection');\n mediaStream.getTracks().forEach(function (track) {\n peerConnection.addTrack(track, mediaStream);\n trace.info(\"Local \" + track.kind + \" track added to peer connection\");\n });\n }\n else {\n trace.info('No media stream was found for publishing');\n }\n })\n .then(function () {\n var remoteDesc = new RTCSessionDescription({ type: 'offer', sdp: sdpOffer });\n return peerConnection.setRemoteDescription(remoteDesc)\n .then(function () {\n trace.info('Remote description was set', remoteDesc);\n return peerConnection.createAnswer()\n .then(function (sdpAnswer) {\n trace.info('_sdpOfferHandler answer created', sdpAnswer);\n _this._socket.emit(TurnConstants_1.SOCKET_EVENTS.OUTGOING.SDP_ANSWER, {\n uid: uid,\n peerId: peerId,\n sessionId: _this._sessionParams.sessionId,\n sdpAnswer: sdpAnswer.sdp\n });\n return peerConnection.setLocalDescription(sdpAnswer)\n .then(function () {\n trace.info('_sdpOfferHandler local desc was set');\n _this._processQueuedIceCandidates(peerId);\n });\n });\n });\n })\n .catch(function (e) {\n trace.error('Error in _sdpOfferHandler', e);\n throw e;\n });\n };\n // Received by Guest after an Initiator reconnects to room\n TurnWebRtcSessionV3.prototype._userPeerReconnectHandler = function () {\n trace.info('_userPeerReconnectHandler');\n this._disconnectInternal(MediaConstants_1.MediaSessionDisconnectReason.UserPeerReconnected)\n .catch(function (error) {\n trace.warn('Error while disconnecting during userPeerReconnectHandler.', error);\n });\n };\n //#endregion WebRTC Guest - session Guest (Agent on dashboard platform)\n //#region Peer Connection\n //#region Streams Handling\n TurnWebRtcSessionV3.prototype.onMediaStreamDestroyed = function (clientRole) {\n var _this = this;\n //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation\n this._peerConnections.forEach(function (peerConnection) {\n _this._disconnectInternal(MediaConstants_1.MediaSessionDisconnectReason.PublishedStreamDestroyed).catch(function () { return undefined; });\n });\n return Promise.resolve();\n };\n TurnWebRtcSessionV3.prototype.onMediaStreamRenewed = function (clientRole, mediaStream) {\n //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation\n return Promise.resolve();\n };\n TurnWebRtcSessionV3.prototype.getRemoteTrackStats = function (mediaTrack) {\n var peerConnectionOfTrack = null;\n this._peerConnections.forEach(function (peerConnection) {\n var remoteTrack = peerConnection.remoteMediaTracks.filter(function (track) { return track.mediaTrack.id === mediaTrack.id; });\n if (remoteTrack.length === 1) {\n peerConnectionOfTrack = peerConnection;\n }\n });\n if (peerConnectionOfTrack !== null) {\n return peerConnectionOfTrack.getStats(mediaTrack);\n }\n return Promise.reject(new Error('Provided track is not remote track'));\n };\n //#endregion\n TurnWebRtcSessionV3.prototype._disconnectInternal = function (reason) {\n var _this = this;\n this._peerConnections.forEach(function (peerConnection) {\n _this._destroyPeerConnection(peerConnection);\n });\n trace.info('Disconnecting from session', reason);\n if (this._socket) {\n this._socket.off();\n this._socket.disconnect();\n }\n this._socket = null;\n setTimeout(function () { return _this._sessionHandlers.onDisconnectedHandler(reason); });\n return Promise.resolve();\n };\n TurnWebRtcSessionV3.prototype._createPeerConnection = function (peerId, peerConnectionType, peerConnectionRole) {\n var _this = this;\n if (this._peerConnections.get(peerId)) {\n throw new Error(this._sessionParams.clientType + \" peer connection for \" + peerId + \" already exists\");\n }\n var peerConnection = new RTCPeerConnection(this._configuration);\n peerConnection.peerId = peerId;\n peerConnection.peerType = peerConnectionType;\n peerConnection.remoteMediaTracks = [];\n peerConnection.peerRole = peerConnectionRole;\n peerConnection.onconnectionstatechange = function () {\n trace.info('onconnectionstatechange', peerConnection);\n };\n peerConnection.oniceconnectionstatechange = function (state) {\n trace.info(\"ICE Connection state for peer \" + peerId + \" was changed to: \" + state.currentTarget.iceConnectionState, state);\n var cnState = state.currentTarget.iceConnectionState;\n if (['closed', 'disconnected', 'failed'].indexOf(cnState) > -1) {\n _this._iceStateDisconnected(peerConnection);\n }\n };\n peerConnection.onicecandidate = function (event) {\n if (event.candidate) {\n trace.info(_this._sessionParams.clientType + \" peerConn.onicecandidate\", event.candidate);\n _this._socket.emit(TurnConstants_1.SOCKET_EVENTS.OUTGOING.ICE_CANDIDATE, {\n sessionId: _this._sessionParams.sessionId,\n peerId: peerId,\n candidate: event.candidate,\n clientType: _this._sessionParams.clientType\n });\n }\n else {\n trace.info('ICE Candidate is null in peerConnection', event);\n }\n };\n this._peerConnections.set(peerId, peerConnection);\n trace.info(peerConnectionType + \" peerConnection created\");\n return peerConnection;\n };\n TurnWebRtcSessionV3.prototype._destroyPeerConnection = function (peerConnection) {\n var _this = this;\n trace.info('Destroying PeerConnection', peerConnection.peerType);\n peerConnection.ontrack = null;\n peerConnection.onicecandidate = null;\n peerConnection.onconnectionstatechange = null;\n peerConnection.oniceconnectionstatechange = null;\n peerConnection.onicegatheringstatechange = null;\n peerConnection.remoteMediaTracks.forEach(function (remoteMediaTrack) {\n _this._sessionStreamsManager.removeMediaTrack(remoteMediaTrack.mediaTrack)\n .catch(function () {\n trace.warn('Error while removing remote media track', remoteMediaTrack);\n });\n });\n this._peerConnections.delete(peerConnection.peerId);\n peerConnection.close();\n };\n TurnWebRtcSessionV3.prototype._withPeerConnection = function (peerId, callback) {\n if (this._peerConnections.get(peerId)) {\n return callback(this._peerConnections.get(peerId));\n }\n return undefined;\n };\n //#endregion\n //#region ICE Candidates\n TurnWebRtcSessionV3.prototype._iceCandidateReceivedHandler = function (iceCandidateData) {\n var candidate = iceCandidateData.candidate, peerId = iceCandidateData.peerId;\n trace.info('_iceCandidateReceivedHandler', candidate);\n if (!candidate) {\n trace.info('Unexpected case, iceCandidate message arrived without candidate');\n return;\n }\n var peerConnection = this._peerConnections.get(peerId);\n if (!peerConnection || !peerConnection.remoteDescription) {\n trace.info('Queueing iceCandidate', candidate);\n this._queueIceCandidate(candidate, peerId);\n return;\n }\n trace.info('Going to add iceCandidate', candidate);\n this._addIceCandidateToPeer(candidate, peerConnection).catch(function () { return undefined; });\n };\n TurnWebRtcSessionV3.prototype._addIceCandidateToPeer = function (iceCandidate, peerConnection) {\n return peerConnection.addIceCandidate(iceCandidate)\n .then(function () {\n trace.info('ICE Candidate add to peer connection');\n })\n .catch(function (e) {\n trace.warn('Error adding ICE Candidate to peer connection', e);\n throw e;\n });\n };\n TurnWebRtcSessionV3.prototype._processQueuedIceCandidates = function (peerId) {\n var _this = this;\n this._withPeerConnection(peerId, function (peerConnection) {\n var pendingIces = _this._pendingPeersIce[peerId];\n if (pendingIces) {\n pendingIces.forEach(function (pendingIce) {\n trace.info('Adding pending ICE to peer connections');\n _this._addIceCandidateToPeer(pendingIce, peerConnection).catch(function () { return undefined; });\n });\n }\n else {\n trace.info('No pending ICE found for peer', peerId);\n }\n });\n };\n TurnWebRtcSessionV3.prototype._queueIceCandidate = function (iceCandidate, peerId) {\n if (!this._pendingPeersIce[peerId]) {\n this._pendingPeersIce[peerId] = [];\n }\n this._pendingPeersIce[peerId].push(iceCandidate);\n };\n TurnWebRtcSessionV3.prototype._iceStateDisconnected = function (peerConnection) {\n this._disconnectInternal(MediaConstants_1.MediaSessionDisconnectReason.PeerConnectionInterrupted).catch(function () { return undefined; });\n };\n return TurnWebRtcSessionV3;\n}());\nexports.TurnWebRtcSessionV3 = TurnWebRtcSessionV3;\n\n//# sourceMappingURL=SessionTurn.v3.js.map\n"]}
1
+ {"version":3,"sources":["MediaSession/SessionTurn.v3.js"],"names":["__extends","extendStatics","d","b","Object","setPrototypeOf","__proto__","Array","p","hasOwnProperty","__","constructor","prototype","create","__importStar","mod","__esModule","result","k","call","__importDefault","defineProperty","exports","value","io","require","once_1","MediaConstants_1","TurnConstants_1","MediaTracer_1","MediaSessionBase_1","trace","getMediaTracer","TurnWebRtcSessionV3","_super","sessionParams","sessionHandlers","streamFactory","_this","_sessionHandlers","_socket","_pendingPeersIce","iceServers","credentials","ice","map","item","urls","url","username","login","credential","password","_configuration","iceTransportPolicy","_joinResponseHandler","bind","_iceCandidateReceivedHandler","_sendOfferHandler","_sdpOfferHandler","_userPeerReconnectHandler","_peerDisconnectedHandler","_onSocketDisconnectedHandler","get","_sessionParams","sessionId","enumerable","configurable","connect","connectOnly","info","_connectSocket","then","emit","SOCKET_EVENTS","OUTGOING","JOIN_ROOM","clientType","catch","error","disconnect","_disconnectInternal","MediaSessionDisconnectReason","ForcedByConsumer","Promise","resolve","reject","socket","SOCKET_RECONNECTION_DELAY","SOCKET_RECONNECTION_DELAY_MAX","SOCKET_RECONNECTION_ATTEMPTS","SOCKET_PATH","done","default","err","once","on","INCOMING","ERROR","SEND_OFFER","JOIN_RESPONSE","PEER_DISCONNECTED","SDP_OFFER","PUBLISHER_RECONNECT","ICE_CANDIDATE","reason","SignalingChannelDisconnect","undefined","sendOfferEventData","uid","peerId","peerConnection","_createPeerConnection","SessionClientType","GUEST","SessionClientRole","AGENT","offerParams","offerToReceiveAudio","offerToReceiveVideo","ontrack","trackEvent","track","kind","registerMediaTrackFromPeer","_sessionStreamsManager","getMediaStreamForRole","mediaStream","getTracks","forEach","addTrack","createOffer","offerDesc","sdpOffer","sdp","setLocalDescription","e","warn","joinResponseData","sdpAnswer","_withPeerConnection","answer","RTCSessionDescription","type","setRemoteDescription","_processQueuedIceCandidates","peerDisconnectedEvent","PeerDisconnected","sdpOfferEvent","INITIATOR","USER","remoteTrack","mediaTrack","trackType","KnownMediaStream","USER_VIDEO_STREAM","USER_AUDIO_STREAM","remoteMediaTracks","push","addRemoteMediaTrack","remoteDesc","createAnswer","SDP_ANSWER","UserPeerReconnected","onMediaStreamDestroyed","clientRole","_peerConnections","PublishedStreamDestroyed","onMediaStreamRenewed","getRemoteTrackStats","peerConnectionOfTrack","getPeerConnectionByMediaTrack","getStats","Error","_destroyPeerConnection","off","setTimeout","onDisconnectedHandler","peerConnectionType","peerConnectionRole","RTCPeerConnection","peerType","peerRole","onconnectionstatechange","oniceconnectionstatechange","state","currentTarget","iceConnectionState","cnState","indexOf","_iceStateDisconnected","onicecandidate","event","candidate","set","onicegatheringstatechange","unregisterPeersRemoteMediaTracks","delete","close","callback","iceCandidateData","remoteDescription","_queueIceCandidate","_addIceCandidateToPeer","iceCandidate","addIceCandidate","pendingIces","pendingIce","PeerConnectionInterrupted","MediaSessionBase"],"mappings":"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","file":"SessionTurn.v3.js","sourcesContent":["\"use strict\";\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\n result[\"default\"] = mod;\n return result;\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar io = __importStar(require(\"socket.io-client\"));\nvar once_1 = __importDefault(require(\"lodash/once\"));\nvar MediaConstants_1 = require(\"../MediaConstants\");\nvar TurnConstants_1 = require(\"./TurnConstants\");\nvar MediaTracer_1 = require(\"../MediaUtils/MediaTracer\");\nvar MediaSessionBase_1 = require(\"./MediaSessionBase\");\nvar trace = MediaTracer_1.getMediaTracer('TurnSessionV3');\n//Currently this version supports subscribing only. Publishing will be implemented as needed.\nvar TurnWebRtcSessionV3 = /** @class */ (function (_super) {\n __extends(TurnWebRtcSessionV3, _super);\n function TurnWebRtcSessionV3(sessionParams, sessionHandlers, streamFactory) {\n var _this = _super.call(this, sessionParams, streamFactory) || this;\n _this._sessionHandlers = sessionHandlers;\n _this._socket = null;\n _this._pendingPeersIce = {};\n var iceServers = sessionParams.credentials.ice.map(function (item) { return ({\n urls: item.url,\n username: item.login,\n credential: item.password\n }); });\n _this._configuration = {\n iceServers: iceServers,\n iceTransportPolicy: 'relay'\n };\n _this._joinResponseHandler = _this._joinResponseHandler.bind(_this);\n _this._iceCandidateReceivedHandler = _this._iceCandidateReceivedHandler.bind(_this);\n _this._sendOfferHandler = _this._sendOfferHandler.bind(_this);\n _this._sdpOfferHandler = _this._sdpOfferHandler.bind(_this);\n _this._userPeerReconnectHandler = _this._userPeerReconnectHandler.bind(_this);\n _this._peerDisconnectedHandler = _this._peerDisconnectedHandler.bind(_this);\n _this._onSocketDisconnectedHandler = _this._onSocketDisconnectedHandler.bind(_this);\n return _this;\n }\n Object.defineProperty(TurnWebRtcSessionV3.prototype, \"id\", {\n get: function () {\n return this._sessionParams.sessionId;\n },\n enumerable: true,\n configurable: true\n });\n //#region Socket Connectivity\n TurnWebRtcSessionV3.prototype.connect = function (connectOnly) {\n var _this = this;\n if (connectOnly === void 0) { connectOnly = false; }\n trace.info('Connect to session');\n return this._connectSocket(this._sessionParams.credentials.url, connectOnly)\n .then(function () {\n trace.info('Joining SessionId: ' + _this._sessionParams.sessionId);\n _this._socket.emit(TurnConstants_1.SOCKET_EVENTS.OUTGOING.JOIN_ROOM, {\n clientType: _this._sessionParams.clientType,\n sessionId: _this._sessionParams.sessionId\n });\n })\n .catch(function (error) {\n throw error;\n });\n };\n TurnWebRtcSessionV3.prototype.disconnect = function () {\n return this._disconnectInternal(MediaConstants_1.MediaSessionDisconnectReason.ForcedByConsumer);\n };\n TurnWebRtcSessionV3.prototype._connectSocket = function (url, connectOnly) {\n var _this = this;\n return new Promise(function (resolve, reject) {\n var socket = _this._socket = io.connect(url, {\n 'forceNew': true,\n 'reconnectionDelay': TurnConstants_1.SOCKET_RECONNECTION_DELAY,\n 'reconnectionDelayMax': TurnConstants_1.SOCKET_RECONNECTION_DELAY_MAX,\n 'reconnectionAttempts': TurnConstants_1.SOCKET_RECONNECTION_ATTEMPTS,\n 'path': TurnConstants_1.SOCKET_PATH\n });\n var done = once_1.default(function (err) {\n err ? reject(err) : resolve();\n });\n socket.once('connect', function () { return done(); });\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.ERROR, done);\n socket.on('connect_error', done);\n socket.on('connect_timeout', done);\n socket.on('disconnect', _this._onSocketDisconnectedHandler);\n if (!connectOnly) {\n trace.info('Subscribing socket events');\n //PUBLISHING NOT SUPPORTED YET\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.SEND_OFFER, _this._sendOfferHandler);\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.JOIN_RESPONSE, _this._joinResponseHandler);\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.PEER_DISCONNECTED, _this._peerDisconnectedHandler);\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.SDP_OFFER, _this._sdpOfferHandler);\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.PUBLISHER_RECONNECT, _this._userPeerReconnectHandler);\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.ICE_CANDIDATE, _this._iceCandidateReceivedHandler);\n }\n });\n };\n TurnWebRtcSessionV3.prototype._onSocketDisconnectedHandler = function (reason) {\n if (this._socket) {\n // The initial example of differentiating between \"forced\" disconnect and \"network\" disconnect is taken from:\n // https://socket.io/docs/client-api/#Event-%E2%80%98disconnect%E2%80%99\n if (reason !== 'io server disconnect' && reason !== 'io client disconnect') {\n // the disconnection was initiated by the server or by client, you need to call (connect) manually\n this._disconnectInternal(MediaConstants_1.MediaSessionDisconnectReason.SignalingChannelDisconnect).catch(function () { return undefined; });\n }\n }\n };\n //#endregion\n //#region WebRTC Initiator - session Initiator (User on mobile device)\n // Received by Initiator, causing him to emit SDP_OFFER\n TurnWebRtcSessionV3.prototype._sendOfferHandler = function (sendOfferEventData) {\n var _this = this;\n var uid = sendOfferEventData.uid, peerId = sendOfferEventData.peerId;\n trace.info('_sendOfferHandler');\n //Currently we not support of passing role through signaling, so we assume every connection is \"AGENT\" like\n var peerConnection = this._createPeerConnection(peerId, MediaConstants_1.SessionClientType.GUEST, MediaConstants_1.SessionClientRole.AGENT);\n var offerParams = { offerToReceiveAudio: true, offerToReceiveVideo: true };\n peerConnection.ontrack = function (trackEvent) {\n var track = trackEvent.track;\n trace.info(\"MediaStreamTrack arrived from peerConnection: \" + track.kind, track);\n _this.registerMediaTrackFromPeer(peerConnection, track);\n };\n //TODO - Alex: Currently we not sending \"role\" through signaling, and by default we assume that the one who asks fot offer, is agent.\n //On later stages we can send or the client \"role\" or the list of \"streams\" that peer is interested in.\n this._sessionStreamsManager.getMediaStreamForRole(MediaConstants_1.SessionClientRole.AGENT)\n .then(function (mediaStream) {\n trace.info('_sendOfferHandler stream and peer created');\n if (mediaStream) {\n trace.info('Adding local tracks to peer connection');\n mediaStream.getTracks().forEach(function (track) {\n peerConnection.addTrack(track, mediaStream);\n trace.info(\"Local \" + track.kind + \" track added to peer connection\");\n });\n }\n else {\n trace.info('No media stream was found for publishing');\n }\n })\n .then(function () { return peerConnection.createOffer(offerParams); })\n .then(function (offerDesc) {\n trace.info('Initiator has created sdp offer', { offerDesc: offerDesc });\n _this._socket.emit(TurnConstants_1.SOCKET_EVENTS.OUTGOING.SDP_OFFER, {\n uid: uid,\n peerId: peerId,\n sessionId: _this._sessionParams.sessionId,\n sdpOffer: offerDesc.sdp\n });\n return peerConnection.setLocalDescription(offerDesc)\n .then(function () {\n trace.info('Local description was set on peerConnection', peerConnection);\n });\n })\n .catch(function (e) {\n trace.warn('Error', e);\n });\n };\n // Received by the Initiator: Indicates that publish should be started\n TurnWebRtcSessionV3.prototype._joinResponseHandler = function (joinResponseData) {\n var _this = this;\n var sdpAnswer = joinResponseData.sdpAnswer, uid = joinResponseData.uid, peerId = joinResponseData.peerId;\n trace.info('joinResponse Received', { sdpAnswer: sdpAnswer });\n this._withPeerConnection(peerId, function (peerConnection) {\n var answer = new RTCSessionDescription({\n type: 'answer',\n sdp: sdpAnswer\n });\n peerConnection.setRemoteDescription(answer)\n .then(function () {\n trace.info('Remote description was set', answer);\n _this._processQueuedIceCandidates(peerId);\n })\n .catch(function (e) {\n trace.warn('Error', e);\n });\n });\n };\n // Received by Initiator after a guests socket has been disconnected\n TurnWebRtcSessionV3.prototype._peerDisconnectedHandler = function (peerDisconnectedEvent) {\n var _this = this;\n var peerId = peerDisconnectedEvent.peerId;\n trace.info('_peerDisconnectedHandler');\n this._withPeerConnection(peerId, function (peerConnection) {\n _this._disconnectInternal(MediaConstants_1.MediaSessionDisconnectReason.PeerDisconnected).catch(function () { return undefined; });\n });\n };\n //#endregion WebRTC Initiator - session Initiator (User on mobile device)\n //#region WebRTC Guest - session Guest (Agent on dashboard platform)\n // Received by Guest, causing him to emit SDP_ANSWER\n TurnWebRtcSessionV3.prototype._sdpOfferHandler = function (sdpOfferEvent) {\n var _this = this;\n var sdpOffer = sdpOfferEvent.sdpOffer, peerId = sdpOfferEvent.peerId, uid = sdpOfferEvent.uid;\n trace.info('sdpOffer Received', { sdpOffer: sdpOffer });\n var peerConnection = this._createPeerConnection(peerId, MediaConstants_1.SessionClientType.INITIATOR, MediaConstants_1.SessionClientRole.USER);\n peerConnection.ontrack = function (trackEvent) {\n var track = trackEvent.track;\n trace.info(\"MediaStreamTrack arrived from peerConnection: \" + track.kind, track);\n var remoteTrack = {\n mediaTrack: track,\n trackType: track.kind === 'video'\n //Although we can have desktop share stream, we still name it USER_VIDEO_STREAM in dashboard.\n //Because currently we support only one video stream to be streamed at the time, it's not an issue.\n //But when we will need to stream more than one stream of a kind from single peer, this will be need to change.\n ? MediaConstants_1.KnownMediaStream.USER_VIDEO_STREAM : MediaConstants_1.KnownMediaStream.USER_AUDIO_STREAM\n };\n peerConnection.remoteMediaTracks.push(remoteTrack);\n _this._sessionStreamsManager.addRemoteMediaTrack(remoteTrack)\n .catch(function () {\n trace.warn('Error adding remote track to stream manager', remoteTrack);\n });\n };\n this._sessionStreamsManager.getMediaStreamForRole(MediaConstants_1.SessionClientRole.USER)\n .then(function (mediaStream) {\n if (mediaStream) {\n trace.info('Adding local tracks to peer connection');\n mediaStream.getTracks().forEach(function (track) {\n peerConnection.addTrack(track, mediaStream);\n trace.info(\"Local \" + track.kind + \" track added to peer connection\");\n });\n }\n else {\n trace.info('No media stream was found for publishing');\n }\n })\n .then(function () {\n var remoteDesc = new RTCSessionDescription({ type: 'offer', sdp: sdpOffer });\n return peerConnection.setRemoteDescription(remoteDesc)\n .then(function () {\n trace.info('Remote description was set', remoteDesc);\n return peerConnection.createAnswer()\n .then(function (sdpAnswer) {\n trace.info('_sdpOfferHandler answer created', sdpAnswer);\n _this._socket.emit(TurnConstants_1.SOCKET_EVENTS.OUTGOING.SDP_ANSWER, {\n uid: uid,\n peerId: peerId,\n sessionId: _this._sessionParams.sessionId,\n sdpAnswer: sdpAnswer.sdp\n });\n return peerConnection.setLocalDescription(sdpAnswer)\n .then(function () {\n trace.info('_sdpOfferHandler local desc was set');\n _this._processQueuedIceCandidates(peerId);\n });\n });\n });\n })\n .catch(function (e) {\n trace.error('Error in _sdpOfferHandler', e);\n throw e;\n });\n };\n // Received by Guest after an Initiator reconnects to room\n TurnWebRtcSessionV3.prototype._userPeerReconnectHandler = function () {\n trace.info('_userPeerReconnectHandler');\n this._disconnectInternal(MediaConstants_1.MediaSessionDisconnectReason.UserPeerReconnected)\n .catch(function (error) {\n trace.warn('Error while disconnecting during userPeerReconnectHandler.', error);\n });\n };\n //#endregion WebRTC Guest - session Guest (Agent on dashboard platform)\n //#region Peer Connection\n //#region Streams Handling\n TurnWebRtcSessionV3.prototype.onMediaStreamDestroyed = function (clientRole) {\n var _this = this;\n //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation\n this._peerConnections.forEach(function (peerConnection) {\n _this._disconnectInternal(MediaConstants_1.MediaSessionDisconnectReason.PublishedStreamDestroyed).catch(function () { return undefined; });\n });\n return Promise.resolve();\n };\n TurnWebRtcSessionV3.prototype.onMediaStreamRenewed = function (clientRole, mediaStream) {\n //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation\n return Promise.resolve();\n };\n TurnWebRtcSessionV3.prototype.getRemoteTrackStats = function (mediaTrack) {\n var peerConnectionOfTrack = this.getPeerConnectionByMediaTrack(mediaTrack);\n if (peerConnectionOfTrack !== null) {\n return peerConnectionOfTrack.getStats(mediaTrack);\n }\n return Promise.reject(new Error('Provided track is not remote track'));\n };\n //#endregion\n TurnWebRtcSessionV3.prototype._disconnectInternal = function (reason) {\n var _this = this;\n this._peerConnections.forEach(function (peerConnection) {\n _this._destroyPeerConnection(peerConnection);\n });\n trace.info('Disconnecting from session', reason);\n if (this._socket) {\n this._socket.off();\n this._socket.disconnect();\n }\n this._socket = null;\n setTimeout(function () { return _this._sessionHandlers.onDisconnectedHandler(reason); });\n return Promise.resolve();\n };\n TurnWebRtcSessionV3.prototype._createPeerConnection = function (peerId, peerConnectionType, peerConnectionRole) {\n var _this = this;\n if (this._peerConnections.get(peerId)) {\n throw new Error(this._sessionParams.clientType + \" peer connection for \" + peerId + \" already exists\");\n }\n var peerConnection = new RTCPeerConnection(this._configuration);\n peerConnection.peerId = peerId;\n peerConnection.peerType = peerConnectionType;\n peerConnection.remoteMediaTracks = [];\n peerConnection.peerRole = peerConnectionRole;\n peerConnection.onconnectionstatechange = function () {\n trace.info('onconnectionstatechange', peerConnection);\n };\n peerConnection.oniceconnectionstatechange = function (state) {\n trace.info(\"ICE Connection state for peer \" + peerId + \" was changed to: \" + state.currentTarget.iceConnectionState, state);\n var cnState = state.currentTarget.iceConnectionState;\n if (['closed', 'disconnected', 'failed'].indexOf(cnState) > -1) {\n _this._iceStateDisconnected(peerConnection);\n }\n };\n peerConnection.onicecandidate = function (event) {\n if (event.candidate) {\n trace.info(_this._sessionParams.clientType + \" peerConn.onicecandidate\", event.candidate);\n _this._socket.emit(TurnConstants_1.SOCKET_EVENTS.OUTGOING.ICE_CANDIDATE, {\n sessionId: _this._sessionParams.sessionId,\n peerId: peerId,\n candidate: event.candidate,\n clientType: _this._sessionParams.clientType\n });\n }\n else {\n trace.info('ICE Candidate is null in peerConnection', event);\n }\n };\n this._peerConnections.set(peerId, peerConnection);\n trace.info(peerConnectionType + \" peerConnection created\");\n return peerConnection;\n };\n TurnWebRtcSessionV3.prototype._destroyPeerConnection = function (peerConnection) {\n trace.info('Destroying PeerConnection', peerConnection.peerType);\n peerConnection.ontrack = null;\n peerConnection.onicecandidate = null;\n peerConnection.onconnectionstatechange = null;\n peerConnection.oniceconnectionstatechange = null;\n peerConnection.onicegatheringstatechange = null;\n this.unregisterPeersRemoteMediaTracks(peerConnection);\n this._peerConnections.delete(peerConnection.peerId);\n peerConnection.close();\n };\n TurnWebRtcSessionV3.prototype._withPeerConnection = function (peerId, callback) {\n if (this._peerConnections.get(peerId)) {\n return callback(this._peerConnections.get(peerId));\n }\n return undefined;\n };\n //#endregion\n //#region ICE Candidates\n TurnWebRtcSessionV3.prototype._iceCandidateReceivedHandler = function (iceCandidateData) {\n var candidate = iceCandidateData.candidate, peerId = iceCandidateData.peerId;\n trace.info('_iceCandidateReceivedHandler', candidate);\n if (!candidate) {\n trace.info('Unexpected case, iceCandidate message arrived without candidate');\n return;\n }\n var peerConnection = this._peerConnections.get(peerId);\n if (!peerConnection || !peerConnection.remoteDescription) {\n trace.info('Queueing iceCandidate', candidate);\n this._queueIceCandidate(candidate, peerId);\n return;\n }\n trace.info('Going to add iceCandidate', candidate);\n this._addIceCandidateToPeer(candidate, peerConnection).catch(function () { return undefined; });\n };\n TurnWebRtcSessionV3.prototype._addIceCandidateToPeer = function (iceCandidate, peerConnection) {\n return peerConnection.addIceCandidate(iceCandidate)\n .then(function () {\n trace.info('ICE Candidate add to peer connection');\n })\n .catch(function (e) {\n trace.warn('Error adding ICE Candidate to peer connection', e);\n throw e;\n });\n };\n TurnWebRtcSessionV3.prototype._processQueuedIceCandidates = function (peerId) {\n var _this = this;\n this._withPeerConnection(peerId, function (peerConnection) {\n var pendingIces = _this._pendingPeersIce[peerId];\n if (pendingIces) {\n pendingIces.forEach(function (pendingIce) {\n trace.info('Adding pending ICE to peer connections');\n _this._addIceCandidateToPeer(pendingIce, peerConnection).catch(function () { return undefined; });\n });\n }\n else {\n trace.info('No pending ICE found for peer', peerId);\n }\n });\n };\n TurnWebRtcSessionV3.prototype._queueIceCandidate = function (iceCandidate, peerId) {\n if (!this._pendingPeersIce[peerId]) {\n this._pendingPeersIce[peerId] = [];\n }\n this._pendingPeersIce[peerId].push(iceCandidate);\n };\n TurnWebRtcSessionV3.prototype._iceStateDisconnected = function (peerConnection) {\n this._disconnectInternal(MediaConstants_1.MediaSessionDisconnectReason.PeerConnectionInterrupted).catch(function () { return undefined; });\n };\n return TurnWebRtcSessionV3;\n}(MediaSessionBase_1.MediaSessionBase));\nexports.TurnWebRtcSessionV3 = TurnWebRtcSessionV3;\n\n//# sourceMappingURL=SessionTurn.v3.js.map\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@techsee/techsee-media-service",
3
- "version": "0.6.1-alpha.3",
3
+ "version": "0.6.1-alpha.5",
4
4
  "description": "Techsee Media Service Client",
5
5
  "author": "TechSee - Alex Danilov",
6
6
  "main": "lib/index.js",