@techsee/techsee-media-service 0.6.1-alpha.4 → 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.
@@ -1,8 +1,9 @@
1
1
  import { IMediaSessionPeer } from './MediaSessionBase';
2
2
  import { SessionClientRole, SessionClientType } from '../MediaConstants';
3
3
  import { ISessionStreamsManager, MediaSessionParams, RemoteMediaTrack } from '../MediaContracts';
4
+ import { Nullable } from '@techsee/techsee-common';
4
5
  export interface IMediaSessionPeer {
5
- peerId: any;
6
+ peerId: string;
6
7
  peerType: SessionClientType;
7
8
  peerRole: SessionClientRole;
8
9
  remoteMediaTracks: RemoteMediaTrack[];
@@ -11,9 +12,12 @@ declare global {
11
12
  interface RTCPeerConnection extends IMediaSessionPeer {
12
13
  }
13
14
  }
14
- export declare abstract class MediaSessionBase {
15
+ export declare abstract class MediaSessionBase<PeerType extends IMediaSessionPeer> {
16
+ protected readonly _peerConnections: Map<string, PeerType>;
15
17
  protected readonly _sessionStreamsManager: ISessionStreamsManager;
16
18
  protected readonly _sessionParams: MediaSessionParams;
17
19
  protected constructor(sessionParams: MediaSessionParams, streamFactory: ISessionStreamsManager);
18
20
  protected registerMediaTrackFromPeer(sourcePeerConnection: IMediaSessionPeer, mediaTrack: MediaStreamTrack): void;
21
+ unregisterPeersRemoteMediaTracks(peerConnection: PeerType): void;
22
+ protected getPeerConnectionByMediaTrack(mediaTrack: MediaStreamTrack): Nullable<PeerType>;
19
23
  }
@@ -1 +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;AAK/F,MAAM,WAAW,iBAAiB;IAC9B,MAAM,EAAE,GAAG,CAAC;IACZ,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;AAKD,8BAAsB,gBAAgB;IAClC,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;IAK9F,SAAS,CAAC,0BAA0B,CAAC,oBAAoB,EAAE,iBAAiB,EAAE,UAAU,EAAE,gBAAgB;CAyB7G","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: any;\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\n\nexport abstract class MediaSessionBase {\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\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"]}
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"]}
@@ -6,8 +6,10 @@ var MediaTracer_1 = require("../MediaUtils/MediaTracer");
6
6
  var trace = MediaTracer_1.getMediaTracer('MediaSessionBase');
7
7
  var MediaSessionBase = /** @class */function () {
8
8
  function MediaSessionBase(sessionParams, streamFactory) {
9
+ this._peerConnections = new Map();
9
10
  this._sessionParams = sessionParams;
10
11
  this._sessionStreamsManager = streamFactory;
12
+ this._peerConnections = new Map();
11
13
  }
12
14
  MediaSessionBase.prototype.registerMediaTrackFromPeer = function (sourcePeerConnection, mediaTrack) {
13
15
  if (mediaTrack.kind === MediaConstants_1.KnownMediaStreamKind.Video && sourcePeerConnection.peerRole === MediaConstants_1.SessionClientRole.AGENT) {
@@ -26,6 +28,29 @@ var MediaSessionBase = /** @class */function () {
26
28
  trace.warn('Error adding remote media track to available streams', error);
27
29
  });
28
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
+ };
29
54
  return MediaSessionBase;
30
55
  }();
31
56
  exports.MediaSessionBase = MediaSessionBase;
@@ -1 +1 @@
1
- {"version":3,"sources":["MediaSession/MediaSessionBase.js"],"names":["Object","defineProperty","exports","value","MediaConstants_1","require","MediaTracer_1","trace","getMediaTracer","MediaSessionBase","sessionParams","streamFactory","_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"],"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,cAAL,GAAsBF,aAAtB;AACA,aAAKG,sBAAL,GAA8BF,aAA9B;AACH;AACDF,qBAAiBK,SAAjB,CAA2BC,0BAA3B,GAAwD,UAAUC,oBAAV,EAAgCC,UAAhC,EAA4C;AAChG,YAAIA,WAAWC,IAAX,KAAoBd,iBAAiBe,oBAAjB,CAAsCC,KAA1D,IACAJ,qBAAqBK,QAArB,KAAkCjB,iBAAiBkB,iBAAjB,CAAmCC,KADzE,EACgF;AAC5E;AACA;AACH;AACD,YAAIC,YAAY,IAAhB;AACA,YAAIP,WAAWC,IAAX,CAAgBO,WAAhB,OAAkCrB,iBAAiBe,oBAAjB,CAAsCO,KAA5E,EAAmF;AAC/EF,wBAAYR,qBAAqBK,QAArB,KAAkCjB,iBAAiBkB,iBAAjB,CAAmCC,KAArE,GACNnB,iBAAiBuB,gBAAjB,CAAkCC,kBAD5B,GACiDxB,iBAAiBuB,gBAAjB,CAAkCE,iBAD/F;AAEH,SAHD,MAIK;AACDL,wBAAYpB,iBAAiBuB,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;AACxB7B,kBAAM8B,IAAN,CAAW,sDAAX,EAAmED,KAAnE;AACH,SAHD;AAIH,KApBD;AAqBA,WAAO3B,gBAAP;AACH,CA3BqC,EAAtC;AA4BAP,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._sessionParams = sessionParams;\n this._sessionStreamsManager = streamFactory;\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 return MediaSessionBase;\n}());\nexports.MediaSessionBase = MediaSessionBase;\n\n//# sourceMappingURL=MediaSessionBase.js.map\n"]}
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,13 +1,28 @@
1
+ import { Nullable } from '@techsee/techsee-common';
1
2
  import { IMediaSession, ISessionStreamsManager, MediaSessionParams, RemoteTrackStats } from '../MediaContracts';
2
3
  import { SessionClientRole } from '../MediaConstants';
3
- import { MediaSessionBase } from './MediaSessionBase';
4
+ import { IMediaSessionPeer, MediaSessionBase } from './MediaSessionBase';
4
5
  declare global {
5
6
  interface Window {
6
7
  OT: any;
7
8
  }
8
9
  }
9
- export declare class OpentokSessionV3 extends MediaSessionBase implements IMediaSession {
10
- 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 {
11
26
  private readonly _credentials;
12
27
  private _session;
13
28
  readonly id: string;
@@ -15,18 +30,19 @@ export declare class OpentokSessionV3 extends MediaSessionBase implements IMedia
15
30
  constructor(sessionParams: MediaSessionParams, streamFactory: ISessionStreamsManager);
16
31
  connect(): Promise<void>;
17
32
  disconnect(): Promise<void>;
18
- onMediaStreamDestroyed(clientRole: SessionClientRole): Promise<void>;
19
- onMediaStreamRenewed(clientRole: SessionClientRole, mediaStream: MediaStream): Promise<void>;
20
- getRemoteTrackStats(mediaTrack: MediaStreamTrack): Promise<RemoteTrackStats>;
21
33
  private connectionCreatedHandler;
22
34
  private connectionDestroyedHandler;
23
35
  private streamCreatedHandler;
24
36
  private streamDestroyedHandler;
37
+ onMediaStreamDestroyed(clientRole: SessionClientRole): Promise<void>;
38
+ onMediaStreamRenewed(clientRole: SessionClientRole, mediaStream: MediaStream): Promise<void>;
39
+ getRemoteTrackStats(mediaTrack: MediaStreamTrack): Promise<RemoteTrackStats>;
25
40
  private createStreamForPublishing;
26
41
  private calculateDestinationRole;
27
42
  private createMediaPublisher;
28
- private clearPeerConnections;
29
- private sessionExistsGuard;
30
43
  private destroyPeerConnection;
31
44
  private destroyPublisherOnPeerConnection;
45
+ private destroySubscriberOnPeerConnection;
46
+ private sessionExistsGuard;
32
47
  }
48
+ export {};
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/MediaSession/SessionOpentok.v3.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,aAAa,EACb,sBAAsB,EACtB,kBAAkB,EAElB,gBAAgB,EACnB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAmB,iBAAiB,EAAoB,MAAM,mBAAmB,CAAC;AAEzF,OAAO,EAAC,gBAAgB,EAAC,MAAM,oBAAoB,CAAC;AAKpD,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,MAAM;QACZ,EAAE,EAAE,GAAG,CAAC;KACX;CACJ;AAoDD,qBAAa,gBAAiB,SAAQ,gBAAiB,YAAW,aAAa;IAC3E,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;IAkBpF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAwCxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAyB3B,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;IA0EhC,OAAO,CAAC,0BAA0B;IAalC,OAAO,CAAC,oBAAoB;IAyD5B,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,\n RemoteTrackStats\n} from '../MediaContracts';\n\nimport {KnownMediaStream, SessionClientRole, SessionClientType} from '../MediaConstants';\nimport {throwableGuard} from '@techsee/techsee-common/lib/core/guards';\nimport {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 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\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 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 implements IMediaSession {\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 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.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 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 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 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 if (peerConnection.peerId === this.ownPeerId) {\n trace.warn('There nothing to do with stream from our own peer.');\n\n return;\n }\n\n trace.info('Subscribing the stream');\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 }\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"]}
@@ -30,7 +30,6 @@ var OpentokSessionV3 = /** @class */function (_super) {
30
30
  __extends(OpentokSessionV3, _super);
31
31
  function OpentokSessionV3(sessionParams, streamFactory) {
32
32
  var _this = _super.call(this, sessionParams, streamFactory) || this;
33
- _this._peerConnections = new Map();
34
33
  _this._session = null;
35
34
  _this._credentials = sessionParams.credentials;
36
35
  _this.connect = _this.connect.bind(_this);
@@ -39,7 +38,6 @@ var OpentokSessionV3 = /** @class */function (_super) {
39
38
  _this.onMediaStreamRenewed = _this.onMediaStreamRenewed.bind(_this);
40
39
  _this.createStreamForPublishing = _this.createStreamForPublishing.bind(_this);
41
40
  _this.createMediaPublisher = _this.createMediaPublisher.bind(_this);
42
- _this.clearPeerConnections = _this.clearPeerConnections.bind(_this);
43
41
  _this.connectionCreatedHandler = _this.connectionCreatedHandler.bind(_this);
44
42
  _this.connectionDestroyedHandler = _this.connectionDestroyedHandler.bind(_this);
45
43
  _this.streamCreatedHandler = _this.streamCreatedHandler.bind(_this);
@@ -94,8 +92,6 @@ var OpentokSessionV3 = /** @class */function (_super) {
94
92
  };
95
93
  OpentokSessionV3.prototype.disconnect = function () {
96
94
  var _this = this;
97
- //TODO - Alex: Implement destroying all publishers (by opentok docs)
98
- //Create a method destroy publisher (or publishers can treated the same as "peerConnections"?
99
95
  return new Promise(function (resolve) {
100
96
  trace.info('Disconnecting from session');
101
97
  var currentSession = _this._session;
@@ -113,23 +109,6 @@ var OpentokSessionV3 = /** @class */function (_super) {
113
109
  resolve();
114
110
  });
115
111
  };
116
- OpentokSessionV3.prototype.onMediaStreamDestroyed = function (clientRole) {
117
- var _this = this;
118
- this._peerConnections.forEach(function (peerConnection) {
119
- if (peerConnection.peerRole === clientRole) {
120
- _this.destroyPublisherOnPeerConnection(peerConnection);
121
- }
122
- });
123
- return Promise.resolve();
124
- };
125
- OpentokSessionV3.prototype.onMediaStreamRenewed = function (clientRole, mediaStream) {
126
- //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation (in OT API)
127
- return Promise.resolve();
128
- };
129
- OpentokSessionV3.prototype.getRemoteTrackStats = function (mediaTrack) {
130
- //https://tokbox.com/developer/sdks/js/reference/Subscriber.html (getStats)
131
- return Promise.reject(new Error('Not implemented yet'));
132
- };
133
112
  //#region OpenTok Events Handlers
134
113
  OpentokSessionV3.prototype.connectionCreatedHandler = function (event) {
135
114
  var _this = this;
@@ -208,11 +187,8 @@ var OpentokSessionV3 = /** @class */function (_super) {
208
187
  return;
209
188
  }
210
189
  var peerConnection = this._peerConnections.get(connection.connectionId);
211
- if (peerConnection.peerId === this.ownPeerId) {
212
- trace.warn('There nothing to do with stream from our own peer.');
213
- return;
214
- }
215
190
  trace.info('Subscribing the stream');
191
+ //TODO - Optimize the code below
216
192
  peerConnection.subscriber = this._session.subscribe(stream, null, null, function (err) {
217
193
  if (err) {
218
194
  peerConnection.subscriber = null;
@@ -236,6 +212,9 @@ var OpentokSessionV3 = /** @class */function (_super) {
236
212
  _this.registerMediaTrackFromPeer(peerConnection, mediaTrack);
237
213
  });
238
214
  });
215
+ peerConnection.subscriber.on('videoElementCreated', function (args) {
216
+ trace.info('videoElementCreated - REDO', args);
217
+ });
239
218
  };
240
219
  OpentokSessionV3.prototype.streamDestroyedHandler = function (event) {
241
220
  trace.info('streamDestroyedHandler', event);
@@ -243,10 +222,46 @@ var OpentokSessionV3 = /** @class */function (_super) {
243
222
  if (!this.sessionExistsGuard(false) || !stream) {
244
223
  return;
245
224
  }
246
- //Find peerConnection by connectionId, add remove tracks from stream
247
- //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);
248
232
  };
249
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
+ };
250
265
  OpentokSessionV3.prototype.createStreamForPublishing = function (destinationRole) {
251
266
  var _this = this;
252
267
  trace.info('createStreamForPublishing');
@@ -293,25 +308,11 @@ var OpentokSessionV3 = /** @class */function (_super) {
293
308
  });
294
309
  });
295
310
  };
296
- OpentokSessionV3.prototype.clearPeerConnections = function () {
297
- return Promise.resolve();
298
- };
299
- OpentokSessionV3.prototype.sessionExistsGuard = function (shouldThrow) {
300
- if (shouldThrow === void 0) {
301
- shouldThrow = true;
302
- }
303
- var connected = !!(this._session && this._session.connection && this._session.connection.connectionId);
304
- return guards_1.throwableGuard(connected, 'There no active session', shouldThrow);
305
- };
306
311
  OpentokSessionV3.prototype.destroyPeerConnection = function (peerConnection) {
307
- var _this = this;
308
312
  this._peerConnections.delete(peerConnection.peerId);
309
313
  this.destroyPublisherOnPeerConnection(peerConnection);
310
- peerConnection.remoteMediaTracks.forEach(function (mediaTrack) {
311
- _this._sessionStreamsManager.removeMediaTrack(mediaTrack.mediaTrack).catch(function (error) {
312
- trace.warn('Error removing media track', error);
313
- });
314
- });
314
+ this.unregisterPeersRemoteMediaTracks(peerConnection);
315
+ this.destroySubscriberOnPeerConnection(peerConnection);
315
316
  };
316
317
  OpentokSessionV3.prototype.destroyPublisherOnPeerConnection = function (peerConnection) {
317
318
  if (peerConnection.publisher) {
@@ -324,6 +325,20 @@ var OpentokSessionV3 = /** @class */function (_super) {
324
325
  peerConnection.localStream = null;
325
326
  }
326
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
+ };
327
342
  return OpentokSessionV3;
328
343
  }(MediaSessionBase_1.MediaSessionBase);
329
344
  exports.OpentokSessionV3 = OpentokSessionV3;
@@ -1 +1 @@
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","_peerConnections","Map","_session","_credentials","credentials","connect","bind","disconnect","onMediaStreamDestroyed","onMediaStreamRenewed","createStreamForPublishing","createMediaPublisher","clearPeerConnections","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","forEach","peerConnection","destroyPeerConnection","clientRole","peerRole","destroyPublisherOnPeerConnection","mediaStream","getRemoteTrackStats","mediaTrack","Error","event","sessionExistsGuard","ownPeerId","destinationRole","calculateDestinationRole","then","streams","peerId","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","registerMediaTrackFromPeer","_sessionStreamsManager","getMediaStreamForRole","track","kind","isAgentConnected","AGENT","OBSERVER","otParams","publishAudio","publishVideo","showControls","name","otPublisher","initPublisher","undefined","shouldThrow","connected","throwableGuard","delete","removeMediaTrack","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._peerConnections = new Map();\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.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 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 //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 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 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 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 if (peerConnection.peerId === this.ownPeerId) {\n trace.warn('There nothing to do with stream from our own peer.');\n return;\n }\n trace.info('Subscribing the stream');\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 };\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}(MediaSessionBase_1.MediaSessionBase));\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,10 +1,9 @@
1
1
  import { IMediaSession, ISessionStreamsManager, MediaSessionHandlers, MediaSessionParams, RemoteTrackStats } from '../MediaContracts';
2
2
  import { SessionClientRole } from '../MediaConstants';
3
3
  import { MediaSessionBase } from './MediaSessionBase';
4
- export declare class TurnWebRtcSessionV3 extends MediaSessionBase implements IMediaSession {
4
+ export declare class TurnWebRtcSessionV3 extends MediaSessionBase<RTCPeerConnection> implements IMediaSession {
5
5
  private readonly _sessionHandlers;
6
6
  private readonly _pendingPeersIce;
7
- private readonly _peerConnections;
8
7
  private readonly _configuration;
9
8
  private _socket;
10
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,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,gBAAiB,YAAW,aAAa;IAC9E,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;IA6B3H,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;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';\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 implements IMediaSession {\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 super(sessionParams, 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 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 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"]}
@@ -46,7 +46,6 @@ var TurnWebRtcSessionV3 = /** @class */function (_super) {
46
46
  _this._sessionHandlers = sessionHandlers;
47
47
  _this._socket = null;
48
48
  _this._pendingPeersIce = {};
49
- _this._peerConnections = new Map();
50
49
  var iceServers = sessionParams.credentials.ice.map(function (item) {
51
50
  return {
52
51
  urls: item.url,
@@ -299,15 +298,7 @@ var TurnWebRtcSessionV3 = /** @class */function (_super) {
299
298
  return Promise.resolve();
300
299
  };
301
300
  TurnWebRtcSessionV3.prototype.getRemoteTrackStats = function (mediaTrack) {
302
- var peerConnectionOfTrack = null;
303
- this._peerConnections.forEach(function (peerConnection) {
304
- var remoteTrack = peerConnection.remoteMediaTracks.filter(function (track) {
305
- return track.mediaTrack.id === mediaTrack.id;
306
- });
307
- if (remoteTrack.length === 1) {
308
- peerConnectionOfTrack = peerConnection;
309
- }
310
- });
301
+ var peerConnectionOfTrack = this.getPeerConnectionByMediaTrack(mediaTrack);
311
302
  if (peerConnectionOfTrack !== null) {
312
303
  return peerConnectionOfTrack.getStats(mediaTrack);
313
304
  }
@@ -368,18 +359,13 @@ var TurnWebRtcSessionV3 = /** @class */function (_super) {
368
359
  return peerConnection;
369
360
  };
370
361
  TurnWebRtcSessionV3.prototype._destroyPeerConnection = function (peerConnection) {
371
- var _this = this;
372
362
  trace.info('Destroying PeerConnection', peerConnection.peerType);
373
363
  peerConnection.ontrack = null;
374
364
  peerConnection.onicecandidate = null;
375
365
  peerConnection.onconnectionstatechange = null;
376
366
  peerConnection.oniceconnectionstatechange = null;
377
367
  peerConnection.onicegatheringstatechange = null;
378
- peerConnection.remoteMediaTracks.forEach(function (remoteMediaTrack) {
379
- _this._sessionStreamsManager.removeMediaTrack(remoteMediaTrack.mediaTrack).catch(function () {
380
- trace.warn('Error while removing remote media track', remoteMediaTrack);
381
- });
382
- });
368
+ this.unregisterPeersRemoteMediaTracks(peerConnection);
383
369
  this._peerConnections.delete(peerConnection.peerId);
384
370
  peerConnection.close();
385
371
  };
@@ -1 +1 @@
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","_peerConnections","Map","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","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","remoteMediaTrack","removeMediaTrack","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 _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 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 = 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}(MediaSessionBase_1.MediaSessionBase));\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.4",
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",