@techsee/techsee-media-service 0.6.1-alpha.3 → 0.6.1-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/MediaSession/MediaSessionBase.d.ts +23 -0
- package/lib/MediaSession/MediaSessionBase.d.ts.map +1 -0
- package/lib/MediaSession/MediaSessionBase.js +59 -0
- package/lib/MediaSession/MediaSessionBase.js.map +1 -0
- package/lib/MediaSession/SessionOpentok.v3.d.ts +24 -9
- package/lib/MediaSession/SessionOpentok.v3.d.ts.map +1 -1
- package/lib/MediaSession/SessionOpentok.v3.js +124 -64
- package/lib/MediaSession/SessionOpentok.v3.js.map +1 -1
- package/lib/MediaSession/SessionTurn.v3.d.ts +4 -14
- package/lib/MediaSession/SessionTurn.v3.d.ts.map +1 -1
- package/lib/MediaSession/SessionTurn.v3.js +39 -42
- package/lib/MediaSession/SessionTurn.v3.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { IMediaSessionPeer } from './MediaSessionBase';
|
|
2
|
+
import { SessionClientRole, SessionClientType } from '../MediaConstants';
|
|
3
|
+
import { ISessionStreamsManager, MediaSessionParams, RemoteMediaTrack } from '../MediaContracts';
|
|
4
|
+
import { Nullable } from '@techsee/techsee-common';
|
|
5
|
+
export interface IMediaSessionPeer {
|
|
6
|
+
peerId: string;
|
|
7
|
+
peerType: SessionClientType;
|
|
8
|
+
peerRole: SessionClientRole;
|
|
9
|
+
remoteMediaTracks: RemoteMediaTrack[];
|
|
10
|
+
}
|
|
11
|
+
declare global {
|
|
12
|
+
interface RTCPeerConnection extends IMediaSessionPeer {
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export declare abstract class MediaSessionBase<PeerType extends IMediaSessionPeer> {
|
|
16
|
+
protected readonly _peerConnections: Map<string, PeerType>;
|
|
17
|
+
protected readonly _sessionStreamsManager: ISessionStreamsManager;
|
|
18
|
+
protected readonly _sessionParams: MediaSessionParams;
|
|
19
|
+
protected constructor(sessionParams: MediaSessionParams, streamFactory: ISessionStreamsManager);
|
|
20
|
+
protected registerMediaTrackFromPeer(sourcePeerConnection: IMediaSessionPeer, mediaTrack: MediaStreamTrack): void;
|
|
21
|
+
unregisterPeersRemoteMediaTracks(peerConnection: PeerType): void;
|
|
22
|
+
protected getPeerConnectionByMediaTrack(mediaTrack: MediaStreamTrack): Nullable<PeerType>;
|
|
23
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/MediaSession/MediaSessionBase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,iBAAiB,EAAC,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAyC,iBAAiB,EAAE,iBAAiB,EAAC,MAAM,mBAAmB,CAAC;AAC/G,OAAO,EAAC,sBAAsB,EAAE,kBAAkB,EAAE,gBAAgB,EAAC,MAAM,mBAAmB,CAAC;AAG/F,OAAO,EAAC,QAAQ,EAAC,MAAM,yBAAyB,CAAC;AAEjD,MAAM,WAAW,iBAAiB;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;CACzC;AAED,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,iBAAkB,SAAQ,iBAAiB;KAEpD;CACJ;AAID,8BAAsB,gBAAgB,CAAC,QAAQ,SAAS,iBAAiB;IACrE,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAa;IACvE,SAAS,CAAC,QAAQ,CAAC,sBAAsB,EAAE,sBAAsB,CAAC;IAClE,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,kBAAkB,CAAC;IAEtD,SAAS,aAAa,aAAa,EAAE,kBAAkB,EAAE,aAAa,EAAE,sBAAsB;IAO9F,SAAS,CAAC,0BAA0B,CAAC,oBAAoB,EAAE,iBAAiB,EAAE,UAAU,EAAE,gBAAgB;IA0B1G,gCAAgC,CAAC,cAAc,EAAE,QAAQ;IASzD,SAAS,CAAC,6BAA6B,CAAC,UAAU,EAAE,gBAAgB,GAAG,QAAQ,CAAC,QAAQ,CAAC;CAiB5F","file":"MediaSessionBase.d.ts","sourcesContent":["import {IMediaSessionPeer} from './MediaSessionBase';\nimport {KnownMediaStream, KnownMediaStreamKind, SessionClientRole, SessionClientType} from '../MediaConstants';\nimport {ISessionStreamsManager, MediaSessionParams, RemoteMediaTrack} from '../MediaContracts';\n\nimport {getMediaTracer} from '../MediaUtils/MediaTracer';\nimport {Nullable} from '@techsee/techsee-common';\n\nexport interface IMediaSessionPeer {\n peerId: string;\n peerType: SessionClientType;\n peerRole: SessionClientRole;\n remoteMediaTracks: RemoteMediaTrack[];\n}\n\ndeclare global {\n interface RTCPeerConnection extends IMediaSessionPeer {\n\n }\n}\n\nconst trace = getMediaTracer('MediaSessionBase');\n\nexport abstract class MediaSessionBase<PeerType extends IMediaSessionPeer> {\n protected readonly _peerConnections: Map<string, PeerType> = new Map();\n protected readonly _sessionStreamsManager: ISessionStreamsManager;\n protected readonly _sessionParams: MediaSessionParams;\n\n protected constructor(sessionParams: MediaSessionParams, streamFactory: ISessionStreamsManager) {\n this._sessionParams = sessionParams;\n this._sessionStreamsManager = streamFactory;\n\n this._peerConnections = new Map();\n }\n\n protected registerMediaTrackFromPeer(sourcePeerConnection: IMediaSessionPeer, mediaTrack: MediaStreamTrack) {\n if (mediaTrack.kind === KnownMediaStreamKind.Video &&\n sourcePeerConnection.peerRole === SessionClientRole.AGENT) {\n //Currently We don't support video streams from Agent side\n return;\n }\n\n let trackType: Nullable<KnownMediaStream> = null;\n\n if (mediaTrack.kind.toLowerCase() === KnownMediaStreamKind.Audio) {\n trackType = sourcePeerConnection.peerRole === SessionClientRole.AGENT\n ? KnownMediaStream.AGENT_AUDIO_STREAM : KnownMediaStream.USER_AUDIO_STREAM;\n\n } else {\n trackType = KnownMediaStream.USER_VIDEO_STREAM;\n }\n\n const remoteMediaTrack = {mediaTrack, trackType};\n\n sourcePeerConnection.remoteMediaTracks.push(remoteMediaTrack);\n this._sessionStreamsManager.addRemoteMediaTrack(remoteMediaTrack)\n .catch((error: any) => {\n trace.warn('Error adding remote media track to available streams', error);\n });\n }\n\n unregisterPeersRemoteMediaTracks(peerConnection: PeerType) {\n peerConnection.remoteMediaTracks.forEach((remoteMediaTrack) => {\n this._sessionStreamsManager.removeMediaTrack(remoteMediaTrack.mediaTrack)\n .catch(() => {\n trace.warn('Error while removing remote media track', remoteMediaTrack);\n });\n });\n }\n\n protected getPeerConnectionByMediaTrack(mediaTrack: MediaStreamTrack): Nullable<PeerType> {\n let peerConnectionOfTrack: Nullable<PeerType> = null;\n\n this._peerConnections.forEach((peerConnection: PeerType) => {\n if (peerConnectionOfTrack !== null) {\n return;\n }\n\n const remoteTrack = peerConnection.remoteMediaTracks.filter((track) => track.mediaTrack.id === mediaTrack.id);\n\n if (remoteTrack.length === 1) {\n peerConnectionOfTrack = peerConnection;\n }\n });\n\n return peerConnectionOfTrack;\n }\n}\n"]}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
var MediaConstants_1 = require("../MediaConstants");
|
|
5
|
+
var MediaTracer_1 = require("../MediaUtils/MediaTracer");
|
|
6
|
+
var trace = MediaTracer_1.getMediaTracer('MediaSessionBase');
|
|
7
|
+
var MediaSessionBase = /** @class */function () {
|
|
8
|
+
function MediaSessionBase(sessionParams, streamFactory) {
|
|
9
|
+
this._peerConnections = new Map();
|
|
10
|
+
this._sessionParams = sessionParams;
|
|
11
|
+
this._sessionStreamsManager = streamFactory;
|
|
12
|
+
this._peerConnections = new Map();
|
|
13
|
+
}
|
|
14
|
+
MediaSessionBase.prototype.registerMediaTrackFromPeer = function (sourcePeerConnection, mediaTrack) {
|
|
15
|
+
if (mediaTrack.kind === MediaConstants_1.KnownMediaStreamKind.Video && sourcePeerConnection.peerRole === MediaConstants_1.SessionClientRole.AGENT) {
|
|
16
|
+
//Currently We don't support video streams from Agent side
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
var trackType = null;
|
|
20
|
+
if (mediaTrack.kind.toLowerCase() === MediaConstants_1.KnownMediaStreamKind.Audio) {
|
|
21
|
+
trackType = sourcePeerConnection.peerRole === MediaConstants_1.SessionClientRole.AGENT ? MediaConstants_1.KnownMediaStream.AGENT_AUDIO_STREAM : MediaConstants_1.KnownMediaStream.USER_AUDIO_STREAM;
|
|
22
|
+
} else {
|
|
23
|
+
trackType = MediaConstants_1.KnownMediaStream.USER_VIDEO_STREAM;
|
|
24
|
+
}
|
|
25
|
+
var remoteMediaTrack = { mediaTrack: mediaTrack, trackType: trackType };
|
|
26
|
+
sourcePeerConnection.remoteMediaTracks.push(remoteMediaTrack);
|
|
27
|
+
this._sessionStreamsManager.addRemoteMediaTrack(remoteMediaTrack).catch(function (error) {
|
|
28
|
+
trace.warn('Error adding remote media track to available streams', error);
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
MediaSessionBase.prototype.unregisterPeersRemoteMediaTracks = function (peerConnection) {
|
|
32
|
+
var _this = this;
|
|
33
|
+
peerConnection.remoteMediaTracks.forEach(function (remoteMediaTrack) {
|
|
34
|
+
_this._sessionStreamsManager.removeMediaTrack(remoteMediaTrack.mediaTrack).catch(function () {
|
|
35
|
+
trace.warn('Error while removing remote media track', remoteMediaTrack);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
MediaSessionBase.prototype.getPeerConnectionByMediaTrack = function (mediaTrack) {
|
|
40
|
+
var peerConnectionOfTrack = null;
|
|
41
|
+
this._peerConnections.forEach(function (peerConnection) {
|
|
42
|
+
if (peerConnectionOfTrack !== null) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
var remoteTrack = peerConnection.remoteMediaTracks.filter(function (track) {
|
|
46
|
+
return track.mediaTrack.id === mediaTrack.id;
|
|
47
|
+
});
|
|
48
|
+
if (remoteTrack.length === 1) {
|
|
49
|
+
peerConnectionOfTrack = peerConnection;
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
return peerConnectionOfTrack;
|
|
53
|
+
};
|
|
54
|
+
return MediaSessionBase;
|
|
55
|
+
}();
|
|
56
|
+
exports.MediaSessionBase = MediaSessionBase;
|
|
57
|
+
|
|
58
|
+
//# sourceMappingURL=MediaSessionBase.js.map
|
|
59
|
+
//# sourceMappingURL=MediaSessionBase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["MediaSession/MediaSessionBase.js"],"names":["Object","defineProperty","exports","value","MediaConstants_1","require","MediaTracer_1","trace","getMediaTracer","MediaSessionBase","sessionParams","streamFactory","_peerConnections","Map","_sessionParams","_sessionStreamsManager","prototype","registerMediaTrackFromPeer","sourcePeerConnection","mediaTrack","kind","KnownMediaStreamKind","Video","peerRole","SessionClientRole","AGENT","trackType","toLowerCase","Audio","KnownMediaStream","AGENT_AUDIO_STREAM","USER_AUDIO_STREAM","USER_VIDEO_STREAM","remoteMediaTrack","remoteMediaTracks","push","addRemoteMediaTrack","catch","error","warn","unregisterPeersRemoteMediaTracks","peerConnection","_this","forEach","removeMediaTrack","getPeerConnectionByMediaTrack","peerConnectionOfTrack","remoteTrack","filter","track","id","length"],"mappings":"AAAA;;AACAA,OAAOC,cAAP,CAAsBC,OAAtB,EAA+B,YAA/B,EAA6C,EAAEC,OAAO,IAAT,EAA7C;AACA,IAAIC,mBAAmBC,QAAQ,mBAAR,CAAvB;AACA,IAAIC,gBAAgBD,QAAQ,2BAAR,CAApB;AACA,IAAIE,QAAQD,cAAcE,cAAd,CAA6B,kBAA7B,CAAZ;AACA,IAAIC,mBAAmB,aAAe,YAAY;AAC9C,aAASA,gBAAT,CAA0BC,aAA1B,EAAyCC,aAAzC,EAAwD;AACpD,aAAKC,gBAAL,GAAwB,IAAIC,GAAJ,EAAxB;AACA,aAAKC,cAAL,GAAsBJ,aAAtB;AACA,aAAKK,sBAAL,GAA8BJ,aAA9B;AACA,aAAKC,gBAAL,GAAwB,IAAIC,GAAJ,EAAxB;AACH;AACDJ,qBAAiBO,SAAjB,CAA2BC,0BAA3B,GAAwD,UAAUC,oBAAV,EAAgCC,UAAhC,EAA4C;AAChG,YAAIA,WAAWC,IAAX,KAAoBhB,iBAAiBiB,oBAAjB,CAAsCC,KAA1D,IACAJ,qBAAqBK,QAArB,KAAkCnB,iBAAiBoB,iBAAjB,CAAmCC,KADzE,EACgF;AAC5E;AACA;AACH;AACD,YAAIC,YAAY,IAAhB;AACA,YAAIP,WAAWC,IAAX,CAAgBO,WAAhB,OAAkCvB,iBAAiBiB,oBAAjB,CAAsCO,KAA5E,EAAmF;AAC/EF,wBAAYR,qBAAqBK,QAArB,KAAkCnB,iBAAiBoB,iBAAjB,CAAmCC,KAArE,GACNrB,iBAAiByB,gBAAjB,CAAkCC,kBAD5B,GACiD1B,iBAAiByB,gBAAjB,CAAkCE,iBAD/F;AAEH,SAHD,MAIK;AACDL,wBAAYtB,iBAAiByB,gBAAjB,CAAkCG,iBAA9C;AACH;AACD,YAAIC,mBAAmB,EAAEd,YAAYA,UAAd,EAA0BO,WAAWA,SAArC,EAAvB;AACAR,6BAAqBgB,iBAArB,CAAuCC,IAAvC,CAA4CF,gBAA5C;AACA,aAAKlB,sBAAL,CAA4BqB,mBAA5B,CAAgDH,gBAAhD,EACKI,KADL,CACW,UAAUC,KAAV,EAAiB;AACxB/B,kBAAMgC,IAAN,CAAW,sDAAX,EAAmED,KAAnE;AACH,SAHD;AAIH,KApBD;AAqBA7B,qBAAiBO,SAAjB,CAA2BwB,gCAA3B,GAA8D,UAAUC,cAAV,EAA0B;AACpF,YAAIC,QAAQ,IAAZ;AACAD,uBAAeP,iBAAf,CAAiCS,OAAjC,CAAyC,UAAUV,gBAAV,EAA4B;AACjES,kBAAM3B,sBAAN,CAA6B6B,gBAA7B,CAA8CX,iBAAiBd,UAA/D,EACKkB,KADL,CACW,YAAY;AACnB9B,sBAAMgC,IAAN,CAAW,yCAAX,EAAsDN,gBAAtD;AACH,aAHD;AAIH,SALD;AAMH,KARD;AASAxB,qBAAiBO,SAAjB,CAA2B6B,6BAA3B,GAA2D,UAAU1B,UAAV,EAAsB;AAC7E,YAAI2B,wBAAwB,IAA5B;AACA,aAAKlC,gBAAL,CAAsB+B,OAAtB,CAA8B,UAAUF,cAAV,EAA0B;AACpD,gBAAIK,0BAA0B,IAA9B,EAAoC;AAChC;AACH;AACD,gBAAIC,cAAcN,eAAeP,iBAAf,CAAiCc,MAAjC,CAAwC,UAAUC,KAAV,EAAiB;AAAE,uBAAOA,MAAM9B,UAAN,CAAiB+B,EAAjB,KAAwB/B,WAAW+B,EAA1C;AAA+C,aAA1G,CAAlB;AACA,gBAAIH,YAAYI,MAAZ,KAAuB,CAA3B,EAA8B;AAC1BL,wCAAwBL,cAAxB;AACH;AACJ,SARD;AASA,eAAOK,qBAAP;AACH,KAZD;AAaA,WAAOrC,gBAAP;AACH,CAnDqC,EAAtC;AAoDAP,QAAQO,gBAAR,GAA2BA,gBAA3B;;AAEA","file":"MediaSessionBase.js","sourcesContent":["\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar MediaConstants_1 = require(\"../MediaConstants\");\nvar MediaTracer_1 = require(\"../MediaUtils/MediaTracer\");\nvar trace = MediaTracer_1.getMediaTracer('MediaSessionBase');\nvar MediaSessionBase = /** @class */ (function () {\n function MediaSessionBase(sessionParams, streamFactory) {\n this._peerConnections = new Map();\n this._sessionParams = sessionParams;\n this._sessionStreamsManager = streamFactory;\n this._peerConnections = new Map();\n }\n MediaSessionBase.prototype.registerMediaTrackFromPeer = function (sourcePeerConnection, mediaTrack) {\n if (mediaTrack.kind === MediaConstants_1.KnownMediaStreamKind.Video &&\n sourcePeerConnection.peerRole === MediaConstants_1.SessionClientRole.AGENT) {\n //Currently We don't support video streams from Agent side\n return;\n }\n var trackType = null;\n if (mediaTrack.kind.toLowerCase() === MediaConstants_1.KnownMediaStreamKind.Audio) {\n trackType = sourcePeerConnection.peerRole === MediaConstants_1.SessionClientRole.AGENT\n ? MediaConstants_1.KnownMediaStream.AGENT_AUDIO_STREAM : MediaConstants_1.KnownMediaStream.USER_AUDIO_STREAM;\n }\n else {\n trackType = MediaConstants_1.KnownMediaStream.USER_VIDEO_STREAM;\n }\n var remoteMediaTrack = { mediaTrack: mediaTrack, trackType: trackType };\n sourcePeerConnection.remoteMediaTracks.push(remoteMediaTrack);\n this._sessionStreamsManager.addRemoteMediaTrack(remoteMediaTrack)\n .catch(function (error) {\n trace.warn('Error adding remote media track to available streams', error);\n });\n };\n MediaSessionBase.prototype.unregisterPeersRemoteMediaTracks = function (peerConnection) {\n var _this = this;\n peerConnection.remoteMediaTracks.forEach(function (remoteMediaTrack) {\n _this._sessionStreamsManager.removeMediaTrack(remoteMediaTrack.mediaTrack)\n .catch(function () {\n trace.warn('Error while removing remote media track', remoteMediaTrack);\n });\n });\n };\n MediaSessionBase.prototype.getPeerConnectionByMediaTrack = function (mediaTrack) {\n var peerConnectionOfTrack = null;\n this._peerConnections.forEach(function (peerConnection) {\n if (peerConnectionOfTrack !== null) {\n return;\n }\n var remoteTrack = peerConnection.remoteMediaTracks.filter(function (track) { return track.mediaTrack.id === mediaTrack.id; });\n if (remoteTrack.length === 1) {\n peerConnectionOfTrack = peerConnection;\n }\n });\n return peerConnectionOfTrack;\n };\n return MediaSessionBase;\n}());\nexports.MediaSessionBase = MediaSessionBase;\n\n//# sourceMappingURL=MediaSessionBase.js.map\n"]}
|
|
@@ -1,14 +1,28 @@
|
|
|
1
|
+
import { Nullable } from '@techsee/techsee-common';
|
|
1
2
|
import { IMediaSession, ISessionStreamsManager, MediaSessionParams, RemoteTrackStats } from '../MediaContracts';
|
|
2
3
|
import { SessionClientRole } from '../MediaConstants';
|
|
4
|
+
import { IMediaSessionPeer, MediaSessionBase } from './MediaSessionBase';
|
|
3
5
|
declare global {
|
|
4
6
|
interface Window {
|
|
5
7
|
OT: any;
|
|
6
8
|
}
|
|
7
9
|
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
declare type OTPublisher = any;
|
|
11
|
+
declare type OTSubscriber = any;
|
|
12
|
+
interface OTConnection {
|
|
13
|
+
connectionId: string;
|
|
14
|
+
}
|
|
15
|
+
interface OTPeerConnection extends IMediaSessionPeer {
|
|
16
|
+
localStream: Nullable<OTStreamSource>;
|
|
17
|
+
connection: OTConnection;
|
|
18
|
+
publisher: Nullable<OTPublisher>;
|
|
19
|
+
subscriber: Nullable<OTSubscriber>;
|
|
20
|
+
}
|
|
21
|
+
interface OTStreamSource {
|
|
22
|
+
videoSource: any;
|
|
23
|
+
audioSource: any;
|
|
24
|
+
}
|
|
25
|
+
export declare class OpentokSessionV3 extends MediaSessionBase<OTPeerConnection> implements IMediaSession {
|
|
12
26
|
private readonly _credentials;
|
|
13
27
|
private _session;
|
|
14
28
|
readonly id: string;
|
|
@@ -16,18 +30,19 @@ export declare class OpentokSessionV3 implements IMediaSession {
|
|
|
16
30
|
constructor(sessionParams: MediaSessionParams, streamFactory: ISessionStreamsManager);
|
|
17
31
|
connect(): Promise<void>;
|
|
18
32
|
disconnect(): Promise<void>;
|
|
19
|
-
onMediaStreamDestroyed(clientRole: SessionClientRole): Promise<void>;
|
|
20
|
-
onMediaStreamRenewed(clientRole: SessionClientRole, mediaStream: MediaStream): Promise<void>;
|
|
21
|
-
getRemoteTrackStats(mediaTrack: MediaStreamTrack): Promise<RemoteTrackStats>;
|
|
22
33
|
private connectionCreatedHandler;
|
|
23
34
|
private connectionDestroyedHandler;
|
|
24
35
|
private streamCreatedHandler;
|
|
25
36
|
private streamDestroyedHandler;
|
|
37
|
+
onMediaStreamDestroyed(clientRole: SessionClientRole): Promise<void>;
|
|
38
|
+
onMediaStreamRenewed(clientRole: SessionClientRole, mediaStream: MediaStream): Promise<void>;
|
|
39
|
+
getRemoteTrackStats(mediaTrack: MediaStreamTrack): Promise<RemoteTrackStats>;
|
|
26
40
|
private createStreamForPublishing;
|
|
27
41
|
private calculateDestinationRole;
|
|
28
42
|
private createMediaPublisher;
|
|
29
|
-
private clearPeerConnections;
|
|
30
|
-
private sessionExistsGuard;
|
|
31
43
|
private destroyPeerConnection;
|
|
32
44
|
private destroyPublisherOnPeerConnection;
|
|
45
|
+
private destroySubscriberOnPeerConnection;
|
|
46
|
+
private sessionExistsGuard;
|
|
33
47
|
}
|
|
48
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/MediaSession/SessionOpentok.v3.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,aAAa,EACb,sBAAsB,EACtB,kBAAkB,EACA,gBAAgB,EACrC,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAEH,iBAAiB,EAEpB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,MAAM;QACZ,EAAE,EAAE,GAAG,CAAC;KACX;CACJ;AAoDD,qBAAa,gBAAiB,YAAW,aAAa;IAClD,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAyB;IAChE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA8C;IAC/E,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAM;IAEnC,OAAO,CAAC,QAAQ,CAA8B;aAE1C,EAAE,EAAI,MAAM;qBAIJ,SAAS;gBAIT,aAAa,EAAE,kBAAkB,EAAE,aAAa,EAAE,sBAAsB;IAmBpF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAwCxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAwB3B,sBAAsB,CAAC,UAAU,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAUpE,oBAAoB,CAAC,UAAU,EAAE,iBAAiB,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAK5F,mBAAmB,CAAC,UAAU,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAO5E,OAAO,CAAC,wBAAwB;IAyEhC,OAAO,CAAC,0BAA0B;IAalC,OAAO,CAAC,oBAAoB;IA4B5B,OAAO,CAAC,sBAAsB;IAc9B,OAAO,CAAC,yBAAyB;IAyBjC,OAAO,CAAC,wBAAwB;IAWhC,OAAO,CAAC,oBAAoB;IAsB5B,OAAO,CAAC,oBAAoB;IAI5B,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,qBAAqB;IAW7B,OAAO,CAAC,gCAAgC;CAY3C","file":"SessionOpentok.v3.d.ts","sourcesContent":["import {Nullable} from '@techsee/techsee-common';\n\nimport {\n IMediaSession,\n ISessionStreamsManager,\n MediaSessionParams,\n RemoteMediaTrack, RemoteTrackStats\n} from '../MediaContracts';\n\nimport {\n KnownMediaStream,\n SessionClientRole,\n SessionClientType\n} from '../MediaConstants';\n\ndeclare global {\n interface Window {\n OT: any;\n }\n}\n\nimport {getMediaTracer} from '../MediaUtils/MediaTracer';\nimport {throwableGuard} from '@techsee/techsee-common/lib/core/guards';\n\nconst trace = getMediaTracer('OpenTokSession');\n\ninterface IOTSession {\n\n sessionId: string;\n\n connection: Nullable<OTConnection>;\n\n isConnected(): boolean;\n\n connect(token: string, cb: any): void;\n\n disconnect(): void;\n\n publish(publisher: any, cb: any): void;\n\n off(): void;\n\n on(param: string, cb: any): void;\n\n once(param: string, cb: any): void;\n}\n\ntype OTPublisher = any\n\ntype OTPeerId = any\n\ninterface OTConnection {\n connectionId: string;\n}\n\ninterface OTPeerConnection {\n peerId: OTPeerId;\n peerType: SessionClientType;\n peerRole: SessionClientRole;\n remoteMediaTracks: RemoteMediaTrack[];\n localStream: Nullable<OTStreamSource>;\n connection: OTConnection;\n publisher: Nullable<OTPublisher>;\n}\n\ninterface OTStreamSource {\n videoSource: any;\n audioSource: any;\n}\n\n//Currently this version supports subscribing only. Publishing will be implemented as needed.\nexport class OpentokSessionV3 implements IMediaSession {\n private readonly _sessionStreamsManager: ISessionStreamsManager;\n private readonly _sessionParams: MediaSessionParams;\n private readonly _peerConnections: Map<OTPeerId, OTPeerConnection> = new Map();\n private readonly _credentials: any;\n\n private _session: Nullable<IOTSession> = null;\n\n get id(): string {\n return this._session && this._session.sessionId ? this._session.sessionId : '';\n }\n\n private get ownPeerId(): string {\n return this._session && this._session.connection ? this._session.connection.connectionId : '';\n }\n\n constructor(sessionParams: MediaSessionParams, streamFactory: ISessionStreamsManager) {\n this._sessionParams = sessionParams;\n this._sessionStreamsManager = streamFactory;\n this._credentials = sessionParams.credentials;\n\n this.connect = this.connect.bind(this);\n this.disconnect = this.disconnect.bind(this);\n this.onMediaStreamDestroyed = this.onMediaStreamDestroyed.bind(this);\n this.onMediaStreamRenewed = this.onMediaStreamRenewed.bind(this);\n\n this.createStreamForPublishing = this.createStreamForPublishing.bind(this);\n this.createMediaPublisher = this.createMediaPublisher.bind(this);\n this.clearPeerConnections = this.clearPeerConnections.bind(this);\n this.connectionCreatedHandler = this.connectionCreatedHandler.bind(this);\n this.connectionDestroyedHandler = this.connectionDestroyedHandler.bind(this);\n this.streamCreatedHandler = this.streamCreatedHandler.bind(this);\n this.streamDestroyedHandler = this.streamDestroyedHandler.bind(this);\n }\n\n connect(): Promise<void> {\n trace.info('Connect to session');\n\n if (this._session) {\n trace.error('Session already exists');\n\n return Promise.reject('Cannot connect to session while another session is active');\n }\n\n return new Promise((resolve, reject) => {\n const handleError = (error: any): void => {\n this._session && this._session!.off();\n this._session = null;\n trace.error('handleConnect error:', error);\n reject(error);\n };\n\n const {apiKey, sessionId} = this._sessionParams.credentials;\n\n this._session = (window as any).OTSESSION = window.OT.initSession(apiKey, sessionId);\n\n this._session!.on('connectionCreated', this.connectionCreatedHandler);\n this._session!.on('connectionDestroyed', this.connectionDestroyedHandler);\n this._session!.on('streamCreated', this.streamCreatedHandler);\n this._session!.on('streamDestroyed', this.streamDestroyedHandler);\n\n const connectHandler = (error: any): void => {\n if (error) {\n handleError(error);\n\n return;\n }\n\n resolve();\n };\n\n this._session!.connect(this._credentials.token, connectHandler);\n });\n }\n\n disconnect(): Promise<void> {\n //TODO - Alex: Implement destroying all publishers (by opentok docs)\n //Create a method destroy publisher (or publishers can treated the same as \"peerConnections\"?\n return new Promise((resolve) => {\n const currentSession = this._session;\n\n this._session = null;\n\n this._peerConnections.forEach((peerConnection) => {\n this.destroyPeerConnection(peerConnection);\n });\n\n if (!currentSession) {\n trace.info('No active session - resolving');\n resolve();\n\n return;\n }\n currentSession.off();\n currentSession.disconnect();\n resolve();\n });\n }\n\n onMediaStreamDestroyed(clientRole: SessionClientRole): Promise<void> {\n this._peerConnections.forEach((peerConnection) => {\n if (peerConnection.peerRole === clientRole) {\n this.destroyPublisherOnPeerConnection(peerConnection);\n }\n });\n\n return Promise.resolve();\n }\n\n onMediaStreamRenewed(clientRole: SessionClientRole, mediaStream: MediaStream): Promise<void> {\n //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation (in OT API)\n return Promise.resolve();\n }\n\n getRemoteTrackStats(mediaTrack: MediaStreamTrack): Promise<RemoteTrackStats> {\n //https://tokbox.com/developer/sdks/js/reference/Subscriber.html (getStats)\n return Promise.reject(new Error('Not implemented yet'));\n }\n\n //#region OpenTok Events Handlers\n\n private connectionCreatedHandler(event: any): void {\n trace.info('connectionCreatedHandler', event);\n const {connection} = event;\n\n if (!this.sessionExistsGuard(false) || !connection) {\n return;\n }\n\n //In case we got our own connection, we have nothing to do with it\n if (connection.connectionId === this.ownPeerId) {\n return;\n }\n\n const destinationRole = this.calculateDestinationRole();\n\n this.createStreamForPublishing(destinationRole)\n .then((streams: OTStreamSource) => {\n const peerConnection: OTPeerConnection = {\n peerId: connection.connectionId,\n peerRole: destinationRole,\n peerType: this._sessionParams.clientType === SessionClientType.INITIATOR\n ? SessionClientType.GUEST : SessionClientType.INITIATOR,\n connection: connection,\n publisher: null,\n remoteMediaTracks: [],\n localStream: streams\n };\n\n if (!streams.videoSource && !streams.audioSource) {\n trace.info('Peer connection without publisher was created', peerConnection);\n\n return peerConnection;\n }\n\n const streamName = destinationRole === SessionClientRole.USER\n ? KnownMediaStream.AGENT_AUDIO_STREAM : KnownMediaStream.USER_VIDEO_STREAM;\n\n\n return this.createMediaPublisher(streams, streamName)\n .then((publisher: OTPublisher) => {\n peerConnection.publisher = publisher;\n trace.info('Peer connection with publisher was created', peerConnection);\n\n return peerConnection;\n });\n })\n .then((peerConnection: OTPeerConnection) => {\n this._peerConnections.set(peerConnection.peerId, peerConnection);\n\n if (peerConnection.publisher) {\n return new Promise<void>((resolve, reject) => {\n trace.info('Starting publish to peerConnection.publisher');\n this._session!.publish(peerConnection.publisher, (error: any) => {\n if (error) {\n trace.error('Publish to peerConnection error', error);\n\n return reject(error);\n }\n trace.info('Publish to peerConnection success');\n\n return resolve();\n });\n });\n }\n\n return Promise.resolve();\n })\n .catch((error: any) => {\n //Need to handle fail cases during reliability\n trace.error('Error handling new peer connection', error);\n });\n }\n\n private connectionDestroyedHandler(event: any): void {\n trace.info('connectionDestroyedHandler', event);\n const {connection} = event;\n\n if (!this.sessionExistsGuard(false) || !connection) {\n return;\n }\n\n if (this._peerConnections.has(connection.connectionId)) {\n this.destroyPeerConnection(this._peerConnections.get(connection.connectionId)!);\n }\n }\n\n private streamCreatedHandler(event: any): void {\n trace.info('streamCreatedHandler', event.stream);\n const {stream} = event;\n const {connection} = stream || {connection: null};\n\n if (!this.sessionExistsGuard(false) || !stream) {\n return;\n }\n\n if (!this._peerConnections.has(connection.connectionId)) {\n trace.warn('Unexpected case, connection should exist on this stage');\n\n return;\n }\n\n const peerConnection = this._peerConnections.get(connection.connectionId);\n\n if (!peerConnection) {\n trace.warn('Unexpected PeerConnection not found');\n\n return;\n }\n\n //Find peerConnection by connectionId, add all tracks to remoteTracks (check if it exists before)\n //We cannot have to tracks with the same id or with the same meaning\n //Register each track using addRemoteTrack\n }\n\n private streamDestroyedHandler(event: any): void {\n trace.info('streamDestroyedHandler', event);\n const {stream} = event;\n\n if (!this.sessionExistsGuard(false) || !stream) {\n return;\n }\n\n //Find peerConnection by connectionId, add remove tracks from stream\n //Register each track using addRemoteTrack\n }\n\n //#endregion\n\n private createStreamForPublishing(destinationRole: SessionClientRole): Promise<OTStreamSource> {\n trace.info('createStreamForPublishing');\n\n return this._sessionStreamsManager.getMediaStreamForRole(destinationRole)\n .then((mediaStream: Nullable<MediaStream>) => {\n\n const stream: OTStreamSource = {videoSource: null, audioSource: null};\n\n if (mediaStream) {\n trace.info('Media stream found for publishing', mediaStream);\n mediaStream.getTracks().forEach((track) => {\n if (track.kind === 'video') {\n stream.videoSource = track;\n } else if (track.kind === 'audio') {\n stream.audioSource = track;\n }\n });\n } else if (this._sessionParams.clientRole === SessionClientRole.USER) {\n trace.warn('No local media was found for publishing to destinationRole:', destinationRole);\n }\n\n return stream;\n });\n }\n\n private calculateDestinationRole(): SessionClientRole {\n if (this._sessionParams.clientRole === SessionClientRole.USER) {\n const isAgentConnected = false;\n\n\n return !isAgentConnected ? SessionClientRole.AGENT : SessionClientRole.OBSERVER;\n }\n\n return SessionClientRole.USER;\n }\n\n private createMediaPublisher(stream: OTStreamSource, streamName: string): Promise<OTPublisher> {\n const otParams = {\n videoSource: stream.videoSource ? stream.videoSource : false,\n audioSource: stream.audioSource ? stream.audioSource : false,\n publishAudio: !!stream.audioSource,\n publishVideo: !!stream.videoSource,\n showControls: false,\n name: streamName\n };\n\n return new Promise((resolve, reject) => {\n const otPublisher = window.OT.initPublisher(undefined, otParams, (error: any) => {\n if (error) {\n reject(error);\n \n return;\n }\n resolve(otPublisher);\n });\n });\n }\n\n private clearPeerConnections(): Promise<void> {\n return Promise.resolve();\n }\n\n private sessionExistsGuard(shouldThrow = true): boolean {\n const connected = !!(this._session && this._session.connection && this._session.connection.connectionId);\n\n\n return throwableGuard(connected, 'There no active session', shouldThrow);\n }\n\n private destroyPeerConnection(peerConnection: OTPeerConnection): void {\n this._peerConnections.delete(peerConnection.peerId);\n this.destroyPublisherOnPeerConnection(peerConnection);\n peerConnection.remoteMediaTracks.forEach((mediaTrack) => {\n this._sessionStreamsManager.removeMediaTrack(mediaTrack.mediaTrack)\n .catch((error: any) => {\n trace.warn('Error removing media track', error);\n });\n });\n }\n\n private destroyPublisherOnPeerConnection(peerConnection: OTPeerConnection): void {\n if (peerConnection.publisher) {\n //TODO - Alex: When destroying the publisher, OT closes the stream by himself, without we ask him.\n //So we not destroying the OT publisher right now in order to preserve our stream alive.\n //Later, we can recreate our stream as new, or manually delete \"video\" element that created by OT.\n // or we just can leave it as is :)\n //peerConnection.publisher.destroy();\n peerConnection.publisher = null;\n peerConnection.localStream = null;\n }\n }\n\n}\n\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/MediaSession/SessionOpentok.v3.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,yBAAyB,CAAC;AAEjD,OAAO,EACH,aAAa,EACb,sBAAsB,EACtB,kBAAkB,EAClB,gBAAgB,EACnB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAmB,iBAAiB,EAAoB,MAAM,mBAAmB,CAAC;AAEzF,OAAO,EAAC,iBAAiB,EAAE,gBAAgB,EAAC,MAAM,oBAAoB,CAAC;AAKvE,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,MAAM;QACZ,EAAE,EAAE,GAAG,CAAC;KACX;CACJ;AA6BD,aAAK,WAAW,GAAG,GAAG,CAAA;AAEtB,aAAK,YAAY,GAAG,GAAG,CAAA;AAEvB,UAAU,YAAY;IAClB,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,UAAU,gBAAiB,SAAQ,iBAAiB;IAChD,WAAW,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;IACtC,UAAU,EAAE,YAAY,CAAC;IACzB,SAAS,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;IACjC,UAAU,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;CACtC;AAED,UAAU,cAAc;IACpB,WAAW,EAAE,GAAG,CAAC;IACjB,WAAW,EAAE,GAAG,CAAC;CACpB;AAGD,qBAAa,gBAAiB,SAAQ,gBAAgB,CAAC,gBAAgB,CAAE,YAAW,aAAa;IAC7F,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAM;IAEnC,OAAO,CAAC,QAAQ,CAA8B;aAE1C,EAAE,EAAI,MAAM;qBAIJ,SAAS;gBAIT,aAAa,EAAE,kBAAkB,EAAE,aAAa,EAAE,sBAAsB;IAiBpF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAwCxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAyB3B,OAAO,CAAC,wBAAwB;IA0EhC,OAAO,CAAC,0BAA0B;IAalC,OAAO,CAAC,oBAAoB;IAwD5B,OAAO,CAAC,sBAAsB;IAsB9B,sBAAsB,CAAC,UAAU,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAUpE,oBAAoB,CAAC,UAAU,EAAE,iBAAiB,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAK5F,mBAAmB,CAAC,UAAU,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAqB5E,OAAO,CAAC,yBAAyB;IAyBjC,OAAO,CAAC,wBAAwB;IAWhC,OAAO,CAAC,oBAAoB;IAsB5B,OAAO,CAAC,qBAAqB;IAO7B,OAAO,CAAC,gCAAgC;IAYxC,OAAO,CAAC,iCAAiC;IASzC,OAAO,CAAC,kBAAkB;CAM7B","file":"SessionOpentok.v3.d.ts","sourcesContent":["import {Nullable} from '@techsee/techsee-common';\n\nimport {\n IMediaSession,\n ISessionStreamsManager,\n MediaSessionParams,\n RemoteTrackStats\n} from '../MediaContracts';\n\nimport {KnownMediaStream, SessionClientRole, SessionClientType} from '../MediaConstants';\nimport {throwableGuard} from '@techsee/techsee-common/lib/core/guards';\nimport {IMediaSessionPeer, MediaSessionBase} from './MediaSessionBase';\nimport {getMediaTracer} from '../MediaUtils/MediaTracer';\n\nconst trace = getMediaTracer('OpentokSessionV3');\n\ndeclare global {\n interface Window {\n OT: any;\n }\n}\n\ninterface IOTSession {\n\n sessionId: string;\n\n connection: Nullable<OTConnection>;\n\n isConnected(): boolean;\n\n connect(token: string, cb: any): void;\n\n disconnect(): void;\n\n publish(publisher: any, cb: any): void;\n\n subscribe(stream: any, container: any, uiProps: any, doneCb: any): OTSubscriber;\n\n unsubscribe(subscriber: OTSubscriber): void;\n\n getSubscribersForStream(stream: any): OTSubscriber[];\n\n off(): void;\n\n on(param: string, cb: any): void;\n\n once(param: string, cb: any): void;\n}\n\ntype OTPublisher = any\n\ntype OTSubscriber = any\n\ninterface OTConnection {\n connectionId: string;\n}\n\ninterface OTPeerConnection extends IMediaSessionPeer {\n localStream: Nullable<OTStreamSource>;\n connection: OTConnection;\n publisher: Nullable<OTPublisher>;\n subscriber: Nullable<OTSubscriber>;\n}\n\ninterface OTStreamSource {\n videoSource: any;\n audioSource: any;\n}\n\n//Currently this version supports subscribing only. Publishing will be implemented as needed.\nexport class OpentokSessionV3 extends MediaSessionBase<OTPeerConnection> implements IMediaSession {\n private readonly _credentials: any;\n\n private _session: Nullable<IOTSession> = null;\n\n get id(): string {\n return this._session && this._session.sessionId ? this._session.sessionId : '';\n }\n\n private get ownPeerId(): string {\n return this._session && this._session.connection ? this._session.connection.connectionId : '';\n }\n\n constructor(sessionParams: MediaSessionParams, streamFactory: ISessionStreamsManager) {\n super(sessionParams, streamFactory);\n this._credentials = sessionParams.credentials;\n\n this.connect = this.connect.bind(this);\n this.disconnect = this.disconnect.bind(this);\n this.onMediaStreamDestroyed = this.onMediaStreamDestroyed.bind(this);\n this.onMediaStreamRenewed = this.onMediaStreamRenewed.bind(this);\n\n this.createStreamForPublishing = this.createStreamForPublishing.bind(this);\n this.createMediaPublisher = this.createMediaPublisher.bind(this);\n this.connectionCreatedHandler = this.connectionCreatedHandler.bind(this);\n this.connectionDestroyedHandler = this.connectionDestroyedHandler.bind(this);\n this.streamCreatedHandler = this.streamCreatedHandler.bind(this);\n this.streamDestroyedHandler = this.streamDestroyedHandler.bind(this);\n }\n\n connect(): Promise<void> {\n trace.info('Connect to session');\n\n if (this._session) {\n trace.error('Session already exists');\n\n return Promise.reject('Cannot connect to session while another session is active');\n }\n\n return new Promise((resolve, reject) => {\n const handleError = (error: any): void => {\n this._session && this._session!.off();\n this._session = null;\n trace.error('handleConnect error:', error);\n reject(error);\n };\n\n const {apiKey, sessionId} = this._sessionParams.credentials;\n\n this._session = (window as any).OTSESSION = window.OT.initSession(apiKey, sessionId);\n\n this._session!.on('connectionCreated', this.connectionCreatedHandler);\n this._session!.on('connectionDestroyed', this.connectionDestroyedHandler);\n this._session!.on('streamCreated', this.streamCreatedHandler);\n this._session!.on('streamDestroyed', this.streamDestroyedHandler);\n\n const connectHandler = (error: any): void => {\n if (error) {\n handleError(error);\n\n return;\n }\n\n resolve();\n };\n\n this._session!.connect(this._credentials.token, connectHandler);\n });\n }\n\n disconnect(): Promise<void> {\n return new Promise((resolve) => {\n trace.info('Disconnecting from session');\n const currentSession = this._session;\n\n this._session = null;\n\n this._peerConnections.forEach((peerConnection) => {\n this.destroyPeerConnection(peerConnection);\n });\n\n if (!currentSession) {\n trace.info('No active session - resolving');\n resolve();\n\n return;\n }\n currentSession.off();\n currentSession.disconnect();\n resolve();\n });\n }\n\n //#region OpenTok Events Handlers\n\n private connectionCreatedHandler(event: any): void {\n trace.info('connectionCreatedHandler', event);\n const {connection} = event;\n\n if (!this.sessionExistsGuard(false) || !connection) {\n return;\n }\n\n //In case we got our own connection, we have nothing to do with it\n if (connection.connectionId === this.ownPeerId) {\n return;\n }\n\n const destinationRole = this.calculateDestinationRole();\n\n this.createStreamForPublishing(destinationRole)\n .then((streams: OTStreamSource) => {\n const peerConnection: OTPeerConnection = {\n peerId: connection.connectionId,\n peerRole: destinationRole,\n peerType: this._sessionParams.clientType === SessionClientType.INITIATOR\n ? SessionClientType.GUEST : SessionClientType.INITIATOR,\n connection: connection,\n publisher: null,\n subscriber: null,\n remoteMediaTracks: [],\n localStream: streams\n };\n\n if (!streams.videoSource && !streams.audioSource) {\n trace.info('Peer connection without publisher was created', peerConnection);\n\n return peerConnection;\n }\n\n const streamName = destinationRole === SessionClientRole.USER\n ? KnownMediaStream.AGENT_AUDIO_STREAM : KnownMediaStream.USER_VIDEO_STREAM;\n\n\n return this.createMediaPublisher(streams, streamName)\n .then((publisher: OTPublisher) => {\n peerConnection.publisher = publisher;\n trace.info('Peer connection with publisher was created', peerConnection);\n\n return peerConnection;\n });\n })\n .then((peerConnection: OTPeerConnection) => {\n this._peerConnections.set(peerConnection.peerId, peerConnection);\n\n if (peerConnection.publisher) {\n return new Promise<void>((resolve, reject) => {\n trace.info('Starting publish to peerConnection.publisher');\n this._session!.publish(peerConnection.publisher, (error: any) => {\n if (error) {\n trace.error('Publish to peerConnection error', error);\n\n return reject(error);\n }\n trace.info('Publish to peerConnection success');\n\n return resolve();\n });\n });\n }\n\n return Promise.resolve();\n })\n .catch((error: any) => {\n //Need to handle fail cases during reliability\n trace.error('Error handling new peer connection', error);\n });\n }\n\n private connectionDestroyedHandler(event: any): void {\n trace.info('connectionDestroyedHandler', event);\n const {connection} = event;\n\n if (!this.sessionExistsGuard(false) || !connection) {\n return;\n }\n\n if (this._peerConnections.has(connection.connectionId)) {\n this.destroyPeerConnection(this._peerConnections.get(connection.connectionId)!);\n }\n }\n\n private streamCreatedHandler(event: any): void {\n trace.info('streamCreatedHandler', event.stream);\n const {stream} = event;\n const {connection} = stream || {connection: null};\n\n if (!this.sessionExistsGuard(false) || !stream) {\n return;\n }\n\n if (!this._peerConnections.has(connection.connectionId)) {\n trace.warn('Unexpected case, connection should exist on this stage');\n\n return;\n }\n\n const peerConnection = this._peerConnections.get(connection.connectionId)!;\n\n trace.info('Subscribing the stream');\n\n //TODO - Optimize the code below\n peerConnection.subscriber = this._session!.subscribe(stream, null, null, (err: any) => {\n if (err) {\n peerConnection.subscriber = null;\n trace.warn('Error in subscriber', err);\n\n return;\n }\n\n const videoElQuery = `#${peerConnection.subscriber.id} .OT_video-element`;\n const otVideoEl = document.querySelector(videoElQuery);\n\n if (!otVideoEl) {\n trace.warn('Cannot fined OT video element');\n\n return;\n }\n\n document.getElementById(peerConnection.subscriber.id)!.style.display = 'none';\n const otMediaStream: MediaStream = (otVideoEl as any).srcObject;\n\n if (!otMediaStream) {\n trace.warn('MediaStream not found in OT video element');\n\n return;\n }\n\n trace.info('Registering remote media tracks', peerConnection.subscriber);\n otMediaStream.getTracks().forEach((mediaTrack: MediaStreamTrack) => {\n this.registerMediaTrackFromPeer(peerConnection, mediaTrack);\n });\n });\n peerConnection.subscriber.on('videoElementCreated', (args: any) => {\n trace.info('videoElementCreated - REDO', args);\n });\n }\n\n private streamDestroyedHandler(event: any): void {\n trace.info('streamDestroyedHandler', event);\n const {stream} = event;\n\n if (!this.sessionExistsGuard(false) || !stream) {\n return;\n }\n\n const peerConnection = this._peerConnections.get(stream.connection.connectionId);\n\n if (!peerConnection) {\n trace.warn('Peer connection for remote stream not found');\n\n return;\n }\n\n this.unregisterPeersRemoteMediaTracks(peerConnection);\n this.destroySubscriberOnPeerConnection(peerConnection);\n }\n\n //#endregion\n\n onMediaStreamDestroyed(clientRole: SessionClientRole): Promise<void> {\n this._peerConnections.forEach((peerConnection) => {\n if (peerConnection.peerRole === clientRole) {\n this.destroyPublisherOnPeerConnection(peerConnection);\n }\n });\n\n return Promise.resolve();\n }\n\n onMediaStreamRenewed(clientRole: SessionClientRole, mediaStream: MediaStream): Promise<void> {\n //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation (in OT API)\n return Promise.resolve();\n }\n\n getRemoteTrackStats(mediaTrack: MediaStreamTrack): Promise<RemoteTrackStats> {\n return new Promise((resolve: any, reject: any) => {\n const peerConnectionOfTrack = this.getPeerConnectionByMediaTrack(mediaTrack);\n\n if (!peerConnectionOfTrack || !peerConnectionOfTrack.subscriber) {\n reject(new Error('Cannot find peer or subscriber for getting stats'));\n }\n\n //https://tokbox.com/developer/sdks/js/reference/Subscriber.html#getStats\n peerConnectionOfTrack!.subscriber.getStats((error: any, stats: any) => {\n if (error) {\n trace.warn('Error getting stats', error);\n resolve({trackId: mediaTrack.id, trackStats: {}});\n\n return;\n }\n resolve({trackId: mediaTrack.id, trackStats: stats});\n });\n });\n }\n\n private createStreamForPublishing(destinationRole: SessionClientRole): Promise<OTStreamSource> {\n trace.info('createStreamForPublishing');\n\n return this._sessionStreamsManager.getMediaStreamForRole(destinationRole)\n .then((mediaStream: Nullable<MediaStream>) => {\n\n const stream: OTStreamSource = {videoSource: null, audioSource: null};\n\n if (mediaStream) {\n trace.info('Media stream found for publishing', mediaStream);\n mediaStream.getTracks().forEach((track) => {\n if (track.kind === 'video') {\n stream.videoSource = track;\n } else if (track.kind === 'audio') {\n stream.audioSource = track;\n }\n });\n } else if (this._sessionParams.clientRole === SessionClientRole.USER) {\n trace.warn('No local media was found for publishing to destinationRole:', destinationRole);\n }\n\n return stream;\n });\n }\n\n private calculateDestinationRole(): SessionClientRole {\n if (this._sessionParams.clientRole === SessionClientRole.USER) {\n const isAgentConnected = false;\n\n\n return !isAgentConnected ? SessionClientRole.AGENT : SessionClientRole.OBSERVER;\n }\n\n return SessionClientRole.USER;\n }\n\n private createMediaPublisher(stream: OTStreamSource, streamName: string): Promise<OTPublisher> {\n const otParams = {\n videoSource: stream.videoSource ? stream.videoSource : false,\n audioSource: stream.audioSource ? stream.audioSource : false,\n publishAudio: !!stream.audioSource,\n publishVideo: !!stream.videoSource,\n showControls: false,\n name: streamName\n };\n\n return new Promise((resolve, reject) => {\n const otPublisher = window.OT.initPublisher(undefined, otParams, (error: any) => {\n if (error) {\n reject(error);\n\n return;\n }\n resolve(otPublisher);\n });\n });\n }\n\n private destroyPeerConnection(peerConnection: OTPeerConnection): void {\n this._peerConnections.delete(peerConnection.peerId);\n this.destroyPublisherOnPeerConnection(peerConnection);\n this.unregisterPeersRemoteMediaTracks(peerConnection);\n this.destroySubscriberOnPeerConnection(peerConnection);\n }\n\n private destroyPublisherOnPeerConnection(peerConnection: OTPeerConnection): void {\n if (peerConnection.publisher) {\n //TODO - Alex: When destroying the publisher, OT closes the stream by himself, without we ask him.\n //So we not destroying the OT publisher right now in order to preserve our stream alive.\n //Later, we can recreate our stream as new, or manually delete \"video\" element that created by OT.\n // or we just can leave it as is :)\n //peerConnection.publisher.destroy();\n peerConnection.publisher = null;\n peerConnection.localStream = null;\n }\n }\n\n private destroySubscriberOnPeerConnection(peerConnection: OTPeerConnection): void {\n if (!this.sessionExistsGuard(false) || peerConnection.subscriber) {\n return;\n }\n\n this._session!.unsubscribe(peerConnection.subscriber);\n peerConnection.subscriber = null;\n }\n\n private sessionExistsGuard(shouldThrow = true): boolean {\n const connected = !!(this._session && this._session.connection && this._session.connection.connectionId);\n\n\n return throwableGuard(connected, 'There no active session', shouldThrow);\n }\n}\n\n"]}
|
|
@@ -1,29 +1,48 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
var __extends = undefined && undefined.__extends || function () {
|
|
4
|
+
var _extendStatics = function extendStatics(d, b) {
|
|
5
|
+
_extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function (d, b) {
|
|
6
|
+
d.__proto__ = b;
|
|
7
|
+
} || function (d, b) {
|
|
8
|
+
for (var p in b) {
|
|
9
|
+
if (b.hasOwnProperty(p)) d[p] = b[p];
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
return _extendStatics(d, b);
|
|
13
|
+
};
|
|
14
|
+
return function (d, b) {
|
|
15
|
+
_extendStatics(d, b);
|
|
16
|
+
function __() {
|
|
17
|
+
this.constructor = d;
|
|
18
|
+
}
|
|
19
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
20
|
+
};
|
|
21
|
+
}();
|
|
3
22
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
23
|
var MediaConstants_1 = require("../MediaConstants");
|
|
5
|
-
var MediaTracer_1 = require("../MediaUtils/MediaTracer");
|
|
6
24
|
var guards_1 = require("@techsee/techsee-common/lib/core/guards");
|
|
7
|
-
var
|
|
25
|
+
var MediaSessionBase_1 = require("./MediaSessionBase");
|
|
26
|
+
var MediaTracer_1 = require("../MediaUtils/MediaTracer");
|
|
27
|
+
var trace = MediaTracer_1.getMediaTracer('OpentokSessionV3');
|
|
8
28
|
//Currently this version supports subscribing only. Publishing will be implemented as needed.
|
|
9
|
-
var OpentokSessionV3 = /** @class */function () {
|
|
29
|
+
var OpentokSessionV3 = /** @class */function (_super) {
|
|
30
|
+
__extends(OpentokSessionV3, _super);
|
|
10
31
|
function OpentokSessionV3(sessionParams, streamFactory) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
this.streamCreatedHandler = this.streamCreatedHandler.bind(this);
|
|
26
|
-
this.streamDestroyedHandler = this.streamDestroyedHandler.bind(this);
|
|
32
|
+
var _this = _super.call(this, sessionParams, streamFactory) || this;
|
|
33
|
+
_this._session = null;
|
|
34
|
+
_this._credentials = sessionParams.credentials;
|
|
35
|
+
_this.connect = _this.connect.bind(_this);
|
|
36
|
+
_this.disconnect = _this.disconnect.bind(_this);
|
|
37
|
+
_this.onMediaStreamDestroyed = _this.onMediaStreamDestroyed.bind(_this);
|
|
38
|
+
_this.onMediaStreamRenewed = _this.onMediaStreamRenewed.bind(_this);
|
|
39
|
+
_this.createStreamForPublishing = _this.createStreamForPublishing.bind(_this);
|
|
40
|
+
_this.createMediaPublisher = _this.createMediaPublisher.bind(_this);
|
|
41
|
+
_this.connectionCreatedHandler = _this.connectionCreatedHandler.bind(_this);
|
|
42
|
+
_this.connectionDestroyedHandler = _this.connectionDestroyedHandler.bind(_this);
|
|
43
|
+
_this.streamCreatedHandler = _this.streamCreatedHandler.bind(_this);
|
|
44
|
+
_this.streamDestroyedHandler = _this.streamDestroyedHandler.bind(_this);
|
|
45
|
+
return _this;
|
|
27
46
|
}
|
|
28
47
|
Object.defineProperty(OpentokSessionV3.prototype, "id", {
|
|
29
48
|
get: function get() {
|
|
@@ -73,9 +92,8 @@ var OpentokSessionV3 = /** @class */function () {
|
|
|
73
92
|
};
|
|
74
93
|
OpentokSessionV3.prototype.disconnect = function () {
|
|
75
94
|
var _this = this;
|
|
76
|
-
//TODO - Alex: Implement destroying all publishers (by opentok docs)
|
|
77
|
-
//Create a method destroy publisher (or publishers can treated the same as "peerConnections"?
|
|
78
95
|
return new Promise(function (resolve) {
|
|
96
|
+
trace.info('Disconnecting from session');
|
|
79
97
|
var currentSession = _this._session;
|
|
80
98
|
_this._session = null;
|
|
81
99
|
_this._peerConnections.forEach(function (peerConnection) {
|
|
@@ -91,23 +109,6 @@ var OpentokSessionV3 = /** @class */function () {
|
|
|
91
109
|
resolve();
|
|
92
110
|
});
|
|
93
111
|
};
|
|
94
|
-
OpentokSessionV3.prototype.onMediaStreamDestroyed = function (clientRole) {
|
|
95
|
-
var _this = this;
|
|
96
|
-
this._peerConnections.forEach(function (peerConnection) {
|
|
97
|
-
if (peerConnection.peerRole === clientRole) {
|
|
98
|
-
_this.destroyPublisherOnPeerConnection(peerConnection);
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
return Promise.resolve();
|
|
102
|
-
};
|
|
103
|
-
OpentokSessionV3.prototype.onMediaStreamRenewed = function (clientRole, mediaStream) {
|
|
104
|
-
//TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation (in OT API)
|
|
105
|
-
return Promise.resolve();
|
|
106
|
-
};
|
|
107
|
-
OpentokSessionV3.prototype.getRemoteTrackStats = function (mediaTrack) {
|
|
108
|
-
//https://tokbox.com/developer/sdks/js/reference/Subscriber.html (getStats)
|
|
109
|
-
return Promise.reject(new Error('Not implemented yet'));
|
|
110
|
-
};
|
|
111
112
|
//#region OpenTok Events Handlers
|
|
112
113
|
OpentokSessionV3.prototype.connectionCreatedHandler = function (event) {
|
|
113
114
|
var _this = this;
|
|
@@ -128,6 +129,7 @@ var OpentokSessionV3 = /** @class */function () {
|
|
|
128
129
|
peerType: _this._sessionParams.clientType === MediaConstants_1.SessionClientType.INITIATOR ? MediaConstants_1.SessionClientType.GUEST : MediaConstants_1.SessionClientType.INITIATOR,
|
|
129
130
|
connection: connection,
|
|
130
131
|
publisher: null,
|
|
132
|
+
subscriber: null,
|
|
131
133
|
remoteMediaTracks: [],
|
|
132
134
|
localStream: streams
|
|
133
135
|
};
|
|
@@ -173,6 +175,7 @@ var OpentokSessionV3 = /** @class */function () {
|
|
|
173
175
|
}
|
|
174
176
|
};
|
|
175
177
|
OpentokSessionV3.prototype.streamCreatedHandler = function (event) {
|
|
178
|
+
var _this = this;
|
|
176
179
|
trace.info('streamCreatedHandler', event.stream);
|
|
177
180
|
var stream = event.stream;
|
|
178
181
|
var connection = (stream || { connection: null }).connection;
|
|
@@ -184,13 +187,34 @@ var OpentokSessionV3 = /** @class */function () {
|
|
|
184
187
|
return;
|
|
185
188
|
}
|
|
186
189
|
var peerConnection = this._peerConnections.get(connection.connectionId);
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
190
|
+
trace.info('Subscribing the stream');
|
|
191
|
+
//TODO - Optimize the code below
|
|
192
|
+
peerConnection.subscriber = this._session.subscribe(stream, null, null, function (err) {
|
|
193
|
+
if (err) {
|
|
194
|
+
peerConnection.subscriber = null;
|
|
195
|
+
trace.warn('Error in subscriber', err);
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
var videoElQuery = "#" + peerConnection.subscriber.id + " .OT_video-element";
|
|
199
|
+
var otVideoEl = document.querySelector(videoElQuery);
|
|
200
|
+
if (!otVideoEl) {
|
|
201
|
+
trace.warn('Cannot fined OT video element');
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
document.getElementById(peerConnection.subscriber.id).style.display = 'none';
|
|
205
|
+
var otMediaStream = otVideoEl.srcObject;
|
|
206
|
+
if (!otMediaStream) {
|
|
207
|
+
trace.warn('MediaStream not found in OT video element');
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
trace.info('Registering remote media tracks', peerConnection.subscriber);
|
|
211
|
+
otMediaStream.getTracks().forEach(function (mediaTrack) {
|
|
212
|
+
_this.registerMediaTrackFromPeer(peerConnection, mediaTrack);
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
peerConnection.subscriber.on('videoElementCreated', function (args) {
|
|
216
|
+
trace.info('videoElementCreated - REDO', args);
|
|
217
|
+
});
|
|
194
218
|
};
|
|
195
219
|
OpentokSessionV3.prototype.streamDestroyedHandler = function (event) {
|
|
196
220
|
trace.info('streamDestroyedHandler', event);
|
|
@@ -198,10 +222,46 @@ var OpentokSessionV3 = /** @class */function () {
|
|
|
198
222
|
if (!this.sessionExistsGuard(false) || !stream) {
|
|
199
223
|
return;
|
|
200
224
|
}
|
|
201
|
-
|
|
202
|
-
|
|
225
|
+
var peerConnection = this._peerConnections.get(stream.connection.connectionId);
|
|
226
|
+
if (!peerConnection) {
|
|
227
|
+
trace.warn('Peer connection for remote stream not found');
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
this.unregisterPeersRemoteMediaTracks(peerConnection);
|
|
231
|
+
this.destroySubscriberOnPeerConnection(peerConnection);
|
|
203
232
|
};
|
|
204
233
|
//#endregion
|
|
234
|
+
OpentokSessionV3.prototype.onMediaStreamDestroyed = function (clientRole) {
|
|
235
|
+
var _this = this;
|
|
236
|
+
this._peerConnections.forEach(function (peerConnection) {
|
|
237
|
+
if (peerConnection.peerRole === clientRole) {
|
|
238
|
+
_this.destroyPublisherOnPeerConnection(peerConnection);
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
return Promise.resolve();
|
|
242
|
+
};
|
|
243
|
+
OpentokSessionV3.prototype.onMediaStreamRenewed = function (clientRole, mediaStream) {
|
|
244
|
+
//TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation (in OT API)
|
|
245
|
+
return Promise.resolve();
|
|
246
|
+
};
|
|
247
|
+
OpentokSessionV3.prototype.getRemoteTrackStats = function (mediaTrack) {
|
|
248
|
+
var _this = this;
|
|
249
|
+
return new Promise(function (resolve, reject) {
|
|
250
|
+
var peerConnectionOfTrack = _this.getPeerConnectionByMediaTrack(mediaTrack);
|
|
251
|
+
if (!peerConnectionOfTrack || !peerConnectionOfTrack.subscriber) {
|
|
252
|
+
reject(new Error('Cannot find peer or subscriber for getting stats'));
|
|
253
|
+
}
|
|
254
|
+
//https://tokbox.com/developer/sdks/js/reference/Subscriber.html#getStats
|
|
255
|
+
peerConnectionOfTrack.subscriber.getStats(function (error, stats) {
|
|
256
|
+
if (error) {
|
|
257
|
+
trace.warn('Error getting stats', error);
|
|
258
|
+
resolve({ trackId: mediaTrack.id, trackStats: {} });
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
resolve({ trackId: mediaTrack.id, trackStats: stats });
|
|
262
|
+
});
|
|
263
|
+
});
|
|
264
|
+
};
|
|
205
265
|
OpentokSessionV3.prototype.createStreamForPublishing = function (destinationRole) {
|
|
206
266
|
var _this = this;
|
|
207
267
|
trace.info('createStreamForPublishing');
|
|
@@ -248,25 +308,11 @@ var OpentokSessionV3 = /** @class */function () {
|
|
|
248
308
|
});
|
|
249
309
|
});
|
|
250
310
|
};
|
|
251
|
-
OpentokSessionV3.prototype.clearPeerConnections = function () {
|
|
252
|
-
return Promise.resolve();
|
|
253
|
-
};
|
|
254
|
-
OpentokSessionV3.prototype.sessionExistsGuard = function (shouldThrow) {
|
|
255
|
-
if (shouldThrow === void 0) {
|
|
256
|
-
shouldThrow = true;
|
|
257
|
-
}
|
|
258
|
-
var connected = !!(this._session && this._session.connection && this._session.connection.connectionId);
|
|
259
|
-
return guards_1.throwableGuard(connected, 'There no active session', shouldThrow);
|
|
260
|
-
};
|
|
261
311
|
OpentokSessionV3.prototype.destroyPeerConnection = function (peerConnection) {
|
|
262
|
-
var _this = this;
|
|
263
312
|
this._peerConnections.delete(peerConnection.peerId);
|
|
264
313
|
this.destroyPublisherOnPeerConnection(peerConnection);
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
trace.warn('Error removing media track', error);
|
|
268
|
-
});
|
|
269
|
-
});
|
|
314
|
+
this.unregisterPeersRemoteMediaTracks(peerConnection);
|
|
315
|
+
this.destroySubscriberOnPeerConnection(peerConnection);
|
|
270
316
|
};
|
|
271
317
|
OpentokSessionV3.prototype.destroyPublisherOnPeerConnection = function (peerConnection) {
|
|
272
318
|
if (peerConnection.publisher) {
|
|
@@ -279,8 +325,22 @@ var OpentokSessionV3 = /** @class */function () {
|
|
|
279
325
|
peerConnection.localStream = null;
|
|
280
326
|
}
|
|
281
327
|
};
|
|
328
|
+
OpentokSessionV3.prototype.destroySubscriberOnPeerConnection = function (peerConnection) {
|
|
329
|
+
if (!this.sessionExistsGuard(false) || peerConnection.subscriber) {
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
this._session.unsubscribe(peerConnection.subscriber);
|
|
333
|
+
peerConnection.subscriber = null;
|
|
334
|
+
};
|
|
335
|
+
OpentokSessionV3.prototype.sessionExistsGuard = function (shouldThrow) {
|
|
336
|
+
if (shouldThrow === void 0) {
|
|
337
|
+
shouldThrow = true;
|
|
338
|
+
}
|
|
339
|
+
var connected = !!(this._session && this._session.connection && this._session.connection.connectionId);
|
|
340
|
+
return guards_1.throwableGuard(connected, 'There no active session', shouldThrow);
|
|
341
|
+
};
|
|
282
342
|
return OpentokSessionV3;
|
|
283
|
-
}();
|
|
343
|
+
}(MediaSessionBase_1.MediaSessionBase);
|
|
284
344
|
exports.OpentokSessionV3 = OpentokSessionV3;
|
|
285
345
|
|
|
286
346
|
//# sourceMappingURL=SessionOpentok.v3.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["MediaSession/SessionOpentok.v3.js"],"names":["Object","defineProperty","exports","value","MediaConstants_1","require","MediaTracer_1","guards_1","trace","getMediaTracer","OpentokSessionV3","sessionParams","streamFactory","_peerConnections","Map","_session","_sessionParams","_sessionStreamsManager","_credentials","credentials","connect","bind","disconnect","onMediaStreamDestroyed","onMediaStreamRenewed","createStreamForPublishing","createMediaPublisher","clearPeerConnections","connectionCreatedHandler","connectionDestroyedHandler","streamCreatedHandler","streamDestroyedHandler","prototype","get","sessionId","enumerable","configurable","connection","connectionId","_this","info","error","Promise","reject","resolve","handleError","off","_a","apiKey","window","OTSESSION","OT","initSession","on","connectHandler","token","currentSession","forEach","peerConnection","destroyPeerConnection","clientRole","peerRole","destroyPublisherOnPeerConnection","mediaStream","getRemoteTrackStats","mediaTrack","Error","event","sessionExistsGuard","ownPeerId","destinationRole","calculateDestinationRole","then","streams","peerId","peerType","clientType","SessionClientType","INITIATOR","GUEST","publisher","remoteMediaTracks","localStream","videoSource","audioSource","streamName","SessionClientRole","USER","KnownMediaStream","AGENT_AUDIO_STREAM","USER_VIDEO_STREAM","set","publish","catch","has","stream","warn","getMediaStreamForRole","getTracks","track","kind","isAgentConnected","AGENT","OBSERVER","otParams","publishAudio","publishVideo","showControls","name","otPublisher","initPublisher","undefined","shouldThrow","connected","throwableGuard","delete","removeMediaTrack"],"mappings":"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","file":"SessionOpentok.v3.js","sourcesContent":["\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar MediaConstants_1 = require(\"../MediaConstants\");\nvar MediaTracer_1 = require(\"../MediaUtils/MediaTracer\");\nvar guards_1 = require(\"@techsee/techsee-common/lib/core/guards\");\nvar trace = MediaTracer_1.getMediaTracer('OpenTokSession');\n//Currently this version supports subscribing only. Publishing will be implemented as needed.\nvar OpentokSessionV3 = /** @class */ (function () {\n function OpentokSessionV3(sessionParams, streamFactory) {\n this._peerConnections = new Map();\n this._session = null;\n this._sessionParams = sessionParams;\n this._sessionStreamsManager = streamFactory;\n this._credentials = sessionParams.credentials;\n this.connect = this.connect.bind(this);\n this.disconnect = this.disconnect.bind(this);\n this.onMediaStreamDestroyed = this.onMediaStreamDestroyed.bind(this);\n this.onMediaStreamRenewed = this.onMediaStreamRenewed.bind(this);\n this.createStreamForPublishing = this.createStreamForPublishing.bind(this);\n this.createMediaPublisher = this.createMediaPublisher.bind(this);\n this.clearPeerConnections = this.clearPeerConnections.bind(this);\n this.connectionCreatedHandler = this.connectionCreatedHandler.bind(this);\n this.connectionDestroyedHandler = this.connectionDestroyedHandler.bind(this);\n this.streamCreatedHandler = this.streamCreatedHandler.bind(this);\n this.streamDestroyedHandler = this.streamDestroyedHandler.bind(this);\n }\n Object.defineProperty(OpentokSessionV3.prototype, \"id\", {\n get: function () {\n return this._session && this._session.sessionId ? this._session.sessionId : '';\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(OpentokSessionV3.prototype, \"ownPeerId\", {\n get: function () {\n return this._session && this._session.connection ? this._session.connection.connectionId : '';\n },\n enumerable: true,\n configurable: true\n });\n OpentokSessionV3.prototype.connect = function () {\n var _this = this;\n trace.info('Connect to session');\n if (this._session) {\n trace.error('Session already exists');\n return Promise.reject('Cannot connect to session while another session is active');\n }\n return new Promise(function (resolve, reject) {\n var handleError = function (error) {\n _this._session && _this._session.off();\n _this._session = null;\n trace.error('handleConnect error:', error);\n reject(error);\n };\n var _a = _this._sessionParams.credentials, apiKey = _a.apiKey, sessionId = _a.sessionId;\n _this._session = window.OTSESSION = window.OT.initSession(apiKey, sessionId);\n _this._session.on('connectionCreated', _this.connectionCreatedHandler);\n _this._session.on('connectionDestroyed', _this.connectionDestroyedHandler);\n _this._session.on('streamCreated', _this.streamCreatedHandler);\n _this._session.on('streamDestroyed', _this.streamDestroyedHandler);\n var connectHandler = function (error) {\n if (error) {\n handleError(error);\n return;\n }\n resolve();\n };\n _this._session.connect(_this._credentials.token, connectHandler);\n });\n };\n OpentokSessionV3.prototype.disconnect = function () {\n var _this = this;\n //TODO - Alex: Implement destroying all publishers (by opentok docs)\n //Create a method destroy publisher (or publishers can treated the same as \"peerConnections\"?\n return new Promise(function (resolve) {\n var currentSession = _this._session;\n _this._session = null;\n _this._peerConnections.forEach(function (peerConnection) {\n _this.destroyPeerConnection(peerConnection);\n });\n if (!currentSession) {\n trace.info('No active session - resolving');\n resolve();\n return;\n }\n currentSession.off();\n currentSession.disconnect();\n resolve();\n });\n };\n OpentokSessionV3.prototype.onMediaStreamDestroyed = function (clientRole) {\n var _this = this;\n this._peerConnections.forEach(function (peerConnection) {\n if (peerConnection.peerRole === clientRole) {\n _this.destroyPublisherOnPeerConnection(peerConnection);\n }\n });\n return Promise.resolve();\n };\n OpentokSessionV3.prototype.onMediaStreamRenewed = function (clientRole, mediaStream) {\n //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation (in OT API)\n return Promise.resolve();\n };\n OpentokSessionV3.prototype.getRemoteTrackStats = function (mediaTrack) {\n //https://tokbox.com/developer/sdks/js/reference/Subscriber.html (getStats)\n return Promise.reject(new Error('Not implemented yet'));\n };\n //#region OpenTok Events Handlers\n OpentokSessionV3.prototype.connectionCreatedHandler = function (event) {\n var _this = this;\n trace.info('connectionCreatedHandler', event);\n var connection = event.connection;\n if (!this.sessionExistsGuard(false) || !connection) {\n return;\n }\n //In case we got our own connection, we have nothing to do with it\n if (connection.connectionId === this.ownPeerId) {\n return;\n }\n var destinationRole = this.calculateDestinationRole();\n this.createStreamForPublishing(destinationRole)\n .then(function (streams) {\n var peerConnection = {\n peerId: connection.connectionId,\n peerRole: destinationRole,\n peerType: _this._sessionParams.clientType === MediaConstants_1.SessionClientType.INITIATOR\n ? MediaConstants_1.SessionClientType.GUEST : MediaConstants_1.SessionClientType.INITIATOR,\n connection: connection,\n publisher: null,\n remoteMediaTracks: [],\n localStream: streams\n };\n if (!streams.videoSource && !streams.audioSource) {\n trace.info('Peer connection without publisher was created', peerConnection);\n return peerConnection;\n }\n var streamName = destinationRole === MediaConstants_1.SessionClientRole.USER\n ? MediaConstants_1.KnownMediaStream.AGENT_AUDIO_STREAM : MediaConstants_1.KnownMediaStream.USER_VIDEO_STREAM;\n return _this.createMediaPublisher(streams, streamName)\n .then(function (publisher) {\n peerConnection.publisher = publisher;\n trace.info('Peer connection with publisher was created', peerConnection);\n return peerConnection;\n });\n })\n .then(function (peerConnection) {\n _this._peerConnections.set(peerConnection.peerId, peerConnection);\n if (peerConnection.publisher) {\n return new Promise(function (resolve, reject) {\n trace.info('Starting publish to peerConnection.publisher');\n _this._session.publish(peerConnection.publisher, function (error) {\n if (error) {\n trace.error('Publish to peerConnection error', error);\n return reject(error);\n }\n trace.info('Publish to peerConnection success');\n return resolve();\n });\n });\n }\n return Promise.resolve();\n })\n .catch(function (error) {\n //Need to handle fail cases during reliability\n trace.error('Error handling new peer connection', error);\n });\n };\n OpentokSessionV3.prototype.connectionDestroyedHandler = function (event) {\n trace.info('connectionDestroyedHandler', event);\n var connection = event.connection;\n if (!this.sessionExistsGuard(false) || !connection) {\n return;\n }\n if (this._peerConnections.has(connection.connectionId)) {\n this.destroyPeerConnection(this._peerConnections.get(connection.connectionId));\n }\n };\n OpentokSessionV3.prototype.streamCreatedHandler = function (event) {\n trace.info('streamCreatedHandler', event.stream);\n var stream = event.stream;\n var connection = (stream || { connection: null }).connection;\n if (!this.sessionExistsGuard(false) || !stream) {\n return;\n }\n if (!this._peerConnections.has(connection.connectionId)) {\n trace.warn('Unexpected case, connection should exist on this stage');\n return;\n }\n var peerConnection = this._peerConnections.get(connection.connectionId);\n if (!peerConnection) {\n trace.warn('Unexpected PeerConnection not found');\n return;\n }\n //Find peerConnection by connectionId, add all tracks to remoteTracks (check if it exists before)\n //We cannot have to tracks with the same id or with the same meaning\n //Register each track using addRemoteTrack\n };\n OpentokSessionV3.prototype.streamDestroyedHandler = function (event) {\n trace.info('streamDestroyedHandler', event);\n var stream = event.stream;\n if (!this.sessionExistsGuard(false) || !stream) {\n return;\n }\n //Find peerConnection by connectionId, add remove tracks from stream\n //Register each track using addRemoteTrack\n };\n //#endregion\n OpentokSessionV3.prototype.createStreamForPublishing = function (destinationRole) {\n var _this = this;\n trace.info('createStreamForPublishing');\n return this._sessionStreamsManager.getMediaStreamForRole(destinationRole)\n .then(function (mediaStream) {\n var stream = { videoSource: null, audioSource: null };\n if (mediaStream) {\n trace.info('Media stream found for publishing', mediaStream);\n mediaStream.getTracks().forEach(function (track) {\n if (track.kind === 'video') {\n stream.videoSource = track;\n }\n else if (track.kind === 'audio') {\n stream.audioSource = track;\n }\n });\n }\n else if (_this._sessionParams.clientRole === MediaConstants_1.SessionClientRole.USER) {\n trace.warn('No local media was found for publishing to destinationRole:', destinationRole);\n }\n return stream;\n });\n };\n OpentokSessionV3.prototype.calculateDestinationRole = function () {\n if (this._sessionParams.clientRole === MediaConstants_1.SessionClientRole.USER) {\n var isAgentConnected = false;\n return !isAgentConnected ? MediaConstants_1.SessionClientRole.AGENT : MediaConstants_1.SessionClientRole.OBSERVER;\n }\n return MediaConstants_1.SessionClientRole.USER;\n };\n OpentokSessionV3.prototype.createMediaPublisher = function (stream, streamName) {\n var otParams = {\n videoSource: stream.videoSource ? stream.videoSource : false,\n audioSource: stream.audioSource ? stream.audioSource : false,\n publishAudio: !!stream.audioSource,\n publishVideo: !!stream.videoSource,\n showControls: false,\n name: streamName\n };\n return new Promise(function (resolve, reject) {\n var otPublisher = window.OT.initPublisher(undefined, otParams, function (error) {\n if (error) {\n reject(error);\n return;\n }\n resolve(otPublisher);\n });\n });\n };\n OpentokSessionV3.prototype.clearPeerConnections = function () {\n return Promise.resolve();\n };\n OpentokSessionV3.prototype.sessionExistsGuard = function (shouldThrow) {\n if (shouldThrow === void 0) { shouldThrow = true; }\n var connected = !!(this._session && this._session.connection && this._session.connection.connectionId);\n return guards_1.throwableGuard(connected, 'There no active session', shouldThrow);\n };\n OpentokSessionV3.prototype.destroyPeerConnection = function (peerConnection) {\n var _this = this;\n this._peerConnections.delete(peerConnection.peerId);\n this.destroyPublisherOnPeerConnection(peerConnection);\n peerConnection.remoteMediaTracks.forEach(function (mediaTrack) {\n _this._sessionStreamsManager.removeMediaTrack(mediaTrack.mediaTrack)\n .catch(function (error) {\n trace.warn('Error removing media track', error);\n });\n });\n };\n OpentokSessionV3.prototype.destroyPublisherOnPeerConnection = function (peerConnection) {\n if (peerConnection.publisher) {\n //TODO - Alex: When destroying the publisher, OT closes the stream by himself, without we ask him.\n //So we not destroying the OT publisher right now in order to preserve our stream alive.\n //Later, we can recreate our stream as new, or manually delete \"video\" element that created by OT.\n // or we just can leave it as is :)\n //peerConnection.publisher.destroy();\n peerConnection.publisher = null;\n peerConnection.localStream = null;\n }\n };\n return OpentokSessionV3;\n}());\nexports.OpentokSessionV3 = OpentokSessionV3;\n\n//# sourceMappingURL=SessionOpentok.v3.js.map\n"]}
|
|
1
|
+
{"version":3,"sources":["MediaSession/SessionOpentok.v3.js"],"names":["__extends","extendStatics","d","b","Object","setPrototypeOf","__proto__","Array","p","hasOwnProperty","__","constructor","prototype","create","defineProperty","exports","value","MediaConstants_1","require","guards_1","MediaSessionBase_1","MediaTracer_1","trace","getMediaTracer","OpentokSessionV3","_super","sessionParams","streamFactory","_this","call","_session","_credentials","credentials","connect","bind","disconnect","onMediaStreamDestroyed","onMediaStreamRenewed","createStreamForPublishing","createMediaPublisher","connectionCreatedHandler","connectionDestroyedHandler","streamCreatedHandler","streamDestroyedHandler","get","sessionId","enumerable","configurable","connection","connectionId","info","error","Promise","reject","resolve","handleError","off","_a","_sessionParams","apiKey","window","OTSESSION","OT","initSession","on","connectHandler","token","currentSession","_peerConnections","forEach","peerConnection","destroyPeerConnection","event","sessionExistsGuard","ownPeerId","destinationRole","calculateDestinationRole","then","streams","peerId","peerRole","peerType","clientType","SessionClientType","INITIATOR","GUEST","publisher","subscriber","remoteMediaTracks","localStream","videoSource","audioSource","streamName","SessionClientRole","USER","KnownMediaStream","AGENT_AUDIO_STREAM","USER_VIDEO_STREAM","set","publish","catch","has","stream","warn","subscribe","err","videoElQuery","id","otVideoEl","document","querySelector","getElementById","style","display","otMediaStream","srcObject","getTracks","mediaTrack","registerMediaTrackFromPeer","args","unregisterPeersRemoteMediaTracks","destroySubscriberOnPeerConnection","clientRole","destroyPublisherOnPeerConnection","mediaStream","getRemoteTrackStats","peerConnectionOfTrack","getPeerConnectionByMediaTrack","Error","getStats","stats","trackId","trackStats","_sessionStreamsManager","getMediaStreamForRole","track","kind","isAgentConnected","AGENT","OBSERVER","otParams","publishAudio","publishVideo","showControls","name","otPublisher","initPublisher","undefined","delete","unsubscribe","shouldThrow","connected","throwableGuard","MediaSessionBase"],"mappings":"AAAA;;AACA,IAAIA,YAAa,aAAQ,UAAKA,SAAd,IAA6B,YAAY;AACrD,QAAIC,iBAAgB,uBAAUC,CAAV,EAAaC,CAAb,EAAgB;AAChCF,yBAAgBG,OAAOC,cAAP,IACX,EAAEC,WAAW,EAAb,cAA6BC,KAA7B,IAAsC,UAAUL,CAAV,EAAaC,CAAb,EAAgB;AAAED,cAAEI,SAAF,GAAcH,CAAd;AAAkB,SAD/D,IAEZ,UAAUD,CAAV,EAAaC,CAAb,EAAgB;AAAE,iBAAK,IAAIK,CAAT,IAAcL,CAAd;AAAiB,oBAAIA,EAAEM,cAAF,CAAiBD,CAAjB,CAAJ,EAAyBN,EAAEM,CAAF,IAAOL,EAAEK,CAAF,CAAP;AAA1C;AAAwD,SAF9E;AAGA,eAAOP,eAAcC,CAAd,EAAiBC,CAAjB,CAAP;AACH,KALD;AAMA,WAAO,UAAUD,CAAV,EAAaC,CAAb,EAAgB;AACnBF,uBAAcC,CAAd,EAAiBC,CAAjB;AACA,iBAASO,EAAT,GAAc;AAAE,iBAAKC,WAAL,GAAmBT,CAAnB;AAAuB;AACvCA,UAAEU,SAAF,GAAcT,MAAM,IAAN,GAAaC,OAAOS,MAAP,CAAcV,CAAd,CAAb,IAAiCO,GAAGE,SAAH,GAAeT,EAAES,SAAjB,EAA4B,IAAIF,EAAJ,EAA7D,CAAd;AACH,KAJD;AAKH,CAZ2C,EAA5C;AAaAN,OAAOU,cAAP,CAAsBC,OAAtB,EAA+B,YAA/B,EAA6C,EAAEC,OAAO,IAAT,EAA7C;AACA,IAAIC,mBAAmBC,QAAQ,mBAAR,CAAvB;AACA,IAAIC,WAAWD,QAAQ,yCAAR,CAAf;AACA,IAAIE,qBAAqBF,QAAQ,oBAAR,CAAzB;AACA,IAAIG,gBAAgBH,QAAQ,2BAAR,CAApB;AACA,IAAII,QAAQD,cAAcE,cAAd,CAA6B,kBAA7B,CAAZ;AACA;AACA,IAAIC,mBAAmB,aAAe,UAAUC,MAAV,EAAkB;AACpDzB,cAAUwB,gBAAV,EAA4BC,MAA5B;AACA,aAASD,gBAAT,CAA0BE,aAA1B,EAAyCC,aAAzC,EAAwD;AACpD,YAAIC,QAAQH,OAAOI,IAAP,CAAY,IAAZ,EAAkBH,aAAlB,EAAiCC,aAAjC,KAAmD,IAA/D;AACAC,cAAME,QAAN,GAAiB,IAAjB;AACAF,cAAMG,YAAN,GAAqBL,cAAcM,WAAnC;AACAJ,cAAMK,OAAN,GAAgBL,MAAMK,OAAN,CAAcC,IAAd,CAAmBN,KAAnB,CAAhB;AACAA,cAAMO,UAAN,GAAmBP,MAAMO,UAAN,CAAiBD,IAAjB,CAAsBN,KAAtB,CAAnB;AACAA,cAAMQ,sBAAN,GAA+BR,MAAMQ,sBAAN,CAA6BF,IAA7B,CAAkCN,KAAlC,CAA/B;AACAA,cAAMS,oBAAN,GAA6BT,MAAMS,oBAAN,CAA2BH,IAA3B,CAAgCN,KAAhC,CAA7B;AACAA,cAAMU,yBAAN,GAAkCV,MAAMU,yBAAN,CAAgCJ,IAAhC,CAAqCN,KAArC,CAAlC;AACAA,cAAMW,oBAAN,GAA6BX,MAAMW,oBAAN,CAA2BL,IAA3B,CAAgCN,KAAhC,CAA7B;AACAA,cAAMY,wBAAN,GAAiCZ,MAAMY,wBAAN,CAA+BN,IAA/B,CAAoCN,KAApC,CAAjC;AACAA,cAAMa,0BAAN,GAAmCb,MAAMa,0BAAN,CAAiCP,IAAjC,CAAsCN,KAAtC,CAAnC;AACAA,cAAMc,oBAAN,GAA6Bd,MAAMc,oBAAN,CAA2BR,IAA3B,CAAgCN,KAAhC,CAA7B;AACAA,cAAMe,sBAAN,GAA+Bf,MAAMe,sBAAN,CAA6BT,IAA7B,CAAkCN,KAAlC,CAA/B;AACA,eAAOA,KAAP;AACH;AACDxB,WAAOU,cAAP,CAAsBU,iBAAiBZ,SAAvC,EAAkD,IAAlD,EAAwD;AACpDgC,aAAK,eAAY;AACb,mBAAO,KAAKd,QAAL,IAAiB,KAAKA,QAAL,CAAce,SAA/B,GAA2C,KAAKf,QAAL,CAAce,SAAzD,GAAqE,EAA5E;AACH,SAHmD;AAIpDC,oBAAY,IAJwC;AAKpDC,sBAAc;AALsC,KAAxD;AAOA3C,WAAOU,cAAP,CAAsBU,iBAAiBZ,SAAvC,EAAkD,WAAlD,EAA+D;AAC3DgC,aAAK,eAAY;AACb,mBAAO,KAAKd,QAAL,IAAiB,KAAKA,QAAL,CAAckB,UAA/B,GAA4C,KAAKlB,QAAL,CAAckB,UAAd,CAAyBC,YAArE,GAAoF,EAA3F;AACH,SAH0D;AAI3DH,oBAAY,IAJ+C;AAK3DC,sBAAc;AAL6C,KAA/D;AAOAvB,qBAAiBZ,SAAjB,CAA2BqB,OAA3B,GAAqC,YAAY;AAC7C,YAAIL,QAAQ,IAAZ;AACAN,cAAM4B,IAAN,CAAW,oBAAX;AACA,YAAI,KAAKpB,QAAT,EAAmB;AACfR,kBAAM6B,KAAN,CAAY,wBAAZ;AACA,mBAAOC,QAAQC,MAAR,CAAe,2DAAf,CAAP;AACH;AACD,eAAO,IAAID,OAAJ,CAAY,UAAUE,OAAV,EAAmBD,MAAnB,EAA2B;AAC1C,gBAAIE,cAAc,SAAdA,WAAc,CAAUJ,KAAV,EAAiB;AAC/BvB,sBAAME,QAAN,IAAkBF,MAAME,QAAN,CAAe0B,GAAf,EAAlB;AACA5B,sBAAME,QAAN,GAAiB,IAAjB;AACAR,sBAAM6B,KAAN,CAAY,sBAAZ,EAAoCA,KAApC;AACAE,uBAAOF,KAAP;AACH,aALD;AAMA,gBAAIM,KAAK7B,MAAM8B,cAAN,CAAqB1B,WAA9B;AAAA,gBAA2C2B,SAASF,GAAGE,MAAvD;AAAA,gBAA+Dd,YAAYY,GAAGZ,SAA9E;AACAjB,kBAAME,QAAN,GAAiB8B,OAAOC,SAAP,GAAmBD,OAAOE,EAAP,CAAUC,WAAV,CAAsBJ,MAAtB,EAA8Bd,SAA9B,CAApC;AACAjB,kBAAME,QAAN,CAAekC,EAAf,CAAkB,mBAAlB,EAAuCpC,MAAMY,wBAA7C;AACAZ,kBAAME,QAAN,CAAekC,EAAf,CAAkB,qBAAlB,EAAyCpC,MAAMa,0BAA/C;AACAb,kBAAME,QAAN,CAAekC,EAAf,CAAkB,eAAlB,EAAmCpC,MAAMc,oBAAzC;AACAd,kBAAME,QAAN,CAAekC,EAAf,CAAkB,iBAAlB,EAAqCpC,MAAMe,sBAA3C;AACA,gBAAIsB,iBAAiB,SAAjBA,cAAiB,CAAUd,KAAV,EAAiB;AAClC,oBAAIA,KAAJ,EAAW;AACPI,gCAAYJ,KAAZ;AACA;AACH;AACDG;AACH,aAND;AAOA1B,kBAAME,QAAN,CAAeG,OAAf,CAAuBL,MAAMG,YAAN,CAAmBmC,KAA1C,EAAiDD,cAAjD;AACH,SArBM,CAAP;AAsBH,KA7BD;AA8BAzC,qBAAiBZ,SAAjB,CAA2BuB,UAA3B,GAAwC,YAAY;AAChD,YAAIP,QAAQ,IAAZ;AACA,eAAO,IAAIwB,OAAJ,CAAY,UAAUE,OAAV,EAAmB;AAClChC,kBAAM4B,IAAN,CAAW,4BAAX;AACA,gBAAIiB,iBAAiBvC,MAAME,QAA3B;AACAF,kBAAME,QAAN,GAAiB,IAAjB;AACAF,kBAAMwC,gBAAN,CAAuBC,OAAvB,CAA+B,UAAUC,cAAV,EAA0B;AACrD1C,sBAAM2C,qBAAN,CAA4BD,cAA5B;AACH,aAFD;AAGA,gBAAI,CAACH,cAAL,EAAqB;AACjB7C,sBAAM4B,IAAN,CAAW,+BAAX;AACAI;AACA;AACH;AACDa,2BAAeX,GAAf;AACAW,2BAAehC,UAAf;AACAmB;AACH,SAfM,CAAP;AAgBH,KAlBD;AAmBA;AACA9B,qBAAiBZ,SAAjB,CAA2B4B,wBAA3B,GAAsD,UAAUgC,KAAV,EAAiB;AACnE,YAAI5C,QAAQ,IAAZ;AACAN,cAAM4B,IAAN,CAAW,0BAAX,EAAuCsB,KAAvC;AACA,YAAIxB,aAAawB,MAAMxB,UAAvB;AACA,YAAI,CAAC,KAAKyB,kBAAL,CAAwB,KAAxB,CAAD,IAAmC,CAACzB,UAAxC,EAAoD;AAChD;AACH;AACD;AACA,YAAIA,WAAWC,YAAX,KAA4B,KAAKyB,SAArC,EAAgD;AAC5C;AACH;AACD,YAAIC,kBAAkB,KAAKC,wBAAL,EAAtB;AACA,aAAKtC,yBAAL,CAA+BqC,eAA/B,EACKE,IADL,CACU,UAAUC,OAAV,EAAmB;AACzB,gBAAIR,iBAAiB;AACjBS,wBAAQ/B,WAAWC,YADF;AAEjB+B,0BAAUL,eAFO;AAGjBM,0BAAUrD,MAAM8B,cAAN,CAAqBwB,UAArB,KAAoCjE,iBAAiBkE,iBAAjB,CAAmCC,SAAvE,GACJnE,iBAAiBkE,iBAAjB,CAAmCE,KAD/B,GACuCpE,iBAAiBkE,iBAAjB,CAAmCC,SAJnE;AAKjBpC,4BAAYA,UALK;AAMjBsC,2BAAW,IANM;AAOjBC,4BAAY,IAPK;AAQjBC,mCAAmB,EARF;AASjBC,6BAAaX;AATI,aAArB;AAWA,gBAAI,CAACA,QAAQY,WAAT,IAAwB,CAACZ,QAAQa,WAArC,EAAkD;AAC9CrE,sBAAM4B,IAAN,CAAW,+CAAX,EAA4DoB,cAA5D;AACA,uBAAOA,cAAP;AACH;AACD,gBAAIsB,aAAajB,oBAAoB1D,iBAAiB4E,iBAAjB,CAAmCC,IAAvD,GACX7E,iBAAiB8E,gBAAjB,CAAkCC,kBADvB,GAC4C/E,iBAAiB8E,gBAAjB,CAAkCE,iBAD/F;AAEA,mBAAOrE,MAAMW,oBAAN,CAA2BuC,OAA3B,EAAoCc,UAApC,EACFf,IADE,CACG,UAAUS,SAAV,EAAqB;AAC3BhB,+BAAegB,SAAf,GAA2BA,SAA3B;AACAhE,sBAAM4B,IAAN,CAAW,4CAAX,EAAyDoB,cAAzD;AACA,uBAAOA,cAAP;AACH,aALM,CAAP;AAMH,SAzBD,EA0BKO,IA1BL,CA0BU,UAAUP,cAAV,EAA0B;AAChC1C,kBAAMwC,gBAAN,CAAuB8B,GAAvB,CAA2B5B,eAAeS,MAA1C,EAAkDT,cAAlD;AACA,gBAAIA,eAAegB,SAAnB,EAA8B;AAC1B,uBAAO,IAAIlC,OAAJ,CAAY,UAAUE,OAAV,EAAmBD,MAAnB,EAA2B;AAC1C/B,0BAAM4B,IAAN,CAAW,8CAAX;AACAtB,0BAAME,QAAN,CAAeqE,OAAf,CAAuB7B,eAAegB,SAAtC,EAAiD,UAAUnC,KAAV,EAAiB;AAC9D,4BAAIA,KAAJ,EAAW;AACP7B,kCAAM6B,KAAN,CAAY,iCAAZ,EAA+CA,KAA/C;AACA,mCAAOE,OAAOF,KAAP,CAAP;AACH;AACD7B,8BAAM4B,IAAN,CAAW,mCAAX;AACA,+BAAOI,SAAP;AACH,qBAPD;AAQH,iBAVM,CAAP;AAWH;AACD,mBAAOF,QAAQE,OAAR,EAAP;AACH,SA1CD,EA2CK8C,KA3CL,CA2CW,UAAUjD,KAAV,EAAiB;AACxB;AACA7B,kBAAM6B,KAAN,CAAY,oCAAZ,EAAkDA,KAAlD;AACH,SA9CD;AA+CH,KA3DD;AA4DA3B,qBAAiBZ,SAAjB,CAA2B6B,0BAA3B,GAAwD,UAAU+B,KAAV,EAAiB;AACrElD,cAAM4B,IAAN,CAAW,4BAAX,EAAyCsB,KAAzC;AACA,YAAIxB,aAAawB,MAAMxB,UAAvB;AACA,YAAI,CAAC,KAAKyB,kBAAL,CAAwB,KAAxB,CAAD,IAAmC,CAACzB,UAAxC,EAAoD;AAChD;AACH;AACD,YAAI,KAAKoB,gBAAL,CAAsBiC,GAAtB,CAA0BrD,WAAWC,YAArC,CAAJ,EAAwD;AACpD,iBAAKsB,qBAAL,CAA2B,KAAKH,gBAAL,CAAsBxB,GAAtB,CAA0BI,WAAWC,YAArC,CAA3B;AACH;AACJ,KATD;AAUAzB,qBAAiBZ,SAAjB,CAA2B8B,oBAA3B,GAAkD,UAAU8B,KAAV,EAAiB;AAC/D,YAAI5C,QAAQ,IAAZ;AACAN,cAAM4B,IAAN,CAAW,sBAAX,EAAmCsB,MAAM8B,MAAzC;AACA,YAAIA,SAAS9B,MAAM8B,MAAnB;AACA,YAAItD,aAAa,CAACsD,UAAU,EAAEtD,YAAY,IAAd,EAAX,EAAiCA,UAAlD;AACA,YAAI,CAAC,KAAKyB,kBAAL,CAAwB,KAAxB,CAAD,IAAmC,CAAC6B,MAAxC,EAAgD;AAC5C;AACH;AACD,YAAI,CAAC,KAAKlC,gBAAL,CAAsBiC,GAAtB,CAA0BrD,WAAWC,YAArC,CAAL,EAAyD;AACrD3B,kBAAMiF,IAAN,CAAW,wDAAX;AACA;AACH;AACD,YAAIjC,iBAAiB,KAAKF,gBAAL,CAAsBxB,GAAtB,CAA0BI,WAAWC,YAArC,CAArB;AACA3B,cAAM4B,IAAN,CAAW,wBAAX;AACA;AACAoB,uBAAeiB,UAAf,GAA4B,KAAKzD,QAAL,CAAc0E,SAAd,CAAwBF,MAAxB,EAAgC,IAAhC,EAAsC,IAAtC,EAA4C,UAAUG,GAAV,EAAe;AACnF,gBAAIA,GAAJ,EAAS;AACLnC,+BAAeiB,UAAf,GAA4B,IAA5B;AACAjE,sBAAMiF,IAAN,CAAW,qBAAX,EAAkCE,GAAlC;AACA;AACH;AACD,gBAAIC,eAAe,MAAMpC,eAAeiB,UAAf,CAA0BoB,EAAhC,GAAqC,oBAAxD;AACA,gBAAIC,YAAYC,SAASC,aAAT,CAAuBJ,YAAvB,CAAhB;AACA,gBAAI,CAACE,SAAL,EAAgB;AACZtF,sBAAMiF,IAAN,CAAW,+BAAX;AACA;AACH;AACDM,qBAASE,cAAT,CAAwBzC,eAAeiB,UAAf,CAA0BoB,EAAlD,EAAsDK,KAAtD,CAA4DC,OAA5D,GAAsE,MAAtE;AACA,gBAAIC,gBAAgBN,UAAUO,SAA9B;AACA,gBAAI,CAACD,aAAL,EAAoB;AAChB5F,sBAAMiF,IAAN,CAAW,2CAAX;AACA;AACH;AACDjF,kBAAM4B,IAAN,CAAW,iCAAX,EAA8CoB,eAAeiB,UAA7D;AACA2B,0BAAcE,SAAd,GAA0B/C,OAA1B,CAAkC,UAAUgD,UAAV,EAAsB;AACpDzF,sBAAM0F,0BAAN,CAAiChD,cAAjC,EAAiD+C,UAAjD;AACH,aAFD;AAGH,SAtB2B,CAA5B;AAuBA/C,uBAAeiB,UAAf,CAA0BvB,EAA1B,CAA6B,qBAA7B,EAAoD,UAAUuD,IAAV,EAAgB;AAChEjG,kBAAM4B,IAAN,CAAW,4BAAX,EAAyCqE,IAAzC;AACH,SAFD;AAGH,KAzCD;AA0CA/F,qBAAiBZ,SAAjB,CAA2B+B,sBAA3B,GAAoD,UAAU6B,KAAV,EAAiB;AACjElD,cAAM4B,IAAN,CAAW,wBAAX,EAAqCsB,KAArC;AACA,YAAI8B,SAAS9B,MAAM8B,MAAnB;AACA,YAAI,CAAC,KAAK7B,kBAAL,CAAwB,KAAxB,CAAD,IAAmC,CAAC6B,MAAxC,EAAgD;AAC5C;AACH;AACD,YAAIhC,iBAAiB,KAAKF,gBAAL,CAAsBxB,GAAtB,CAA0B0D,OAAOtD,UAAP,CAAkBC,YAA5C,CAArB;AACA,YAAI,CAACqB,cAAL,EAAqB;AACjBhD,kBAAMiF,IAAN,CAAW,6CAAX;AACA;AACH;AACD,aAAKiB,gCAAL,CAAsClD,cAAtC;AACA,aAAKmD,iCAAL,CAAuCnD,cAAvC;AACH,KAbD;AAcA;AACA9C,qBAAiBZ,SAAjB,CAA2BwB,sBAA3B,GAAoD,UAAUsF,UAAV,EAAsB;AACtE,YAAI9F,QAAQ,IAAZ;AACA,aAAKwC,gBAAL,CAAsBC,OAAtB,CAA8B,UAAUC,cAAV,EAA0B;AACpD,gBAAIA,eAAeU,QAAf,KAA4B0C,UAAhC,EAA4C;AACxC9F,sBAAM+F,gCAAN,CAAuCrD,cAAvC;AACH;AACJ,SAJD;AAKA,eAAOlB,QAAQE,OAAR,EAAP;AACH,KARD;AASA9B,qBAAiBZ,SAAjB,CAA2ByB,oBAA3B,GAAkD,UAAUqF,UAAV,EAAsBE,WAAtB,EAAmC;AACjF;AACA,eAAOxE,QAAQE,OAAR,EAAP;AACH,KAHD;AAIA9B,qBAAiBZ,SAAjB,CAA2BiH,mBAA3B,GAAiD,UAAUR,UAAV,EAAsB;AACnE,YAAIzF,QAAQ,IAAZ;AACA,eAAO,IAAIwB,OAAJ,CAAY,UAAUE,OAAV,EAAmBD,MAAnB,EAA2B;AAC1C,gBAAIyE,wBAAwBlG,MAAMmG,6BAAN,CAAoCV,UAApC,CAA5B;AACA,gBAAI,CAACS,qBAAD,IAA0B,CAACA,sBAAsBvC,UAArD,EAAiE;AAC7DlC,uBAAO,IAAI2E,KAAJ,CAAU,kDAAV,CAAP;AACH;AACD;AACAF,kCAAsBvC,UAAtB,CAAiC0C,QAAjC,CAA0C,UAAU9E,KAAV,EAAiB+E,KAAjB,EAAwB;AAC9D,oBAAI/E,KAAJ,EAAW;AACP7B,0BAAMiF,IAAN,CAAW,qBAAX,EAAkCpD,KAAlC;AACAG,4BAAQ,EAAE6E,SAASd,WAAWV,EAAtB,EAA0ByB,YAAY,EAAtC,EAAR;AACA;AACH;AACD9E,wBAAQ,EAAE6E,SAASd,WAAWV,EAAtB,EAA0ByB,YAAYF,KAAtC,EAAR;AACH,aAPD;AAQH,SAdM,CAAP;AAeH,KAjBD;AAkBA1G,qBAAiBZ,SAAjB,CAA2B0B,yBAA3B,GAAuD,UAAUqC,eAAV,EAA2B;AAC9E,YAAI/C,QAAQ,IAAZ;AACAN,cAAM4B,IAAN,CAAW,2BAAX;AACA,eAAO,KAAKmF,sBAAL,CAA4BC,qBAA5B,CAAkD3D,eAAlD,EACFE,IADE,CACG,UAAU+C,WAAV,EAAuB;AAC7B,gBAAItB,SAAS,EAAEZ,aAAa,IAAf,EAAqBC,aAAa,IAAlC,EAAb;AACA,gBAAIiC,WAAJ,EAAiB;AACbtG,sBAAM4B,IAAN,CAAW,mCAAX,EAAgD0E,WAAhD;AACAA,4BAAYR,SAAZ,GAAwB/C,OAAxB,CAAgC,UAAUkE,KAAV,EAAiB;AAC7C,wBAAIA,MAAMC,IAAN,KAAe,OAAnB,EAA4B;AACxBlC,+BAAOZ,WAAP,GAAqB6C,KAArB;AACH,qBAFD,MAGK,IAAIA,MAAMC,IAAN,KAAe,OAAnB,EAA4B;AAC7BlC,+BAAOX,WAAP,GAAqB4C,KAArB;AACH;AACJ,iBAPD;AAQH,aAVD,MAWK,IAAI3G,MAAM8B,cAAN,CAAqBgE,UAArB,KAAoCzG,iBAAiB4E,iBAAjB,CAAmCC,IAA3E,EAAiF;AAClFxE,sBAAMiF,IAAN,CAAW,6DAAX,EAA0E5B,eAA1E;AACH;AACD,mBAAO2B,MAAP;AACH,SAlBM,CAAP;AAmBH,KAtBD;AAuBA9E,qBAAiBZ,SAAjB,CAA2BgE,wBAA3B,GAAsD,YAAY;AAC9D,YAAI,KAAKlB,cAAL,CAAoBgE,UAApB,KAAmCzG,iBAAiB4E,iBAAjB,CAAmCC,IAA1E,EAAgF;AAC5E,gBAAI2C,mBAAmB,KAAvB;AACA,mBAAO,CAACA,gBAAD,GAAoBxH,iBAAiB4E,iBAAjB,CAAmC6C,KAAvD,GAA+DzH,iBAAiB4E,iBAAjB,CAAmC8C,QAAzG;AACH;AACD,eAAO1H,iBAAiB4E,iBAAjB,CAAmCC,IAA1C;AACH,KAND;AAOAtE,qBAAiBZ,SAAjB,CAA2B2B,oBAA3B,GAAkD,UAAU+D,MAAV,EAAkBV,UAAlB,EAA8B;AAC5E,YAAIgD,WAAW;AACXlD,yBAAaY,OAAOZ,WAAP,GAAqBY,OAAOZ,WAA5B,GAA0C,KAD5C;AAEXC,yBAAaW,OAAOX,WAAP,GAAqBW,OAAOX,WAA5B,GAA0C,KAF5C;AAGXkD,0BAAc,CAAC,CAACvC,OAAOX,WAHZ;AAIXmD,0BAAc,CAAC,CAACxC,OAAOZ,WAJZ;AAKXqD,0BAAc,KALH;AAMXC,kBAAMpD;AANK,SAAf;AAQA,eAAO,IAAIxC,OAAJ,CAAY,UAAUE,OAAV,EAAmBD,MAAnB,EAA2B;AAC1C,gBAAI4F,cAAcrF,OAAOE,EAAP,CAAUoF,aAAV,CAAwBC,SAAxB,EAAmCP,QAAnC,EAA6C,UAAUzF,KAAV,EAAiB;AAC5E,oBAAIA,KAAJ,EAAW;AACPE,2BAAOF,KAAP;AACA;AACH;AACDG,wBAAQ2F,WAAR;AACH,aANiB,CAAlB;AAOH,SARM,CAAP;AASH,KAlBD;AAmBAzH,qBAAiBZ,SAAjB,CAA2B2D,qBAA3B,GAAmD,UAAUD,cAAV,EAA0B;AACzE,aAAKF,gBAAL,CAAsBgF,MAAtB,CAA6B9E,eAAeS,MAA5C;AACA,aAAK4C,gCAAL,CAAsCrD,cAAtC;AACA,aAAKkD,gCAAL,CAAsClD,cAAtC;AACA,aAAKmD,iCAAL,CAAuCnD,cAAvC;AACH,KALD;AAMA9C,qBAAiBZ,SAAjB,CAA2B+G,gCAA3B,GAA8D,UAAUrD,cAAV,EAA0B;AACpF,YAAIA,eAAegB,SAAnB,EAA8B;AAC1B;AACA;AACA;AACA;AACA;AACAhB,2BAAegB,SAAf,GAA2B,IAA3B;AACAhB,2BAAemB,WAAf,GAA6B,IAA7B;AACH;AACJ,KAVD;AAWAjE,qBAAiBZ,SAAjB,CAA2B6G,iCAA3B,GAA+D,UAAUnD,cAAV,EAA0B;AACrF,YAAI,CAAC,KAAKG,kBAAL,CAAwB,KAAxB,CAAD,IAAmCH,eAAeiB,UAAtD,EAAkE;AAC9D;AACH;AACD,aAAKzD,QAAL,CAAcuH,WAAd,CAA0B/E,eAAeiB,UAAzC;AACAjB,uBAAeiB,UAAf,GAA4B,IAA5B;AACH,KAND;AAOA/D,qBAAiBZ,SAAjB,CAA2B6D,kBAA3B,GAAgD,UAAU6E,WAAV,EAAuB;AACnE,YAAIA,gBAAgB,KAAK,CAAzB,EAA4B;AAAEA,0BAAc,IAAd;AAAqB;AACnD,YAAIC,YAAY,CAAC,EAAE,KAAKzH,QAAL,IAAiB,KAAKA,QAAL,CAAckB,UAA/B,IAA6C,KAAKlB,QAAL,CAAckB,UAAd,CAAyBC,YAAxE,CAAjB;AACA,eAAO9B,SAASqI,cAAT,CAAwBD,SAAxB,EAAmC,yBAAnC,EAA8DD,WAA9D,CAAP;AACH,KAJD;AAKA,WAAO9H,gBAAP;AACH,CA/TqC,CA+TpCJ,mBAAmBqI,gBA/TiB,CAAtC;AAgUA1I,QAAQS,gBAAR,GAA2BA,gBAA3B;;AAEA","file":"SessionOpentok.v3.js","sourcesContent":["\"use strict\";\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar MediaConstants_1 = require(\"../MediaConstants\");\nvar guards_1 = require(\"@techsee/techsee-common/lib/core/guards\");\nvar MediaSessionBase_1 = require(\"./MediaSessionBase\");\nvar MediaTracer_1 = require(\"../MediaUtils/MediaTracer\");\nvar trace = MediaTracer_1.getMediaTracer('OpentokSessionV3');\n//Currently this version supports subscribing only. Publishing will be implemented as needed.\nvar OpentokSessionV3 = /** @class */ (function (_super) {\n __extends(OpentokSessionV3, _super);\n function OpentokSessionV3(sessionParams, streamFactory) {\n var _this = _super.call(this, sessionParams, streamFactory) || this;\n _this._session = null;\n _this._credentials = sessionParams.credentials;\n _this.connect = _this.connect.bind(_this);\n _this.disconnect = _this.disconnect.bind(_this);\n _this.onMediaStreamDestroyed = _this.onMediaStreamDestroyed.bind(_this);\n _this.onMediaStreamRenewed = _this.onMediaStreamRenewed.bind(_this);\n _this.createStreamForPublishing = _this.createStreamForPublishing.bind(_this);\n _this.createMediaPublisher = _this.createMediaPublisher.bind(_this);\n _this.connectionCreatedHandler = _this.connectionCreatedHandler.bind(_this);\n _this.connectionDestroyedHandler = _this.connectionDestroyedHandler.bind(_this);\n _this.streamCreatedHandler = _this.streamCreatedHandler.bind(_this);\n _this.streamDestroyedHandler = _this.streamDestroyedHandler.bind(_this);\n return _this;\n }\n Object.defineProperty(OpentokSessionV3.prototype, \"id\", {\n get: function () {\n return this._session && this._session.sessionId ? this._session.sessionId : '';\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(OpentokSessionV3.prototype, \"ownPeerId\", {\n get: function () {\n return this._session && this._session.connection ? this._session.connection.connectionId : '';\n },\n enumerable: true,\n configurable: true\n });\n OpentokSessionV3.prototype.connect = function () {\n var _this = this;\n trace.info('Connect to session');\n if (this._session) {\n trace.error('Session already exists');\n return Promise.reject('Cannot connect to session while another session is active');\n }\n return new Promise(function (resolve, reject) {\n var handleError = function (error) {\n _this._session && _this._session.off();\n _this._session = null;\n trace.error('handleConnect error:', error);\n reject(error);\n };\n var _a = _this._sessionParams.credentials, apiKey = _a.apiKey, sessionId = _a.sessionId;\n _this._session = window.OTSESSION = window.OT.initSession(apiKey, sessionId);\n _this._session.on('connectionCreated', _this.connectionCreatedHandler);\n _this._session.on('connectionDestroyed', _this.connectionDestroyedHandler);\n _this._session.on('streamCreated', _this.streamCreatedHandler);\n _this._session.on('streamDestroyed', _this.streamDestroyedHandler);\n var connectHandler = function (error) {\n if (error) {\n handleError(error);\n return;\n }\n resolve();\n };\n _this._session.connect(_this._credentials.token, connectHandler);\n });\n };\n OpentokSessionV3.prototype.disconnect = function () {\n var _this = this;\n return new Promise(function (resolve) {\n trace.info('Disconnecting from session');\n var currentSession = _this._session;\n _this._session = null;\n _this._peerConnections.forEach(function (peerConnection) {\n _this.destroyPeerConnection(peerConnection);\n });\n if (!currentSession) {\n trace.info('No active session - resolving');\n resolve();\n return;\n }\n currentSession.off();\n currentSession.disconnect();\n resolve();\n });\n };\n //#region OpenTok Events Handlers\n OpentokSessionV3.prototype.connectionCreatedHandler = function (event) {\n var _this = this;\n trace.info('connectionCreatedHandler', event);\n var connection = event.connection;\n if (!this.sessionExistsGuard(false) || !connection) {\n return;\n }\n //In case we got our own connection, we have nothing to do with it\n if (connection.connectionId === this.ownPeerId) {\n return;\n }\n var destinationRole = this.calculateDestinationRole();\n this.createStreamForPublishing(destinationRole)\n .then(function (streams) {\n var peerConnection = {\n peerId: connection.connectionId,\n peerRole: destinationRole,\n peerType: _this._sessionParams.clientType === MediaConstants_1.SessionClientType.INITIATOR\n ? MediaConstants_1.SessionClientType.GUEST : MediaConstants_1.SessionClientType.INITIATOR,\n connection: connection,\n publisher: null,\n subscriber: null,\n remoteMediaTracks: [],\n localStream: streams\n };\n if (!streams.videoSource && !streams.audioSource) {\n trace.info('Peer connection without publisher was created', peerConnection);\n return peerConnection;\n }\n var streamName = destinationRole === MediaConstants_1.SessionClientRole.USER\n ? MediaConstants_1.KnownMediaStream.AGENT_AUDIO_STREAM : MediaConstants_1.KnownMediaStream.USER_VIDEO_STREAM;\n return _this.createMediaPublisher(streams, streamName)\n .then(function (publisher) {\n peerConnection.publisher = publisher;\n trace.info('Peer connection with publisher was created', peerConnection);\n return peerConnection;\n });\n })\n .then(function (peerConnection) {\n _this._peerConnections.set(peerConnection.peerId, peerConnection);\n if (peerConnection.publisher) {\n return new Promise(function (resolve, reject) {\n trace.info('Starting publish to peerConnection.publisher');\n _this._session.publish(peerConnection.publisher, function (error) {\n if (error) {\n trace.error('Publish to peerConnection error', error);\n return reject(error);\n }\n trace.info('Publish to peerConnection success');\n return resolve();\n });\n });\n }\n return Promise.resolve();\n })\n .catch(function (error) {\n //Need to handle fail cases during reliability\n trace.error('Error handling new peer connection', error);\n });\n };\n OpentokSessionV3.prototype.connectionDestroyedHandler = function (event) {\n trace.info('connectionDestroyedHandler', event);\n var connection = event.connection;\n if (!this.sessionExistsGuard(false) || !connection) {\n return;\n }\n if (this._peerConnections.has(connection.connectionId)) {\n this.destroyPeerConnection(this._peerConnections.get(connection.connectionId));\n }\n };\n OpentokSessionV3.prototype.streamCreatedHandler = function (event) {\n var _this = this;\n trace.info('streamCreatedHandler', event.stream);\n var stream = event.stream;\n var connection = (stream || { connection: null }).connection;\n if (!this.sessionExistsGuard(false) || !stream) {\n return;\n }\n if (!this._peerConnections.has(connection.connectionId)) {\n trace.warn('Unexpected case, connection should exist on this stage');\n return;\n }\n var peerConnection = this._peerConnections.get(connection.connectionId);\n trace.info('Subscribing the stream');\n //TODO - Optimize the code below\n peerConnection.subscriber = this._session.subscribe(stream, null, null, function (err) {\n if (err) {\n peerConnection.subscriber = null;\n trace.warn('Error in subscriber', err);\n return;\n }\n var videoElQuery = \"#\" + peerConnection.subscriber.id + \" .OT_video-element\";\n var otVideoEl = document.querySelector(videoElQuery);\n if (!otVideoEl) {\n trace.warn('Cannot fined OT video element');\n return;\n }\n document.getElementById(peerConnection.subscriber.id).style.display = 'none';\n var otMediaStream = otVideoEl.srcObject;\n if (!otMediaStream) {\n trace.warn('MediaStream not found in OT video element');\n return;\n }\n trace.info('Registering remote media tracks', peerConnection.subscriber);\n otMediaStream.getTracks().forEach(function (mediaTrack) {\n _this.registerMediaTrackFromPeer(peerConnection, mediaTrack);\n });\n });\n peerConnection.subscriber.on('videoElementCreated', function (args) {\n trace.info('videoElementCreated - REDO', args);\n });\n };\n OpentokSessionV3.prototype.streamDestroyedHandler = function (event) {\n trace.info('streamDestroyedHandler', event);\n var stream = event.stream;\n if (!this.sessionExistsGuard(false) || !stream) {\n return;\n }\n var peerConnection = this._peerConnections.get(stream.connection.connectionId);\n if (!peerConnection) {\n trace.warn('Peer connection for remote stream not found');\n return;\n }\n this.unregisterPeersRemoteMediaTracks(peerConnection);\n this.destroySubscriberOnPeerConnection(peerConnection);\n };\n //#endregion\n OpentokSessionV3.prototype.onMediaStreamDestroyed = function (clientRole) {\n var _this = this;\n this._peerConnections.forEach(function (peerConnection) {\n if (peerConnection.peerRole === clientRole) {\n _this.destroyPublisherOnPeerConnection(peerConnection);\n }\n });\n return Promise.resolve();\n };\n OpentokSessionV3.prototype.onMediaStreamRenewed = function (clientRole, mediaStream) {\n //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation (in OT API)\n return Promise.resolve();\n };\n OpentokSessionV3.prototype.getRemoteTrackStats = function (mediaTrack) {\n var _this = this;\n return new Promise(function (resolve, reject) {\n var peerConnectionOfTrack = _this.getPeerConnectionByMediaTrack(mediaTrack);\n if (!peerConnectionOfTrack || !peerConnectionOfTrack.subscriber) {\n reject(new Error('Cannot find peer or subscriber for getting stats'));\n }\n //https://tokbox.com/developer/sdks/js/reference/Subscriber.html#getStats\n peerConnectionOfTrack.subscriber.getStats(function (error, stats) {\n if (error) {\n trace.warn('Error getting stats', error);\n resolve({ trackId: mediaTrack.id, trackStats: {} });\n return;\n }\n resolve({ trackId: mediaTrack.id, trackStats: stats });\n });\n });\n };\n OpentokSessionV3.prototype.createStreamForPublishing = function (destinationRole) {\n var _this = this;\n trace.info('createStreamForPublishing');\n return this._sessionStreamsManager.getMediaStreamForRole(destinationRole)\n .then(function (mediaStream) {\n var stream = { videoSource: null, audioSource: null };\n if (mediaStream) {\n trace.info('Media stream found for publishing', mediaStream);\n mediaStream.getTracks().forEach(function (track) {\n if (track.kind === 'video') {\n stream.videoSource = track;\n }\n else if (track.kind === 'audio') {\n stream.audioSource = track;\n }\n });\n }\n else if (_this._sessionParams.clientRole === MediaConstants_1.SessionClientRole.USER) {\n trace.warn('No local media was found for publishing to destinationRole:', destinationRole);\n }\n return stream;\n });\n };\n OpentokSessionV3.prototype.calculateDestinationRole = function () {\n if (this._sessionParams.clientRole === MediaConstants_1.SessionClientRole.USER) {\n var isAgentConnected = false;\n return !isAgentConnected ? MediaConstants_1.SessionClientRole.AGENT : MediaConstants_1.SessionClientRole.OBSERVER;\n }\n return MediaConstants_1.SessionClientRole.USER;\n };\n OpentokSessionV3.prototype.createMediaPublisher = function (stream, streamName) {\n var otParams = {\n videoSource: stream.videoSource ? stream.videoSource : false,\n audioSource: stream.audioSource ? stream.audioSource : false,\n publishAudio: !!stream.audioSource,\n publishVideo: !!stream.videoSource,\n showControls: false,\n name: streamName\n };\n return new Promise(function (resolve, reject) {\n var otPublisher = window.OT.initPublisher(undefined, otParams, function (error) {\n if (error) {\n reject(error);\n return;\n }\n resolve(otPublisher);\n });\n });\n };\n OpentokSessionV3.prototype.destroyPeerConnection = function (peerConnection) {\n this._peerConnections.delete(peerConnection.peerId);\n this.destroyPublisherOnPeerConnection(peerConnection);\n this.unregisterPeersRemoteMediaTracks(peerConnection);\n this.destroySubscriberOnPeerConnection(peerConnection);\n };\n OpentokSessionV3.prototype.destroyPublisherOnPeerConnection = function (peerConnection) {\n if (peerConnection.publisher) {\n //TODO - Alex: When destroying the publisher, OT closes the stream by himself, without we ask him.\n //So we not destroying the OT publisher right now in order to preserve our stream alive.\n //Later, we can recreate our stream as new, or manually delete \"video\" element that created by OT.\n // or we just can leave it as is :)\n //peerConnection.publisher.destroy();\n peerConnection.publisher = null;\n peerConnection.localStream = null;\n }\n };\n OpentokSessionV3.prototype.destroySubscriberOnPeerConnection = function (peerConnection) {\n if (!this.sessionExistsGuard(false) || peerConnection.subscriber) {\n return;\n }\n this._session.unsubscribe(peerConnection.subscriber);\n peerConnection.subscriber = null;\n };\n OpentokSessionV3.prototype.sessionExistsGuard = function (shouldThrow) {\n if (shouldThrow === void 0) { shouldThrow = true; }\n var connected = !!(this._session && this._session.connection && this._session.connection.connectionId);\n return guards_1.throwableGuard(connected, 'There no active session', shouldThrow);\n };\n return OpentokSessionV3;\n}(MediaSessionBase_1.MediaSessionBase));\nexports.OpentokSessionV3 = OpentokSessionV3;\n\n//# sourceMappingURL=SessionOpentok.v3.js.map\n"]}
|
|
@@ -1,19 +1,9 @@
|
|
|
1
|
-
import { IMediaSession, ISessionStreamsManager, MediaSessionHandlers, MediaSessionParams,
|
|
2
|
-
import { SessionClientRole
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
peerId: any;
|
|
6
|
-
peerType: SessionClientType;
|
|
7
|
-
peerRole: SessionClientRole;
|
|
8
|
-
remoteMediaTracks: RemoteMediaTrack[];
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
export declare class TurnWebRtcSessionV3 implements IMediaSession {
|
|
12
|
-
private readonly _sessionStreamsManager;
|
|
13
|
-
private readonly _sessionParams;
|
|
1
|
+
import { IMediaSession, ISessionStreamsManager, MediaSessionHandlers, MediaSessionParams, RemoteTrackStats } from '../MediaContracts';
|
|
2
|
+
import { SessionClientRole } from '../MediaConstants';
|
|
3
|
+
import { MediaSessionBase } from './MediaSessionBase';
|
|
4
|
+
export declare class TurnWebRtcSessionV3 extends MediaSessionBase<RTCPeerConnection> implements IMediaSession {
|
|
14
5
|
private readonly _sessionHandlers;
|
|
15
6
|
private readonly _pendingPeersIce;
|
|
16
|
-
private readonly _peerConnections;
|
|
17
7
|
private readonly _configuration;
|
|
18
8
|
private _socket;
|
|
19
9
|
readonly id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/MediaSession/SessionTurn.v3.ts"],"names":[],"mappings":"AAIA,OAAO,EACH,aAAa,EACb,sBAAsB,EACtB,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAAE,gBAAgB,EACrC,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAGH,iBAAiB,EACjB,iBAAiB,EACpB,MAAM,mBAAmB,CAAC;AAc3B,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,iBAAiB;QACvB,MAAM,EAAE,GAAG,CAAC;QACZ,QAAQ,EAAE,iBAAiB,CAAC;QAC5B,QAAQ,EAAE,iBAAiB,CAAC;QAC5B,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;KACzC;CACJ;AAGD,qBAAa,mBAAoB,YAAW,aAAa;IACrD,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAyB;IAChE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAuB;IACxD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAM;IACvC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAM;IACvC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAM;IACrC,OAAO,CAAC,OAAO,CAAM;aAEjB,EAAE,EAAI,MAAM;gBAIJ,aAAa,EAAE,kBAAkB,EAAE,eAAe,EAAE,oBAAoB,EAAE,aAAa,EAAE,sBAAsB;IA8B3H,OAAO,CAAC,WAAW,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB3C,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAkChE,4BAA4B,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAgBlD,iBAAiB,CAAC,kBAAkB,EAAE,GAAG,GAAG,IAAI;IAmEhD,oBAAoB,CAAC,gBAAgB,EAAE,GAAG,GAAG,IAAI;IAwBjD,wBAAwB,CAAC,qBAAqB,EAAE,GAAG,GAAG,IAAI;IAe1D,gBAAgB,CAAC,aAAa,EAAE,GAAG,GAAG,IAAI;IA2E1C,yBAAyB,IAAI,IAAI;IAcjC,sBAAsB,CAAC,UAAU,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IASpE,oBAAoB,CAAC,UAAU,EAAE,iBAAiB,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAK5F,mBAAmB,CAAC,UAAU,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAoB5E,OAAO,CAAC,mBAAmB;IAkB3B,OAAO,CAAC,qBAAqB;IA8C7B,OAAO,CAAC,sBAAsB;IAmB9B,OAAO,CAAC,mBAAmB;IAY3B,4BAA4B,CAAC,gBAAgB,EAAE,GAAG,GAAG,IAAI;IAuBzD,sBAAsB,CAAC,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAWvG,2BAA2B,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAejD,kBAAkB,CAAC,YAAY,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAQvE,qBAAqB,CAAC,cAAc,EAAE,iBAAiB,GAAG,IAAI;CAKjE","file":"SessionTurn.v3.d.ts","sourcesContent":["import * as io from 'socket.io-client';\nimport once from 'lodash/once';\nimport {Nullable} from '@techsee/techsee-common';\n\nimport {\n IMediaSession,\n ISessionStreamsManager,\n MediaSessionHandlers,\n MediaSessionParams,\n RemoteMediaTrack, RemoteTrackStats\n} from '../MediaContracts';\n\nimport {\n KnownMediaStream,\n MediaSessionDisconnectReason,\n SessionClientRole,\n SessionClientType\n} from '../MediaConstants';\n\nimport {\n SOCKET_EVENTS, SOCKET_PATH,\n SOCKET_RECONNECTION_ATTEMPTS,\n SOCKET_RECONNECTION_DELAY,\n SOCKET_RECONNECTION_DELAY_MAX\n} from './TurnConstants';\n\nimport {getMediaTracer} from '../MediaUtils/MediaTracer';\n\nconst trace = getMediaTracer('TurnSessionV3');\n\n\ndeclare global {\n interface RTCPeerConnection {\n peerId: any;\n peerType: SessionClientType;\n peerRole: SessionClientRole;\n remoteMediaTracks: RemoteMediaTrack[];\n }\n}\n\n//Currently this version supports subscribing only. Publishing will be implemented as needed.\nexport class TurnWebRtcSessionV3 implements IMediaSession {\n private readonly _sessionStreamsManager: ISessionStreamsManager;\n private readonly _sessionParams: MediaSessionParams;\n private readonly _sessionHandlers: MediaSessionHandlers;\n private readonly _pendingPeersIce: any;\n private readonly _peerConnections: any;\n private readonly _configuration: any;\n private _socket: any;\n\n get id(): string {\n return this._sessionParams.sessionId;\n }\n\n constructor(sessionParams: MediaSessionParams, sessionHandlers: MediaSessionHandlers, streamFactory: ISessionStreamsManager) {\n this._sessionParams = sessionParams;\n this._sessionStreamsManager = streamFactory;\n this._sessionHandlers = sessionHandlers;\n this._socket = null;\n this._pendingPeersIce = {};\n this._peerConnections = new Map();\n\n const iceServers = sessionParams.credentials.ice.map((item: any) => ({\n urls: item.url,\n username: item.login,\n credential: item.password\n }));\n\n this._configuration = {\n iceServers,\n iceTransportPolicy: 'relay'\n };\n\n this._joinResponseHandler = this._joinResponseHandler.bind(this);\n this._iceCandidateReceivedHandler = this._iceCandidateReceivedHandler.bind(this);\n this._sendOfferHandler = this._sendOfferHandler.bind(this);\n this._sdpOfferHandler = this._sdpOfferHandler.bind(this);\n this._userPeerReconnectHandler = this._userPeerReconnectHandler.bind(this);\n this._peerDisconnectedHandler = this._peerDisconnectedHandler.bind(this);\n this._onSocketDisconnectedHandler = this._onSocketDisconnectedHandler.bind(this);\n }\n\n //#region Socket Connectivity\n\n connect(connectOnly = false): Promise<void> {\n trace.info('Connect to session');\n\n return this._connectSocket(this._sessionParams.credentials.url, connectOnly)\n .then(() => {\n trace.info('Joining SessionId: ' + this._sessionParams.sessionId);\n\n this._socket.emit(SOCKET_EVENTS.OUTGOING.JOIN_ROOM, {\n clientType: this._sessionParams.clientType,\n sessionId: this._sessionParams.sessionId\n });\n })\n .catch((error) => {\n throw error;\n });\n }\n\n disconnect(): Promise<void> {\n return this._disconnectInternal(MediaSessionDisconnectReason.ForcedByConsumer);\n }\n\n _connectSocket(url: string, connectOnly: boolean): Promise<void> {\n return new Promise((resolve, reject) => {\n const socket = this._socket = io.connect(url, {\n 'forceNew': true,\n 'reconnectionDelay': SOCKET_RECONNECTION_DELAY,\n 'reconnectionDelayMax': SOCKET_RECONNECTION_DELAY_MAX,\n 'reconnectionAttempts': SOCKET_RECONNECTION_ATTEMPTS,\n 'path': SOCKET_PATH\n });\n\n const done = once((err?: any) => {\n err ? reject(err) : resolve();\n });\n\n socket.once('connect', () => done());\n socket.on(SOCKET_EVENTS.INCOMING.ERROR, done);\n socket.on('connect_error', done);\n socket.on('connect_timeout', done);\n socket.on('disconnect', this._onSocketDisconnectedHandler);\n\n if (!connectOnly) {\n trace.info('Subscribing socket events');\n\n //PUBLISHING NOT SUPPORTED YET\n socket.on(SOCKET_EVENTS.INCOMING.SEND_OFFER, this._sendOfferHandler);\n socket.on(SOCKET_EVENTS.INCOMING.JOIN_RESPONSE, this._joinResponseHandler);\n socket.on(SOCKET_EVENTS.INCOMING.PEER_DISCONNECTED, this._peerDisconnectedHandler);\n socket.on(SOCKET_EVENTS.INCOMING.SDP_OFFER, this._sdpOfferHandler);\n socket.on(SOCKET_EVENTS.INCOMING.PUBLISHER_RECONNECT, this._userPeerReconnectHandler);\n socket.on(SOCKET_EVENTS.INCOMING.ICE_CANDIDATE, this._iceCandidateReceivedHandler);\n }\n });\n }\n\n _onSocketDisconnectedHandler(reason: string): void {\n if (this._socket) {\n // The initial example of differentiating between \"forced\" disconnect and \"network\" disconnect is taken from:\n // https://socket.io/docs/client-api/#Event-%E2%80%98disconnect%E2%80%99\n if (reason !== 'io server disconnect' && reason !== 'io client disconnect') {\n // the disconnection was initiated by the server or by client, you need to call (connect) manually\n this._disconnectInternal(MediaSessionDisconnectReason.SignalingChannelDisconnect).catch(() => undefined);\n }\n }\n }\n\n //#endregion\n\n //#region WebRTC Initiator - session Initiator (User on mobile device)\n\n // Received by Initiator, causing him to emit SDP_OFFER\n _sendOfferHandler(sendOfferEventData: any): void {\n const {uid, peerId} = sendOfferEventData;\n\n trace.info('_sendOfferHandler');\n\n //Currently we not support of passing role through signaling, so we assume every connection is \"AGENT\" like\n const peerConnection = this._createPeerConnection(peerId, SessionClientType.GUEST, SessionClientRole.AGENT);\n const offerParams = {offerToReceiveAudio: true, offerToReceiveVideo: true};\n\n peerConnection.ontrack = (trackEvent: any) => {\n const track: MediaStreamTrack = trackEvent.track;\n\n trace.info(`MediaStreamTrack arrived from peerConnection: ${track.kind}`, track);\n\n //We only support to stream audio from dashboard\n if (track.kind.toLowerCase() === 'audio') {\n const remoteMediaTrack: RemoteMediaTrack = {\n mediaTrack: track,\n trackType: KnownMediaStream.AGENT_AUDIO_STREAM\n };\n\n peerConnection.remoteMediaTracks.push(remoteMediaTrack);\n this._sessionStreamsManager.addRemoteMediaTrack(remoteMediaTrack)\n .catch((error: any) => {\n trace.warn('Error adding remote media track to available streams', error);\n });\n }\n };\n\n //TODO - Alex: Currently we not sending \"role\" through signaling, and by default we assume that the one who asks fot offer, is agent.\n //On later stages we can send or the client \"role\" or the list of \"streams\" that peer is interested in.\n this._sessionStreamsManager.getMediaStreamForRole(SessionClientRole.AGENT)\n .then((mediaStream: Nullable<MediaStream>) => {\n trace.info('_sendOfferHandler stream and peer created');\n\n if (mediaStream) {\n trace.info('Adding local tracks to peer connection');\n mediaStream.getTracks().forEach((track) => {\n peerConnection.addTrack(track, mediaStream);\n trace.info(`Local ${track.kind} track added to peer connection`);\n });\n } else {\n trace.info('No media stream was found for publishing');\n }\n })\n .then(() => peerConnection.createOffer(offerParams))\n .then((offerDesc) => {\n trace.info('Initiator has created sdp offer', {offerDesc});\n\n this._socket.emit(SOCKET_EVENTS.OUTGOING.SDP_OFFER, {\n uid,\n peerId,\n sessionId: this._sessionParams.sessionId,\n sdpOffer: offerDesc.sdp\n });\n\n return peerConnection.setLocalDescription(offerDesc)\n .then(() => {\n trace.info('Local description was set on peerConnection', peerConnection);\n });\n })\n .catch((e) => {\n trace.warn('Error', e);\n });\n }\n\n // Received by the Initiator: Indicates that publish should be started\n _joinResponseHandler(joinResponseData: any): void {\n const {sdpAnswer, uid, peerId} = joinResponseData;\n\n trace.info('joinResponse Received', {sdpAnswer});\n\n this._withPeerConnection(peerId, (peerConnection: RTCPeerConnection) => {\n const answer = new RTCSessionDescription({\n type: 'answer',\n sdp: sdpAnswer\n });\n\n peerConnection.setRemoteDescription(answer)\n .then(() => {\n trace.info('Remote description was set', answer);\n\n this._processQueuedIceCandidates(peerId);\n })\n .catch((e) => {\n trace.warn('Error', e);\n });\n });\n }\n\n // Received by Initiator after a guests socket has been disconnected\n _peerDisconnectedHandler(peerDisconnectedEvent: any): void {\n const {peerId} = peerDisconnectedEvent;\n\n trace.info('_peerDisconnectedHandler');\n\n this._withPeerConnection(peerId, (peerConnection: any) => {\n this._disconnectInternal(MediaSessionDisconnectReason.PeerDisconnected).catch(() => undefined);\n });\n }\n\n //#endregion WebRTC Initiator - session Initiator (User on mobile device)\n\n //#region WebRTC Guest - session Guest (Agent on dashboard platform)\n\n // Received by Guest, causing him to emit SDP_ANSWER\n _sdpOfferHandler(sdpOfferEvent: any): void {\n const {sdpOffer, peerId, uid} = sdpOfferEvent;\n\n trace.info('sdpOffer Received', {sdpOffer});\n\n const peerConnection = this._createPeerConnection(peerId, SessionClientType.INITIATOR, SessionClientRole.USER);\n\n peerConnection.ontrack = (trackEvent: any) => {\n const {track} = trackEvent;\n\n trace.info(`MediaStreamTrack arrived from peerConnection: ${track.kind}`, track);\n\n const remoteTrack: RemoteMediaTrack = {\n mediaTrack: track,\n trackType: track.kind === 'video'\n //Although we can have desktop share stream, we still name it USER_VIDEO_STREAM in dashboard.\n //Because currently we support only one video stream to be streamed at the time, it's not an issue.\n //But when we will need to stream more than one stream of a kind from single peer, this will be need to change.\n ? KnownMediaStream.USER_VIDEO_STREAM : KnownMediaStream.USER_AUDIO_STREAM\n };\n\n peerConnection.remoteMediaTracks.push(remoteTrack);\n this._sessionStreamsManager.addRemoteMediaTrack(remoteTrack)\n .catch(() => {\n trace.warn('Error adding remote track to stream manager', remoteTrack);\n });\n };\n\n this._sessionStreamsManager.getMediaStreamForRole(SessionClientRole.USER)\n .then((mediaStream: Nullable<MediaStream>) => {\n if (mediaStream) {\n trace.info('Adding local tracks to peer connection');\n mediaStream.getTracks().forEach((track) => {\n peerConnection.addTrack(track, mediaStream);\n trace.info(`Local ${track.kind} track added to peer connection`);\n });\n } else {\n trace.info('No media stream was found for publishing');\n }\n })\n .then(() => {\n const remoteDesc = new RTCSessionDescription({type: 'offer', sdp: sdpOffer});\n\n return peerConnection.setRemoteDescription(remoteDesc)\n .then(() => {\n trace.info('Remote description was set', remoteDesc);\n\n return peerConnection.createAnswer()\n .then((sdpAnswer) => {\n trace.info('_sdpOfferHandler answer created', sdpAnswer);\n\n this._socket.emit(SOCKET_EVENTS.OUTGOING.SDP_ANSWER, {\n uid,\n peerId,\n sessionId: this._sessionParams.sessionId,\n sdpAnswer: sdpAnswer.sdp\n });\n\n return peerConnection.setLocalDescription(sdpAnswer)\n .then(() => {\n trace.info('_sdpOfferHandler local desc was set');\n\n this._processQueuedIceCandidates(peerId);\n });\n });\n });\n\n })\n .catch((e) => {\n trace.error('Error in _sdpOfferHandler', e);\n throw e;\n });\n }\n\n // Received by Guest after an Initiator reconnects to room\n _userPeerReconnectHandler(): void {\n trace.info('_userPeerReconnectHandler');\n this._disconnectInternal(MediaSessionDisconnectReason.UserPeerReconnected)\n .catch((error: any) => {\n trace.warn('Error while disconnecting during userPeerReconnectHandler.', error);\n });\n }\n\n //#endregion WebRTC Guest - session Guest (Agent on dashboard platform)\n\n //#region Peer Connection\n\n //#region Streams Handling\n\n onMediaStreamDestroyed(clientRole: SessionClientRole): Promise<void> {\n //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation\n this._peerConnections.forEach((peerConnection: RTCPeerConnection) => {\n this._disconnectInternal(MediaSessionDisconnectReason.PublishedStreamDestroyed).catch(() => undefined);\n });\n\n return Promise.resolve();\n }\n\n onMediaStreamRenewed(clientRole: SessionClientRole, mediaStream: MediaStream): Promise<void> {\n //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation\n return Promise.resolve();\n }\n\n getRemoteTrackStats(mediaTrack: MediaStreamTrack): Promise<RemoteTrackStats> {\n let peerConnectionOfTrack: Nullable<RTCPeerConnection> = null;\n\n this._peerConnections.forEach((peerConnection: RTCPeerConnection) => {\n const remoteTrack = peerConnection.remoteMediaTracks.filter((track) => track.mediaTrack.id === mediaTrack.id);\n\n if (remoteTrack.length === 1) {\n peerConnectionOfTrack = peerConnection;\n }\n });\n\n if (peerConnectionOfTrack !== null) {\n return (peerConnectionOfTrack as any).getStats(mediaTrack);\n }\n\n return Promise.reject(new Error('Provided track is not remote track'));\n }\n\n //#endregion\n\n private _disconnectInternal(reason: MediaSessionDisconnectReason): Promise<void> {\n this._peerConnections.forEach((peerConnection: RTCPeerConnection) => {\n this._destroyPeerConnection(peerConnection);\n });\n\n trace.info('Disconnecting from session', reason);\n\n if (this._socket) {\n this._socket.off();\n this._socket.disconnect();\n }\n\n this._socket = null;\n setTimeout(() => this._sessionHandlers.onDisconnectedHandler(reason));\n\n return Promise.resolve();\n }\n\n private _createPeerConnection(peerId: string, peerConnectionType: SessionClientType, peerConnectionRole: SessionClientRole): RTCPeerConnection {\n if (this._peerConnections.get(peerId)) {\n throw new Error(`${this._sessionParams.clientType} peer connection for ${peerId} already exists`);\n }\n\n const peerConnection: any = new RTCPeerConnection(this._configuration);\n\n peerConnection.peerId = peerId;\n peerConnection.peerType = peerConnectionType;\n peerConnection.remoteMediaTracks = [];\n peerConnection.peerRole = peerConnectionRole;\n\n peerConnection.onconnectionstatechange = () => {\n trace.info('onconnectionstatechange', peerConnection);\n };\n\n peerConnection.oniceconnectionstatechange = (state: any) => {\n trace.info(`ICE Connection state for peer ${peerId} was changed to: ${state.currentTarget.iceConnectionState}`, state);\n const cnState = state.currentTarget.iceConnectionState;\n\n if (['closed', 'disconnected', 'failed'].indexOf(cnState) > -1) {\n this._iceStateDisconnected(peerConnection);\n }\n };\n\n peerConnection.onicecandidate = (event: any) => {\n if (event.candidate) {\n trace.info(`${this._sessionParams.clientType} peerConn.onicecandidate`, event.candidate);\n this._socket.emit(SOCKET_EVENTS.OUTGOING.ICE_CANDIDATE, {\n sessionId: this._sessionParams.sessionId,\n peerId: peerId,\n candidate: event.candidate,\n clientType: this._sessionParams.clientType\n });\n } else {\n trace.info('ICE Candidate is null in peerConnection', event);\n }\n };\n\n this._peerConnections.set(peerId, peerConnection);\n\n trace.info(`${peerConnectionType} peerConnection created`);\n\n return peerConnection;\n }\n\n private _destroyPeerConnection(peerConnection: RTCPeerConnection): void {\n trace.info('Destroying PeerConnection', peerConnection.peerType);\n peerConnection.ontrack = null;\n peerConnection.onicecandidate = null;\n peerConnection.onconnectionstatechange = null;\n peerConnection.oniceconnectionstatechange = null;\n peerConnection.onicegatheringstatechange = null;\n\n peerConnection.remoteMediaTracks.forEach((remoteMediaTrack) => {\n this._sessionStreamsManager.removeMediaTrack(remoteMediaTrack.mediaTrack)\n .catch(() => {\n trace.warn('Error while removing remote media track', remoteMediaTrack);\n });\n });\n\n this._peerConnections.delete(peerConnection.peerId);\n peerConnection.close();\n }\n\n private _withPeerConnection(peerId: any, callback: any): void | undefined {\n if (this._peerConnections.get(peerId)) {\n return callback(this._peerConnections.get(peerId));\n }\n\n return undefined;\n }\n\n //#endregion\n\n //#region ICE Candidates\n\n _iceCandidateReceivedHandler(iceCandidateData: any): void {\n const {candidate, peerId} = iceCandidateData;\n\n trace.info('_iceCandidateReceivedHandler', candidate);\n if (!candidate) {\n trace.info('Unexpected case, iceCandidate message arrived without candidate');\n\n return;\n }\n\n const peerConnection = this._peerConnections.get(peerId);\n\n if (!peerConnection || !peerConnection.remoteDescription) {\n trace.info('Queueing iceCandidate', candidate);\n this._queueIceCandidate(candidate, peerId);\n\n return;\n }\n\n trace.info('Going to add iceCandidate', candidate);\n this._addIceCandidateToPeer(candidate, peerConnection).catch(() => undefined);\n }\n\n _addIceCandidateToPeer(iceCandidate: RTCIceCandidate, peerConnection: RTCPeerConnection): Promise<void> {\n return peerConnection.addIceCandidate(iceCandidate)\n .then(() => {\n trace.info('ICE Candidate add to peer connection');\n })\n .catch((e) => {\n trace.warn('Error adding ICE Candidate to peer connection', e);\n throw e;\n });\n }\n\n _processQueuedIceCandidates(peerId: string): void {\n this._withPeerConnection(peerId, (peerConnection: RTCPeerConnection) => {\n const pendingIces = this._pendingPeersIce[peerId];\n\n if (pendingIces) {\n pendingIces.forEach((pendingIce: RTCIceCandidate) => {\n trace.info('Adding pending ICE to peer connections');\n this._addIceCandidateToPeer(pendingIce, peerConnection).catch(() => undefined);\n });\n } else {\n trace.info('No pending ICE found for peer', peerId);\n }\n });\n }\n\n _queueIceCandidate(iceCandidate: RTCIceCandidate, peerId: string): void {\n if (!this._pendingPeersIce[peerId]) {\n this._pendingPeersIce[peerId] = [];\n }\n\n this._pendingPeersIce[peerId].push(iceCandidate);\n }\n\n _iceStateDisconnected(peerConnection: RTCPeerConnection): void {\n this._disconnectInternal(MediaSessionDisconnectReason.PeerConnectionInterrupted).catch(() => undefined);\n }\n\n //#endregion\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/MediaSession/SessionTurn.v3.ts"],"names":[],"mappings":"AAIA,OAAO,EACH,aAAa,EACb,sBAAsB,EACtB,oBAAoB,EACpB,kBAAkB,EACA,gBAAgB,EACrC,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAGH,iBAAiB,EAEpB,MAAM,mBAAmB,CAAC;AAU3B,OAAO,EAAC,gBAAgB,EAAC,MAAM,oBAAoB,CAAC;AAKpD,qBAAa,mBAAoB,SAAQ,gBAAgB,CAAC,iBAAiB,CAAE,YAAW,aAAa;IACjG,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAuB;IACxD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAM;IACvC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAM;IACrC,OAAO,CAAC,OAAO,CAAM;aAEjB,EAAE,EAAI,MAAM;gBAIJ,aAAa,EAAE,kBAAkB,EAAE,eAAe,EAAE,oBAAoB,EAAE,aAAa,EAAE,sBAAsB;IA4B3H,OAAO,CAAC,WAAW,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB3C,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAkChE,4BAA4B,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAgBlD,iBAAiB,CAAC,kBAAkB,EAAE,GAAG,GAAG,IAAI;IAsDhD,oBAAoB,CAAC,gBAAgB,EAAE,GAAG,GAAG,IAAI;IAwBjD,wBAAwB,CAAC,qBAAqB,EAAE,GAAG,GAAG,IAAI;IAe1D,gBAAgB,CAAC,aAAa,EAAE,GAAG,GAAG,IAAI;IA2E1C,yBAAyB,IAAI,IAAI;IAcjC,sBAAsB,CAAC,UAAU,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IASpE,oBAAoB,CAAC,UAAU,EAAE,iBAAiB,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAK5F,mBAAmB,CAAC,UAAU,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAY5E,OAAO,CAAC,mBAAmB;IAkB3B,OAAO,CAAC,qBAAqB;IA8C7B,OAAO,CAAC,sBAAsB;IAc9B,OAAO,CAAC,mBAAmB;IAY3B,4BAA4B,CAAC,gBAAgB,EAAE,GAAG,GAAG,IAAI;IAuBzD,sBAAsB,CAAC,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAWvG,2BAA2B,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAejD,kBAAkB,CAAC,YAAY,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAQvE,qBAAqB,CAAC,cAAc,EAAE,iBAAiB,GAAG,IAAI;CAKjE","file":"SessionTurn.v3.d.ts","sourcesContent":["import * as io from 'socket.io-client';\nimport once from 'lodash/once';\nimport {Nullable} from '@techsee/techsee-common';\n\nimport {\n IMediaSession,\n ISessionStreamsManager,\n MediaSessionHandlers,\n MediaSessionParams,\n RemoteMediaTrack, RemoteTrackStats\n} from '../MediaContracts';\n\nimport {\n KnownMediaStream,\n MediaSessionDisconnectReason,\n SessionClientRole,\n SessionClientType\n} from '../MediaConstants';\n\nimport {\n SOCKET_EVENTS, SOCKET_PATH,\n SOCKET_RECONNECTION_ATTEMPTS,\n SOCKET_RECONNECTION_DELAY,\n SOCKET_RECONNECTION_DELAY_MAX\n} from './TurnConstants';\n\nimport {getMediaTracer} from '../MediaUtils/MediaTracer';\nimport {MediaSessionBase} from './MediaSessionBase';\n\nconst trace = getMediaTracer('TurnSessionV3');\n\n//Currently this version supports subscribing only. Publishing will be implemented as needed.\nexport class TurnWebRtcSessionV3 extends MediaSessionBase<RTCPeerConnection> implements IMediaSession {\n private readonly _sessionHandlers: MediaSessionHandlers;\n private readonly _pendingPeersIce: any;\n private readonly _configuration: any;\n private _socket: any;\n\n get id(): string {\n return this._sessionParams.sessionId;\n }\n\n constructor(sessionParams: MediaSessionParams, sessionHandlers: MediaSessionHandlers, streamFactory: ISessionStreamsManager) {\n super(sessionParams, streamFactory);\n this._sessionHandlers = sessionHandlers;\n this._socket = null;\n this._pendingPeersIce = {};\n\n const iceServers = sessionParams.credentials.ice.map((item: any) => ({\n urls: item.url,\n username: item.login,\n credential: item.password\n }));\n\n this._configuration = {\n iceServers,\n iceTransportPolicy: 'relay'\n };\n\n this._joinResponseHandler = this._joinResponseHandler.bind(this);\n this._iceCandidateReceivedHandler = this._iceCandidateReceivedHandler.bind(this);\n this._sendOfferHandler = this._sendOfferHandler.bind(this);\n this._sdpOfferHandler = this._sdpOfferHandler.bind(this);\n this._userPeerReconnectHandler = this._userPeerReconnectHandler.bind(this);\n this._peerDisconnectedHandler = this._peerDisconnectedHandler.bind(this);\n this._onSocketDisconnectedHandler = this._onSocketDisconnectedHandler.bind(this);\n }\n\n //#region Socket Connectivity\n\n connect(connectOnly = false): Promise<void> {\n trace.info('Connect to session');\n\n return this._connectSocket(this._sessionParams.credentials.url, connectOnly)\n .then(() => {\n trace.info('Joining SessionId: ' + this._sessionParams.sessionId);\n\n this._socket.emit(SOCKET_EVENTS.OUTGOING.JOIN_ROOM, {\n clientType: this._sessionParams.clientType,\n sessionId: this._sessionParams.sessionId\n });\n })\n .catch((error) => {\n throw error;\n });\n }\n\n disconnect(): Promise<void> {\n return this._disconnectInternal(MediaSessionDisconnectReason.ForcedByConsumer);\n }\n\n _connectSocket(url: string, connectOnly: boolean): Promise<void> {\n return new Promise((resolve, reject) => {\n const socket = this._socket = io.connect(url, {\n 'forceNew': true,\n 'reconnectionDelay': SOCKET_RECONNECTION_DELAY,\n 'reconnectionDelayMax': SOCKET_RECONNECTION_DELAY_MAX,\n 'reconnectionAttempts': SOCKET_RECONNECTION_ATTEMPTS,\n 'path': SOCKET_PATH\n });\n\n const done = once((err?: any) => {\n err ? reject(err) : resolve();\n });\n\n socket.once('connect', () => done());\n socket.on(SOCKET_EVENTS.INCOMING.ERROR, done);\n socket.on('connect_error', done);\n socket.on('connect_timeout', done);\n socket.on('disconnect', this._onSocketDisconnectedHandler);\n\n if (!connectOnly) {\n trace.info('Subscribing socket events');\n\n //PUBLISHING NOT SUPPORTED YET\n socket.on(SOCKET_EVENTS.INCOMING.SEND_OFFER, this._sendOfferHandler);\n socket.on(SOCKET_EVENTS.INCOMING.JOIN_RESPONSE, this._joinResponseHandler);\n socket.on(SOCKET_EVENTS.INCOMING.PEER_DISCONNECTED, this._peerDisconnectedHandler);\n socket.on(SOCKET_EVENTS.INCOMING.SDP_OFFER, this._sdpOfferHandler);\n socket.on(SOCKET_EVENTS.INCOMING.PUBLISHER_RECONNECT, this._userPeerReconnectHandler);\n socket.on(SOCKET_EVENTS.INCOMING.ICE_CANDIDATE, this._iceCandidateReceivedHandler);\n }\n });\n }\n\n _onSocketDisconnectedHandler(reason: string): void {\n if (this._socket) {\n // The initial example of differentiating between \"forced\" disconnect and \"network\" disconnect is taken from:\n // https://socket.io/docs/client-api/#Event-%E2%80%98disconnect%E2%80%99\n if (reason !== 'io server disconnect' && reason !== 'io client disconnect') {\n // the disconnection was initiated by the server or by client, you need to call (connect) manually\n this._disconnectInternal(MediaSessionDisconnectReason.SignalingChannelDisconnect).catch(() => undefined);\n }\n }\n }\n\n //#endregion\n\n //#region WebRTC Initiator - session Initiator (User on mobile device)\n\n // Received by Initiator, causing him to emit SDP_OFFER\n _sendOfferHandler(sendOfferEventData: any): void {\n const {uid, peerId} = sendOfferEventData;\n\n trace.info('_sendOfferHandler');\n\n //Currently we not support of passing role through signaling, so we assume every connection is \"AGENT\" like\n const peerConnection = this._createPeerConnection(peerId, SessionClientType.GUEST, SessionClientRole.AGENT);\n const offerParams = {offerToReceiveAudio: true, offerToReceiveVideo: true};\n\n peerConnection.ontrack = (trackEvent: any) => {\n const track: MediaStreamTrack = trackEvent.track;\n\n trace.info(`MediaStreamTrack arrived from peerConnection: ${track.kind}`, track);\n this.registerMediaTrackFromPeer(peerConnection, track);\n };\n\n //TODO - Alex: Currently we not sending \"role\" through signaling, and by default we assume that the one who asks fot offer, is agent.\n //On later stages we can send or the client \"role\" or the list of \"streams\" that peer is interested in.\n this._sessionStreamsManager.getMediaStreamForRole(SessionClientRole.AGENT)\n .then((mediaStream: Nullable<MediaStream>) => {\n trace.info('_sendOfferHandler stream and peer created');\n\n if (mediaStream) {\n trace.info('Adding local tracks to peer connection');\n mediaStream.getTracks().forEach((track) => {\n peerConnection.addTrack(track, mediaStream);\n trace.info(`Local ${track.kind} track added to peer connection`);\n });\n } else {\n trace.info('No media stream was found for publishing');\n }\n })\n .then(() => peerConnection.createOffer(offerParams))\n .then((offerDesc) => {\n trace.info('Initiator has created sdp offer', {offerDesc});\n\n this._socket.emit(SOCKET_EVENTS.OUTGOING.SDP_OFFER, {\n uid,\n peerId,\n sessionId: this._sessionParams.sessionId,\n sdpOffer: offerDesc.sdp\n });\n\n return peerConnection.setLocalDescription(offerDesc)\n .then(() => {\n trace.info('Local description was set on peerConnection', peerConnection);\n });\n })\n .catch((e) => {\n trace.warn('Error', e);\n });\n }\n\n // Received by the Initiator: Indicates that publish should be started\n _joinResponseHandler(joinResponseData: any): void {\n const {sdpAnswer, uid, peerId} = joinResponseData;\n\n trace.info('joinResponse Received', {sdpAnswer});\n\n this._withPeerConnection(peerId, (peerConnection: RTCPeerConnection) => {\n const answer = new RTCSessionDescription({\n type: 'answer',\n sdp: sdpAnswer\n });\n\n peerConnection.setRemoteDescription(answer)\n .then(() => {\n trace.info('Remote description was set', answer);\n\n this._processQueuedIceCandidates(peerId);\n })\n .catch((e) => {\n trace.warn('Error', e);\n });\n });\n }\n\n // Received by Initiator after a guests socket has been disconnected\n _peerDisconnectedHandler(peerDisconnectedEvent: any): void {\n const {peerId} = peerDisconnectedEvent;\n\n trace.info('_peerDisconnectedHandler');\n\n this._withPeerConnection(peerId, (peerConnection: any) => {\n this._disconnectInternal(MediaSessionDisconnectReason.PeerDisconnected).catch(() => undefined);\n });\n }\n\n //#endregion WebRTC Initiator - session Initiator (User on mobile device)\n\n //#region WebRTC Guest - session Guest (Agent on dashboard platform)\n\n // Received by Guest, causing him to emit SDP_ANSWER\n _sdpOfferHandler(sdpOfferEvent: any): void {\n const {sdpOffer, peerId, uid} = sdpOfferEvent;\n\n trace.info('sdpOffer Received', {sdpOffer});\n\n const peerConnection = this._createPeerConnection(peerId, SessionClientType.INITIATOR, SessionClientRole.USER);\n\n peerConnection.ontrack = (trackEvent: any) => {\n const {track} = trackEvent;\n\n trace.info(`MediaStreamTrack arrived from peerConnection: ${track.kind}`, track);\n\n const remoteTrack: RemoteMediaTrack = {\n mediaTrack: track,\n trackType: track.kind === 'video'\n //Although we can have desktop share stream, we still name it USER_VIDEO_STREAM in dashboard.\n //Because currently we support only one video stream to be streamed at the time, it's not an issue.\n //But when we will need to stream more than one stream of a kind from single peer, this will be need to change.\n ? KnownMediaStream.USER_VIDEO_STREAM : KnownMediaStream.USER_AUDIO_STREAM\n };\n\n peerConnection.remoteMediaTracks.push(remoteTrack);\n this._sessionStreamsManager.addRemoteMediaTrack(remoteTrack)\n .catch(() => {\n trace.warn('Error adding remote track to stream manager', remoteTrack);\n });\n };\n\n this._sessionStreamsManager.getMediaStreamForRole(SessionClientRole.USER)\n .then((mediaStream: Nullable<MediaStream>) => {\n if (mediaStream) {\n trace.info('Adding local tracks to peer connection');\n mediaStream.getTracks().forEach((track) => {\n peerConnection.addTrack(track, mediaStream);\n trace.info(`Local ${track.kind} track added to peer connection`);\n });\n } else {\n trace.info('No media stream was found for publishing');\n }\n })\n .then(() => {\n const remoteDesc = new RTCSessionDescription({type: 'offer', sdp: sdpOffer});\n\n return peerConnection.setRemoteDescription(remoteDesc)\n .then(() => {\n trace.info('Remote description was set', remoteDesc);\n\n return peerConnection.createAnswer()\n .then((sdpAnswer) => {\n trace.info('_sdpOfferHandler answer created', sdpAnswer);\n\n this._socket.emit(SOCKET_EVENTS.OUTGOING.SDP_ANSWER, {\n uid,\n peerId,\n sessionId: this._sessionParams.sessionId,\n sdpAnswer: sdpAnswer.sdp\n });\n\n return peerConnection.setLocalDescription(sdpAnswer)\n .then(() => {\n trace.info('_sdpOfferHandler local desc was set');\n\n this._processQueuedIceCandidates(peerId);\n });\n });\n });\n\n })\n .catch((e) => {\n trace.error('Error in _sdpOfferHandler', e);\n throw e;\n });\n }\n\n // Received by Guest after an Initiator reconnects to room\n _userPeerReconnectHandler(): void {\n trace.info('_userPeerReconnectHandler');\n this._disconnectInternal(MediaSessionDisconnectReason.UserPeerReconnected)\n .catch((error: any) => {\n trace.warn('Error while disconnecting during userPeerReconnectHandler.', error);\n });\n }\n\n //#endregion WebRTC Guest - session Guest (Agent on dashboard platform)\n\n //#region Peer Connection\n\n //#region Streams Handling\n\n onMediaStreamDestroyed(clientRole: SessionClientRole): Promise<void> {\n //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation\n this._peerConnections.forEach((peerConnection: RTCPeerConnection) => {\n this._disconnectInternal(MediaSessionDisconnectReason.PublishedStreamDestroyed).catch(() => undefined);\n });\n\n return Promise.resolve();\n }\n\n onMediaStreamRenewed(clientRole: SessionClientRole, mediaStream: MediaStream): Promise<void> {\n //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation\n return Promise.resolve();\n }\n\n getRemoteTrackStats(mediaTrack: MediaStreamTrack): Promise<RemoteTrackStats> {\n const peerConnectionOfTrack = this.getPeerConnectionByMediaTrack(mediaTrack);\n\n if (peerConnectionOfTrack !== null) {\n return (peerConnectionOfTrack as any).getStats(mediaTrack);\n }\n\n return Promise.reject(new Error('Provided track is not remote track'));\n }\n\n //#endregion\n\n private _disconnectInternal(reason: MediaSessionDisconnectReason): Promise<void> {\n this._peerConnections.forEach((peerConnection: RTCPeerConnection) => {\n this._destroyPeerConnection(peerConnection);\n });\n\n trace.info('Disconnecting from session', reason);\n\n if (this._socket) {\n this._socket.off();\n this._socket.disconnect();\n }\n\n this._socket = null;\n setTimeout(() => this._sessionHandlers.onDisconnectedHandler(reason));\n\n return Promise.resolve();\n }\n\n private _createPeerConnection(peerId: string, peerConnectionType: SessionClientType, peerConnectionRole: SessionClientRole): RTCPeerConnection {\n if (this._peerConnections.get(peerId)) {\n throw new Error(`${this._sessionParams.clientType} peer connection for ${peerId} already exists`);\n }\n\n const peerConnection: any = new RTCPeerConnection(this._configuration);\n\n peerConnection.peerId = peerId;\n peerConnection.peerType = peerConnectionType;\n peerConnection.remoteMediaTracks = [];\n peerConnection.peerRole = peerConnectionRole;\n\n peerConnection.onconnectionstatechange = () => {\n trace.info('onconnectionstatechange', peerConnection);\n };\n\n peerConnection.oniceconnectionstatechange = (state: any) => {\n trace.info(`ICE Connection state for peer ${peerId} was changed to: ${state.currentTarget.iceConnectionState}`, state);\n const cnState = state.currentTarget.iceConnectionState;\n\n if (['closed', 'disconnected', 'failed'].indexOf(cnState) > -1) {\n this._iceStateDisconnected(peerConnection);\n }\n };\n\n peerConnection.onicecandidate = (event: any) => {\n if (event.candidate) {\n trace.info(`${this._sessionParams.clientType} peerConn.onicecandidate`, event.candidate);\n this._socket.emit(SOCKET_EVENTS.OUTGOING.ICE_CANDIDATE, {\n sessionId: this._sessionParams.sessionId,\n peerId: peerId,\n candidate: event.candidate,\n clientType: this._sessionParams.clientType\n });\n } else {\n trace.info('ICE Candidate is null in peerConnection', event);\n }\n };\n\n this._peerConnections.set(peerId, peerConnection);\n\n trace.info(`${peerConnectionType} peerConnection created`);\n\n return peerConnection;\n }\n\n private _destroyPeerConnection(peerConnection: RTCPeerConnection): void {\n trace.info('Destroying PeerConnection', peerConnection.peerType);\n peerConnection.ontrack = null;\n peerConnection.onicecandidate = null;\n peerConnection.onconnectionstatechange = null;\n peerConnection.oniceconnectionstatechange = null;\n peerConnection.onicegatheringstatechange = null;\n\n this.unregisterPeersRemoteMediaTracks(peerConnection);\n\n this._peerConnections.delete(peerConnection.peerId);\n peerConnection.close();\n }\n\n private _withPeerConnection(peerId: any, callback: any): void | undefined {\n if (this._peerConnections.get(peerId)) {\n return callback(this._peerConnections.get(peerId));\n }\n\n return undefined;\n }\n\n //#endregion\n\n //#region ICE Candidates\n\n _iceCandidateReceivedHandler(iceCandidateData: any): void {\n const {candidate, peerId} = iceCandidateData;\n\n trace.info('_iceCandidateReceivedHandler', candidate);\n if (!candidate) {\n trace.info('Unexpected case, iceCandidate message arrived without candidate');\n\n return;\n }\n\n const peerConnection = this._peerConnections.get(peerId);\n\n if (!peerConnection || !peerConnection.remoteDescription) {\n trace.info('Queueing iceCandidate', candidate);\n this._queueIceCandidate(candidate, peerId);\n\n return;\n }\n\n trace.info('Going to add iceCandidate', candidate);\n this._addIceCandidateToPeer(candidate, peerConnection).catch(() => undefined);\n }\n\n _addIceCandidateToPeer(iceCandidate: RTCIceCandidate, peerConnection: RTCPeerConnection): Promise<void> {\n return peerConnection.addIceCandidate(iceCandidate)\n .then(() => {\n trace.info('ICE Candidate add to peer connection');\n })\n .catch((e) => {\n trace.warn('Error adding ICE Candidate to peer connection', e);\n throw e;\n });\n }\n\n _processQueuedIceCandidates(peerId: string): void {\n this._withPeerConnection(peerId, (peerConnection: RTCPeerConnection) => {\n const pendingIces = this._pendingPeersIce[peerId];\n\n if (pendingIces) {\n pendingIces.forEach((pendingIce: RTCIceCandidate) => {\n trace.info('Adding pending ICE to peer connections');\n this._addIceCandidateToPeer(pendingIce, peerConnection).catch(() => undefined);\n });\n } else {\n trace.info('No pending ICE found for peer', peerId);\n }\n });\n }\n\n _queueIceCandidate(iceCandidate: RTCIceCandidate, peerId: string): void {\n if (!this._pendingPeersIce[peerId]) {\n this._pendingPeersIce[peerId] = [];\n }\n\n this._pendingPeersIce[peerId].push(iceCandidate);\n }\n\n _iceStateDisconnected(peerConnection: RTCPeerConnection): void {\n this._disconnectInternal(MediaSessionDisconnectReason.PeerConnectionInterrupted).catch(() => undefined);\n }\n\n //#endregion\n}\n"]}
|
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
var __extends = undefined && undefined.__extends || function () {
|
|
4
|
+
var _extendStatics = function extendStatics(d, b) {
|
|
5
|
+
_extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function (d, b) {
|
|
6
|
+
d.__proto__ = b;
|
|
7
|
+
} || function (d, b) {
|
|
8
|
+
for (var p in b) {
|
|
9
|
+
if (b.hasOwnProperty(p)) d[p] = b[p];
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
return _extendStatics(d, b);
|
|
13
|
+
};
|
|
14
|
+
return function (d, b) {
|
|
15
|
+
_extendStatics(d, b);
|
|
16
|
+
function __() {
|
|
17
|
+
this.constructor = d;
|
|
18
|
+
}
|
|
19
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
20
|
+
};
|
|
21
|
+
}();
|
|
3
22
|
var __importStar = undefined && undefined.__importStar || function (mod) {
|
|
4
23
|
if (mod && mod.__esModule) return mod;
|
|
5
24
|
var result = {};
|
|
@@ -17,16 +36,16 @@ var once_1 = __importDefault(require("lodash/once"));
|
|
|
17
36
|
var MediaConstants_1 = require("../MediaConstants");
|
|
18
37
|
var TurnConstants_1 = require("./TurnConstants");
|
|
19
38
|
var MediaTracer_1 = require("../MediaUtils/MediaTracer");
|
|
39
|
+
var MediaSessionBase_1 = require("./MediaSessionBase");
|
|
20
40
|
var trace = MediaTracer_1.getMediaTracer('TurnSessionV3');
|
|
21
41
|
//Currently this version supports subscribing only. Publishing will be implemented as needed.
|
|
22
|
-
var TurnWebRtcSessionV3 = /** @class */function () {
|
|
42
|
+
var TurnWebRtcSessionV3 = /** @class */function (_super) {
|
|
43
|
+
__extends(TurnWebRtcSessionV3, _super);
|
|
23
44
|
function TurnWebRtcSessionV3(sessionParams, sessionHandlers, streamFactory) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
this._pendingPeersIce = {};
|
|
29
|
-
this._peerConnections = new Map();
|
|
45
|
+
var _this = _super.call(this, sessionParams, streamFactory) || this;
|
|
46
|
+
_this._sessionHandlers = sessionHandlers;
|
|
47
|
+
_this._socket = null;
|
|
48
|
+
_this._pendingPeersIce = {};
|
|
30
49
|
var iceServers = sessionParams.credentials.ice.map(function (item) {
|
|
31
50
|
return {
|
|
32
51
|
urls: item.url,
|
|
@@ -34,17 +53,18 @@ var TurnWebRtcSessionV3 = /** @class */function () {
|
|
|
34
53
|
credential: item.password
|
|
35
54
|
};
|
|
36
55
|
});
|
|
37
|
-
|
|
56
|
+
_this._configuration = {
|
|
38
57
|
iceServers: iceServers,
|
|
39
58
|
iceTransportPolicy: 'relay'
|
|
40
59
|
};
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
60
|
+
_this._joinResponseHandler = _this._joinResponseHandler.bind(_this);
|
|
61
|
+
_this._iceCandidateReceivedHandler = _this._iceCandidateReceivedHandler.bind(_this);
|
|
62
|
+
_this._sendOfferHandler = _this._sendOfferHandler.bind(_this);
|
|
63
|
+
_this._sdpOfferHandler = _this._sdpOfferHandler.bind(_this);
|
|
64
|
+
_this._userPeerReconnectHandler = _this._userPeerReconnectHandler.bind(_this);
|
|
65
|
+
_this._peerDisconnectedHandler = _this._peerDisconnectedHandler.bind(_this);
|
|
66
|
+
_this._onSocketDisconnectedHandler = _this._onSocketDisconnectedHandler.bind(_this);
|
|
67
|
+
return _this;
|
|
48
68
|
}
|
|
49
69
|
Object.defineProperty(TurnWebRtcSessionV3.prototype, "id", {
|
|
50
70
|
get: function get() {
|
|
@@ -131,17 +151,7 @@ var TurnWebRtcSessionV3 = /** @class */function () {
|
|
|
131
151
|
peerConnection.ontrack = function (trackEvent) {
|
|
132
152
|
var track = trackEvent.track;
|
|
133
153
|
trace.info("MediaStreamTrack arrived from peerConnection: " + track.kind, track);
|
|
134
|
-
|
|
135
|
-
if (track.kind.toLowerCase() === 'audio') {
|
|
136
|
-
var remoteMediaTrack = {
|
|
137
|
-
mediaTrack: track,
|
|
138
|
-
trackType: MediaConstants_1.KnownMediaStream.AGENT_AUDIO_STREAM
|
|
139
|
-
};
|
|
140
|
-
peerConnection.remoteMediaTracks.push(remoteMediaTrack);
|
|
141
|
-
_this._sessionStreamsManager.addRemoteMediaTrack(remoteMediaTrack).catch(function (error) {
|
|
142
|
-
trace.warn('Error adding remote media track to available streams', error);
|
|
143
|
-
});
|
|
144
|
-
}
|
|
154
|
+
_this.registerMediaTrackFromPeer(peerConnection, track);
|
|
145
155
|
};
|
|
146
156
|
//TODO - Alex: Currently we not sending "role" through signaling, and by default we assume that the one who asks fot offer, is agent.
|
|
147
157
|
//On later stages we can send or the client "role" or the list of "streams" that peer is interested in.
|
|
@@ -288,15 +298,7 @@ var TurnWebRtcSessionV3 = /** @class */function () {
|
|
|
288
298
|
return Promise.resolve();
|
|
289
299
|
};
|
|
290
300
|
TurnWebRtcSessionV3.prototype.getRemoteTrackStats = function (mediaTrack) {
|
|
291
|
-
var peerConnectionOfTrack =
|
|
292
|
-
this._peerConnections.forEach(function (peerConnection) {
|
|
293
|
-
var remoteTrack = peerConnection.remoteMediaTracks.filter(function (track) {
|
|
294
|
-
return track.mediaTrack.id === mediaTrack.id;
|
|
295
|
-
});
|
|
296
|
-
if (remoteTrack.length === 1) {
|
|
297
|
-
peerConnectionOfTrack = peerConnection;
|
|
298
|
-
}
|
|
299
|
-
});
|
|
301
|
+
var peerConnectionOfTrack = this.getPeerConnectionByMediaTrack(mediaTrack);
|
|
300
302
|
if (peerConnectionOfTrack !== null) {
|
|
301
303
|
return peerConnectionOfTrack.getStats(mediaTrack);
|
|
302
304
|
}
|
|
@@ -357,18 +359,13 @@ var TurnWebRtcSessionV3 = /** @class */function () {
|
|
|
357
359
|
return peerConnection;
|
|
358
360
|
};
|
|
359
361
|
TurnWebRtcSessionV3.prototype._destroyPeerConnection = function (peerConnection) {
|
|
360
|
-
var _this = this;
|
|
361
362
|
trace.info('Destroying PeerConnection', peerConnection.peerType);
|
|
362
363
|
peerConnection.ontrack = null;
|
|
363
364
|
peerConnection.onicecandidate = null;
|
|
364
365
|
peerConnection.onconnectionstatechange = null;
|
|
365
366
|
peerConnection.oniceconnectionstatechange = null;
|
|
366
367
|
peerConnection.onicegatheringstatechange = null;
|
|
367
|
-
|
|
368
|
-
_this._sessionStreamsManager.removeMediaTrack(remoteMediaTrack.mediaTrack).catch(function () {
|
|
369
|
-
trace.warn('Error while removing remote media track', remoteMediaTrack);
|
|
370
|
-
});
|
|
371
|
-
});
|
|
368
|
+
this.unregisterPeersRemoteMediaTracks(peerConnection);
|
|
372
369
|
this._peerConnections.delete(peerConnection.peerId);
|
|
373
370
|
peerConnection.close();
|
|
374
371
|
};
|
|
@@ -435,7 +432,7 @@ var TurnWebRtcSessionV3 = /** @class */function () {
|
|
|
435
432
|
});
|
|
436
433
|
};
|
|
437
434
|
return TurnWebRtcSessionV3;
|
|
438
|
-
}();
|
|
435
|
+
}(MediaSessionBase_1.MediaSessionBase);
|
|
439
436
|
exports.TurnWebRtcSessionV3 = TurnWebRtcSessionV3;
|
|
440
437
|
|
|
441
438
|
//# sourceMappingURL=SessionTurn.v3.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["MediaSession/SessionTurn.v3.js"],"names":["__importStar","mod","__esModule","result","k","Object","hasOwnProperty","call","__importDefault","defineProperty","exports","value","io","require","once_1","MediaConstants_1","TurnConstants_1","MediaTracer_1","trace","getMediaTracer","TurnWebRtcSessionV3","sessionParams","sessionHandlers","streamFactory","_sessionParams","_sessionStreamsManager","_sessionHandlers","_socket","_pendingPeersIce","_peerConnections","Map","iceServers","credentials","ice","map","item","urls","url","username","login","credential","password","_configuration","iceTransportPolicy","_joinResponseHandler","bind","_iceCandidateReceivedHandler","_sendOfferHandler","_sdpOfferHandler","_userPeerReconnectHandler","_peerDisconnectedHandler","_onSocketDisconnectedHandler","prototype","get","sessionId","enumerable","configurable","connect","connectOnly","_this","info","_connectSocket","then","emit","SOCKET_EVENTS","OUTGOING","JOIN_ROOM","clientType","catch","error","disconnect","_disconnectInternal","MediaSessionDisconnectReason","ForcedByConsumer","Promise","resolve","reject","socket","SOCKET_RECONNECTION_DELAY","SOCKET_RECONNECTION_DELAY_MAX","SOCKET_RECONNECTION_ATTEMPTS","SOCKET_PATH","done","default","err","once","on","INCOMING","ERROR","SEND_OFFER","JOIN_RESPONSE","PEER_DISCONNECTED","SDP_OFFER","PUBLISHER_RECONNECT","ICE_CANDIDATE","reason","SignalingChannelDisconnect","undefined","sendOfferEventData","uid","peerId","peerConnection","_createPeerConnection","SessionClientType","GUEST","SessionClientRole","AGENT","offerParams","offerToReceiveAudio","offerToReceiveVideo","ontrack","trackEvent","track","kind","toLowerCase","remoteMediaTrack","mediaTrack","trackType","KnownMediaStream","AGENT_AUDIO_STREAM","remoteMediaTracks","push","addRemoteMediaTrack","warn","getMediaStreamForRole","mediaStream","getTracks","forEach","addTrack","createOffer","offerDesc","sdpOffer","sdp","setLocalDescription","e","joinResponseData","sdpAnswer","_withPeerConnection","answer","RTCSessionDescription","type","setRemoteDescription","_processQueuedIceCandidates","peerDisconnectedEvent","PeerDisconnected","sdpOfferEvent","INITIATOR","USER","remoteTrack","USER_VIDEO_STREAM","USER_AUDIO_STREAM","remoteDesc","createAnswer","SDP_ANSWER","UserPeerReconnected","onMediaStreamDestroyed","clientRole","PublishedStreamDestroyed","onMediaStreamRenewed","getRemoteTrackStats","peerConnectionOfTrack","filter","id","length","getStats","Error","_destroyPeerConnection","off","setTimeout","onDisconnectedHandler","peerConnectionType","peerConnectionRole","RTCPeerConnection","peerType","peerRole","onconnectionstatechange","oniceconnectionstatechange","state","currentTarget","iceConnectionState","cnState","indexOf","_iceStateDisconnected","onicecandidate","event","candidate","set","onicegatheringstatechange","removeMediaTrack","delete","close","callback","iceCandidateData","remoteDescription","_queueIceCandidate","_addIceCandidateToPeer","iceCandidate","addIceCandidate","pendingIces","pendingIce","PeerConnectionInterrupted"],"mappings":"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","file":"SessionTurn.v3.js","sourcesContent":["\"use strict\";\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\n result[\"default\"] = mod;\n return result;\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar io = __importStar(require(\"socket.io-client\"));\nvar once_1 = __importDefault(require(\"lodash/once\"));\nvar MediaConstants_1 = require(\"../MediaConstants\");\nvar TurnConstants_1 = require(\"./TurnConstants\");\nvar MediaTracer_1 = require(\"../MediaUtils/MediaTracer\");\nvar trace = MediaTracer_1.getMediaTracer('TurnSessionV3');\n//Currently this version supports subscribing only. Publishing will be implemented as needed.\nvar TurnWebRtcSessionV3 = /** @class */ (function () {\n function TurnWebRtcSessionV3(sessionParams, sessionHandlers, streamFactory) {\n this._sessionParams = sessionParams;\n this._sessionStreamsManager = streamFactory;\n this._sessionHandlers = sessionHandlers;\n this._socket = null;\n this._pendingPeersIce = {};\n this._peerConnections = new Map();\n var iceServers = sessionParams.credentials.ice.map(function (item) { return ({\n urls: item.url,\n username: item.login,\n credential: item.password\n }); });\n this._configuration = {\n iceServers: iceServers,\n iceTransportPolicy: 'relay'\n };\n this._joinResponseHandler = this._joinResponseHandler.bind(this);\n this._iceCandidateReceivedHandler = this._iceCandidateReceivedHandler.bind(this);\n this._sendOfferHandler = this._sendOfferHandler.bind(this);\n this._sdpOfferHandler = this._sdpOfferHandler.bind(this);\n this._userPeerReconnectHandler = this._userPeerReconnectHandler.bind(this);\n this._peerDisconnectedHandler = this._peerDisconnectedHandler.bind(this);\n this._onSocketDisconnectedHandler = this._onSocketDisconnectedHandler.bind(this);\n }\n Object.defineProperty(TurnWebRtcSessionV3.prototype, \"id\", {\n get: function () {\n return this._sessionParams.sessionId;\n },\n enumerable: true,\n configurable: true\n });\n //#region Socket Connectivity\n TurnWebRtcSessionV3.prototype.connect = function (connectOnly) {\n var _this = this;\n if (connectOnly === void 0) { connectOnly = false; }\n trace.info('Connect to session');\n return this._connectSocket(this._sessionParams.credentials.url, connectOnly)\n .then(function () {\n trace.info('Joining SessionId: ' + _this._sessionParams.sessionId);\n _this._socket.emit(TurnConstants_1.SOCKET_EVENTS.OUTGOING.JOIN_ROOM, {\n clientType: _this._sessionParams.clientType,\n sessionId: _this._sessionParams.sessionId\n });\n })\n .catch(function (error) {\n throw error;\n });\n };\n TurnWebRtcSessionV3.prototype.disconnect = function () {\n return this._disconnectInternal(MediaConstants_1.MediaSessionDisconnectReason.ForcedByConsumer);\n };\n TurnWebRtcSessionV3.prototype._connectSocket = function (url, connectOnly) {\n var _this = this;\n return new Promise(function (resolve, reject) {\n var socket = _this._socket = io.connect(url, {\n 'forceNew': true,\n 'reconnectionDelay': TurnConstants_1.SOCKET_RECONNECTION_DELAY,\n 'reconnectionDelayMax': TurnConstants_1.SOCKET_RECONNECTION_DELAY_MAX,\n 'reconnectionAttempts': TurnConstants_1.SOCKET_RECONNECTION_ATTEMPTS,\n 'path': TurnConstants_1.SOCKET_PATH\n });\n var done = once_1.default(function (err) {\n err ? reject(err) : resolve();\n });\n socket.once('connect', function () { return done(); });\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.ERROR, done);\n socket.on('connect_error', done);\n socket.on('connect_timeout', done);\n socket.on('disconnect', _this._onSocketDisconnectedHandler);\n if (!connectOnly) {\n trace.info('Subscribing socket events');\n //PUBLISHING NOT SUPPORTED YET\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.SEND_OFFER, _this._sendOfferHandler);\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.JOIN_RESPONSE, _this._joinResponseHandler);\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.PEER_DISCONNECTED, _this._peerDisconnectedHandler);\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.SDP_OFFER, _this._sdpOfferHandler);\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.PUBLISHER_RECONNECT, _this._userPeerReconnectHandler);\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.ICE_CANDIDATE, _this._iceCandidateReceivedHandler);\n }\n });\n };\n TurnWebRtcSessionV3.prototype._onSocketDisconnectedHandler = function (reason) {\n if (this._socket) {\n // The initial example of differentiating between \"forced\" disconnect and \"network\" disconnect is taken from:\n // https://socket.io/docs/client-api/#Event-%E2%80%98disconnect%E2%80%99\n if (reason !== 'io server disconnect' && reason !== 'io client disconnect') {\n // the disconnection was initiated by the server or by client, you need to call (connect) manually\n this._disconnectInternal(MediaConstants_1.MediaSessionDisconnectReason.SignalingChannelDisconnect).catch(function () { return undefined; });\n }\n }\n };\n //#endregion\n //#region WebRTC Initiator - session Initiator (User on mobile device)\n // Received by Initiator, causing him to emit SDP_OFFER\n TurnWebRtcSessionV3.prototype._sendOfferHandler = function (sendOfferEventData) {\n var _this = this;\n var uid = sendOfferEventData.uid, peerId = sendOfferEventData.peerId;\n trace.info('_sendOfferHandler');\n //Currently we not support of passing role through signaling, so we assume every connection is \"AGENT\" like\n var peerConnection = this._createPeerConnection(peerId, MediaConstants_1.SessionClientType.GUEST, MediaConstants_1.SessionClientRole.AGENT);\n var offerParams = { offerToReceiveAudio: true, offerToReceiveVideo: true };\n peerConnection.ontrack = function (trackEvent) {\n var track = trackEvent.track;\n trace.info(\"MediaStreamTrack arrived from peerConnection: \" + track.kind, track);\n //We only support to stream audio from dashboard\n if (track.kind.toLowerCase() === 'audio') {\n var remoteMediaTrack = {\n mediaTrack: track,\n trackType: MediaConstants_1.KnownMediaStream.AGENT_AUDIO_STREAM\n };\n peerConnection.remoteMediaTracks.push(remoteMediaTrack);\n _this._sessionStreamsManager.addRemoteMediaTrack(remoteMediaTrack)\n .catch(function (error) {\n trace.warn('Error adding remote media track to available streams', error);\n });\n }\n };\n //TODO - Alex: Currently we not sending \"role\" through signaling, and by default we assume that the one who asks fot offer, is agent.\n //On later stages we can send or the client \"role\" or the list of \"streams\" that peer is interested in.\n this._sessionStreamsManager.getMediaStreamForRole(MediaConstants_1.SessionClientRole.AGENT)\n .then(function (mediaStream) {\n trace.info('_sendOfferHandler stream and peer created');\n if (mediaStream) {\n trace.info('Adding local tracks to peer connection');\n mediaStream.getTracks().forEach(function (track) {\n peerConnection.addTrack(track, mediaStream);\n trace.info(\"Local \" + track.kind + \" track added to peer connection\");\n });\n }\n else {\n trace.info('No media stream was found for publishing');\n }\n })\n .then(function () { return peerConnection.createOffer(offerParams); })\n .then(function (offerDesc) {\n trace.info('Initiator has created sdp offer', { offerDesc: offerDesc });\n _this._socket.emit(TurnConstants_1.SOCKET_EVENTS.OUTGOING.SDP_OFFER, {\n uid: uid,\n peerId: peerId,\n sessionId: _this._sessionParams.sessionId,\n sdpOffer: offerDesc.sdp\n });\n return peerConnection.setLocalDescription(offerDesc)\n .then(function () {\n trace.info('Local description was set on peerConnection', peerConnection);\n });\n })\n .catch(function (e) {\n trace.warn('Error', e);\n });\n };\n // Received by the Initiator: Indicates that publish should be started\n TurnWebRtcSessionV3.prototype._joinResponseHandler = function (joinResponseData) {\n var _this = this;\n var sdpAnswer = joinResponseData.sdpAnswer, uid = joinResponseData.uid, peerId = joinResponseData.peerId;\n trace.info('joinResponse Received', { sdpAnswer: sdpAnswer });\n this._withPeerConnection(peerId, function (peerConnection) {\n var answer = new RTCSessionDescription({\n type: 'answer',\n sdp: sdpAnswer\n });\n peerConnection.setRemoteDescription(answer)\n .then(function () {\n trace.info('Remote description was set', answer);\n _this._processQueuedIceCandidates(peerId);\n })\n .catch(function (e) {\n trace.warn('Error', e);\n });\n });\n };\n // Received by Initiator after a guests socket has been disconnected\n TurnWebRtcSessionV3.prototype._peerDisconnectedHandler = function (peerDisconnectedEvent) {\n var _this = this;\n var peerId = peerDisconnectedEvent.peerId;\n trace.info('_peerDisconnectedHandler');\n this._withPeerConnection(peerId, function (peerConnection) {\n _this._disconnectInternal(MediaConstants_1.MediaSessionDisconnectReason.PeerDisconnected).catch(function () { return undefined; });\n });\n };\n //#endregion WebRTC Initiator - session Initiator (User on mobile device)\n //#region WebRTC Guest - session Guest (Agent on dashboard platform)\n // Received by Guest, causing him to emit SDP_ANSWER\n TurnWebRtcSessionV3.prototype._sdpOfferHandler = function (sdpOfferEvent) {\n var _this = this;\n var sdpOffer = sdpOfferEvent.sdpOffer, peerId = sdpOfferEvent.peerId, uid = sdpOfferEvent.uid;\n trace.info('sdpOffer Received', { sdpOffer: sdpOffer });\n var peerConnection = this._createPeerConnection(peerId, MediaConstants_1.SessionClientType.INITIATOR, MediaConstants_1.SessionClientRole.USER);\n peerConnection.ontrack = function (trackEvent) {\n var track = trackEvent.track;\n trace.info(\"MediaStreamTrack arrived from peerConnection: \" + track.kind, track);\n var remoteTrack = {\n mediaTrack: track,\n trackType: track.kind === 'video'\n //Although we can have desktop share stream, we still name it USER_VIDEO_STREAM in dashboard.\n //Because currently we support only one video stream to be streamed at the time, it's not an issue.\n //But when we will need to stream more than one stream of a kind from single peer, this will be need to change.\n ? MediaConstants_1.KnownMediaStream.USER_VIDEO_STREAM : MediaConstants_1.KnownMediaStream.USER_AUDIO_STREAM\n };\n peerConnection.remoteMediaTracks.push(remoteTrack);\n _this._sessionStreamsManager.addRemoteMediaTrack(remoteTrack)\n .catch(function () {\n trace.warn('Error adding remote track to stream manager', remoteTrack);\n });\n };\n this._sessionStreamsManager.getMediaStreamForRole(MediaConstants_1.SessionClientRole.USER)\n .then(function (mediaStream) {\n if (mediaStream) {\n trace.info('Adding local tracks to peer connection');\n mediaStream.getTracks().forEach(function (track) {\n peerConnection.addTrack(track, mediaStream);\n trace.info(\"Local \" + track.kind + \" track added to peer connection\");\n });\n }\n else {\n trace.info('No media stream was found for publishing');\n }\n })\n .then(function () {\n var remoteDesc = new RTCSessionDescription({ type: 'offer', sdp: sdpOffer });\n return peerConnection.setRemoteDescription(remoteDesc)\n .then(function () {\n trace.info('Remote description was set', remoteDesc);\n return peerConnection.createAnswer()\n .then(function (sdpAnswer) {\n trace.info('_sdpOfferHandler answer created', sdpAnswer);\n _this._socket.emit(TurnConstants_1.SOCKET_EVENTS.OUTGOING.SDP_ANSWER, {\n uid: uid,\n peerId: peerId,\n sessionId: _this._sessionParams.sessionId,\n sdpAnswer: sdpAnswer.sdp\n });\n return peerConnection.setLocalDescription(sdpAnswer)\n .then(function () {\n trace.info('_sdpOfferHandler local desc was set');\n _this._processQueuedIceCandidates(peerId);\n });\n });\n });\n })\n .catch(function (e) {\n trace.error('Error in _sdpOfferHandler', e);\n throw e;\n });\n };\n // Received by Guest after an Initiator reconnects to room\n TurnWebRtcSessionV3.prototype._userPeerReconnectHandler = function () {\n trace.info('_userPeerReconnectHandler');\n this._disconnectInternal(MediaConstants_1.MediaSessionDisconnectReason.UserPeerReconnected)\n .catch(function (error) {\n trace.warn('Error while disconnecting during userPeerReconnectHandler.', error);\n });\n };\n //#endregion WebRTC Guest - session Guest (Agent on dashboard platform)\n //#region Peer Connection\n //#region Streams Handling\n TurnWebRtcSessionV3.prototype.onMediaStreamDestroyed = function (clientRole) {\n var _this = this;\n //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation\n this._peerConnections.forEach(function (peerConnection) {\n _this._disconnectInternal(MediaConstants_1.MediaSessionDisconnectReason.PublishedStreamDestroyed).catch(function () { return undefined; });\n });\n return Promise.resolve();\n };\n TurnWebRtcSessionV3.prototype.onMediaStreamRenewed = function (clientRole, mediaStream) {\n //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation\n return Promise.resolve();\n };\n TurnWebRtcSessionV3.prototype.getRemoteTrackStats = function (mediaTrack) {\n var peerConnectionOfTrack = null;\n this._peerConnections.forEach(function (peerConnection) {\n var remoteTrack = peerConnection.remoteMediaTracks.filter(function (track) { return track.mediaTrack.id === mediaTrack.id; });\n if (remoteTrack.length === 1) {\n peerConnectionOfTrack = peerConnection;\n }\n });\n if (peerConnectionOfTrack !== null) {\n return peerConnectionOfTrack.getStats(mediaTrack);\n }\n return Promise.reject(new Error('Provided track is not remote track'));\n };\n //#endregion\n TurnWebRtcSessionV3.prototype._disconnectInternal = function (reason) {\n var _this = this;\n this._peerConnections.forEach(function (peerConnection) {\n _this._destroyPeerConnection(peerConnection);\n });\n trace.info('Disconnecting from session', reason);\n if (this._socket) {\n this._socket.off();\n this._socket.disconnect();\n }\n this._socket = null;\n setTimeout(function () { return _this._sessionHandlers.onDisconnectedHandler(reason); });\n return Promise.resolve();\n };\n TurnWebRtcSessionV3.prototype._createPeerConnection = function (peerId, peerConnectionType, peerConnectionRole) {\n var _this = this;\n if (this._peerConnections.get(peerId)) {\n throw new Error(this._sessionParams.clientType + \" peer connection for \" + peerId + \" already exists\");\n }\n var peerConnection = new RTCPeerConnection(this._configuration);\n peerConnection.peerId = peerId;\n peerConnection.peerType = peerConnectionType;\n peerConnection.remoteMediaTracks = [];\n peerConnection.peerRole = peerConnectionRole;\n peerConnection.onconnectionstatechange = function () {\n trace.info('onconnectionstatechange', peerConnection);\n };\n peerConnection.oniceconnectionstatechange = function (state) {\n trace.info(\"ICE Connection state for peer \" + peerId + \" was changed to: \" + state.currentTarget.iceConnectionState, state);\n var cnState = state.currentTarget.iceConnectionState;\n if (['closed', 'disconnected', 'failed'].indexOf(cnState) > -1) {\n _this._iceStateDisconnected(peerConnection);\n }\n };\n peerConnection.onicecandidate = function (event) {\n if (event.candidate) {\n trace.info(_this._sessionParams.clientType + \" peerConn.onicecandidate\", event.candidate);\n _this._socket.emit(TurnConstants_1.SOCKET_EVENTS.OUTGOING.ICE_CANDIDATE, {\n sessionId: _this._sessionParams.sessionId,\n peerId: peerId,\n candidate: event.candidate,\n clientType: _this._sessionParams.clientType\n });\n }\n else {\n trace.info('ICE Candidate is null in peerConnection', event);\n }\n };\n this._peerConnections.set(peerId, peerConnection);\n trace.info(peerConnectionType + \" peerConnection created\");\n return peerConnection;\n };\n TurnWebRtcSessionV3.prototype._destroyPeerConnection = function (peerConnection) {\n var _this = this;\n trace.info('Destroying PeerConnection', peerConnection.peerType);\n peerConnection.ontrack = null;\n peerConnection.onicecandidate = null;\n peerConnection.onconnectionstatechange = null;\n peerConnection.oniceconnectionstatechange = null;\n peerConnection.onicegatheringstatechange = null;\n peerConnection.remoteMediaTracks.forEach(function (remoteMediaTrack) {\n _this._sessionStreamsManager.removeMediaTrack(remoteMediaTrack.mediaTrack)\n .catch(function () {\n trace.warn('Error while removing remote media track', remoteMediaTrack);\n });\n });\n this._peerConnections.delete(peerConnection.peerId);\n peerConnection.close();\n };\n TurnWebRtcSessionV3.prototype._withPeerConnection = function (peerId, callback) {\n if (this._peerConnections.get(peerId)) {\n return callback(this._peerConnections.get(peerId));\n }\n return undefined;\n };\n //#endregion\n //#region ICE Candidates\n TurnWebRtcSessionV3.prototype._iceCandidateReceivedHandler = function (iceCandidateData) {\n var candidate = iceCandidateData.candidate, peerId = iceCandidateData.peerId;\n trace.info('_iceCandidateReceivedHandler', candidate);\n if (!candidate) {\n trace.info('Unexpected case, iceCandidate message arrived without candidate');\n return;\n }\n var peerConnection = this._peerConnections.get(peerId);\n if (!peerConnection || !peerConnection.remoteDescription) {\n trace.info('Queueing iceCandidate', candidate);\n this._queueIceCandidate(candidate, peerId);\n return;\n }\n trace.info('Going to add iceCandidate', candidate);\n this._addIceCandidateToPeer(candidate, peerConnection).catch(function () { return undefined; });\n };\n TurnWebRtcSessionV3.prototype._addIceCandidateToPeer = function (iceCandidate, peerConnection) {\n return peerConnection.addIceCandidate(iceCandidate)\n .then(function () {\n trace.info('ICE Candidate add to peer connection');\n })\n .catch(function (e) {\n trace.warn('Error adding ICE Candidate to peer connection', e);\n throw e;\n });\n };\n TurnWebRtcSessionV3.prototype._processQueuedIceCandidates = function (peerId) {\n var _this = this;\n this._withPeerConnection(peerId, function (peerConnection) {\n var pendingIces = _this._pendingPeersIce[peerId];\n if (pendingIces) {\n pendingIces.forEach(function (pendingIce) {\n trace.info('Adding pending ICE to peer connections');\n _this._addIceCandidateToPeer(pendingIce, peerConnection).catch(function () { return undefined; });\n });\n }\n else {\n trace.info('No pending ICE found for peer', peerId);\n }\n });\n };\n TurnWebRtcSessionV3.prototype._queueIceCandidate = function (iceCandidate, peerId) {\n if (!this._pendingPeersIce[peerId]) {\n this._pendingPeersIce[peerId] = [];\n }\n this._pendingPeersIce[peerId].push(iceCandidate);\n };\n TurnWebRtcSessionV3.prototype._iceStateDisconnected = function (peerConnection) {\n this._disconnectInternal(MediaConstants_1.MediaSessionDisconnectReason.PeerConnectionInterrupted).catch(function () { return undefined; });\n };\n return TurnWebRtcSessionV3;\n}());\nexports.TurnWebRtcSessionV3 = TurnWebRtcSessionV3;\n\n//# sourceMappingURL=SessionTurn.v3.js.map\n"]}
|
|
1
|
+
{"version":3,"sources":["MediaSession/SessionTurn.v3.js"],"names":["__extends","extendStatics","d","b","Object","setPrototypeOf","__proto__","Array","p","hasOwnProperty","__","constructor","prototype","create","__importStar","mod","__esModule","result","k","call","__importDefault","defineProperty","exports","value","io","require","once_1","MediaConstants_1","TurnConstants_1","MediaTracer_1","MediaSessionBase_1","trace","getMediaTracer","TurnWebRtcSessionV3","_super","sessionParams","sessionHandlers","streamFactory","_this","_sessionHandlers","_socket","_pendingPeersIce","iceServers","credentials","ice","map","item","urls","url","username","login","credential","password","_configuration","iceTransportPolicy","_joinResponseHandler","bind","_iceCandidateReceivedHandler","_sendOfferHandler","_sdpOfferHandler","_userPeerReconnectHandler","_peerDisconnectedHandler","_onSocketDisconnectedHandler","get","_sessionParams","sessionId","enumerable","configurable","connect","connectOnly","info","_connectSocket","then","emit","SOCKET_EVENTS","OUTGOING","JOIN_ROOM","clientType","catch","error","disconnect","_disconnectInternal","MediaSessionDisconnectReason","ForcedByConsumer","Promise","resolve","reject","socket","SOCKET_RECONNECTION_DELAY","SOCKET_RECONNECTION_DELAY_MAX","SOCKET_RECONNECTION_ATTEMPTS","SOCKET_PATH","done","default","err","once","on","INCOMING","ERROR","SEND_OFFER","JOIN_RESPONSE","PEER_DISCONNECTED","SDP_OFFER","PUBLISHER_RECONNECT","ICE_CANDIDATE","reason","SignalingChannelDisconnect","undefined","sendOfferEventData","uid","peerId","peerConnection","_createPeerConnection","SessionClientType","GUEST","SessionClientRole","AGENT","offerParams","offerToReceiveAudio","offerToReceiveVideo","ontrack","trackEvent","track","kind","registerMediaTrackFromPeer","_sessionStreamsManager","getMediaStreamForRole","mediaStream","getTracks","forEach","addTrack","createOffer","offerDesc","sdpOffer","sdp","setLocalDescription","e","warn","joinResponseData","sdpAnswer","_withPeerConnection","answer","RTCSessionDescription","type","setRemoteDescription","_processQueuedIceCandidates","peerDisconnectedEvent","PeerDisconnected","sdpOfferEvent","INITIATOR","USER","remoteTrack","mediaTrack","trackType","KnownMediaStream","USER_VIDEO_STREAM","USER_AUDIO_STREAM","remoteMediaTracks","push","addRemoteMediaTrack","remoteDesc","createAnswer","SDP_ANSWER","UserPeerReconnected","onMediaStreamDestroyed","clientRole","_peerConnections","PublishedStreamDestroyed","onMediaStreamRenewed","getRemoteTrackStats","peerConnectionOfTrack","getPeerConnectionByMediaTrack","getStats","Error","_destroyPeerConnection","off","setTimeout","onDisconnectedHandler","peerConnectionType","peerConnectionRole","RTCPeerConnection","peerType","peerRole","onconnectionstatechange","oniceconnectionstatechange","state","currentTarget","iceConnectionState","cnState","indexOf","_iceStateDisconnected","onicecandidate","event","candidate","set","onicegatheringstatechange","unregisterPeersRemoteMediaTracks","delete","close","callback","iceCandidateData","remoteDescription","_queueIceCandidate","_addIceCandidateToPeer","iceCandidate","addIceCandidate","pendingIces","pendingIce","PeerConnectionInterrupted","MediaSessionBase"],"mappings":"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","file":"SessionTurn.v3.js","sourcesContent":["\"use strict\";\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\n result[\"default\"] = mod;\n return result;\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar io = __importStar(require(\"socket.io-client\"));\nvar once_1 = __importDefault(require(\"lodash/once\"));\nvar MediaConstants_1 = require(\"../MediaConstants\");\nvar TurnConstants_1 = require(\"./TurnConstants\");\nvar MediaTracer_1 = require(\"../MediaUtils/MediaTracer\");\nvar MediaSessionBase_1 = require(\"./MediaSessionBase\");\nvar trace = MediaTracer_1.getMediaTracer('TurnSessionV3');\n//Currently this version supports subscribing only. Publishing will be implemented as needed.\nvar TurnWebRtcSessionV3 = /** @class */ (function (_super) {\n __extends(TurnWebRtcSessionV3, _super);\n function TurnWebRtcSessionV3(sessionParams, sessionHandlers, streamFactory) {\n var _this = _super.call(this, sessionParams, streamFactory) || this;\n _this._sessionHandlers = sessionHandlers;\n _this._socket = null;\n _this._pendingPeersIce = {};\n var iceServers = sessionParams.credentials.ice.map(function (item) { return ({\n urls: item.url,\n username: item.login,\n credential: item.password\n }); });\n _this._configuration = {\n iceServers: iceServers,\n iceTransportPolicy: 'relay'\n };\n _this._joinResponseHandler = _this._joinResponseHandler.bind(_this);\n _this._iceCandidateReceivedHandler = _this._iceCandidateReceivedHandler.bind(_this);\n _this._sendOfferHandler = _this._sendOfferHandler.bind(_this);\n _this._sdpOfferHandler = _this._sdpOfferHandler.bind(_this);\n _this._userPeerReconnectHandler = _this._userPeerReconnectHandler.bind(_this);\n _this._peerDisconnectedHandler = _this._peerDisconnectedHandler.bind(_this);\n _this._onSocketDisconnectedHandler = _this._onSocketDisconnectedHandler.bind(_this);\n return _this;\n }\n Object.defineProperty(TurnWebRtcSessionV3.prototype, \"id\", {\n get: function () {\n return this._sessionParams.sessionId;\n },\n enumerable: true,\n configurable: true\n });\n //#region Socket Connectivity\n TurnWebRtcSessionV3.prototype.connect = function (connectOnly) {\n var _this = this;\n if (connectOnly === void 0) { connectOnly = false; }\n trace.info('Connect to session');\n return this._connectSocket(this._sessionParams.credentials.url, connectOnly)\n .then(function () {\n trace.info('Joining SessionId: ' + _this._sessionParams.sessionId);\n _this._socket.emit(TurnConstants_1.SOCKET_EVENTS.OUTGOING.JOIN_ROOM, {\n clientType: _this._sessionParams.clientType,\n sessionId: _this._sessionParams.sessionId\n });\n })\n .catch(function (error) {\n throw error;\n });\n };\n TurnWebRtcSessionV3.prototype.disconnect = function () {\n return this._disconnectInternal(MediaConstants_1.MediaSessionDisconnectReason.ForcedByConsumer);\n };\n TurnWebRtcSessionV3.prototype._connectSocket = function (url, connectOnly) {\n var _this = this;\n return new Promise(function (resolve, reject) {\n var socket = _this._socket = io.connect(url, {\n 'forceNew': true,\n 'reconnectionDelay': TurnConstants_1.SOCKET_RECONNECTION_DELAY,\n 'reconnectionDelayMax': TurnConstants_1.SOCKET_RECONNECTION_DELAY_MAX,\n 'reconnectionAttempts': TurnConstants_1.SOCKET_RECONNECTION_ATTEMPTS,\n 'path': TurnConstants_1.SOCKET_PATH\n });\n var done = once_1.default(function (err) {\n err ? reject(err) : resolve();\n });\n socket.once('connect', function () { return done(); });\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.ERROR, done);\n socket.on('connect_error', done);\n socket.on('connect_timeout', done);\n socket.on('disconnect', _this._onSocketDisconnectedHandler);\n if (!connectOnly) {\n trace.info('Subscribing socket events');\n //PUBLISHING NOT SUPPORTED YET\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.SEND_OFFER, _this._sendOfferHandler);\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.JOIN_RESPONSE, _this._joinResponseHandler);\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.PEER_DISCONNECTED, _this._peerDisconnectedHandler);\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.SDP_OFFER, _this._sdpOfferHandler);\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.PUBLISHER_RECONNECT, _this._userPeerReconnectHandler);\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.ICE_CANDIDATE, _this._iceCandidateReceivedHandler);\n }\n });\n };\n TurnWebRtcSessionV3.prototype._onSocketDisconnectedHandler = function (reason) {\n if (this._socket) {\n // The initial example of differentiating between \"forced\" disconnect and \"network\" disconnect is taken from:\n // https://socket.io/docs/client-api/#Event-%E2%80%98disconnect%E2%80%99\n if (reason !== 'io server disconnect' && reason !== 'io client disconnect') {\n // the disconnection was initiated by the server or by client, you need to call (connect) manually\n this._disconnectInternal(MediaConstants_1.MediaSessionDisconnectReason.SignalingChannelDisconnect).catch(function () { return undefined; });\n }\n }\n };\n //#endregion\n //#region WebRTC Initiator - session Initiator (User on mobile device)\n // Received by Initiator, causing him to emit SDP_OFFER\n TurnWebRtcSessionV3.prototype._sendOfferHandler = function (sendOfferEventData) {\n var _this = this;\n var uid = sendOfferEventData.uid, peerId = sendOfferEventData.peerId;\n trace.info('_sendOfferHandler');\n //Currently we not support of passing role through signaling, so we assume every connection is \"AGENT\" like\n var peerConnection = this._createPeerConnection(peerId, MediaConstants_1.SessionClientType.GUEST, MediaConstants_1.SessionClientRole.AGENT);\n var offerParams = { offerToReceiveAudio: true, offerToReceiveVideo: true };\n peerConnection.ontrack = function (trackEvent) {\n var track = trackEvent.track;\n trace.info(\"MediaStreamTrack arrived from peerConnection: \" + track.kind, track);\n _this.registerMediaTrackFromPeer(peerConnection, track);\n };\n //TODO - Alex: Currently we not sending \"role\" through signaling, and by default we assume that the one who asks fot offer, is agent.\n //On later stages we can send or the client \"role\" or the list of \"streams\" that peer is interested in.\n this._sessionStreamsManager.getMediaStreamForRole(MediaConstants_1.SessionClientRole.AGENT)\n .then(function (mediaStream) {\n trace.info('_sendOfferHandler stream and peer created');\n if (mediaStream) {\n trace.info('Adding local tracks to peer connection');\n mediaStream.getTracks().forEach(function (track) {\n peerConnection.addTrack(track, mediaStream);\n trace.info(\"Local \" + track.kind + \" track added to peer connection\");\n });\n }\n else {\n trace.info('No media stream was found for publishing');\n }\n })\n .then(function () { return peerConnection.createOffer(offerParams); })\n .then(function (offerDesc) {\n trace.info('Initiator has created sdp offer', { offerDesc: offerDesc });\n _this._socket.emit(TurnConstants_1.SOCKET_EVENTS.OUTGOING.SDP_OFFER, {\n uid: uid,\n peerId: peerId,\n sessionId: _this._sessionParams.sessionId,\n sdpOffer: offerDesc.sdp\n });\n return peerConnection.setLocalDescription(offerDesc)\n .then(function () {\n trace.info('Local description was set on peerConnection', peerConnection);\n });\n })\n .catch(function (e) {\n trace.warn('Error', e);\n });\n };\n // Received by the Initiator: Indicates that publish should be started\n TurnWebRtcSessionV3.prototype._joinResponseHandler = function (joinResponseData) {\n var _this = this;\n var sdpAnswer = joinResponseData.sdpAnswer, uid = joinResponseData.uid, peerId = joinResponseData.peerId;\n trace.info('joinResponse Received', { sdpAnswer: sdpAnswer });\n this._withPeerConnection(peerId, function (peerConnection) {\n var answer = new RTCSessionDescription({\n type: 'answer',\n sdp: sdpAnswer\n });\n peerConnection.setRemoteDescription(answer)\n .then(function () {\n trace.info('Remote description was set', answer);\n _this._processQueuedIceCandidates(peerId);\n })\n .catch(function (e) {\n trace.warn('Error', e);\n });\n });\n };\n // Received by Initiator after a guests socket has been disconnected\n TurnWebRtcSessionV3.prototype._peerDisconnectedHandler = function (peerDisconnectedEvent) {\n var _this = this;\n var peerId = peerDisconnectedEvent.peerId;\n trace.info('_peerDisconnectedHandler');\n this._withPeerConnection(peerId, function (peerConnection) {\n _this._disconnectInternal(MediaConstants_1.MediaSessionDisconnectReason.PeerDisconnected).catch(function () { return undefined; });\n });\n };\n //#endregion WebRTC Initiator - session Initiator (User on mobile device)\n //#region WebRTC Guest - session Guest (Agent on dashboard platform)\n // Received by Guest, causing him to emit SDP_ANSWER\n TurnWebRtcSessionV3.prototype._sdpOfferHandler = function (sdpOfferEvent) {\n var _this = this;\n var sdpOffer = sdpOfferEvent.sdpOffer, peerId = sdpOfferEvent.peerId, uid = sdpOfferEvent.uid;\n trace.info('sdpOffer Received', { sdpOffer: sdpOffer });\n var peerConnection = this._createPeerConnection(peerId, MediaConstants_1.SessionClientType.INITIATOR, MediaConstants_1.SessionClientRole.USER);\n peerConnection.ontrack = function (trackEvent) {\n var track = trackEvent.track;\n trace.info(\"MediaStreamTrack arrived from peerConnection: \" + track.kind, track);\n var remoteTrack = {\n mediaTrack: track,\n trackType: track.kind === 'video'\n //Although we can have desktop share stream, we still name it USER_VIDEO_STREAM in dashboard.\n //Because currently we support only one video stream to be streamed at the time, it's not an issue.\n //But when we will need to stream more than one stream of a kind from single peer, this will be need to change.\n ? MediaConstants_1.KnownMediaStream.USER_VIDEO_STREAM : MediaConstants_1.KnownMediaStream.USER_AUDIO_STREAM\n };\n peerConnection.remoteMediaTracks.push(remoteTrack);\n _this._sessionStreamsManager.addRemoteMediaTrack(remoteTrack)\n .catch(function () {\n trace.warn('Error adding remote track to stream manager', remoteTrack);\n });\n };\n this._sessionStreamsManager.getMediaStreamForRole(MediaConstants_1.SessionClientRole.USER)\n .then(function (mediaStream) {\n if (mediaStream) {\n trace.info('Adding local tracks to peer connection');\n mediaStream.getTracks().forEach(function (track) {\n peerConnection.addTrack(track, mediaStream);\n trace.info(\"Local \" + track.kind + \" track added to peer connection\");\n });\n }\n else {\n trace.info('No media stream was found for publishing');\n }\n })\n .then(function () {\n var remoteDesc = new RTCSessionDescription({ type: 'offer', sdp: sdpOffer });\n return peerConnection.setRemoteDescription(remoteDesc)\n .then(function () {\n trace.info('Remote description was set', remoteDesc);\n return peerConnection.createAnswer()\n .then(function (sdpAnswer) {\n trace.info('_sdpOfferHandler answer created', sdpAnswer);\n _this._socket.emit(TurnConstants_1.SOCKET_EVENTS.OUTGOING.SDP_ANSWER, {\n uid: uid,\n peerId: peerId,\n sessionId: _this._sessionParams.sessionId,\n sdpAnswer: sdpAnswer.sdp\n });\n return peerConnection.setLocalDescription(sdpAnswer)\n .then(function () {\n trace.info('_sdpOfferHandler local desc was set');\n _this._processQueuedIceCandidates(peerId);\n });\n });\n });\n })\n .catch(function (e) {\n trace.error('Error in _sdpOfferHandler', e);\n throw e;\n });\n };\n // Received by Guest after an Initiator reconnects to room\n TurnWebRtcSessionV3.prototype._userPeerReconnectHandler = function () {\n trace.info('_userPeerReconnectHandler');\n this._disconnectInternal(MediaConstants_1.MediaSessionDisconnectReason.UserPeerReconnected)\n .catch(function (error) {\n trace.warn('Error while disconnecting during userPeerReconnectHandler.', error);\n });\n };\n //#endregion WebRTC Guest - session Guest (Agent on dashboard platform)\n //#region Peer Connection\n //#region Streams Handling\n TurnWebRtcSessionV3.prototype.onMediaStreamDestroyed = function (clientRole) {\n var _this = this;\n //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation\n this._peerConnections.forEach(function (peerConnection) {\n _this._disconnectInternal(MediaConstants_1.MediaSessionDisconnectReason.PublishedStreamDestroyed).catch(function () { return undefined; });\n });\n return Promise.resolve();\n };\n TurnWebRtcSessionV3.prototype.onMediaStreamRenewed = function (clientRole, mediaStream) {\n //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation\n return Promise.resolve();\n };\n TurnWebRtcSessionV3.prototype.getRemoteTrackStats = function (mediaTrack) {\n var peerConnectionOfTrack = this.getPeerConnectionByMediaTrack(mediaTrack);\n if (peerConnectionOfTrack !== null) {\n return peerConnectionOfTrack.getStats(mediaTrack);\n }\n return Promise.reject(new Error('Provided track is not remote track'));\n };\n //#endregion\n TurnWebRtcSessionV3.prototype._disconnectInternal = function (reason) {\n var _this = this;\n this._peerConnections.forEach(function (peerConnection) {\n _this._destroyPeerConnection(peerConnection);\n });\n trace.info('Disconnecting from session', reason);\n if (this._socket) {\n this._socket.off();\n this._socket.disconnect();\n }\n this._socket = null;\n setTimeout(function () { return _this._sessionHandlers.onDisconnectedHandler(reason); });\n return Promise.resolve();\n };\n TurnWebRtcSessionV3.prototype._createPeerConnection = function (peerId, peerConnectionType, peerConnectionRole) {\n var _this = this;\n if (this._peerConnections.get(peerId)) {\n throw new Error(this._sessionParams.clientType + \" peer connection for \" + peerId + \" already exists\");\n }\n var peerConnection = new RTCPeerConnection(this._configuration);\n peerConnection.peerId = peerId;\n peerConnection.peerType = peerConnectionType;\n peerConnection.remoteMediaTracks = [];\n peerConnection.peerRole = peerConnectionRole;\n peerConnection.onconnectionstatechange = function () {\n trace.info('onconnectionstatechange', peerConnection);\n };\n peerConnection.oniceconnectionstatechange = function (state) {\n trace.info(\"ICE Connection state for peer \" + peerId + \" was changed to: \" + state.currentTarget.iceConnectionState, state);\n var cnState = state.currentTarget.iceConnectionState;\n if (['closed', 'disconnected', 'failed'].indexOf(cnState) > -1) {\n _this._iceStateDisconnected(peerConnection);\n }\n };\n peerConnection.onicecandidate = function (event) {\n if (event.candidate) {\n trace.info(_this._sessionParams.clientType + \" peerConn.onicecandidate\", event.candidate);\n _this._socket.emit(TurnConstants_1.SOCKET_EVENTS.OUTGOING.ICE_CANDIDATE, {\n sessionId: _this._sessionParams.sessionId,\n peerId: peerId,\n candidate: event.candidate,\n clientType: _this._sessionParams.clientType\n });\n }\n else {\n trace.info('ICE Candidate is null in peerConnection', event);\n }\n };\n this._peerConnections.set(peerId, peerConnection);\n trace.info(peerConnectionType + \" peerConnection created\");\n return peerConnection;\n };\n TurnWebRtcSessionV3.prototype._destroyPeerConnection = function (peerConnection) {\n trace.info('Destroying PeerConnection', peerConnection.peerType);\n peerConnection.ontrack = null;\n peerConnection.onicecandidate = null;\n peerConnection.onconnectionstatechange = null;\n peerConnection.oniceconnectionstatechange = null;\n peerConnection.onicegatheringstatechange = null;\n this.unregisterPeersRemoteMediaTracks(peerConnection);\n this._peerConnections.delete(peerConnection.peerId);\n peerConnection.close();\n };\n TurnWebRtcSessionV3.prototype._withPeerConnection = function (peerId, callback) {\n if (this._peerConnections.get(peerId)) {\n return callback(this._peerConnections.get(peerId));\n }\n return undefined;\n };\n //#endregion\n //#region ICE Candidates\n TurnWebRtcSessionV3.prototype._iceCandidateReceivedHandler = function (iceCandidateData) {\n var candidate = iceCandidateData.candidate, peerId = iceCandidateData.peerId;\n trace.info('_iceCandidateReceivedHandler', candidate);\n if (!candidate) {\n trace.info('Unexpected case, iceCandidate message arrived without candidate');\n return;\n }\n var peerConnection = this._peerConnections.get(peerId);\n if (!peerConnection || !peerConnection.remoteDescription) {\n trace.info('Queueing iceCandidate', candidate);\n this._queueIceCandidate(candidate, peerId);\n return;\n }\n trace.info('Going to add iceCandidate', candidate);\n this._addIceCandidateToPeer(candidate, peerConnection).catch(function () { return undefined; });\n };\n TurnWebRtcSessionV3.prototype._addIceCandidateToPeer = function (iceCandidate, peerConnection) {\n return peerConnection.addIceCandidate(iceCandidate)\n .then(function () {\n trace.info('ICE Candidate add to peer connection');\n })\n .catch(function (e) {\n trace.warn('Error adding ICE Candidate to peer connection', e);\n throw e;\n });\n };\n TurnWebRtcSessionV3.prototype._processQueuedIceCandidates = function (peerId) {\n var _this = this;\n this._withPeerConnection(peerId, function (peerConnection) {\n var pendingIces = _this._pendingPeersIce[peerId];\n if (pendingIces) {\n pendingIces.forEach(function (pendingIce) {\n trace.info('Adding pending ICE to peer connections');\n _this._addIceCandidateToPeer(pendingIce, peerConnection).catch(function () { return undefined; });\n });\n }\n else {\n trace.info('No pending ICE found for peer', peerId);\n }\n });\n };\n TurnWebRtcSessionV3.prototype._queueIceCandidate = function (iceCandidate, peerId) {\n if (!this._pendingPeersIce[peerId]) {\n this._pendingPeersIce[peerId] = [];\n }\n this._pendingPeersIce[peerId].push(iceCandidate);\n };\n TurnWebRtcSessionV3.prototype._iceStateDisconnected = function (peerConnection) {\n this._disconnectInternal(MediaConstants_1.MediaSessionDisconnectReason.PeerConnectionInterrupted).catch(function () { return undefined; });\n };\n return TurnWebRtcSessionV3;\n}(MediaSessionBase_1.MediaSessionBase));\nexports.TurnWebRtcSessionV3 = TurnWebRtcSessionV3;\n\n//# sourceMappingURL=SessionTurn.v3.js.map\n"]}
|