@techsee/techsee-media-service 0.6.1-alpha.2 → 0.6.1-alpha.4
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 +19 -0
- package/lib/MediaSession/MediaSessionBase.d.ts.map +1 -0
- package/lib/MediaSession/MediaSessionBase.js +34 -0
- package/lib/MediaSession/MediaSessionBase.js.map +1 -0
- package/lib/MediaSession/SessionOpentok.v3.d.ts +2 -3
- package/lib/MediaSession/SessionOpentok.v3.d.ts.map +1 -1
- package/lib/MediaSession/SessionOpentok.v3.js +70 -25
- package/lib/MediaSession/SessionOpentok.v3.js.map +1 -1
- package/lib/MediaSession/SessionTurn.v3.d.ts +4 -13
- package/lib/MediaSession/SessionTurn.v3.d.ts.map +1 -1
- package/lib/MediaSession/SessionTurn.v3.js +38 -27
- package/lib/MediaSession/SessionTurn.v3.js.map +1 -1
- package/lib/oldCode/index.js +1 -1
- package/lib/oldCode/index.js.map +1 -1
- package/lib/qos/raw-qos.js.map +1 -0
- package/package.json +1 -1
- package/lib/oldCode/qos/raw-qos.js.map +0 -1
- /package/lib/{oldCode/qos → qos}/raw-qos.js +0 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { IMediaSessionPeer } from './MediaSessionBase';
|
|
2
|
+
import { SessionClientRole, SessionClientType } from '../MediaConstants';
|
|
3
|
+
import { ISessionStreamsManager, MediaSessionParams, RemoteMediaTrack } from '../MediaContracts';
|
|
4
|
+
export interface IMediaSessionPeer {
|
|
5
|
+
peerId: any;
|
|
6
|
+
peerType: SessionClientType;
|
|
7
|
+
peerRole: SessionClientRole;
|
|
8
|
+
remoteMediaTracks: RemoteMediaTrack[];
|
|
9
|
+
}
|
|
10
|
+
declare global {
|
|
11
|
+
interface RTCPeerConnection extends IMediaSessionPeer {
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export declare abstract class MediaSessionBase {
|
|
15
|
+
protected readonly _sessionStreamsManager: ISessionStreamsManager;
|
|
16
|
+
protected readonly _sessionParams: MediaSessionParams;
|
|
17
|
+
protected constructor(sessionParams: MediaSessionParams, streamFactory: ISessionStreamsManager);
|
|
18
|
+
protected registerMediaTrackFromPeer(sourcePeerConnection: IMediaSessionPeer, mediaTrack: MediaStreamTrack): void;
|
|
19
|
+
}
|
|
@@ -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;AAK/F,MAAM,WAAW,iBAAiB;IAC9B,MAAM,EAAE,GAAG,CAAC;IACZ,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;CACzC;AAED,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,iBAAkB,SAAQ,iBAAiB;KAEpD;CACJ;AAKD,8BAAsB,gBAAgB;IAClC,SAAS,CAAC,QAAQ,CAAC,sBAAsB,EAAE,sBAAsB,CAAC;IAClE,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,kBAAkB,CAAC;IAEtD,SAAS,aAAa,aAAa,EAAE,kBAAkB,EAAE,aAAa,EAAE,sBAAsB;IAK9F,SAAS,CAAC,0BAA0B,CAAC,oBAAoB,EAAE,iBAAiB,EAAE,UAAU,EAAE,gBAAgB;CAyB7G","file":"MediaSessionBase.d.ts","sourcesContent":["import {IMediaSessionPeer} from './MediaSessionBase';\nimport {KnownMediaStream, KnownMediaStreamKind, SessionClientRole, SessionClientType} from '../MediaConstants';\nimport {ISessionStreamsManager, MediaSessionParams, RemoteMediaTrack} from '../MediaContracts';\n\nimport {getMediaTracer} from '../MediaUtils/MediaTracer';\nimport {Nullable} from '@techsee/techsee-common';\n\nexport interface IMediaSessionPeer {\n peerId: any;\n peerType: SessionClientType;\n peerRole: SessionClientRole;\n remoteMediaTracks: RemoteMediaTrack[];\n}\n\ndeclare global {\n interface RTCPeerConnection extends IMediaSessionPeer {\n\n }\n}\n\nconst trace = getMediaTracer('MediaSessionBase');\n\n\nexport abstract class MediaSessionBase {\n protected readonly _sessionStreamsManager: ISessionStreamsManager;\n protected readonly _sessionParams: MediaSessionParams;\n\n protected constructor(sessionParams: MediaSessionParams, streamFactory: ISessionStreamsManager) {\n this._sessionParams = sessionParams;\n this._sessionStreamsManager = streamFactory;\n }\n\n protected registerMediaTrackFromPeer(sourcePeerConnection: IMediaSessionPeer, mediaTrack: MediaStreamTrack) {\n if (mediaTrack.kind === KnownMediaStreamKind.Video &&\n sourcePeerConnection.peerRole === SessionClientRole.AGENT) {\n //Currently We don't support video streams from Agent side\n return;\n }\n\n let trackType: Nullable<KnownMediaStream> = null;\n\n if (mediaTrack.kind.toLowerCase() === KnownMediaStreamKind.Audio) {\n trackType = sourcePeerConnection.peerRole === SessionClientRole.AGENT\n ? KnownMediaStream.AGENT_AUDIO_STREAM : KnownMediaStream.USER_AUDIO_STREAM;\n\n } else {\n trackType = KnownMediaStream.USER_VIDEO_STREAM;\n }\n\n const remoteMediaTrack = {mediaTrack, trackType};\n\n sourcePeerConnection.remoteMediaTracks.push(remoteMediaTrack);\n this._sessionStreamsManager.addRemoteMediaTrack(remoteMediaTrack)\n .catch((error: any) => {\n trace.warn('Error adding remote media track to available streams', error);\n });\n }\n}\n"]}
|
|
@@ -0,0 +1,34 @@
|
|
|
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._sessionParams = sessionParams;
|
|
10
|
+
this._sessionStreamsManager = streamFactory;
|
|
11
|
+
}
|
|
12
|
+
MediaSessionBase.prototype.registerMediaTrackFromPeer = function (sourcePeerConnection, mediaTrack) {
|
|
13
|
+
if (mediaTrack.kind === MediaConstants_1.KnownMediaStreamKind.Video && sourcePeerConnection.peerRole === MediaConstants_1.SessionClientRole.AGENT) {
|
|
14
|
+
//Currently We don't support video streams from Agent side
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
var trackType = null;
|
|
18
|
+
if (mediaTrack.kind.toLowerCase() === MediaConstants_1.KnownMediaStreamKind.Audio) {
|
|
19
|
+
trackType = sourcePeerConnection.peerRole === MediaConstants_1.SessionClientRole.AGENT ? MediaConstants_1.KnownMediaStream.AGENT_AUDIO_STREAM : MediaConstants_1.KnownMediaStream.USER_AUDIO_STREAM;
|
|
20
|
+
} else {
|
|
21
|
+
trackType = MediaConstants_1.KnownMediaStream.USER_VIDEO_STREAM;
|
|
22
|
+
}
|
|
23
|
+
var remoteMediaTrack = { mediaTrack: mediaTrack, trackType: trackType };
|
|
24
|
+
sourcePeerConnection.remoteMediaTracks.push(remoteMediaTrack);
|
|
25
|
+
this._sessionStreamsManager.addRemoteMediaTrack(remoteMediaTrack).catch(function (error) {
|
|
26
|
+
trace.warn('Error adding remote media track to available streams', error);
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
return MediaSessionBase;
|
|
30
|
+
}();
|
|
31
|
+
exports.MediaSessionBase = MediaSessionBase;
|
|
32
|
+
|
|
33
|
+
//# sourceMappingURL=MediaSessionBase.js.map
|
|
34
|
+
//# 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","_sessionParams","_sessionStreamsManager","prototype","registerMediaTrackFromPeer","sourcePeerConnection","mediaTrack","kind","KnownMediaStreamKind","Video","peerRole","SessionClientRole","AGENT","trackType","toLowerCase","Audio","KnownMediaStream","AGENT_AUDIO_STREAM","USER_AUDIO_STREAM","USER_VIDEO_STREAM","remoteMediaTrack","remoteMediaTracks","push","addRemoteMediaTrack","catch","error","warn"],"mappings":"AAAA;;AACAA,OAAOC,cAAP,CAAsBC,OAAtB,EAA+B,YAA/B,EAA6C,EAAEC,OAAO,IAAT,EAA7C;AACA,IAAIC,mBAAmBC,QAAQ,mBAAR,CAAvB;AACA,IAAIC,gBAAgBD,QAAQ,2BAAR,CAApB;AACA,IAAIE,QAAQD,cAAcE,cAAd,CAA6B,kBAA7B,CAAZ;AACA,IAAIC,mBAAmB,aAAe,YAAY;AAC9C,aAASA,gBAAT,CAA0BC,aAA1B,EAAyCC,aAAzC,EAAwD;AACpD,aAAKC,cAAL,GAAsBF,aAAtB;AACA,aAAKG,sBAAL,GAA8BF,aAA9B;AACH;AACDF,qBAAiBK,SAAjB,CAA2BC,0BAA3B,GAAwD,UAAUC,oBAAV,EAAgCC,UAAhC,EAA4C;AAChG,YAAIA,WAAWC,IAAX,KAAoBd,iBAAiBe,oBAAjB,CAAsCC,KAA1D,IACAJ,qBAAqBK,QAArB,KAAkCjB,iBAAiBkB,iBAAjB,CAAmCC,KADzE,EACgF;AAC5E;AACA;AACH;AACD,YAAIC,YAAY,IAAhB;AACA,YAAIP,WAAWC,IAAX,CAAgBO,WAAhB,OAAkCrB,iBAAiBe,oBAAjB,CAAsCO,KAA5E,EAAmF;AAC/EF,wBAAYR,qBAAqBK,QAArB,KAAkCjB,iBAAiBkB,iBAAjB,CAAmCC,KAArE,GACNnB,iBAAiBuB,gBAAjB,CAAkCC,kBAD5B,GACiDxB,iBAAiBuB,gBAAjB,CAAkCE,iBAD/F;AAEH,SAHD,MAIK;AACDL,wBAAYpB,iBAAiBuB,gBAAjB,CAAkCG,iBAA9C;AACH;AACD,YAAIC,mBAAmB,EAAEd,YAAYA,UAAd,EAA0BO,WAAWA,SAArC,EAAvB;AACAR,6BAAqBgB,iBAArB,CAAuCC,IAAvC,CAA4CF,gBAA5C;AACA,aAAKlB,sBAAL,CAA4BqB,mBAA5B,CAAgDH,gBAAhD,EACKI,KADL,CACW,UAAUC,KAAV,EAAiB;AACxB7B,kBAAM8B,IAAN,CAAW,sDAAX,EAAmED,KAAnE;AACH,SAHD;AAIH,KApBD;AAqBA,WAAO3B,gBAAP;AACH,CA3BqC,EAAtC;AA4BAP,QAAQO,gBAAR,GAA2BA,gBAA3B;;AAEA","file":"MediaSessionBase.js","sourcesContent":["\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar MediaConstants_1 = require(\"../MediaConstants\");\nvar MediaTracer_1 = require(\"../MediaUtils/MediaTracer\");\nvar trace = MediaTracer_1.getMediaTracer('MediaSessionBase');\nvar MediaSessionBase = /** @class */ (function () {\n function MediaSessionBase(sessionParams, streamFactory) {\n this._sessionParams = sessionParams;\n this._sessionStreamsManager = streamFactory;\n }\n MediaSessionBase.prototype.registerMediaTrackFromPeer = function (sourcePeerConnection, mediaTrack) {\n if (mediaTrack.kind === MediaConstants_1.KnownMediaStreamKind.Video &&\n sourcePeerConnection.peerRole === MediaConstants_1.SessionClientRole.AGENT) {\n //Currently We don't support video streams from Agent side\n return;\n }\n var trackType = null;\n if (mediaTrack.kind.toLowerCase() === MediaConstants_1.KnownMediaStreamKind.Audio) {\n trackType = sourcePeerConnection.peerRole === MediaConstants_1.SessionClientRole.AGENT\n ? MediaConstants_1.KnownMediaStream.AGENT_AUDIO_STREAM : MediaConstants_1.KnownMediaStream.USER_AUDIO_STREAM;\n }\n else {\n trackType = MediaConstants_1.KnownMediaStream.USER_VIDEO_STREAM;\n }\n var remoteMediaTrack = { mediaTrack: mediaTrack, trackType: trackType };\n sourcePeerConnection.remoteMediaTracks.push(remoteMediaTrack);\n this._sessionStreamsManager.addRemoteMediaTrack(remoteMediaTrack)\n .catch(function (error) {\n trace.warn('Error adding remote media track to available streams', error);\n });\n };\n return MediaSessionBase;\n}());\nexports.MediaSessionBase = MediaSessionBase;\n\n//# sourceMappingURL=MediaSessionBase.js.map\n"]}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { IMediaSession, ISessionStreamsManager, MediaSessionParams, RemoteTrackStats } from '../MediaContracts';
|
|
2
2
|
import { SessionClientRole } from '../MediaConstants';
|
|
3
|
+
import { MediaSessionBase } from './MediaSessionBase';
|
|
3
4
|
declare global {
|
|
4
5
|
interface Window {
|
|
5
6
|
OT: any;
|
|
6
7
|
}
|
|
7
8
|
}
|
|
8
|
-
export declare class OpentokSessionV3 implements IMediaSession {
|
|
9
|
-
private readonly _sessionStreamsManager;
|
|
10
|
-
private readonly _sessionParams;
|
|
9
|
+
export declare class OpentokSessionV3 extends MediaSessionBase implements IMediaSession {
|
|
11
10
|
private readonly _peerConnections;
|
|
12
11
|
private readonly _credentials;
|
|
13
12
|
private _session;
|
|
@@ -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":"AAEA,OAAO,EACH,aAAa,EACb,sBAAsB,EACtB,kBAAkB,EAElB,gBAAgB,EACnB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAmB,iBAAiB,EAAoB,MAAM,mBAAmB,CAAC;AAEzF,OAAO,EAAC,gBAAgB,EAAC,MAAM,oBAAoB,CAAC;AAKpD,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,MAAM;QACZ,EAAE,EAAE,GAAG,CAAC;KACX;CACJ;AAoDD,qBAAa,gBAAiB,SAAQ,gBAAiB,YAAW,aAAa;IAC3E,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA8C;IAC/E,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAM;IAEnC,OAAO,CAAC,QAAQ,CAA8B;aAE1C,EAAE,EAAI,MAAM;qBAIJ,SAAS;gBAIT,aAAa,EAAE,kBAAkB,EAAE,aAAa,EAAE,sBAAsB;IAkBpF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAwCxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAyB3B,sBAAsB,CAAC,UAAU,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAUpE,oBAAoB,CAAC,UAAU,EAAE,iBAAiB,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAK5F,mBAAmB,CAAC,UAAU,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAO5E,OAAO,CAAC,wBAAwB;IA0EhC,OAAO,CAAC,0BAA0B;IAalC,OAAO,CAAC,oBAAoB;IAyD5B,OAAO,CAAC,sBAAsB;IAc9B,OAAO,CAAC,yBAAyB;IAyBjC,OAAO,CAAC,wBAAwB;IAWhC,OAAO,CAAC,oBAAoB;IAsB5B,OAAO,CAAC,oBAAoB;IAI5B,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,qBAAqB;IAW7B,OAAO,CAAC,gCAAgC;CAY3C","file":"SessionOpentok.v3.d.ts","sourcesContent":["import {Nullable} from '@techsee/techsee-common';\n\nimport {\n IMediaSession,\n ISessionStreamsManager,\n MediaSessionParams,\n RemoteMediaTrack,\n RemoteTrackStats\n} from '../MediaContracts';\n\nimport {KnownMediaStream, SessionClientRole, SessionClientType} from '../MediaConstants';\nimport {throwableGuard} from '@techsee/techsee-common/lib/core/guards';\nimport {MediaSessionBase} from './MediaSessionBase';\nimport {getMediaTracer} from '../MediaUtils/MediaTracer';\n\nconst trace = getMediaTracer('OpentokSessionV3');\n\ndeclare global {\n interface Window {\n OT: any;\n }\n}\n\ninterface IOTSession {\n\n sessionId: string;\n\n connection: Nullable<OTConnection>;\n\n isConnected(): boolean;\n\n connect(token: string, cb: any): void;\n\n disconnect(): void;\n\n publish(publisher: any, cb: any): void;\n\n subscribe(stream: any, container: any, uiProps: any, doneCb: any): OTSubscriber;\n\n off(): void;\n\n on(param: string, cb: any): void;\n\n once(param: string, cb: any): void;\n}\n\ntype OTPublisher = any\n\ntype OTSubscriber = any\n\ntype OTPeerId = any\n\ninterface OTConnection {\n connectionId: string;\n}\n\ninterface OTPeerConnection {\n peerId: OTPeerId;\n peerType: SessionClientType;\n peerRole: SessionClientRole;\n remoteMediaTracks: RemoteMediaTrack[];\n localStream: Nullable<OTStreamSource>;\n connection: OTConnection;\n publisher: Nullable<OTPublisher>;\n subscriber: Nullable<OTSubscriber>;\n}\n\ninterface OTStreamSource {\n videoSource: any;\n audioSource: any;\n}\n\n//Currently this version supports subscribing only. Publishing will be implemented as needed.\nexport class OpentokSessionV3 extends MediaSessionBase implements IMediaSession {\n private readonly _peerConnections: Map<OTPeerId, OTPeerConnection> = new Map();\n private readonly _credentials: any;\n\n private _session: Nullable<IOTSession> = null;\n\n get id(): string {\n return this._session && this._session.sessionId ? this._session.sessionId : '';\n }\n\n private get ownPeerId(): string {\n return this._session && this._session.connection ? this._session.connection.connectionId : '';\n }\n\n constructor(sessionParams: MediaSessionParams, streamFactory: ISessionStreamsManager) {\n super(sessionParams, streamFactory);\n this._credentials = sessionParams.credentials;\n\n this.connect = this.connect.bind(this);\n this.disconnect = this.disconnect.bind(this);\n this.onMediaStreamDestroyed = this.onMediaStreamDestroyed.bind(this);\n this.onMediaStreamRenewed = this.onMediaStreamRenewed.bind(this);\n\n this.createStreamForPublishing = this.createStreamForPublishing.bind(this);\n this.createMediaPublisher = this.createMediaPublisher.bind(this);\n this.clearPeerConnections = this.clearPeerConnections.bind(this);\n this.connectionCreatedHandler = this.connectionCreatedHandler.bind(this);\n this.connectionDestroyedHandler = this.connectionDestroyedHandler.bind(this);\n this.streamCreatedHandler = this.streamCreatedHandler.bind(this);\n this.streamDestroyedHandler = this.streamDestroyedHandler.bind(this);\n }\n\n connect(): Promise<void> {\n trace.info('Connect to session');\n\n if (this._session) {\n trace.error('Session already exists');\n\n return Promise.reject('Cannot connect to session while another session is active');\n }\n\n return new Promise((resolve, reject) => {\n const handleError = (error: any): void => {\n this._session && this._session!.off();\n this._session = null;\n trace.error('handleConnect error:', error);\n reject(error);\n };\n\n const {apiKey, sessionId} = this._sessionParams.credentials;\n\n this._session = (window as any).OTSESSION = window.OT.initSession(apiKey, sessionId);\n\n this._session!.on('connectionCreated', this.connectionCreatedHandler);\n this._session!.on('connectionDestroyed', this.connectionDestroyedHandler);\n this._session!.on('streamCreated', this.streamCreatedHandler);\n this._session!.on('streamDestroyed', this.streamDestroyedHandler);\n\n const connectHandler = (error: any): void => {\n if (error) {\n handleError(error);\n\n return;\n }\n\n resolve();\n };\n\n this._session!.connect(this._credentials.token, connectHandler);\n });\n }\n\n disconnect(): Promise<void> {\n //TODO - Alex: Implement destroying all publishers (by opentok docs)\n //Create a method destroy publisher (or publishers can treated the same as \"peerConnections\"?\n return new Promise((resolve) => {\n trace.info('Disconnecting from session');\n const currentSession = this._session;\n\n this._session = null;\n\n this._peerConnections.forEach((peerConnection) => {\n this.destroyPeerConnection(peerConnection);\n });\n\n if (!currentSession) {\n trace.info('No active session - resolving');\n resolve();\n\n return;\n }\n currentSession.off();\n currentSession.disconnect();\n resolve();\n });\n }\n\n onMediaStreamDestroyed(clientRole: SessionClientRole): Promise<void> {\n this._peerConnections.forEach((peerConnection) => {\n if (peerConnection.peerRole === clientRole) {\n this.destroyPublisherOnPeerConnection(peerConnection);\n }\n });\n\n return Promise.resolve();\n }\n\n onMediaStreamRenewed(clientRole: SessionClientRole, mediaStream: MediaStream): Promise<void> {\n //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation (in OT API)\n return Promise.resolve();\n }\n\n getRemoteTrackStats(mediaTrack: MediaStreamTrack): Promise<RemoteTrackStats> {\n //https://tokbox.com/developer/sdks/js/reference/Subscriber.html (getStats)\n return Promise.reject(new Error('Not implemented yet'));\n }\n\n //#region OpenTok Events Handlers\n\n private connectionCreatedHandler(event: any): void {\n trace.info('connectionCreatedHandler', event);\n const {connection} = event;\n\n if (!this.sessionExistsGuard(false) || !connection) {\n return;\n }\n\n //In case we got our own connection, we have nothing to do with it\n if (connection.connectionId === this.ownPeerId) {\n return;\n }\n\n const destinationRole = this.calculateDestinationRole();\n\n this.createStreamForPublishing(destinationRole)\n .then((streams: OTStreamSource) => {\n const peerConnection: OTPeerConnection = {\n peerId: connection.connectionId,\n peerRole: destinationRole,\n peerType: this._sessionParams.clientType === SessionClientType.INITIATOR\n ? SessionClientType.GUEST : SessionClientType.INITIATOR,\n connection: connection,\n publisher: null,\n subscriber: null,\n remoteMediaTracks: [],\n localStream: streams\n };\n\n if (!streams.videoSource && !streams.audioSource) {\n trace.info('Peer connection without publisher was created', peerConnection);\n\n return peerConnection;\n }\n\n const streamName = destinationRole === SessionClientRole.USER\n ? KnownMediaStream.AGENT_AUDIO_STREAM : KnownMediaStream.USER_VIDEO_STREAM;\n\n\n return this.createMediaPublisher(streams, streamName)\n .then((publisher: OTPublisher) => {\n peerConnection.publisher = publisher;\n trace.info('Peer connection with publisher was created', peerConnection);\n\n return peerConnection;\n });\n })\n .then((peerConnection: OTPeerConnection) => {\n this._peerConnections.set(peerConnection.peerId, peerConnection);\n\n if (peerConnection.publisher) {\n return new Promise<void>((resolve, reject) => {\n trace.info('Starting publish to peerConnection.publisher');\n this._session!.publish(peerConnection.publisher, (error: any) => {\n if (error) {\n trace.error('Publish to peerConnection error', error);\n\n return reject(error);\n }\n trace.info('Publish to peerConnection success');\n\n return resolve();\n });\n });\n }\n\n return Promise.resolve();\n })\n .catch((error: any) => {\n //Need to handle fail cases during reliability\n trace.error('Error handling new peer connection', error);\n });\n }\n\n private connectionDestroyedHandler(event: any): void {\n trace.info('connectionDestroyedHandler', event);\n const {connection} = event;\n\n if (!this.sessionExistsGuard(false) || !connection) {\n return;\n }\n\n if (this._peerConnections.has(connection.connectionId)) {\n this.destroyPeerConnection(this._peerConnections.get(connection.connectionId)!);\n }\n }\n\n private streamCreatedHandler(event: any): void {\n trace.info('streamCreatedHandler', event.stream);\n const {stream} = event;\n const {connection} = stream || {connection: null};\n\n if (!this.sessionExistsGuard(false) || !stream) {\n return;\n }\n\n if (!this._peerConnections.has(connection.connectionId)) {\n trace.warn('Unexpected case, connection should exist on this stage');\n\n return;\n }\n\n const peerConnection = this._peerConnections.get(connection.connectionId)!;\n\n if (peerConnection.peerId === this.ownPeerId) {\n trace.warn('There nothing to do with stream from our own peer.');\n\n return;\n }\n\n trace.info('Subscribing the stream');\n peerConnection.subscriber = this._session!.subscribe(stream, null, null, (err: any) => {\n if (err) {\n peerConnection.subscriber = null;\n trace.warn('Error in subscriber', err);\n \n return;\n }\n\n const videoElQuery = `#${peerConnection.subscriber.id} .OT_video-element`;\n const otVideoEl = document.querySelector(videoElQuery);\n\n if (!otVideoEl) {\n trace.warn('Cannot fined OT video element');\n \n return;\n }\n\n document.getElementById(peerConnection.subscriber.id)!.style.display = 'none';\n const otMediaStream: MediaStream = (otVideoEl as any).srcObject;\n\n if (!otMediaStream) {\n trace.warn('MediaStream not found in OT video element');\n \n return;\n }\n\n trace.info('Registering remote media tracks', peerConnection.subscriber);\n otMediaStream.getTracks().forEach((mediaTrack: MediaStreamTrack) => {\n this.registerMediaTrackFromPeer(peerConnection, mediaTrack);\n });\n });\n }\n\n private streamDestroyedHandler(event: any): void {\n trace.info('streamDestroyedHandler', event);\n const {stream} = event;\n\n if (!this.sessionExistsGuard(false) || !stream) {\n return;\n }\n\n //Find peerConnection by connectionId, add remove tracks from stream\n //Register each track using addRemoteTrack\n }\n\n //#endregion\n\n private createStreamForPublishing(destinationRole: SessionClientRole): Promise<OTStreamSource> {\n trace.info('createStreamForPublishing');\n\n return this._sessionStreamsManager.getMediaStreamForRole(destinationRole)\n .then((mediaStream: Nullable<MediaStream>) => {\n\n const stream: OTStreamSource = {videoSource: null, audioSource: null};\n\n if (mediaStream) {\n trace.info('Media stream found for publishing', mediaStream);\n mediaStream.getTracks().forEach((track) => {\n if (track.kind === 'video') {\n stream.videoSource = track;\n } else if (track.kind === 'audio') {\n stream.audioSource = track;\n }\n });\n } else if (this._sessionParams.clientRole === SessionClientRole.USER) {\n trace.warn('No local media was found for publishing to destinationRole:', destinationRole);\n }\n\n return stream;\n });\n }\n\n private calculateDestinationRole(): SessionClientRole {\n if (this._sessionParams.clientRole === SessionClientRole.USER) {\n const isAgentConnected = false;\n\n\n return !isAgentConnected ? SessionClientRole.AGENT : SessionClientRole.OBSERVER;\n }\n\n return SessionClientRole.USER;\n }\n\n private createMediaPublisher(stream: OTStreamSource, streamName: string): Promise<OTPublisher> {\n const otParams = {\n videoSource: stream.videoSource ? stream.videoSource : false,\n audioSource: stream.audioSource ? stream.audioSource : false,\n publishAudio: !!stream.audioSource,\n publishVideo: !!stream.videoSource,\n showControls: false,\n name: streamName\n };\n\n return new Promise((resolve, reject) => {\n const otPublisher = window.OT.initPublisher(undefined, otParams, (error: any) => {\n if (error) {\n reject(error);\n\n return;\n }\n resolve(otPublisher);\n });\n });\n }\n\n private clearPeerConnections(): Promise<void> {\n return Promise.resolve();\n }\n\n private sessionExistsGuard(shouldThrow = true): boolean {\n const connected = !!(this._session && this._session.connection && this._session.connection.connectionId);\n\n\n return throwableGuard(connected, 'There no active session', shouldThrow);\n }\n\n private destroyPeerConnection(peerConnection: OTPeerConnection): void {\n this._peerConnections.delete(peerConnection.peerId);\n this.destroyPublisherOnPeerConnection(peerConnection);\n peerConnection.remoteMediaTracks.forEach((mediaTrack) => {\n this._sessionStreamsManager.removeMediaTrack(mediaTrack.mediaTrack)\n .catch((error: any) => {\n trace.warn('Error removing media track', error);\n });\n });\n }\n\n private destroyPublisherOnPeerConnection(peerConnection: OTPeerConnection): void {\n if (peerConnection.publisher) {\n //TODO - Alex: When destroying the publisher, OT closes the stream by himself, without we ask him.\n //So we not destroying the OT publisher right now in order to preserve our stream alive.\n //Later, we can recreate our stream as new, or manually delete \"video\" element that created by OT.\n // or we just can leave it as is :)\n //peerConnection.publisher.destroy();\n peerConnection.publisher = null;\n peerConnection.localStream = null;\n }\n }\n\n}\n\n"]}
|
|
@@ -1,29 +1,50 @@
|
|
|
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
|
-
|
|
26
|
-
|
|
32
|
+
var _this = _super.call(this, sessionParams, streamFactory) || this;
|
|
33
|
+
_this._peerConnections = new Map();
|
|
34
|
+
_this._session = null;
|
|
35
|
+
_this._credentials = sessionParams.credentials;
|
|
36
|
+
_this.connect = _this.connect.bind(_this);
|
|
37
|
+
_this.disconnect = _this.disconnect.bind(_this);
|
|
38
|
+
_this.onMediaStreamDestroyed = _this.onMediaStreamDestroyed.bind(_this);
|
|
39
|
+
_this.onMediaStreamRenewed = _this.onMediaStreamRenewed.bind(_this);
|
|
40
|
+
_this.createStreamForPublishing = _this.createStreamForPublishing.bind(_this);
|
|
41
|
+
_this.createMediaPublisher = _this.createMediaPublisher.bind(_this);
|
|
42
|
+
_this.clearPeerConnections = _this.clearPeerConnections.bind(_this);
|
|
43
|
+
_this.connectionCreatedHandler = _this.connectionCreatedHandler.bind(_this);
|
|
44
|
+
_this.connectionDestroyedHandler = _this.connectionDestroyedHandler.bind(_this);
|
|
45
|
+
_this.streamCreatedHandler = _this.streamCreatedHandler.bind(_this);
|
|
46
|
+
_this.streamDestroyedHandler = _this.streamDestroyedHandler.bind(_this);
|
|
47
|
+
return _this;
|
|
27
48
|
}
|
|
28
49
|
Object.defineProperty(OpentokSessionV3.prototype, "id", {
|
|
29
50
|
get: function get() {
|
|
@@ -76,6 +97,7 @@ var OpentokSessionV3 = /** @class */function () {
|
|
|
76
97
|
//TODO - Alex: Implement destroying all publishers (by opentok docs)
|
|
77
98
|
//Create a method destroy publisher (or publishers can treated the same as "peerConnections"?
|
|
78
99
|
return new Promise(function (resolve) {
|
|
100
|
+
trace.info('Disconnecting from session');
|
|
79
101
|
var currentSession = _this._session;
|
|
80
102
|
_this._session = null;
|
|
81
103
|
_this._peerConnections.forEach(function (peerConnection) {
|
|
@@ -128,6 +150,7 @@ var OpentokSessionV3 = /** @class */function () {
|
|
|
128
150
|
peerType: _this._sessionParams.clientType === MediaConstants_1.SessionClientType.INITIATOR ? MediaConstants_1.SessionClientType.GUEST : MediaConstants_1.SessionClientType.INITIATOR,
|
|
129
151
|
connection: connection,
|
|
130
152
|
publisher: null,
|
|
153
|
+
subscriber: null,
|
|
131
154
|
remoteMediaTracks: [],
|
|
132
155
|
localStream: streams
|
|
133
156
|
};
|
|
@@ -173,6 +196,7 @@ var OpentokSessionV3 = /** @class */function () {
|
|
|
173
196
|
}
|
|
174
197
|
};
|
|
175
198
|
OpentokSessionV3.prototype.streamCreatedHandler = function (event) {
|
|
199
|
+
var _this = this;
|
|
176
200
|
trace.info('streamCreatedHandler', event.stream);
|
|
177
201
|
var stream = event.stream;
|
|
178
202
|
var connection = (stream || { connection: null }).connection;
|
|
@@ -184,13 +208,34 @@ var OpentokSessionV3 = /** @class */function () {
|
|
|
184
208
|
return;
|
|
185
209
|
}
|
|
186
210
|
var peerConnection = this._peerConnections.get(connection.connectionId);
|
|
187
|
-
if (
|
|
188
|
-
trace.warn('
|
|
211
|
+
if (peerConnection.peerId === this.ownPeerId) {
|
|
212
|
+
trace.warn('There nothing to do with stream from our own peer.');
|
|
189
213
|
return;
|
|
190
214
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
215
|
+
trace.info('Subscribing the stream');
|
|
216
|
+
peerConnection.subscriber = this._session.subscribe(stream, null, null, function (err) {
|
|
217
|
+
if (err) {
|
|
218
|
+
peerConnection.subscriber = null;
|
|
219
|
+
trace.warn('Error in subscriber', err);
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
var videoElQuery = "#" + peerConnection.subscriber.id + " .OT_video-element";
|
|
223
|
+
var otVideoEl = document.querySelector(videoElQuery);
|
|
224
|
+
if (!otVideoEl) {
|
|
225
|
+
trace.warn('Cannot fined OT video element');
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
document.getElementById(peerConnection.subscriber.id).style.display = 'none';
|
|
229
|
+
var otMediaStream = otVideoEl.srcObject;
|
|
230
|
+
if (!otMediaStream) {
|
|
231
|
+
trace.warn('MediaStream not found in OT video element');
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
trace.info('Registering remote media tracks', peerConnection.subscriber);
|
|
235
|
+
otMediaStream.getTracks().forEach(function (mediaTrack) {
|
|
236
|
+
_this.registerMediaTrackFromPeer(peerConnection, mediaTrack);
|
|
237
|
+
});
|
|
238
|
+
});
|
|
194
239
|
};
|
|
195
240
|
OpentokSessionV3.prototype.streamDestroyedHandler = function (event) {
|
|
196
241
|
trace.info('streamDestroyedHandler', event);
|
|
@@ -280,7 +325,7 @@ var OpentokSessionV3 = /** @class */function () {
|
|
|
280
325
|
}
|
|
281
326
|
};
|
|
282
327
|
return OpentokSessionV3;
|
|
283
|
-
}();
|
|
328
|
+
}(MediaSessionBase_1.MediaSessionBase);
|
|
284
329
|
exports.OpentokSessionV3 = OpentokSessionV3;
|
|
285
330
|
|
|
286
331
|
//# 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","_peerConnections","Map","_session","_credentials","credentials","connect","bind","disconnect","onMediaStreamDestroyed","onMediaStreamRenewed","createStreamForPublishing","createMediaPublisher","clearPeerConnections","connectionCreatedHandler","connectionDestroyedHandler","streamCreatedHandler","streamDestroyedHandler","get","sessionId","enumerable","configurable","connection","connectionId","info","error","Promise","reject","resolve","handleError","off","_a","_sessionParams","apiKey","window","OTSESSION","OT","initSession","on","connectHandler","token","currentSession","forEach","peerConnection","destroyPeerConnection","clientRole","peerRole","destroyPublisherOnPeerConnection","mediaStream","getRemoteTrackStats","mediaTrack","Error","event","sessionExistsGuard","ownPeerId","destinationRole","calculateDestinationRole","then","streams","peerId","peerType","clientType","SessionClientType","INITIATOR","GUEST","publisher","subscriber","remoteMediaTracks","localStream","videoSource","audioSource","streamName","SessionClientRole","USER","KnownMediaStream","AGENT_AUDIO_STREAM","USER_VIDEO_STREAM","set","publish","catch","has","stream","warn","subscribe","err","videoElQuery","id","otVideoEl","document","querySelector","getElementById","style","display","otMediaStream","srcObject","getTracks","registerMediaTrackFromPeer","_sessionStreamsManager","getMediaStreamForRole","track","kind","isAgentConnected","AGENT","OBSERVER","otParams","publishAudio","publishVideo","showControls","name","otPublisher","initPublisher","undefined","shouldThrow","connected","throwableGuard","delete","removeMediaTrack","MediaSessionBase"],"mappings":"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","file":"SessionOpentok.v3.js","sourcesContent":["\"use strict\";\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar MediaConstants_1 = require(\"../MediaConstants\");\nvar guards_1 = require(\"@techsee/techsee-common/lib/core/guards\");\nvar MediaSessionBase_1 = require(\"./MediaSessionBase\");\nvar MediaTracer_1 = require(\"../MediaUtils/MediaTracer\");\nvar trace = MediaTracer_1.getMediaTracer('OpentokSessionV3');\n//Currently this version supports subscribing only. Publishing will be implemented as needed.\nvar OpentokSessionV3 = /** @class */ (function (_super) {\n __extends(OpentokSessionV3, _super);\n function OpentokSessionV3(sessionParams, streamFactory) {\n var _this = _super.call(this, sessionParams, streamFactory) || this;\n _this._peerConnections = new Map();\n _this._session = null;\n _this._credentials = sessionParams.credentials;\n _this.connect = _this.connect.bind(_this);\n _this.disconnect = _this.disconnect.bind(_this);\n _this.onMediaStreamDestroyed = _this.onMediaStreamDestroyed.bind(_this);\n _this.onMediaStreamRenewed = _this.onMediaStreamRenewed.bind(_this);\n _this.createStreamForPublishing = _this.createStreamForPublishing.bind(_this);\n _this.createMediaPublisher = _this.createMediaPublisher.bind(_this);\n _this.clearPeerConnections = _this.clearPeerConnections.bind(_this);\n _this.connectionCreatedHandler = _this.connectionCreatedHandler.bind(_this);\n _this.connectionDestroyedHandler = _this.connectionDestroyedHandler.bind(_this);\n _this.streamCreatedHandler = _this.streamCreatedHandler.bind(_this);\n _this.streamDestroyedHandler = _this.streamDestroyedHandler.bind(_this);\n return _this;\n }\n Object.defineProperty(OpentokSessionV3.prototype, \"id\", {\n get: function () {\n return this._session && this._session.sessionId ? this._session.sessionId : '';\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(OpentokSessionV3.prototype, \"ownPeerId\", {\n get: function () {\n return this._session && this._session.connection ? this._session.connection.connectionId : '';\n },\n enumerable: true,\n configurable: true\n });\n OpentokSessionV3.prototype.connect = function () {\n var _this = this;\n trace.info('Connect to session');\n if (this._session) {\n trace.error('Session already exists');\n return Promise.reject('Cannot connect to session while another session is active');\n }\n return new Promise(function (resolve, reject) {\n var handleError = function (error) {\n _this._session && _this._session.off();\n _this._session = null;\n trace.error('handleConnect error:', error);\n reject(error);\n };\n var _a = _this._sessionParams.credentials, apiKey = _a.apiKey, sessionId = _a.sessionId;\n _this._session = window.OTSESSION = window.OT.initSession(apiKey, sessionId);\n _this._session.on('connectionCreated', _this.connectionCreatedHandler);\n _this._session.on('connectionDestroyed', _this.connectionDestroyedHandler);\n _this._session.on('streamCreated', _this.streamCreatedHandler);\n _this._session.on('streamDestroyed', _this.streamDestroyedHandler);\n var connectHandler = function (error) {\n if (error) {\n handleError(error);\n return;\n }\n resolve();\n };\n _this._session.connect(_this._credentials.token, connectHandler);\n });\n };\n OpentokSessionV3.prototype.disconnect = function () {\n var _this = this;\n //TODO - Alex: Implement destroying all publishers (by opentok docs)\n //Create a method destroy publisher (or publishers can treated the same as \"peerConnections\"?\n return new Promise(function (resolve) {\n trace.info('Disconnecting from session');\n var currentSession = _this._session;\n _this._session = null;\n _this._peerConnections.forEach(function (peerConnection) {\n _this.destroyPeerConnection(peerConnection);\n });\n if (!currentSession) {\n trace.info('No active session - resolving');\n resolve();\n return;\n }\n currentSession.off();\n currentSession.disconnect();\n resolve();\n });\n };\n OpentokSessionV3.prototype.onMediaStreamDestroyed = function (clientRole) {\n var _this = this;\n this._peerConnections.forEach(function (peerConnection) {\n if (peerConnection.peerRole === clientRole) {\n _this.destroyPublisherOnPeerConnection(peerConnection);\n }\n });\n return Promise.resolve();\n };\n OpentokSessionV3.prototype.onMediaStreamRenewed = function (clientRole, mediaStream) {\n //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation (in OT API)\n return Promise.resolve();\n };\n OpentokSessionV3.prototype.getRemoteTrackStats = function (mediaTrack) {\n //https://tokbox.com/developer/sdks/js/reference/Subscriber.html (getStats)\n return Promise.reject(new Error('Not implemented yet'));\n };\n //#region OpenTok Events Handlers\n OpentokSessionV3.prototype.connectionCreatedHandler = function (event) {\n var _this = this;\n trace.info('connectionCreatedHandler', event);\n var connection = event.connection;\n if (!this.sessionExistsGuard(false) || !connection) {\n return;\n }\n //In case we got our own connection, we have nothing to do with it\n if (connection.connectionId === this.ownPeerId) {\n return;\n }\n var destinationRole = this.calculateDestinationRole();\n this.createStreamForPublishing(destinationRole)\n .then(function (streams) {\n var peerConnection = {\n peerId: connection.connectionId,\n peerRole: destinationRole,\n peerType: _this._sessionParams.clientType === MediaConstants_1.SessionClientType.INITIATOR\n ? MediaConstants_1.SessionClientType.GUEST : MediaConstants_1.SessionClientType.INITIATOR,\n connection: connection,\n publisher: null,\n subscriber: null,\n remoteMediaTracks: [],\n localStream: streams\n };\n if (!streams.videoSource && !streams.audioSource) {\n trace.info('Peer connection without publisher was created', peerConnection);\n return peerConnection;\n }\n var streamName = destinationRole === MediaConstants_1.SessionClientRole.USER\n ? MediaConstants_1.KnownMediaStream.AGENT_AUDIO_STREAM : MediaConstants_1.KnownMediaStream.USER_VIDEO_STREAM;\n return _this.createMediaPublisher(streams, streamName)\n .then(function (publisher) {\n peerConnection.publisher = publisher;\n trace.info('Peer connection with publisher was created', peerConnection);\n return peerConnection;\n });\n })\n .then(function (peerConnection) {\n _this._peerConnections.set(peerConnection.peerId, peerConnection);\n if (peerConnection.publisher) {\n return new Promise(function (resolve, reject) {\n trace.info('Starting publish to peerConnection.publisher');\n _this._session.publish(peerConnection.publisher, function (error) {\n if (error) {\n trace.error('Publish to peerConnection error', error);\n return reject(error);\n }\n trace.info('Publish to peerConnection success');\n return resolve();\n });\n });\n }\n return Promise.resolve();\n })\n .catch(function (error) {\n //Need to handle fail cases during reliability\n trace.error('Error handling new peer connection', error);\n });\n };\n OpentokSessionV3.prototype.connectionDestroyedHandler = function (event) {\n trace.info('connectionDestroyedHandler', event);\n var connection = event.connection;\n if (!this.sessionExistsGuard(false) || !connection) {\n return;\n }\n if (this._peerConnections.has(connection.connectionId)) {\n this.destroyPeerConnection(this._peerConnections.get(connection.connectionId));\n }\n };\n OpentokSessionV3.prototype.streamCreatedHandler = function (event) {\n var _this = this;\n trace.info('streamCreatedHandler', event.stream);\n var stream = event.stream;\n var connection = (stream || { connection: null }).connection;\n if (!this.sessionExistsGuard(false) || !stream) {\n return;\n }\n if (!this._peerConnections.has(connection.connectionId)) {\n trace.warn('Unexpected case, connection should exist on this stage');\n return;\n }\n var peerConnection = this._peerConnections.get(connection.connectionId);\n if (peerConnection.peerId === this.ownPeerId) {\n trace.warn('There nothing to do with stream from our own peer.');\n return;\n }\n trace.info('Subscribing the stream');\n peerConnection.subscriber = this._session.subscribe(stream, null, null, function (err) {\n if (err) {\n peerConnection.subscriber = null;\n trace.warn('Error in subscriber', err);\n return;\n }\n var videoElQuery = \"#\" + peerConnection.subscriber.id + \" .OT_video-element\";\n var otVideoEl = document.querySelector(videoElQuery);\n if (!otVideoEl) {\n trace.warn('Cannot fined OT video element');\n return;\n }\n document.getElementById(peerConnection.subscriber.id).style.display = 'none';\n var otMediaStream = otVideoEl.srcObject;\n if (!otMediaStream) {\n trace.warn('MediaStream not found in OT video element');\n return;\n }\n trace.info('Registering remote media tracks', peerConnection.subscriber);\n otMediaStream.getTracks().forEach(function (mediaTrack) {\n _this.registerMediaTrackFromPeer(peerConnection, mediaTrack);\n });\n });\n };\n OpentokSessionV3.prototype.streamDestroyedHandler = function (event) {\n trace.info('streamDestroyedHandler', event);\n var stream = event.stream;\n if (!this.sessionExistsGuard(false) || !stream) {\n return;\n }\n //Find peerConnection by connectionId, add remove tracks from stream\n //Register each track using addRemoteTrack\n };\n //#endregion\n OpentokSessionV3.prototype.createStreamForPublishing = function (destinationRole) {\n var _this = this;\n trace.info('createStreamForPublishing');\n return this._sessionStreamsManager.getMediaStreamForRole(destinationRole)\n .then(function (mediaStream) {\n var stream = { videoSource: null, audioSource: null };\n if (mediaStream) {\n trace.info('Media stream found for publishing', mediaStream);\n mediaStream.getTracks().forEach(function (track) {\n if (track.kind === 'video') {\n stream.videoSource = track;\n }\n else if (track.kind === 'audio') {\n stream.audioSource = track;\n }\n });\n }\n else if (_this._sessionParams.clientRole === MediaConstants_1.SessionClientRole.USER) {\n trace.warn('No local media was found for publishing to destinationRole:', destinationRole);\n }\n return stream;\n });\n };\n OpentokSessionV3.prototype.calculateDestinationRole = function () {\n if (this._sessionParams.clientRole === MediaConstants_1.SessionClientRole.USER) {\n var isAgentConnected = false;\n return !isAgentConnected ? MediaConstants_1.SessionClientRole.AGENT : MediaConstants_1.SessionClientRole.OBSERVER;\n }\n return MediaConstants_1.SessionClientRole.USER;\n };\n OpentokSessionV3.prototype.createMediaPublisher = function (stream, streamName) {\n var otParams = {\n videoSource: stream.videoSource ? stream.videoSource : false,\n audioSource: stream.audioSource ? stream.audioSource : false,\n publishAudio: !!stream.audioSource,\n publishVideo: !!stream.videoSource,\n showControls: false,\n name: streamName\n };\n return new Promise(function (resolve, reject) {\n var otPublisher = window.OT.initPublisher(undefined, otParams, function (error) {\n if (error) {\n reject(error);\n return;\n }\n resolve(otPublisher);\n });\n });\n };\n OpentokSessionV3.prototype.clearPeerConnections = function () {\n return Promise.resolve();\n };\n OpentokSessionV3.prototype.sessionExistsGuard = function (shouldThrow) {\n if (shouldThrow === void 0) { shouldThrow = true; }\n var connected = !!(this._session && this._session.connection && this._session.connection.connectionId);\n return guards_1.throwableGuard(connected, 'There no active session', shouldThrow);\n };\n OpentokSessionV3.prototype.destroyPeerConnection = function (peerConnection) {\n var _this = this;\n this._peerConnections.delete(peerConnection.peerId);\n this.destroyPublisherOnPeerConnection(peerConnection);\n peerConnection.remoteMediaTracks.forEach(function (mediaTrack) {\n _this._sessionStreamsManager.removeMediaTrack(mediaTrack.mediaTrack)\n .catch(function (error) {\n trace.warn('Error removing media track', error);\n });\n });\n };\n OpentokSessionV3.prototype.destroyPublisherOnPeerConnection = function (peerConnection) {\n if (peerConnection.publisher) {\n //TODO - Alex: When destroying the publisher, OT closes the stream by himself, without we ask him.\n //So we not destroying the OT publisher right now in order to preserve our stream alive.\n //Later, we can recreate our stream as new, or manually delete \"video\" element that created by OT.\n // or we just can leave it as is :)\n //peerConnection.publisher.destroy();\n peerConnection.publisher = null;\n peerConnection.localStream = null;\n }\n };\n return OpentokSessionV3;\n}(MediaSessionBase_1.MediaSessionBase));\nexports.OpentokSessionV3 = OpentokSessionV3;\n\n//# sourceMappingURL=SessionOpentok.v3.js.map\n"]}
|
|
@@ -1,16 +1,7 @@
|
|
|
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 implements IMediaSession {
|
|
14
5
|
private readonly _sessionHandlers;
|
|
15
6
|
private readonly _pendingPeersIce;
|
|
16
7
|
private readonly _peerConnections;
|
|
@@ -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,gBAAiB,YAAW,aAAa;IAC9E,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAuB;IACxD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAM;IACvC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAM;IACvC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAM;IACrC,OAAO,CAAC,OAAO,CAAM;aAEjB,EAAE,EAAI,MAAM;gBAIJ,aAAa,EAAE,kBAAkB,EAAE,eAAe,EAAE,oBAAoB,EAAE,aAAa,EAAE,sBAAsB;IA6B3H,OAAO,CAAC,WAAW,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB3C,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAkChE,4BAA4B,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAgBlD,iBAAiB,CAAC,kBAAkB,EAAE,GAAG,GAAG,IAAI;IAsDhD,oBAAoB,CAAC,gBAAgB,EAAE,GAAG,GAAG,IAAI;IAwBjD,wBAAwB,CAAC,qBAAqB,EAAE,GAAG,GAAG,IAAI;IAe1D,gBAAgB,CAAC,aAAa,EAAE,GAAG,GAAG,IAAI;IA2E1C,yBAAyB,IAAI,IAAI;IAcjC,sBAAsB,CAAC,UAAU,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IASpE,oBAAoB,CAAC,UAAU,EAAE,iBAAiB,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAK5F,mBAAmB,CAAC,UAAU,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAoB5E,OAAO,CAAC,mBAAmB;IAkB3B,OAAO,CAAC,qBAAqB;IA8C7B,OAAO,CAAC,sBAAsB;IAmB9B,OAAO,CAAC,mBAAmB;IAY3B,4BAA4B,CAAC,gBAAgB,EAAE,GAAG,GAAG,IAAI;IAuBzD,sBAAsB,CAAC,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAWvG,2BAA2B,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAejD,kBAAkB,CAAC,YAAY,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAQvE,qBAAqB,CAAC,cAAc,EAAE,iBAAiB,GAAG,IAAI;CAKjE","file":"SessionTurn.v3.d.ts","sourcesContent":["import * as io from 'socket.io-client';\nimport once from 'lodash/once';\nimport {Nullable} from '@techsee/techsee-common';\n\nimport {\n IMediaSession,\n ISessionStreamsManager,\n MediaSessionHandlers,\n MediaSessionParams,\n RemoteMediaTrack, RemoteTrackStats\n} from '../MediaContracts';\n\nimport {\n KnownMediaStream,\n MediaSessionDisconnectReason,\n SessionClientRole,\n SessionClientType\n} from '../MediaConstants';\n\nimport {\n SOCKET_EVENTS, SOCKET_PATH,\n SOCKET_RECONNECTION_ATTEMPTS,\n SOCKET_RECONNECTION_DELAY,\n SOCKET_RECONNECTION_DELAY_MAX\n} from './TurnConstants';\n\nimport {getMediaTracer} from '../MediaUtils/MediaTracer';\nimport {MediaSessionBase} from './MediaSessionBase';\n\nconst trace = getMediaTracer('TurnSessionV3');\n\n//Currently this version supports subscribing only. Publishing will be implemented as needed.\nexport class TurnWebRtcSessionV3 extends MediaSessionBase implements IMediaSession {\n private readonly _sessionHandlers: MediaSessionHandlers;\n private readonly _pendingPeersIce: any;\n private readonly _peerConnections: any;\n private readonly _configuration: any;\n private _socket: any;\n\n get id(): string {\n return this._sessionParams.sessionId;\n }\n\n constructor(sessionParams: MediaSessionParams, sessionHandlers: MediaSessionHandlers, streamFactory: ISessionStreamsManager) {\n super(sessionParams, streamFactory);\n this._sessionHandlers = sessionHandlers;\n this._socket = null;\n this._pendingPeersIce = {};\n this._peerConnections = new Map();\n\n const iceServers = sessionParams.credentials.ice.map((item: any) => ({\n urls: item.url,\n username: item.login,\n credential: item.password\n }));\n\n this._configuration = {\n iceServers,\n iceTransportPolicy: 'relay'\n };\n\n this._joinResponseHandler = this._joinResponseHandler.bind(this);\n this._iceCandidateReceivedHandler = this._iceCandidateReceivedHandler.bind(this);\n this._sendOfferHandler = this._sendOfferHandler.bind(this);\n this._sdpOfferHandler = this._sdpOfferHandler.bind(this);\n this._userPeerReconnectHandler = this._userPeerReconnectHandler.bind(this);\n this._peerDisconnectedHandler = this._peerDisconnectedHandler.bind(this);\n this._onSocketDisconnectedHandler = this._onSocketDisconnectedHandler.bind(this);\n }\n\n //#region Socket Connectivity\n\n connect(connectOnly = false): Promise<void> {\n trace.info('Connect to session');\n\n return this._connectSocket(this._sessionParams.credentials.url, connectOnly)\n .then(() => {\n trace.info('Joining SessionId: ' + this._sessionParams.sessionId);\n\n this._socket.emit(SOCKET_EVENTS.OUTGOING.JOIN_ROOM, {\n clientType: this._sessionParams.clientType,\n sessionId: this._sessionParams.sessionId\n });\n })\n .catch((error) => {\n throw error;\n });\n }\n\n disconnect(): Promise<void> {\n return this._disconnectInternal(MediaSessionDisconnectReason.ForcedByConsumer);\n }\n\n _connectSocket(url: string, connectOnly: boolean): Promise<void> {\n return new Promise((resolve, reject) => {\n const socket = this._socket = io.connect(url, {\n 'forceNew': true,\n 'reconnectionDelay': SOCKET_RECONNECTION_DELAY,\n 'reconnectionDelayMax': SOCKET_RECONNECTION_DELAY_MAX,\n 'reconnectionAttempts': SOCKET_RECONNECTION_ATTEMPTS,\n 'path': SOCKET_PATH\n });\n\n const done = once((err?: any) => {\n err ? reject(err) : resolve();\n });\n\n socket.once('connect', () => done());\n socket.on(SOCKET_EVENTS.INCOMING.ERROR, done);\n socket.on('connect_error', done);\n socket.on('connect_timeout', done);\n socket.on('disconnect', this._onSocketDisconnectedHandler);\n\n if (!connectOnly) {\n trace.info('Subscribing socket events');\n\n //PUBLISHING NOT SUPPORTED YET\n socket.on(SOCKET_EVENTS.INCOMING.SEND_OFFER, this._sendOfferHandler);\n socket.on(SOCKET_EVENTS.INCOMING.JOIN_RESPONSE, this._joinResponseHandler);\n socket.on(SOCKET_EVENTS.INCOMING.PEER_DISCONNECTED, this._peerDisconnectedHandler);\n socket.on(SOCKET_EVENTS.INCOMING.SDP_OFFER, this._sdpOfferHandler);\n socket.on(SOCKET_EVENTS.INCOMING.PUBLISHER_RECONNECT, this._userPeerReconnectHandler);\n socket.on(SOCKET_EVENTS.INCOMING.ICE_CANDIDATE, this._iceCandidateReceivedHandler);\n }\n });\n }\n\n _onSocketDisconnectedHandler(reason: string): void {\n if (this._socket) {\n // The initial example of differentiating between \"forced\" disconnect and \"network\" disconnect is taken from:\n // https://socket.io/docs/client-api/#Event-%E2%80%98disconnect%E2%80%99\n if (reason !== 'io server disconnect' && reason !== 'io client disconnect') {\n // the disconnection was initiated by the server or by client, you need to call (connect) manually\n this._disconnectInternal(MediaSessionDisconnectReason.SignalingChannelDisconnect).catch(() => undefined);\n }\n }\n }\n\n //#endregion\n\n //#region WebRTC Initiator - session Initiator (User on mobile device)\n\n // Received by Initiator, causing him to emit SDP_OFFER\n _sendOfferHandler(sendOfferEventData: any): void {\n const {uid, peerId} = sendOfferEventData;\n\n trace.info('_sendOfferHandler');\n\n //Currently we not support of passing role through signaling, so we assume every connection is \"AGENT\" like\n const peerConnection = this._createPeerConnection(peerId, SessionClientType.GUEST, SessionClientRole.AGENT);\n const offerParams = {offerToReceiveAudio: true, offerToReceiveVideo: true};\n\n peerConnection.ontrack = (trackEvent: any) => {\n const track: MediaStreamTrack = trackEvent.track;\n\n trace.info(`MediaStreamTrack arrived from peerConnection: ${track.kind}`, track);\n this.registerMediaTrackFromPeer(peerConnection, track);\n };\n\n //TODO - Alex: Currently we not sending \"role\" through signaling, and by default we assume that the one who asks fot offer, is agent.\n //On later stages we can send or the client \"role\" or the list of \"streams\" that peer is interested in.\n this._sessionStreamsManager.getMediaStreamForRole(SessionClientRole.AGENT)\n .then((mediaStream: Nullable<MediaStream>) => {\n trace.info('_sendOfferHandler stream and peer created');\n\n if (mediaStream) {\n trace.info('Adding local tracks to peer connection');\n mediaStream.getTracks().forEach((track) => {\n peerConnection.addTrack(track, mediaStream);\n trace.info(`Local ${track.kind} track added to peer connection`);\n });\n } else {\n trace.info('No media stream was found for publishing');\n }\n })\n .then(() => peerConnection.createOffer(offerParams))\n .then((offerDesc) => {\n trace.info('Initiator has created sdp offer', {offerDesc});\n\n this._socket.emit(SOCKET_EVENTS.OUTGOING.SDP_OFFER, {\n uid,\n peerId,\n sessionId: this._sessionParams.sessionId,\n sdpOffer: offerDesc.sdp\n });\n\n return peerConnection.setLocalDescription(offerDesc)\n .then(() => {\n trace.info('Local description was set on peerConnection', peerConnection);\n });\n })\n .catch((e) => {\n trace.warn('Error', e);\n });\n }\n\n // Received by the Initiator: Indicates that publish should be started\n _joinResponseHandler(joinResponseData: any): void {\n const {sdpAnswer, uid, peerId} = joinResponseData;\n\n trace.info('joinResponse Received', {sdpAnswer});\n\n this._withPeerConnection(peerId, (peerConnection: RTCPeerConnection) => {\n const answer = new RTCSessionDescription({\n type: 'answer',\n sdp: sdpAnswer\n });\n\n peerConnection.setRemoteDescription(answer)\n .then(() => {\n trace.info('Remote description was set', answer);\n\n this._processQueuedIceCandidates(peerId);\n })\n .catch((e) => {\n trace.warn('Error', e);\n });\n });\n }\n\n // Received by Initiator after a guests socket has been disconnected\n _peerDisconnectedHandler(peerDisconnectedEvent: any): void {\n const {peerId} = peerDisconnectedEvent;\n\n trace.info('_peerDisconnectedHandler');\n\n this._withPeerConnection(peerId, (peerConnection: any) => {\n this._disconnectInternal(MediaSessionDisconnectReason.PeerDisconnected).catch(() => undefined);\n });\n }\n\n //#endregion WebRTC Initiator - session Initiator (User on mobile device)\n\n //#region WebRTC Guest - session Guest (Agent on dashboard platform)\n\n // Received by Guest, causing him to emit SDP_ANSWER\n _sdpOfferHandler(sdpOfferEvent: any): void {\n const {sdpOffer, peerId, uid} = sdpOfferEvent;\n\n trace.info('sdpOffer Received', {sdpOffer});\n\n const peerConnection = this._createPeerConnection(peerId, SessionClientType.INITIATOR, SessionClientRole.USER);\n\n peerConnection.ontrack = (trackEvent: any) => {\n const {track} = trackEvent;\n\n trace.info(`MediaStreamTrack arrived from peerConnection: ${track.kind}`, track);\n\n const remoteTrack: RemoteMediaTrack = {\n mediaTrack: track,\n trackType: track.kind === 'video'\n //Although we can have desktop share stream, we still name it USER_VIDEO_STREAM in dashboard.\n //Because currently we support only one video stream to be streamed at the time, it's not an issue.\n //But when we will need to stream more than one stream of a kind from single peer, this will be need to change.\n ? KnownMediaStream.USER_VIDEO_STREAM : KnownMediaStream.USER_AUDIO_STREAM\n };\n\n peerConnection.remoteMediaTracks.push(remoteTrack);\n this._sessionStreamsManager.addRemoteMediaTrack(remoteTrack)\n .catch(() => {\n trace.warn('Error adding remote track to stream manager', remoteTrack);\n });\n };\n\n this._sessionStreamsManager.getMediaStreamForRole(SessionClientRole.USER)\n .then((mediaStream: Nullable<MediaStream>) => {\n if (mediaStream) {\n trace.info('Adding local tracks to peer connection');\n mediaStream.getTracks().forEach((track) => {\n peerConnection.addTrack(track, mediaStream);\n trace.info(`Local ${track.kind} track added to peer connection`);\n });\n } else {\n trace.info('No media stream was found for publishing');\n }\n })\n .then(() => {\n const remoteDesc = new RTCSessionDescription({type: 'offer', sdp: sdpOffer});\n\n return peerConnection.setRemoteDescription(remoteDesc)\n .then(() => {\n trace.info('Remote description was set', remoteDesc);\n\n return peerConnection.createAnswer()\n .then((sdpAnswer) => {\n trace.info('_sdpOfferHandler answer created', sdpAnswer);\n\n this._socket.emit(SOCKET_EVENTS.OUTGOING.SDP_ANSWER, {\n uid,\n peerId,\n sessionId: this._sessionParams.sessionId,\n sdpAnswer: sdpAnswer.sdp\n });\n\n return peerConnection.setLocalDescription(sdpAnswer)\n .then(() => {\n trace.info('_sdpOfferHandler local desc was set');\n\n this._processQueuedIceCandidates(peerId);\n });\n });\n });\n\n })\n .catch((e) => {\n trace.error('Error in _sdpOfferHandler', e);\n throw e;\n });\n }\n\n // Received by Guest after an Initiator reconnects to room\n _userPeerReconnectHandler(): void {\n trace.info('_userPeerReconnectHandler');\n this._disconnectInternal(MediaSessionDisconnectReason.UserPeerReconnected)\n .catch((error: any) => {\n trace.warn('Error while disconnecting during userPeerReconnectHandler.', error);\n });\n }\n\n //#endregion WebRTC Guest - session Guest (Agent on dashboard platform)\n\n //#region Peer Connection\n\n //#region Streams Handling\n\n onMediaStreamDestroyed(clientRole: SessionClientRole): Promise<void> {\n //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation\n this._peerConnections.forEach((peerConnection: RTCPeerConnection) => {\n this._disconnectInternal(MediaSessionDisconnectReason.PublishedStreamDestroyed).catch(() => undefined);\n });\n\n return Promise.resolve();\n }\n\n onMediaStreamRenewed(clientRole: SessionClientRole, mediaStream: MediaStream): Promise<void> {\n //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation\n return Promise.resolve();\n }\n\n getRemoteTrackStats(mediaTrack: MediaStreamTrack): Promise<RemoteTrackStats> {\n let peerConnectionOfTrack: Nullable<RTCPeerConnection> = null;\n\n this._peerConnections.forEach((peerConnection: RTCPeerConnection) => {\n const remoteTrack = peerConnection.remoteMediaTracks.filter((track) => track.mediaTrack.id === mediaTrack.id);\n\n if (remoteTrack.length === 1) {\n peerConnectionOfTrack = peerConnection;\n }\n });\n\n if (peerConnectionOfTrack !== null) {\n return (peerConnectionOfTrack as any).getStats(mediaTrack);\n }\n\n return Promise.reject(new Error('Provided track is not remote track'));\n }\n\n //#endregion\n\n private _disconnectInternal(reason: MediaSessionDisconnectReason): Promise<void> {\n this._peerConnections.forEach((peerConnection: RTCPeerConnection) => {\n this._destroyPeerConnection(peerConnection);\n });\n\n trace.info('Disconnecting from session', reason);\n\n if (this._socket) {\n this._socket.off();\n this._socket.disconnect();\n }\n\n this._socket = null;\n setTimeout(() => this._sessionHandlers.onDisconnectedHandler(reason));\n\n return Promise.resolve();\n }\n\n private _createPeerConnection(peerId: string, peerConnectionType: SessionClientType, peerConnectionRole: SessionClientRole): RTCPeerConnection {\n if (this._peerConnections.get(peerId)) {\n throw new Error(`${this._sessionParams.clientType} peer connection for ${peerId} already exists`);\n }\n\n const peerConnection: any = new RTCPeerConnection(this._configuration);\n\n peerConnection.peerId = peerId;\n peerConnection.peerType = peerConnectionType;\n peerConnection.remoteMediaTracks = [];\n peerConnection.peerRole = peerConnectionRole;\n\n peerConnection.onconnectionstatechange = () => {\n trace.info('onconnectionstatechange', peerConnection);\n };\n\n peerConnection.oniceconnectionstatechange = (state: any) => {\n trace.info(`ICE Connection state for peer ${peerId} was changed to: ${state.currentTarget.iceConnectionState}`, state);\n const cnState = state.currentTarget.iceConnectionState;\n\n if (['closed', 'disconnected', 'failed'].indexOf(cnState) > -1) {\n this._iceStateDisconnected(peerConnection);\n }\n };\n\n peerConnection.onicecandidate = (event: any) => {\n if (event.candidate) {\n trace.info(`${this._sessionParams.clientType} peerConn.onicecandidate`, event.candidate);\n this._socket.emit(SOCKET_EVENTS.OUTGOING.ICE_CANDIDATE, {\n sessionId: this._sessionParams.sessionId,\n peerId: peerId,\n candidate: event.candidate,\n clientType: this._sessionParams.clientType\n });\n } else {\n trace.info('ICE Candidate is null in peerConnection', event);\n }\n };\n\n this._peerConnections.set(peerId, peerConnection);\n\n trace.info(`${peerConnectionType} peerConnection created`);\n\n return peerConnection;\n }\n\n private _destroyPeerConnection(peerConnection: RTCPeerConnection): void {\n trace.info('Destroying PeerConnection', peerConnection.peerType);\n peerConnection.ontrack = null;\n peerConnection.onicecandidate = null;\n peerConnection.onconnectionstatechange = null;\n peerConnection.oniceconnectionstatechange = null;\n peerConnection.onicegatheringstatechange = null;\n\n peerConnection.remoteMediaTracks.forEach((remoteMediaTrack) => {\n this._sessionStreamsManager.removeMediaTrack(remoteMediaTrack.mediaTrack)\n .catch(() => {\n trace.warn('Error while removing remote media track', remoteMediaTrack);\n });\n });\n\n this._peerConnections.delete(peerConnection.peerId);\n peerConnection.close();\n }\n\n private _withPeerConnection(peerId: any, callback: any): void | undefined {\n if (this._peerConnections.get(peerId)) {\n return callback(this._peerConnections.get(peerId));\n }\n\n return undefined;\n }\n\n //#endregion\n\n //#region ICE Candidates\n\n _iceCandidateReceivedHandler(iceCandidateData: any): void {\n const {candidate, peerId} = iceCandidateData;\n\n trace.info('_iceCandidateReceivedHandler', candidate);\n if (!candidate) {\n trace.info('Unexpected case, iceCandidate message arrived without candidate');\n\n return;\n }\n\n const peerConnection = this._peerConnections.get(peerId);\n\n if (!peerConnection || !peerConnection.remoteDescription) {\n trace.info('Queueing iceCandidate', candidate);\n this._queueIceCandidate(candidate, peerId);\n\n return;\n }\n\n trace.info('Going to add iceCandidate', candidate);\n this._addIceCandidateToPeer(candidate, peerConnection).catch(() => undefined);\n }\n\n _addIceCandidateToPeer(iceCandidate: RTCIceCandidate, peerConnection: RTCPeerConnection): Promise<void> {\n return peerConnection.addIceCandidate(iceCandidate)\n .then(() => {\n trace.info('ICE Candidate add to peer connection');\n })\n .catch((e) => {\n trace.warn('Error adding ICE Candidate to peer connection', e);\n throw e;\n });\n }\n\n _processQueuedIceCandidates(peerId: string): void {\n this._withPeerConnection(peerId, (peerConnection: RTCPeerConnection) => {\n const pendingIces = this._pendingPeersIce[peerId];\n\n if (pendingIces) {\n pendingIces.forEach((pendingIce: RTCIceCandidate) => {\n trace.info('Adding pending ICE to peer connections');\n this._addIceCandidateToPeer(pendingIce, peerConnection).catch(() => undefined);\n });\n } else {\n trace.info('No pending ICE found for peer', peerId);\n }\n });\n }\n\n _queueIceCandidate(iceCandidate: RTCIceCandidate, peerId: string): void {\n if (!this._pendingPeersIce[peerId]) {\n this._pendingPeersIce[peerId] = [];\n }\n\n this._pendingPeersIce[peerId].push(iceCandidate);\n }\n\n _iceStateDisconnected(peerConnection: RTCPeerConnection): void {\n this._disconnectInternal(MediaSessionDisconnectReason.PeerConnectionInterrupted).catch(() => undefined);\n }\n\n //#endregion\n}\n"]}
|
|
@@ -1,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,17 @@ 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
|
-
|
|
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 = {};
|
|
49
|
+
_this._peerConnections = new Map();
|
|
30
50
|
var iceServers = sessionParams.credentials.ice.map(function (item) {
|
|
31
51
|
return {
|
|
32
52
|
urls: item.url,
|
|
@@ -34,17 +54,18 @@ var TurnWebRtcSessionV3 = /** @class */function () {
|
|
|
34
54
|
credential: item.password
|
|
35
55
|
};
|
|
36
56
|
});
|
|
37
|
-
|
|
57
|
+
_this._configuration = {
|
|
38
58
|
iceServers: iceServers,
|
|
39
59
|
iceTransportPolicy: 'relay'
|
|
40
60
|
};
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
61
|
+
_this._joinResponseHandler = _this._joinResponseHandler.bind(_this);
|
|
62
|
+
_this._iceCandidateReceivedHandler = _this._iceCandidateReceivedHandler.bind(_this);
|
|
63
|
+
_this._sendOfferHandler = _this._sendOfferHandler.bind(_this);
|
|
64
|
+
_this._sdpOfferHandler = _this._sdpOfferHandler.bind(_this);
|
|
65
|
+
_this._userPeerReconnectHandler = _this._userPeerReconnectHandler.bind(_this);
|
|
66
|
+
_this._peerDisconnectedHandler = _this._peerDisconnectedHandler.bind(_this);
|
|
67
|
+
_this._onSocketDisconnectedHandler = _this._onSocketDisconnectedHandler.bind(_this);
|
|
68
|
+
return _this;
|
|
48
69
|
}
|
|
49
70
|
Object.defineProperty(TurnWebRtcSessionV3.prototype, "id", {
|
|
50
71
|
get: function get() {
|
|
@@ -131,17 +152,7 @@ var TurnWebRtcSessionV3 = /** @class */function () {
|
|
|
131
152
|
peerConnection.ontrack = function (trackEvent) {
|
|
132
153
|
var track = trackEvent.track;
|
|
133
154
|
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
|
-
}
|
|
155
|
+
_this.registerMediaTrackFromPeer(peerConnection, track);
|
|
145
156
|
};
|
|
146
157
|
//TODO - Alex: Currently we not sending "role" through signaling, and by default we assume that the one who asks fot offer, is agent.
|
|
147
158
|
//On later stages we can send or the client "role" or the list of "streams" that peer is interested in.
|
|
@@ -435,7 +446,7 @@ var TurnWebRtcSessionV3 = /** @class */function () {
|
|
|
435
446
|
});
|
|
436
447
|
};
|
|
437
448
|
return TurnWebRtcSessionV3;
|
|
438
|
-
}();
|
|
449
|
+
}(MediaSessionBase_1.MediaSessionBase);
|
|
439
450
|
exports.TurnWebRtcSessionV3 = TurnWebRtcSessionV3;
|
|
440
451
|
|
|
441
452
|
//# 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","_peerConnections","Map","iceServers","credentials","ice","map","item","urls","url","username","login","credential","password","_configuration","iceTransportPolicy","_joinResponseHandler","bind","_iceCandidateReceivedHandler","_sendOfferHandler","_sdpOfferHandler","_userPeerReconnectHandler","_peerDisconnectedHandler","_onSocketDisconnectedHandler","get","_sessionParams","sessionId","enumerable","configurable","connect","connectOnly","info","_connectSocket","then","emit","SOCKET_EVENTS","OUTGOING","JOIN_ROOM","clientType","catch","error","disconnect","_disconnectInternal","MediaSessionDisconnectReason","ForcedByConsumer","Promise","resolve","reject","socket","SOCKET_RECONNECTION_DELAY","SOCKET_RECONNECTION_DELAY_MAX","SOCKET_RECONNECTION_ATTEMPTS","SOCKET_PATH","done","default","err","once","on","INCOMING","ERROR","SEND_OFFER","JOIN_RESPONSE","PEER_DISCONNECTED","SDP_OFFER","PUBLISHER_RECONNECT","ICE_CANDIDATE","reason","SignalingChannelDisconnect","undefined","sendOfferEventData","uid","peerId","peerConnection","_createPeerConnection","SessionClientType","GUEST","SessionClientRole","AGENT","offerParams","offerToReceiveAudio","offerToReceiveVideo","ontrack","trackEvent","track","kind","registerMediaTrackFromPeer","_sessionStreamsManager","getMediaStreamForRole","mediaStream","getTracks","forEach","addTrack","createOffer","offerDesc","sdpOffer","sdp","setLocalDescription","e","warn","joinResponseData","sdpAnswer","_withPeerConnection","answer","RTCSessionDescription","type","setRemoteDescription","_processQueuedIceCandidates","peerDisconnectedEvent","PeerDisconnected","sdpOfferEvent","INITIATOR","USER","remoteTrack","mediaTrack","trackType","KnownMediaStream","USER_VIDEO_STREAM","USER_AUDIO_STREAM","remoteMediaTracks","push","addRemoteMediaTrack","remoteDesc","createAnswer","SDP_ANSWER","UserPeerReconnected","onMediaStreamDestroyed","clientRole","PublishedStreamDestroyed","onMediaStreamRenewed","getRemoteTrackStats","peerConnectionOfTrack","filter","id","length","getStats","Error","_destroyPeerConnection","off","setTimeout","onDisconnectedHandler","peerConnectionType","peerConnectionRole","RTCPeerConnection","peerType","peerRole","onconnectionstatechange","oniceconnectionstatechange","state","currentTarget","iceConnectionState","cnState","indexOf","_iceStateDisconnected","onicecandidate","event","candidate","set","onicegatheringstatechange","remoteMediaTrack","removeMediaTrack","delete","close","callback","iceCandidateData","remoteDescription","_queueIceCandidate","_addIceCandidateToPeer","iceCandidate","addIceCandidate","pendingIces","pendingIce","PeerConnectionInterrupted","MediaSessionBase"],"mappings":"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","file":"SessionTurn.v3.js","sourcesContent":["\"use strict\";\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\n result[\"default\"] = mod;\n return result;\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar io = __importStar(require(\"socket.io-client\"));\nvar once_1 = __importDefault(require(\"lodash/once\"));\nvar MediaConstants_1 = require(\"../MediaConstants\");\nvar TurnConstants_1 = require(\"./TurnConstants\");\nvar MediaTracer_1 = require(\"../MediaUtils/MediaTracer\");\nvar MediaSessionBase_1 = require(\"./MediaSessionBase\");\nvar trace = MediaTracer_1.getMediaTracer('TurnSessionV3');\n//Currently this version supports subscribing only. Publishing will be implemented as needed.\nvar TurnWebRtcSessionV3 = /** @class */ (function (_super) {\n __extends(TurnWebRtcSessionV3, _super);\n function TurnWebRtcSessionV3(sessionParams, sessionHandlers, streamFactory) {\n var _this = _super.call(this, sessionParams, streamFactory) || this;\n _this._sessionHandlers = sessionHandlers;\n _this._socket = null;\n _this._pendingPeersIce = {};\n _this._peerConnections = new Map();\n var iceServers = sessionParams.credentials.ice.map(function (item) { return ({\n urls: item.url,\n username: item.login,\n credential: item.password\n }); });\n _this._configuration = {\n iceServers: iceServers,\n iceTransportPolicy: 'relay'\n };\n _this._joinResponseHandler = _this._joinResponseHandler.bind(_this);\n _this._iceCandidateReceivedHandler = _this._iceCandidateReceivedHandler.bind(_this);\n _this._sendOfferHandler = _this._sendOfferHandler.bind(_this);\n _this._sdpOfferHandler = _this._sdpOfferHandler.bind(_this);\n _this._userPeerReconnectHandler = _this._userPeerReconnectHandler.bind(_this);\n _this._peerDisconnectedHandler = _this._peerDisconnectedHandler.bind(_this);\n _this._onSocketDisconnectedHandler = _this._onSocketDisconnectedHandler.bind(_this);\n return _this;\n }\n Object.defineProperty(TurnWebRtcSessionV3.prototype, \"id\", {\n get: function () {\n return this._sessionParams.sessionId;\n },\n enumerable: true,\n configurable: true\n });\n //#region Socket Connectivity\n TurnWebRtcSessionV3.prototype.connect = function (connectOnly) {\n var _this = this;\n if (connectOnly === void 0) { connectOnly = false; }\n trace.info('Connect to session');\n return this._connectSocket(this._sessionParams.credentials.url, connectOnly)\n .then(function () {\n trace.info('Joining SessionId: ' + _this._sessionParams.sessionId);\n _this._socket.emit(TurnConstants_1.SOCKET_EVENTS.OUTGOING.JOIN_ROOM, {\n clientType: _this._sessionParams.clientType,\n sessionId: _this._sessionParams.sessionId\n });\n })\n .catch(function (error) {\n throw error;\n });\n };\n TurnWebRtcSessionV3.prototype.disconnect = function () {\n return this._disconnectInternal(MediaConstants_1.MediaSessionDisconnectReason.ForcedByConsumer);\n };\n TurnWebRtcSessionV3.prototype._connectSocket = function (url, connectOnly) {\n var _this = this;\n return new Promise(function (resolve, reject) {\n var socket = _this._socket = io.connect(url, {\n 'forceNew': true,\n 'reconnectionDelay': TurnConstants_1.SOCKET_RECONNECTION_DELAY,\n 'reconnectionDelayMax': TurnConstants_1.SOCKET_RECONNECTION_DELAY_MAX,\n 'reconnectionAttempts': TurnConstants_1.SOCKET_RECONNECTION_ATTEMPTS,\n 'path': TurnConstants_1.SOCKET_PATH\n });\n var done = once_1.default(function (err) {\n err ? reject(err) : resolve();\n });\n socket.once('connect', function () { return done(); });\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.ERROR, done);\n socket.on('connect_error', done);\n socket.on('connect_timeout', done);\n socket.on('disconnect', _this._onSocketDisconnectedHandler);\n if (!connectOnly) {\n trace.info('Subscribing socket events');\n //PUBLISHING NOT SUPPORTED YET\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.SEND_OFFER, _this._sendOfferHandler);\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.JOIN_RESPONSE, _this._joinResponseHandler);\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.PEER_DISCONNECTED, _this._peerDisconnectedHandler);\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.SDP_OFFER, _this._sdpOfferHandler);\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.PUBLISHER_RECONNECT, _this._userPeerReconnectHandler);\n socket.on(TurnConstants_1.SOCKET_EVENTS.INCOMING.ICE_CANDIDATE, _this._iceCandidateReceivedHandler);\n }\n });\n };\n TurnWebRtcSessionV3.prototype._onSocketDisconnectedHandler = function (reason) {\n if (this._socket) {\n // The initial example of differentiating between \"forced\" disconnect and \"network\" disconnect is taken from:\n // https://socket.io/docs/client-api/#Event-%E2%80%98disconnect%E2%80%99\n if (reason !== 'io server disconnect' && reason !== 'io client disconnect') {\n // the disconnection was initiated by the server or by client, you need to call (connect) manually\n this._disconnectInternal(MediaConstants_1.MediaSessionDisconnectReason.SignalingChannelDisconnect).catch(function () { return undefined; });\n }\n }\n };\n //#endregion\n //#region WebRTC Initiator - session Initiator (User on mobile device)\n // Received by Initiator, causing him to emit SDP_OFFER\n TurnWebRtcSessionV3.prototype._sendOfferHandler = function (sendOfferEventData) {\n var _this = this;\n var uid = sendOfferEventData.uid, peerId = sendOfferEventData.peerId;\n trace.info('_sendOfferHandler');\n //Currently we not support of passing role through signaling, so we assume every connection is \"AGENT\" like\n var peerConnection = this._createPeerConnection(peerId, MediaConstants_1.SessionClientType.GUEST, MediaConstants_1.SessionClientRole.AGENT);\n var offerParams = { offerToReceiveAudio: true, offerToReceiveVideo: true };\n peerConnection.ontrack = function (trackEvent) {\n var track = trackEvent.track;\n trace.info(\"MediaStreamTrack arrived from peerConnection: \" + track.kind, track);\n _this.registerMediaTrackFromPeer(peerConnection, track);\n };\n //TODO - Alex: Currently we not sending \"role\" through signaling, and by default we assume that the one who asks fot offer, is agent.\n //On later stages we can send or the client \"role\" or the list of \"streams\" that peer is interested in.\n this._sessionStreamsManager.getMediaStreamForRole(MediaConstants_1.SessionClientRole.AGENT)\n .then(function (mediaStream) {\n trace.info('_sendOfferHandler stream and peer created');\n if (mediaStream) {\n trace.info('Adding local tracks to peer connection');\n mediaStream.getTracks().forEach(function (track) {\n peerConnection.addTrack(track, mediaStream);\n trace.info(\"Local \" + track.kind + \" track added to peer connection\");\n });\n }\n else {\n trace.info('No media stream was found for publishing');\n }\n })\n .then(function () { return peerConnection.createOffer(offerParams); })\n .then(function (offerDesc) {\n trace.info('Initiator has created sdp offer', { offerDesc: offerDesc });\n _this._socket.emit(TurnConstants_1.SOCKET_EVENTS.OUTGOING.SDP_OFFER, {\n uid: uid,\n peerId: peerId,\n sessionId: _this._sessionParams.sessionId,\n sdpOffer: offerDesc.sdp\n });\n return peerConnection.setLocalDescription(offerDesc)\n .then(function () {\n trace.info('Local description was set on peerConnection', peerConnection);\n });\n })\n .catch(function (e) {\n trace.warn('Error', e);\n });\n };\n // Received by the Initiator: Indicates that publish should be started\n TurnWebRtcSessionV3.prototype._joinResponseHandler = function (joinResponseData) {\n var _this = this;\n var sdpAnswer = joinResponseData.sdpAnswer, uid = joinResponseData.uid, peerId = joinResponseData.peerId;\n trace.info('joinResponse Received', { sdpAnswer: sdpAnswer });\n this._withPeerConnection(peerId, function (peerConnection) {\n var answer = new RTCSessionDescription({\n type: 'answer',\n sdp: sdpAnswer\n });\n peerConnection.setRemoteDescription(answer)\n .then(function () {\n trace.info('Remote description was set', answer);\n _this._processQueuedIceCandidates(peerId);\n })\n .catch(function (e) {\n trace.warn('Error', e);\n });\n });\n };\n // Received by Initiator after a guests socket has been disconnected\n TurnWebRtcSessionV3.prototype._peerDisconnectedHandler = function (peerDisconnectedEvent) {\n var _this = this;\n var peerId = peerDisconnectedEvent.peerId;\n trace.info('_peerDisconnectedHandler');\n this._withPeerConnection(peerId, function (peerConnection) {\n _this._disconnectInternal(MediaConstants_1.MediaSessionDisconnectReason.PeerDisconnected).catch(function () { return undefined; });\n });\n };\n //#endregion WebRTC Initiator - session Initiator (User on mobile device)\n //#region WebRTC Guest - session Guest (Agent on dashboard platform)\n // Received by Guest, causing him to emit SDP_ANSWER\n TurnWebRtcSessionV3.prototype._sdpOfferHandler = function (sdpOfferEvent) {\n var _this = this;\n var sdpOffer = sdpOfferEvent.sdpOffer, peerId = sdpOfferEvent.peerId, uid = sdpOfferEvent.uid;\n trace.info('sdpOffer Received', { sdpOffer: sdpOffer });\n var peerConnection = this._createPeerConnection(peerId, MediaConstants_1.SessionClientType.INITIATOR, MediaConstants_1.SessionClientRole.USER);\n peerConnection.ontrack = function (trackEvent) {\n var track = trackEvent.track;\n trace.info(\"MediaStreamTrack arrived from peerConnection: \" + track.kind, track);\n var remoteTrack = {\n mediaTrack: track,\n trackType: track.kind === 'video'\n //Although we can have desktop share stream, we still name it USER_VIDEO_STREAM in dashboard.\n //Because currently we support only one video stream to be streamed at the time, it's not an issue.\n //But when we will need to stream more than one stream of a kind from single peer, this will be need to change.\n ? MediaConstants_1.KnownMediaStream.USER_VIDEO_STREAM : MediaConstants_1.KnownMediaStream.USER_AUDIO_STREAM\n };\n peerConnection.remoteMediaTracks.push(remoteTrack);\n _this._sessionStreamsManager.addRemoteMediaTrack(remoteTrack)\n .catch(function () {\n trace.warn('Error adding remote track to stream manager', remoteTrack);\n });\n };\n this._sessionStreamsManager.getMediaStreamForRole(MediaConstants_1.SessionClientRole.USER)\n .then(function (mediaStream) {\n if (mediaStream) {\n trace.info('Adding local tracks to peer connection');\n mediaStream.getTracks().forEach(function (track) {\n peerConnection.addTrack(track, mediaStream);\n trace.info(\"Local \" + track.kind + \" track added to peer connection\");\n });\n }\n else {\n trace.info('No media stream was found for publishing');\n }\n })\n .then(function () {\n var remoteDesc = new RTCSessionDescription({ type: 'offer', sdp: sdpOffer });\n return peerConnection.setRemoteDescription(remoteDesc)\n .then(function () {\n trace.info('Remote description was set', remoteDesc);\n return peerConnection.createAnswer()\n .then(function (sdpAnswer) {\n trace.info('_sdpOfferHandler answer created', sdpAnswer);\n _this._socket.emit(TurnConstants_1.SOCKET_EVENTS.OUTGOING.SDP_ANSWER, {\n uid: uid,\n peerId: peerId,\n sessionId: _this._sessionParams.sessionId,\n sdpAnswer: sdpAnswer.sdp\n });\n return peerConnection.setLocalDescription(sdpAnswer)\n .then(function () {\n trace.info('_sdpOfferHandler local desc was set');\n _this._processQueuedIceCandidates(peerId);\n });\n });\n });\n })\n .catch(function (e) {\n trace.error('Error in _sdpOfferHandler', e);\n throw e;\n });\n };\n // Received by Guest after an Initiator reconnects to room\n TurnWebRtcSessionV3.prototype._userPeerReconnectHandler = function () {\n trace.info('_userPeerReconnectHandler');\n this._disconnectInternal(MediaConstants_1.MediaSessionDisconnectReason.UserPeerReconnected)\n .catch(function (error) {\n trace.warn('Error while disconnecting during userPeerReconnectHandler.', error);\n });\n };\n //#endregion WebRTC Guest - session Guest (Agent on dashboard platform)\n //#region Peer Connection\n //#region Streams Handling\n TurnWebRtcSessionV3.prototype.onMediaStreamDestroyed = function (clientRole) {\n var _this = this;\n //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation\n this._peerConnections.forEach(function (peerConnection) {\n _this._disconnectInternal(MediaConstants_1.MediaSessionDisconnectReason.PublishedStreamDestroyed).catch(function () { return undefined; });\n });\n return Promise.resolve();\n };\n TurnWebRtcSessionV3.prototype.onMediaStreamRenewed = function (clientRole, mediaStream) {\n //TODO - Alex: need to implement adding new tracks to peer connection and forcing negotiation\n return Promise.resolve();\n };\n TurnWebRtcSessionV3.prototype.getRemoteTrackStats = function (mediaTrack) {\n var peerConnectionOfTrack = null;\n this._peerConnections.forEach(function (peerConnection) {\n var remoteTrack = peerConnection.remoteMediaTracks.filter(function (track) { return track.mediaTrack.id === mediaTrack.id; });\n if (remoteTrack.length === 1) {\n peerConnectionOfTrack = peerConnection;\n }\n });\n if (peerConnectionOfTrack !== null) {\n return peerConnectionOfTrack.getStats(mediaTrack);\n }\n return Promise.reject(new Error('Provided track is not remote track'));\n };\n //#endregion\n TurnWebRtcSessionV3.prototype._disconnectInternal = function (reason) {\n var _this = this;\n this._peerConnections.forEach(function (peerConnection) {\n _this._destroyPeerConnection(peerConnection);\n });\n trace.info('Disconnecting from session', reason);\n if (this._socket) {\n this._socket.off();\n this._socket.disconnect();\n }\n this._socket = null;\n setTimeout(function () { return _this._sessionHandlers.onDisconnectedHandler(reason); });\n return Promise.resolve();\n };\n TurnWebRtcSessionV3.prototype._createPeerConnection = function (peerId, peerConnectionType, peerConnectionRole) {\n var _this = this;\n if (this._peerConnections.get(peerId)) {\n throw new Error(this._sessionParams.clientType + \" peer connection for \" + peerId + \" already exists\");\n }\n var peerConnection = new RTCPeerConnection(this._configuration);\n peerConnection.peerId = peerId;\n peerConnection.peerType = peerConnectionType;\n peerConnection.remoteMediaTracks = [];\n peerConnection.peerRole = peerConnectionRole;\n peerConnection.onconnectionstatechange = function () {\n trace.info('onconnectionstatechange', peerConnection);\n };\n peerConnection.oniceconnectionstatechange = function (state) {\n trace.info(\"ICE Connection state for peer \" + peerId + \" was changed to: \" + state.currentTarget.iceConnectionState, state);\n var cnState = state.currentTarget.iceConnectionState;\n if (['closed', 'disconnected', 'failed'].indexOf(cnState) > -1) {\n _this._iceStateDisconnected(peerConnection);\n }\n };\n peerConnection.onicecandidate = function (event) {\n if (event.candidate) {\n trace.info(_this._sessionParams.clientType + \" peerConn.onicecandidate\", event.candidate);\n _this._socket.emit(TurnConstants_1.SOCKET_EVENTS.OUTGOING.ICE_CANDIDATE, {\n sessionId: _this._sessionParams.sessionId,\n peerId: peerId,\n candidate: event.candidate,\n clientType: _this._sessionParams.clientType\n });\n }\n else {\n trace.info('ICE Candidate is null in peerConnection', event);\n }\n };\n this._peerConnections.set(peerId, peerConnection);\n trace.info(peerConnectionType + \" peerConnection created\");\n return peerConnection;\n };\n TurnWebRtcSessionV3.prototype._destroyPeerConnection = function (peerConnection) {\n var _this = this;\n trace.info('Destroying PeerConnection', peerConnection.peerType);\n peerConnection.ontrack = null;\n peerConnection.onicecandidate = null;\n peerConnection.onconnectionstatechange = null;\n peerConnection.oniceconnectionstatechange = null;\n peerConnection.onicegatheringstatechange = null;\n peerConnection.remoteMediaTracks.forEach(function (remoteMediaTrack) {\n _this._sessionStreamsManager.removeMediaTrack(remoteMediaTrack.mediaTrack)\n .catch(function () {\n trace.warn('Error while removing remote media track', remoteMediaTrack);\n });\n });\n this._peerConnections.delete(peerConnection.peerId);\n peerConnection.close();\n };\n TurnWebRtcSessionV3.prototype._withPeerConnection = function (peerId, callback) {\n if (this._peerConnections.get(peerId)) {\n return callback(this._peerConnections.get(peerId));\n }\n return undefined;\n };\n //#endregion\n //#region ICE Candidates\n TurnWebRtcSessionV3.prototype._iceCandidateReceivedHandler = function (iceCandidateData) {\n var candidate = iceCandidateData.candidate, peerId = iceCandidateData.peerId;\n trace.info('_iceCandidateReceivedHandler', candidate);\n if (!candidate) {\n trace.info('Unexpected case, iceCandidate message arrived without candidate');\n return;\n }\n var peerConnection = this._peerConnections.get(peerId);\n if (!peerConnection || !peerConnection.remoteDescription) {\n trace.info('Queueing iceCandidate', candidate);\n this._queueIceCandidate(candidate, peerId);\n return;\n }\n trace.info('Going to add iceCandidate', candidate);\n this._addIceCandidateToPeer(candidate, peerConnection).catch(function () { return undefined; });\n };\n TurnWebRtcSessionV3.prototype._addIceCandidateToPeer = function (iceCandidate, peerConnection) {\n return peerConnection.addIceCandidate(iceCandidate)\n .then(function () {\n trace.info('ICE Candidate add to peer connection');\n })\n .catch(function (e) {\n trace.warn('Error adding ICE Candidate to peer connection', e);\n throw e;\n });\n };\n TurnWebRtcSessionV3.prototype._processQueuedIceCandidates = function (peerId) {\n var _this = this;\n this._withPeerConnection(peerId, function (peerConnection) {\n var pendingIces = _this._pendingPeersIce[peerId];\n if (pendingIces) {\n pendingIces.forEach(function (pendingIce) {\n trace.info('Adding pending ICE to peer connections');\n _this._addIceCandidateToPeer(pendingIce, peerConnection).catch(function () { return undefined; });\n });\n }\n else {\n trace.info('No pending ICE found for peer', peerId);\n }\n });\n };\n TurnWebRtcSessionV3.prototype._queueIceCandidate = function (iceCandidate, peerId) {\n if (!this._pendingPeersIce[peerId]) {\n this._pendingPeersIce[peerId] = [];\n }\n this._pendingPeersIce[peerId].push(iceCandidate);\n };\n TurnWebRtcSessionV3.prototype._iceStateDisconnected = function (peerConnection) {\n this._disconnectInternal(MediaConstants_1.MediaSessionDisconnectReason.PeerConnectionInterrupted).catch(function () { return undefined; });\n };\n return TurnWebRtcSessionV3;\n}(MediaSessionBase_1.MediaSessionBase));\nexports.TurnWebRtcSessionV3 = TurnWebRtcSessionV3;\n\n//# sourceMappingURL=SessionTurn.v3.js.map\n"]}
|
package/lib/oldCode/index.js
CHANGED
package/lib/oldCode/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["oldCode/index.js"],"names":["TsMediaService","EVENTS","RawQos"],"mappings":";;;;;;;;;wBACIA,c;;;;;;wBACAC,M;;;;;;;;;wBAIAA,M;;;;;;;;;uBAIAA,M;;;;;;;;;0BAIAA,M;;;;;;;;;2BAIAA,M;;;;;;;;;uBAIAC,M","file":"index.js","sourcesContent":["export {\n TsMediaService,\n EVENTS as SERVICE_EVENTS,\n} from './service';\n\nexport {\n EVENTS as SESSION_EVENTS,\n} from './session';\n\nexport {\n EVENTS as STREAM_EVENTS,\n} from './stream';\n\nexport {\n EVENTS as PUBLISHER_EVENTS,\n} from './publisher';\n\nexport {\n EVENTS as SUBSCRIBER_EVENTS,\n} from './subscriber';\n\nexport {\n RawQos\n} from '
|
|
1
|
+
{"version":3,"sources":["oldCode/index.js"],"names":["TsMediaService","EVENTS","RawQos"],"mappings":";;;;;;;;;wBACIA,c;;;;;;wBACAC,M;;;;;;;;;wBAIAA,M;;;;;;;;;uBAIAA,M;;;;;;;;;0BAIAA,M;;;;;;;;;2BAIAA,M;;;;;;;;;uBAIAC,M","file":"index.js","sourcesContent":["export {\n TsMediaService,\n EVENTS as SERVICE_EVENTS,\n} from './service';\n\nexport {\n EVENTS as SESSION_EVENTS,\n} from './session';\n\nexport {\n EVENTS as STREAM_EVENTS,\n} from './stream';\n\nexport {\n EVENTS as PUBLISHER_EVENTS,\n} from './publisher';\n\nexport {\n EVENTS as SUBSCRIBER_EVENTS,\n} from './subscriber';\n\nexport {\n RawQos\n} from '../qos/raw-qos';\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["qos/raw-qos.js"],"names":["RawQos","instance","VIDEO_CODECS","rawQoSEntry","enableRawEntries","bytesPrev","timestampPrev","startTimestamp","parse","stats","self","_clearRaw","values","stat","isRemote","type","_addRaw","_parseOutStats","remote","get","remoteId","_parseInStats","_parseRelated","bytesSent","bytesReceived","servers","_parseServerStats","track","frameWidth","_parseTrack","trackId","codec","codecId","_parseCodec","raw","item","push","_dumpItem","result","parent","totalRoundTripTime","currentRoundTripTime","availableOutgoingBitrate","localCandidate","localCandidateId","_parseLocal","remoteCandidate","remoteCandidateId","_parseRemote","mimeType","index","findIndex","toLowerCase","includes","videoCodec","localIP","ip","ipAddress","localPort","port","portNumber","localProtocol","protocol","transport","remoteIP","remotePort","remoteProtocol","frameHeight","framesPerSecond","videoFrameRate","isPublisher","videoSentPackets","packetsSent","videoSentPacketsLost","packetsLost","videoSentBytes","_parseBitrate","_parseFrameRate","_parseOther","_saveSomeMetrics","_parseVideoDuration","timestamp","videoDuration","toFixed","isSubscriber","videoReceivedPackets","packetsReceived","videoReceivedPacketsLost","videoReceivedBytes","ssrcPrev","ssrc","framesDecodedPrev","framesDecoded","discardedPackets","jitter","packetsRepaired","bytes","bitrateMean","videoBitRate","totalBytes","Math","floor","framerateMean","Number","res","statsString","Object","keys","forEach","k","length"],"mappings":"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","file":"raw-qos.js","sourcesContent":["'use strict';\n\nexport class RawQos {\n constructor() {\n if (RawQos.instance) {\n return RawQos.instance;\n }\n\n this.VIDEO_CODECS = ['vp9', 'vp8', 'h264'];\n this.rawQoSEntry = {};\n this.enableRawEntries = true;\n\n this.bytesPrev = null;\n this.timestampPrev = null;\n this.startTimestamp = null;\n\n RawQos.instance = this;\n }\n\n parse(stats) {\n const self = this;\n\n self.rawQoSEntry = {};\n self._clearRaw();\n\n for (const stat of stats.values()) {\n if (!stat.isRemote) {\n switch (stat.type) {\n case 'outbound-rtp': {\n self._addRaw(stat);\n self._parseOutStats(stat, self.rawQoSEntry);\n\n const remote = stats.get(stat.remoteId);\n\n if (remote) {\n self._addRaw(remote);\n self.rawQoSEntry.remote = {};\n self._parseInStats(remote, self.rawQoSEntry.remote);\n }\n\n this._parseRelated(stats, stat, self);\n break;\n }\n case 'inbound-rtp': {\n self._addRaw(stat);\n self._parseInStats(stat, self.rawQoSEntry);\n\n const remote = stats.get(stat.remoteId);\n\n if (remote) {\n self._addRaw(remote);\n self.rawQoSEntry.remote = {};\n self._parseOutStats(remote, self.rawQoSEntry.remote);\n }\n\n this._parseRelated(stats, stat, self);\n break;\n }\n case 'remote-inbound-rtp': {\n self._addRaw(stat);\n self.rawQoSEntry.remote = {};\n self._parseInStats(stat, self.rawQoSEntry.remote);\n break;\n }\n case 'remote-outbound-rtp': {\n self._addRaw(stat);\n self.rawQoSEntry.remote = {};\n self._parseOutStats(stat, self.rawQoSEntry.remote);\n break;\n }\n case 'candidate-pair': {\n if ((stat.bytesSent > 0 || stat.bytesReceived > 0) &&\n (!self.rawQoSEntry.servers || stat.bytesSent > self.rawQoSEntry.servers.bytesSent ||\n stat.bytesReceived > self.rawQoSEntry.servers.bytesReceived)) {\n self.rawQoSEntry.servers = {};\n self._addRaw(stat);\n self._parseServerStats(stat, self.rawQoSEntry.servers, stats);\n }\n break;\n }\n case 'track': {\n self.track = stat;\n break;\n }\n }\n }\n }\n\n if (!self.rawQoSEntry.frameWidth && self.track) {\n self._addRaw(self.track);\n self._parseTrack(self.track, self.rawQoSEntry);\n }\n self.track = null;\n\n return self.rawQoSEntry;\n }\n\n _parseRelated(stats, stat, self) {\n const track = stats.get(stat.trackId);\n\n if (track) {\n self._addRaw(track);\n self._parseTrack(track, self.rawQoSEntry);\n }\n\n const codec = stats.get(stat.codecId);\n\n if (codec) {\n self._addRaw(codec);\n self._parseCodec(codec, self.rawQoSEntry);\n }\n }\n\n _clearRaw() {\n if (this.enableRawEntries) {\n this.rawQoSEntry.raw = [];\n }\n }\n\n _addRaw(item) {\n if (this.enableRawEntries && item) {\n if (!this.rawQoSEntry.raw) {\n this.rawQoSEntry.raw = [];\n }\n\n this.rawQoSEntry.raw.push(this._dumpItem(item));\n }\n }\n\n _parseServerStats(result, parent, stats) {\n parent.bytesSent = result.bytesSent;\n parent.bytesReceived = result.bytesReceived;\n if (typeof result.totalRoundTripTime === 'number') {\n parent.totalRoundTripTime = result.totalRoundTripTime;\n }\n if (typeof result.currentRoundTripTime === 'number') {\n parent.currentRoundTripTime = result.currentRoundTripTime;\n }\n if (typeof result.availableOutgoingBitrate === 'number') {\n parent.availableOutgoingBitrate = result.availableOutgoingBitrate;\n }\n\n const localCandidate = stats.get(result.localCandidateId);\n\n if (localCandidate) {\n this._addRaw(localCandidate);\n this._parseLocal(localCandidate, parent);\n }\n\n const remoteCandidate = stats.get(result.remoteCandidateId);\n\n if (remoteCandidate) {\n this._addRaw(remoteCandidate);\n this._parseRemote(remoteCandidate, parent);\n }\n }\n\n _parseCodec(result, parent) {\n if (result.mimeType) {\n const index = this.VIDEO_CODECS.findIndex((codec) => result.mimeType.toLowerCase().includes(codec));\n\n if (index >= 0) {\n parent.videoCodec = this.VIDEO_CODECS[index];\n }\n }\n }\n\n _parseLocal(result, parent) {\n parent.localIP = result.ip || result.ipAddress;\n parent.localPort = result.port || result.portNumber;\n parent.localProtocol = result.protocol || result.transport;\n }\n\n _parseRemote(result, parent) {\n parent.remoteIP = result.ip || result.ipAddress;\n parent.remotePort = result.port || result.portNumber;\n parent.remoteProtocol = result.protocol || result.transport;\n }\n\n _parseTrack(result, parent) {\n if (typeof result.frameWidth === 'number') {\n parent.frameWidth = result.frameWidth;\n }\n if (typeof result.frameHeight === 'number') {\n parent.frameHeight = result.frameHeight;\n }\n if (typeof result.framesPerSecond === 'number') {\n parent.videoFrameRate = result.framesPerSecond;\n }\n }\n\n _parseOutStats(result, parent) {\n parent.isPublisher = true;\n parent.videoSentPackets = result.packetsSent;\n parent.videoSentPacketsLost = result.packetsLost;\n parent.videoSentBytes = result.bytesSent;\n this._parseBitrate(result, parent, parent.videoSentBytes);\n this._parseFrameRate(result, parent, parent.videoSentBytes);\n this._parseOther(result, parent);\n this._saveSomeMetrics(parent, result);\n }\n\n _parseVideoDuration(result, parent) {\n if (!this.startTimestamp) {\n this.startTimestamp = result.timestamp;\n }\n parent.videoDuration = ((result.timestamp - this.startTimestamp) / 1000).toFixed(2);\n }\n\n _parseInStats(result, parent) {\n parent.isSubscriber = true;\n parent.videoReceivedPackets = result.packetsReceived;\n parent.videoReceivedPacketsLost = result.packetsLost;\n parent.videoReceivedBytes = result.bytesReceived;\n this._parseBitrate(result, parent, parent.videoReceivedBytes);\n this._parseFrameRate(result, parent, parent.videoReceivedBytes);\n this._parseOther(result, parent);\n this._saveSomeMetrics(parent, result);\n }\n\n _saveSomeMetrics(parent, result) {\n if (parent === this.rawQoSEntry) {\n this.bytesPrev = parent.videoReceivedBytes;\n this.timestampPrev = result.timestamp;\n this.ssrcPrev = result.ssrc;\n this.framesDecodedPrev = result.framesDecoded;\n this._parseVideoDuration(result, parent);\n }\n }\n\n _parseOther(result, parent) {\n parent.timestamp = result.timestamp;\n parent.ssrc = result.ssrc;\n if (typeof result.discardedPackets === 'number') {\n parent.discardedPackets = result.discardedPackets;\n }\n if (typeof result.jitter === 'number') {\n parent.jitter = result.jitter;\n }\n if (typeof result.packetsRepaired === 'number') {\n parent.packetsRepaired = result.packetsRepaired;\n }\n }\n\n _parseBitrate(result, parent, bytes) {\n if (bytes > 0) {\n if (typeof result.bitrateMean === 'number') {\n parent.videoBitRate = (result.bitrateMean).toFixed(2);\n\n } else if (this.bytesPrev && this.timestampPrev) {\n let totalBytes = bytes;\n\n if ((result.ssrc === this.ssrcPrev) && (bytes > this.bytesPrev)) {\n totalBytes = bytes - this.bytesPrev;\n }\n\n parent.videoBitRate = Math.floor((8 * totalBytes) / ((result.timestamp - this.timestampPrev) / 1000));\n }\n } else {\n parent.videoBitRate = 0;\n }\n }\n\n _parseFrameRate(result, parent, bytes) {\n if (bytes > 0) {\n if (typeof result.framerateMean === 'number') {\n parent.videoFrameRate = Number(result.framerateMean).toFixed(2);\n } else if (this.framesDecodedPrev && this.timestampPrev) {\n if (result.framesDecoded >= this.framesDecodedPrev && result.timestamp > this.timestampPrev) {\n parent.videoFrameRate = ((result.framesDecoded - this.framesDecodedPrev) / ((result.timestamp - this.timestampPrev) / 1000)).toFixed(2);\n }\n }\n } else {\n parent.videoFrameRate = 0;\n }\n }\n\n _dumpItem(res) {\n let statsString = '{';\n let index = 0;\n\n Object.keys(res).forEach((k) => {\n statsString += `\"${k}\": \"${res[k]}\"`;\n if (++index !== res.length) {\n statsString += ',';\n }\n });\n statsString += '}';\n\n return statsString;\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["oldCode/qos/raw-qos.js"],"names":["RawQos","instance","VIDEO_CODECS","rawQoSEntry","enableRawEntries","bytesPrev","timestampPrev","startTimestamp","parse","stats","self","_clearRaw","values","stat","isRemote","type","_addRaw","_parseOutStats","remote","get","remoteId","_parseInStats","_parseRelated","bytesSent","bytesReceived","servers","_parseServerStats","track","frameWidth","_parseTrack","trackId","codec","codecId","_parseCodec","raw","item","push","_dumpItem","result","parent","totalRoundTripTime","currentRoundTripTime","availableOutgoingBitrate","localCandidate","localCandidateId","_parseLocal","remoteCandidate","remoteCandidateId","_parseRemote","mimeType","index","findIndex","toLowerCase","includes","videoCodec","localIP","ip","ipAddress","localPort","port","portNumber","localProtocol","protocol","transport","remoteIP","remotePort","remoteProtocol","frameHeight","framesPerSecond","videoFrameRate","isPublisher","videoSentPackets","packetsSent","videoSentPacketsLost","packetsLost","videoSentBytes","_parseBitrate","_parseFrameRate","_parseOther","_saveSomeMetrics","_parseVideoDuration","timestamp","videoDuration","toFixed","isSubscriber","videoReceivedPackets","packetsReceived","videoReceivedPacketsLost","videoReceivedBytes","ssrcPrev","ssrc","framesDecodedPrev","framesDecoded","discardedPackets","jitter","packetsRepaired","bytes","bitrateMean","videoBitRate","totalBytes","Math","floor","framerateMean","Number","res","statsString","Object","keys","forEach","k","length"],"mappings":"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","file":"raw-qos.js","sourcesContent":["'use strict';\n\nexport class RawQos {\n constructor() {\n if (RawQos.instance) {\n return RawQos.instance;\n }\n\n this.VIDEO_CODECS = ['vp9', 'vp8', 'h264'];\n this.rawQoSEntry = {};\n this.enableRawEntries = true;\n\n this.bytesPrev = null;\n this.timestampPrev = null;\n this.startTimestamp = null;\n\n RawQos.instance = this;\n }\n\n parse(stats) {\n const self = this;\n\n self.rawQoSEntry = {};\n self._clearRaw();\n\n for (const stat of stats.values()) {\n if (!stat.isRemote) {\n switch (stat.type) {\n case 'outbound-rtp': {\n self._addRaw(stat);\n self._parseOutStats(stat, self.rawQoSEntry);\n\n const remote = stats.get(stat.remoteId);\n\n if (remote) {\n self._addRaw(remote);\n self.rawQoSEntry.remote = {};\n self._parseInStats(remote, self.rawQoSEntry.remote);\n }\n\n this._parseRelated(stats, stat, self);\n break;\n }\n case 'inbound-rtp': {\n self._addRaw(stat);\n self._parseInStats(stat, self.rawQoSEntry);\n\n const remote = stats.get(stat.remoteId);\n\n if (remote) {\n self._addRaw(remote);\n self.rawQoSEntry.remote = {};\n self._parseOutStats(remote, self.rawQoSEntry.remote);\n }\n\n this._parseRelated(stats, stat, self);\n break;\n }\n case 'remote-inbound-rtp': {\n self._addRaw(stat);\n self.rawQoSEntry.remote = {};\n self._parseInStats(stat, self.rawQoSEntry.remote);\n break;\n }\n case 'remote-outbound-rtp': {\n self._addRaw(stat);\n self.rawQoSEntry.remote = {};\n self._parseOutStats(stat, self.rawQoSEntry.remote);\n break;\n }\n case 'candidate-pair': {\n if ((stat.bytesSent > 0 || stat.bytesReceived > 0) &&\n (!self.rawQoSEntry.servers || stat.bytesSent > self.rawQoSEntry.servers.bytesSent ||\n stat.bytesReceived > self.rawQoSEntry.servers.bytesReceived)) {\n self.rawQoSEntry.servers = {};\n self._addRaw(stat);\n self._parseServerStats(stat, self.rawQoSEntry.servers, stats);\n }\n break;\n }\n case 'track': {\n self.track = stat;\n break;\n }\n }\n }\n }\n\n if (!self.rawQoSEntry.frameWidth && self.track) {\n self._addRaw(self.track);\n self._parseTrack(self.track, self.rawQoSEntry);\n }\n self.track = null;\n\n return self.rawQoSEntry;\n }\n\n _parseRelated(stats, stat, self) {\n const track = stats.get(stat.trackId);\n\n if (track) {\n self._addRaw(track);\n self._parseTrack(track, self.rawQoSEntry);\n }\n\n const codec = stats.get(stat.codecId);\n\n if (codec) {\n self._addRaw(codec);\n self._parseCodec(codec, self.rawQoSEntry);\n }\n }\n\n _clearRaw() {\n if (this.enableRawEntries) {\n this.rawQoSEntry.raw = [];\n }\n }\n\n _addRaw(item) {\n if (this.enableRawEntries && item) {\n if (!this.rawQoSEntry.raw) {\n this.rawQoSEntry.raw = [];\n }\n\n this.rawQoSEntry.raw.push(this._dumpItem(item));\n }\n }\n\n _parseServerStats(result, parent, stats) {\n parent.bytesSent = result.bytesSent;\n parent.bytesReceived = result.bytesReceived;\n if (typeof result.totalRoundTripTime === 'number') {\n parent.totalRoundTripTime = result.totalRoundTripTime;\n }\n if (typeof result.currentRoundTripTime === 'number') {\n parent.currentRoundTripTime = result.currentRoundTripTime;\n }\n if (typeof result.availableOutgoingBitrate === 'number') {\n parent.availableOutgoingBitrate = result.availableOutgoingBitrate;\n }\n\n const localCandidate = stats.get(result.localCandidateId);\n\n if (localCandidate) {\n this._addRaw(localCandidate);\n this._parseLocal(localCandidate, parent);\n }\n\n const remoteCandidate = stats.get(result.remoteCandidateId);\n\n if (remoteCandidate) {\n this._addRaw(remoteCandidate);\n this._parseRemote(remoteCandidate, parent);\n }\n }\n\n _parseCodec(result, parent) {\n if (result.mimeType) {\n const index = this.VIDEO_CODECS.findIndex((codec) => result.mimeType.toLowerCase().includes(codec));\n\n if (index >= 0) {\n parent.videoCodec = this.VIDEO_CODECS[index];\n }\n }\n }\n\n _parseLocal(result, parent) {\n parent.localIP = result.ip || result.ipAddress;\n parent.localPort = result.port || result.portNumber;\n parent.localProtocol = result.protocol || result.transport;\n }\n\n _parseRemote(result, parent) {\n parent.remoteIP = result.ip || result.ipAddress;\n parent.remotePort = result.port || result.portNumber;\n parent.remoteProtocol = result.protocol || result.transport;\n }\n\n _parseTrack(result, parent) {\n if (typeof result.frameWidth === 'number') {\n parent.frameWidth = result.frameWidth;\n }\n if (typeof result.frameHeight === 'number') {\n parent.frameHeight = result.frameHeight;\n }\n if (typeof result.framesPerSecond === 'number') {\n parent.videoFrameRate = result.framesPerSecond;\n }\n }\n\n _parseOutStats(result, parent) {\n parent.isPublisher = true;\n parent.videoSentPackets = result.packetsSent;\n parent.videoSentPacketsLost = result.packetsLost;\n parent.videoSentBytes = result.bytesSent;\n this._parseBitrate(result, parent, parent.videoSentBytes);\n this._parseFrameRate(result, parent, parent.videoSentBytes);\n this._parseOther(result, parent);\n this._saveSomeMetrics(parent, result);\n }\n\n _parseVideoDuration(result, parent) {\n if (!this.startTimestamp) {\n this.startTimestamp = result.timestamp;\n }\n parent.videoDuration = ((result.timestamp - this.startTimestamp) / 1000).toFixed(2);\n }\n\n _parseInStats(result, parent) {\n parent.isSubscriber = true;\n parent.videoReceivedPackets = result.packetsReceived;\n parent.videoReceivedPacketsLost = result.packetsLost;\n parent.videoReceivedBytes = result.bytesReceived;\n this._parseBitrate(result, parent, parent.videoReceivedBytes);\n this._parseFrameRate(result, parent, parent.videoReceivedBytes);\n this._parseOther(result, parent);\n this._saveSomeMetrics(parent, result);\n }\n\n _saveSomeMetrics(parent, result) {\n if (parent === this.rawQoSEntry) {\n this.bytesPrev = parent.videoReceivedBytes;\n this.timestampPrev = result.timestamp;\n this.ssrcPrev = result.ssrc;\n this.framesDecodedPrev = result.framesDecoded;\n this._parseVideoDuration(result, parent);\n }\n }\n\n _parseOther (result, parent) {\n parent.timestamp = result.timestamp;\n parent.ssrc = result.ssrc;\n if (typeof result.discardedPackets === 'number') {\n parent.discardedPackets = result.discardedPackets;\n }\n if (typeof result.jitter === 'number') {\n parent.jitter = result.jitter;\n }\n if (typeof result.packetsRepaired === 'number') {\n parent.packetsRepaired = result.packetsRepaired;\n }\n }\n\n _parseBitrate (result, parent, bytes) {\n if (bytes > 0) {\n if (typeof result.bitrateMean === 'number') {\n parent.videoBitRate = (result.bitrateMean).toFixed(2);\n\n } else if (this.bytesPrev && this.timestampPrev) {\n let totalBytes = bytes;\n\n if((result.ssrc === this.ssrcPrev) && (bytes > this.bytesPrev)) {\n totalBytes = bytes - this.bytesPrev;\n }\n\n parent.videoBitRate = Math.floor((8 * totalBytes) / ((result.timestamp - this.timestampPrev) / 1000));\n }\n } else {\n parent.videoBitRate = 0;\n }\n }\n\n _parseFrameRate (result, parent, bytes) {\n if (bytes > 0) {\n if (typeof result.framerateMean === 'number') {\n parent.videoFrameRate = Number(result.framerateMean).toFixed(2);\n } else if (this.framesDecodedPrev && this.timestampPrev) {\n if (result.framesDecoded >= this.framesDecodedPrev && result.timestamp > this.timestampPrev) {\n parent.videoFrameRate = ((result.framesDecoded - this.framesDecodedPrev) / ((result.timestamp - this.timestampPrev) / 1000)).toFixed(2);\n }\n }\n } else {\n parent.videoFrameRate = 0;\n }\n }\n\n _dumpItem (res) {\n let statsString = '{';\n let index = 0;\n\n Object.keys(res).forEach((k) => {\n statsString += `\"${k}\": \"${res[k]}\"`;\n if (++index !== res.length) {\n statsString += ',';\n }\n });\n statsString += '}';\n\n return statsString;\n }\n}\n"]}
|
|
File without changes
|