@techsee/techsee-media-service 999.7.9 → 999.8.7-roy-alpha1

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.
@@ -8,6 +8,7 @@ declare global {
8
8
  }
9
9
  export declare class LocalStreamManager {
10
10
  private environment;
11
+ private _groupedDevices;
11
12
  constructor(environment: IMediaEnvironment);
12
13
  getUserMediaStream(constraints: LocalMediaConstraints): Promise<MediaRequestSuccessResult>;
13
14
  getDesktopMediaStream(constraints: LocalVideoStreamConstraints): Promise<MediaRequestSuccessResult>;
@@ -15,7 +16,12 @@ export declare class LocalStreamManager {
15
16
  destroyDesktopMediaStream(): Promise<void>;
16
17
  clearAllStreams(): Promise<void>;
17
18
  private getHighestResolutionStream;
19
+ private getUserMediaStreamMediaDevice;
18
20
  private getStreamPromiseByParsedConstraints;
21
+ setGroupedDevices(groupedDevices: {
22
+ video: MediaDeviceInfo[];
23
+ audio: MediaDeviceInfo[];
24
+ }): void;
19
25
  private getParsedConstraints;
20
26
  private parseMediaErrorThenThrow;
21
27
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/LocalStreamManager.ts"],"names":[],"mappings":"AAKA,OAAO,EAAC,QAAQ,EAAC,MAAM,yBAAyB,CAAC;AAEjD,OAAO,EAEH,qBAAqB,EACrB,2BAA2B,EAE3B,yBAAyB,EACzB,iBAAiB,EACpB,MAAM,kBAAkB,CAAC;AAS1B,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,MAAM;QACZ,qBAAqB,EAAE,QAAQ,CAAC,yBAAyB,CAAC,CAAC;QAC3D,wBAAwB,EAAE,QAAQ,CAAC,yBAAyB,CAAC,CAAC;KACjE;CACJ;AAcD,qBAAa,kBAAkB;IAC3B,OAAO,CAAC,WAAW,CAAoB;gBAE3B,WAAW,EAAE,iBAAiB;IAO1C,kBAAkB,CAAC,WAAW,EAAE,qBAAqB,GAAG,OAAO,CAAC,yBAAyB,CAAC;IAyC1F,qBAAqB,CAAC,WAAW,EAAE,2BAA2B,GAAG,OAAO,CAAC,yBAAyB,CAAC;IA0CnG,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC;IAevC,yBAAyB,IAAI,OAAO,CAAC,IAAI,CAAC;IAe1C,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAShC,OAAO,CAAC,0BAA0B;IAqDlC,OAAO,CAAC,mCAAmC;IAsB3C,OAAO,CAAC,oBAAoB;IAsD5B,OAAO,CAAC,wBAAwB;CAoCnC","file":"LocalStreamManager.d.ts","sourcesContent":["import assign from 'lodash/assign';\nimport get from 'lodash/get';\nimport isEmpty from 'lodash/isEmpty';\nimport {Promise} from 'bluebird';\n\nimport {Nullable} from '@techsee/techsee-common';\n\nimport {\n VideoStreamResolution,\n LocalMediaConstraints,\n LocalVideoStreamConstraints,\n MediaRequestFailResult,\n MediaRequestSuccessResult,\n IMediaEnvironment\n} from './MediaContracts';\n\nimport {\n ConstraintType,\n DEFAULT_VIDEO_CONSTRAINT_TYPE,\n DEFAULT_VIDEO_RESOLUTION,\n MediaRequestErrorCode\n} from './MediaConstants';\n\ndeclare global {\n interface Window {\n latestUserMediaStream: Nullable<MediaRequestSuccessResult>;\n latestDesktopMediaStream: Nullable<MediaRequestSuccessResult>;\n }\n}\n\ndeclare const window: Window;\n\nwindow.latestUserMediaStream = null;\nlet userMediaPromise: Nullable<Promise<MediaRequestSuccessResult>> = null;\n\nwindow.latestDesktopMediaStream = null;\nlet desktopMediaPromise: Nullable<Promise<MediaRequestSuccessResult>> = null;\n\nimport {getMediaTracer} from './MediaUtils/MediaTracer';\n\nconst trace = getMediaTracer('LocalStreamManager');\n\nexport class LocalStreamManager {\n private environment: IMediaEnvironment;\n\n constructor(environment: IMediaEnvironment) {\n this.environment = environment;\n\n this.parseMediaErrorThenThrow = this.parseMediaErrorThenThrow.bind(this);\n this.clearAllStreams = this.clearAllStreams.bind(this);\n }\n\n getUserMediaStream(constraints: LocalMediaConstraints): Promise<MediaRequestSuccessResult> {\n trace.info('getUserMediaStream', constraints);\n if (userMediaPromise) {\n return userMediaPromise;\n }\n\n if (window.latestUserMediaStream) {\n const videoTrack = window.latestUserMediaStream.mediaStream.getVideoTracks();\n\n if (videoTrack.length > 0 && videoTrack[0].readyState === 'live') {\n return Promise.resolve({...window.latestUserMediaStream, isNew: false});\n }\n this.destroyUserMediaStream();\n\n }\n\n\n userMediaPromise = new Promise((resolve, reject) => {\n const catchHandler = (err: any): void => {\n userMediaPromise = null;\n window.latestUserMediaStream = null;\n trace.error('getUserMedia error', err);\n reject(err);\n };\n\n try {\n this.getHighestResolutionStream(false, constraints)\n .then((streamResult: MediaRequestSuccessResult) => {\n userMediaPromise = null;\n window.latestUserMediaStream = streamResult;\n resolve({...window.latestUserMediaStream, isNew: true});\n })\n .catch(catchHandler);\n } catch (err) {\n catchHandler(err);\n }\n });\n\n return userMediaPromise;\n }\n\n getDesktopMediaStream(constraints: LocalVideoStreamConstraints): Promise<MediaRequestSuccessResult> {\n if (desktopMediaPromise) {\n return desktopMediaPromise;\n }\n\n if (window.latestDesktopMediaStream) {\n const track = window.latestDesktopMediaStream.mediaStream.getVideoTracks();\n\n if (track.length > 0 && track[0].readyState === 'live') {\n //return Promise.resolve();\n return Promise.resolve({...window.latestDesktopMediaStream, isNew: false});\n }\n this.destroyDesktopMediaStream().catch((error: any) => {\n trace.error('Error destroying desktop media stream', error);\n });\n\n }\n\n desktopMediaPromise = new Promise((resolve, reject) => {\n const mediaCatchHandler = (err: any): void => {\n desktopMediaPromise = null;\n window.latestDesktopMediaStream = null;\n trace.error('getDisplayMedia error', err);\n reject(err);\n };\n\n try {\n this.getHighestResolutionStream(true, {video: constraints, audio: false})\n .then((streamResult: MediaRequestSuccessResult) => {\n desktopMediaPromise = null;\n window.latestDesktopMediaStream = streamResult;\n\n resolve({...window.latestDesktopMediaStream, isNew: true});\n }).catch(mediaCatchHandler);\n } catch (err) {\n mediaCatchHandler(err);\n }\n });\n\n return desktopMediaPromise;\n }\n\n destroyUserMediaStream(): Promise<void> {\n const streamResult = window.latestUserMediaStream;\n\n window.latestUserMediaStream = null;\n userMediaPromise = null;\n\n if (streamResult) {\n streamResult.mediaStream.getTracks().forEach((track: MediaStreamTrack) => {\n track.stop();\n });\n }\n\n return Promise.resolve();\n }\n\n destroyDesktopMediaStream(): Promise<void> {\n const streamResult = window.latestDesktopMediaStream;\n\n window.latestDesktopMediaStream = null;\n desktopMediaPromise = null;\n\n if (streamResult) {\n streamResult.mediaStream.getTracks().forEach((track: MediaStreamTrack) => {\n track.stop();\n });\n }\n\n return Promise.resolve();\n }\n\n clearAllStreams(): Promise<void> {\n trace.info('LocalStreamManager Clearing all streams');\n\n return Promise.all([\n this.destroyDesktopMediaStream(),\n this.destroyUserMediaStream()\n ]).then(() => undefined);\n }\n\n private getHighestResolutionStream(isDesktopMedia: boolean, constraints?: LocalMediaConstraints): Promise<MediaRequestSuccessResult> {\n const constraintsCandidates = this.getParsedConstraints(isDesktopMedia, constraints);\n\n if (constraintsCandidates.length === 0) {\n return Promise.reject(new Error('No constraints to retrieve the stream'));\n }\n\n return new Promise((resolve, reject) => {\n let lastSuccessfulResult: Nullable<MediaRequestSuccessResult> = null;\n let lastFailedResult: Nullable<MediaRequestFailResult> = null;\n let isStreamRequestFulfilled = false;\n\n (Promise as any).reduce(constraintsCandidates, (total: any, candidate: MediaStreamConstraints) => {\n if (isStreamRequestFulfilled) {\n return;\n }\n const constraintType = get(constraints, 'video.videoResolution.constraintType') || get(constraints, 'video.videoResolution[0].constraintType');\n\n return this.getStreamPromiseByParsedConstraints(candidate, isDesktopMedia)\n .then((stream: MediaStream) => {\n lastSuccessfulResult = {\n mediaStream: stream,\n constraint: candidate,\n constraintType,\n isNew: true\n };\n trace.info('getHighestResolutionStream Success', lastSuccessfulResult);\n isStreamRequestFulfilled = true;\n resolve(lastSuccessfulResult);\n })\n .catch((failResult: MediaRequestFailResult) => {\n lastFailedResult = failResult;\n if (lastFailedResult.errorCode === MediaRequestErrorCode.PermissionDenied) {\n isStreamRequestFulfilled = true;\n reject(lastFailedResult);\n }\n });\n }, 0)\n .then(() => {\n if (!isStreamRequestFulfilled) {\n if (!lastFailedResult) {\n lastFailedResult = {\n errorCode: MediaRequestErrorCode.GeneralError,\n message: 'Suitable stream cannot be created'\n };\n }\n reject(lastFailedResult);\n }\n });\n });\n }\n\n //@ts-ignore\n private getStreamPromiseByParsedConstraints(constraints: MediaStreamConstraints, isDesktopMedia: boolean): Promise<MediaStream> {\n let streamPromise = null;\n\n trace.info('getStreamPromiseByParsedConstraints', constraints);\n\n try {\n if (!isDesktopMedia) {\n streamPromise = navigator.mediaDevices.getUserMedia(constraints);\n } else {\n //@ts-ignore\n streamPromise = navigator.mediaDevices.getDisplayMedia\n //@ts-ignore\n ? navigator.mediaDevices.getDisplayMedia(constraints)\n : navigator.getDisplayMedia(constraints);\n }\n\n return streamPromise.catch(this.parseMediaErrorThenThrow);\n } catch (e) {\n this.parseMediaErrorThenThrow(e);\n }\n }\n\n private getParsedConstraints(isDesktopMedia: boolean, streamConstraints?: LocalMediaConstraints): MediaStreamConstraints[] {\n const constraintCandidates: MediaStreamConstraints[] = [];\n\n //TODO - Alex: need to understand which constraints not compatible with screen share\n if (isDesktopMedia) {\n return [{video: true}];\n }\n\n if (!streamConstraints) {\n return constraintCandidates;\n }\n\n const baseConstraints: MediaStreamConstraints = {};\n\n baseConstraints.audio = !isEmpty(streamConstraints.audio) ? streamConstraints.audio : undefined;\n\n if (!streamConstraints.video) {\n return [baseConstraints];\n }\n\n baseConstraints.video = {\n facingMode: 'environment',\n frameRate: {ideal: 15, max: 30}\n };\n\n const assignConstraint = (videoResolution: VideoStreamResolution): void => {\n const [width, height] = videoResolution.resolution.split('x');\n const constraintCandidate = assign({}, baseConstraints);\n\n constraintCandidate.video = assign({}, baseConstraints.video, {\n width: _constraintByType(width, videoResolution.constraintType),\n height: _constraintByType(height, videoResolution.constraintType)\n });\n constraintCandidates.push(constraintCandidate);\n };\n\n if ((baseConstraints.video && typeof streamConstraints.video === 'boolean') ||\n !((streamConstraints.video as LocalVideoStreamConstraints).videoResolution instanceof Array)) {\n\n const defaultResolution: VideoStreamResolution = {\n resolution: DEFAULT_VIDEO_RESOLUTION,\n constraintType: DEFAULT_VIDEO_CONSTRAINT_TYPE\n };\n\n assignConstraint(defaultResolution);\n\n return constraintCandidates;\n }\n\n (streamConstraints.video as any).videoResolution.forEach(assignConstraint);\n\n return constraintCandidates;\n }\n\n private parseMediaErrorThenThrow(error: any): MediaRequestFailResult {\n trace.error('Get media stream error.', error);\n const errorName = error && error.name ? error.name : '';\n\n const permissionErrorNames = [\n 'NotAllowedError',\n 'PermissionDismissedError',\n 'PermissionDeniedError'\n\n ];\n\n // const generalError = [\n // 'NotFoundError',\n // 'DevicesNotFoundError',\n // 'NotReadableError',\n // 'TrackStartError'\n // ];\n\n const constraintsErrors = [\n 'OverconstrainedError',\n 'ConstraintNotSatisfiedError'\n\n ];\n\n const isErrorOfType = (errorsArr: string[]) => errorsArr.filter((err: string) => err === errorName).length > 0;\n\n if (isErrorOfType(permissionErrorNames)) {\n throw {errorCode: MediaRequestErrorCode.PermissionDenied, message: errorName};\n }\n\n if (isErrorOfType(constraintsErrors)) {\n throw {errorCode: MediaRequestErrorCode.Overconstrained, message: errorName};\n }\n\n throw {errorCode: MediaRequestErrorCode.GeneralError, message: errorName};\n }\n}\n\nfunction _constraintByType(value: any, type: ConstraintType): any {\n switch (type) {\n case ConstraintType.MIN:\n return {min: value};\n default:\n return {ideal: value};\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/LocalStreamManager.ts"],"names":[],"mappings":"AAKA,OAAO,EAAC,QAAQ,EAAC,MAAM,yBAAyB,CAAC;AAEjD,OAAO,EAEH,qBAAqB,EACrB,2BAA2B,EAE3B,yBAAyB,EACzB,iBAAiB,EACpB,MAAM,kBAAkB,CAAC;AAS1B,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,MAAM;QACZ,qBAAqB,EAAE,QAAQ,CAAC,yBAAyB,CAAC,CAAC;QAC3D,wBAAwB,EAAE,QAAQ,CAAC,yBAAyB,CAAC,CAAC;KACjE;CACJ;AAcD,qBAAa,kBAAkB;IAC3B,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,eAAe,CAAoG;gBAE/G,WAAW,EAAE,iBAAiB;IAO1C,kBAAkB,CAAC,WAAW,EAAE,qBAAqB,GAAG,OAAO,CAAC,yBAAyB,CAAC;IAwC1F,qBAAqB,CAAC,WAAW,EAAE,2BAA2B,GAAG,OAAO,CAAC,yBAAyB,CAAC;IA4CnG,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC;IAevC,yBAAyB,IAAI,OAAO,CAAC,IAAI,CAAC;IAe1C,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAShC,OAAO,CAAC,0BAA0B;IAwDlC,OAAO,CAAC,6BAA6B;IAiBrC,OAAO,CAAC,mCAAmC;IAgD3C,iBAAiB,CAAC,cAAc,EAAE;QAAC,KAAK,EAAE,eAAe,EAAE,CAAC;QAAC,KAAK,EAAE,eAAe,EAAE,CAAA;KAAC;IAKtF,OAAO,CAAC,oBAAoB;IA4D5B,OAAO,CAAC,wBAAwB;CAwCnC","file":"LocalStreamManager.d.ts","sourcesContent":["import assign from 'lodash/assign';\nimport get from 'lodash/get';\nimport last from 'lodash/last';\nimport {Promise} from 'bluebird';\n\nimport {Nullable} from '@techsee/techsee-common';\n\nimport {\n VideoStreamResolution,\n LocalMediaConstraints,\n LocalVideoStreamConstraints,\n MediaRequestFailResult,\n MediaRequestSuccessResult,\n IMediaEnvironment\n} from './MediaContracts';\n\nimport {\n ConstraintType,\n DEFAULT_VIDEO_CONSTRAINT_TYPE,\n DEFAULT_VIDEO_RESOLUTION,\n MediaRequestErrorCode\n} from './MediaConstants';\n\ndeclare global {\n interface Window {\n latestUserMediaStream: Nullable<MediaRequestSuccessResult>;\n latestDesktopMediaStream: Nullable<MediaRequestSuccessResult>;\n }\n}\n\ndeclare const window: Window;\n\nwindow.latestUserMediaStream = null;\nlet userMediaPromise: Nullable<Promise<MediaRequestSuccessResult>> = null;\n\nwindow.latestDesktopMediaStream = null;\nlet desktopMediaPromise: Nullable<Promise<MediaRequestSuccessResult>> = null;\n\nimport {getMediaTracer} from './MediaUtils/MediaTracer';\n\nconst trace = getMediaTracer('LocalStreamManager');\n\nexport class LocalStreamManager {\n private environment: IMediaEnvironment;\n private _groupedDevices: {video: Nullable<MediaDeviceInfo>; audio: Nullable<MediaDeviceInfo>} = {video: null, audio: null};\n\n constructor(environment: IMediaEnvironment) {\n this.environment = environment;\n\n this.parseMediaErrorThenThrow = this.parseMediaErrorThenThrow.bind(this);\n this.clearAllStreams = this.clearAllStreams.bind(this);\n }\n\n getUserMediaStream(constraints: LocalMediaConstraints): Promise<MediaRequestSuccessResult> {\n trace.info('getUserMediaStream', constraints);\n if (userMediaPromise) {\n return userMediaPromise;\n }\n\n if (window.latestUserMediaStream) {\n const videoTrack = window.latestUserMediaStream.mediaStream.getVideoTracks();\n\n if (videoTrack.length > 0 && videoTrack[0].readyState === 'live') {\n return Promise.resolve({...window.latestUserMediaStream, isNew: false});\n }\n\n this.destroyUserMediaStream();\n }\n\n userMediaPromise = new Promise((resolve, reject) => {\n const catchHandler = (err: any): void => {\n userMediaPromise = null;\n window.latestUserMediaStream = null;\n trace.error('getUserMedia error', err);\n reject(err);\n };\n\n try {\n this.getHighestResolutionStream(false, constraints)\n .then((streamResult: MediaRequestSuccessResult) => {\n userMediaPromise = null;\n window.latestUserMediaStream = streamResult;\n resolve({...window.latestUserMediaStream, isNew: true});\n })\n .catch(catchHandler);\n } catch (err) {\n catchHandler(err);\n }\n });\n\n return userMediaPromise;\n }\n\n getDesktopMediaStream(constraints: LocalVideoStreamConstraints): Promise<MediaRequestSuccessResult> {\n if (desktopMediaPromise) {\n return desktopMediaPromise;\n }\n\n trace.info('getDesktopMediaStream', constraints);\n\n if (window.latestDesktopMediaStream) {\n const track = window.latestDesktopMediaStream.mediaStream.getVideoTracks();\n\n if (track.length > 0 && track[0].readyState === 'live') {\n //return Promise.resolve();\n return Promise.resolve({...window.latestDesktopMediaStream, isNew: false});\n }\n this.destroyDesktopMediaStream().catch((error: any) => {\n trace.error('Error destroying desktop media stream', error);\n });\n\n }\n\n desktopMediaPromise = new Promise((resolve, reject) => {\n const mediaCatchHandler = (err: any): void => {\n desktopMediaPromise = null;\n window.latestDesktopMediaStream = null;\n trace.error('getDisplayMedia error', err);\n reject(err);\n };\n\n try {\n this.getHighestResolutionStream(true, {video: constraints, audio: false})\n .then((streamResult: MediaRequestSuccessResult) => {\n desktopMediaPromise = null;\n window.latestDesktopMediaStream = streamResult;\n\n resolve({...window.latestDesktopMediaStream, isNew: true});\n }).catch(mediaCatchHandler);\n } catch (err) {\n mediaCatchHandler(err);\n }\n });\n\n return desktopMediaPromise;\n }\n\n destroyUserMediaStream(): Promise<void> {\n const streamResult = window.latestUserMediaStream;\n\n window.latestUserMediaStream = null;\n userMediaPromise = null;\n\n if (streamResult && streamResult.mediaStream) {\n streamResult.mediaStream.getTracks().forEach((track: MediaStreamTrack) => {\n track.stop();\n });\n }\n\n return Promise.resolve();\n }\n\n destroyDesktopMediaStream(): Promise<void> {\n const streamResult = window.latestDesktopMediaStream;\n\n window.latestDesktopMediaStream = null;\n desktopMediaPromise = null;\n\n if (streamResult && streamResult.mediaStream) {\n streamResult.mediaStream.getTracks().forEach((track: MediaStreamTrack) => {\n track.stop();\n });\n }\n\n return Promise.resolve();\n }\n\n clearAllStreams(): Promise<void> {\n trace.info('LocalStreamManager Clearing all streams');\n\n return Promise.all([\n this.destroyDesktopMediaStream(),\n this.destroyUserMediaStream()\n ]).then(() => undefined);\n }\n\n private getHighestResolutionStream(isDesktopMedia: boolean, constraints?: LocalMediaConstraints): Promise<MediaRequestSuccessResult> {\n const constraintsCandidates = this.getParsedConstraints(isDesktopMedia, constraints);\n\n trace.info('getHighestResolutionStream - constraintsCandidates:', constraintsCandidates);\n\n if (constraintsCandidates.length === 0) {\n return Promise.reject(new Error('No constraints to retrieve the stream'));\n }\n\n return new Promise((resolve, reject) => {\n let lastSuccessfulResult: Nullable<MediaRequestSuccessResult> = null;\n let lastFailedResult: Nullable<MediaRequestFailResult> = null;\n let isStreamRequestFulfilled = false;\n\n (Promise as any).reduce(constraintsCandidates, (total: any, candidate: MediaStreamConstraints) => {\n if (isStreamRequestFulfilled) {\n return;\n }\n\n const constraintType = get(constraints, 'video.videoResolution.constraintType') || get(constraints, 'video.videoResolution[0].constraintType');\n\n return this.getStreamPromiseByParsedConstraints(candidate, isDesktopMedia)\n .then((stream: MediaStream) => {\n lastSuccessfulResult = {\n mediaStream: stream,\n constraint: candidate,\n constraintType,\n isNew: true\n };\n trace.info('getHighestResolutionStream Success', lastSuccessfulResult);\n isStreamRequestFulfilled = true;\n resolve(lastSuccessfulResult);\n })\n .catch((failResult: MediaRequestFailResult) => {\n lastFailedResult = failResult;\n\n if (lastFailedResult.errorCode === MediaRequestErrorCode.PermissionDenied) {\n isStreamRequestFulfilled = true;\n reject(lastFailedResult);\n }\n });\n }, 0)\n .then(() => {\n if (!isStreamRequestFulfilled) {\n if (!lastFailedResult) {\n lastFailedResult = {\n errorCode: MediaRequestErrorCode.GeneralError,\n message: 'Suitable stream cannot be created'\n };\n }\n reject(lastFailedResult);\n }\n });\n });\n }\n\n private getUserMediaStreamMediaDevice(constraints: MediaStreamConstraints, isDesktopMedia: boolean) {\n let streamPromise = null;\n\n if (!isDesktopMedia) {\n streamPromise = navigator.mediaDevices.getUserMedia(constraints);\n } else {\n //@ts-ignore\n streamPromise = navigator.mediaDevices.getDisplayMedia\n //@ts-ignore\n ? navigator.mediaDevices.getDisplayMedia(constraints)\n : navigator.getDisplayMedia(constraints);\n }\n\n return streamPromise;\n }\n\n //@ts-ignore\n private getStreamPromiseByParsedConstraints(constraints: MediaStreamConstraints, isDesktopMedia: boolean): Promise<MediaStream> {\n trace.info('getStreamPromiseByParsedConstraints', constraints);\n\n try {\n return this.getUserMediaStreamMediaDevice(constraints, isDesktopMedia).catch((err: any) => {\n let streamPromise = null;\n\n trace.info('getStreamPromiseByParsedConstraints - get user stream error', err.name);\n\n // Android (Galaxy esp.) have a bug that when using facingMode it might cause NotReadableError. So\n // we should try again but without facingMode. The exception to the rule is when we don't have specific\n // device to use (like in IOS13 bug, as can be seen in MediaServiceBase.ts), in that case, we might end\n // up using the front camera, which is a privacy concern and the preference is to fallback from video\n if (err && (err.name === 'NotReadableError') && get(constraints, 'video.facingMode') &&\n get(this._groupedDevices, 'video.deviceId')) {\n\n const newConstraints = constraints;\n\n trace.info('getStreamPromiseByParsedConstraints - NotReadableError - Failed to get video user media stream with facingMode=environment', err.name);\n\n // @ts-ignore\n delete newConstraints.video.facingMode;\n\n streamPromise = this.getStreamPromiseByParsedConstraints(newConstraints, isDesktopMedia);\n } else if (err && err.name && constraints.audio && !constraints.video) {\n trace.info('getStreamPromiseByParsedConstraints - audioStreamFailed - Failed to get audio user media stream', err.name);\n\n return this.parseMediaErrorThenThrow({name: 'audioStreamFailed'});\n } else if (err && err.name && constraints.audio) {\n const newConstraints = constraints;\n\n trace.info('getStreamPromiseByParsedConstraints - Failed to get video and audio user media stream, try to get video media stream only', err.name);\n\n newConstraints.audio = false;\n streamPromise = this.getStreamPromiseByParsedConstraints(newConstraints, isDesktopMedia);\n } else if (err && !streamPromise) {\n trace.info('getStreamPromiseByParsedConstraints - Failed to get video user media stream', err && err.name);\n\n streamPromise = Promise.reject(err);\n }\n\n return streamPromise && streamPromise.catch(this.parseMediaErrorThenThrow);\n });\n } catch (e) {\n this.parseMediaErrorThenThrow(e);\n }\n }\n\n setGroupedDevices(groupedDevices: {video: MediaDeviceInfo[]; audio: MediaDeviceInfo[]}) {\n trace.info('setGroupedDevices', groupedDevices);\n this._groupedDevices = {video: last(groupedDevices.video) || null, audio: last(groupedDevices.audio) || null};\n }\n\n private getParsedConstraints(isDesktopMedia: boolean, streamConstraints?: LocalMediaConstraints): MediaStreamConstraints[] {\n const constraintCandidates: MediaStreamConstraints[] = [];\n\n //TODO - Alex: need to understand which constraints not compatible with screen share\n if (isDesktopMedia) {\n return [{video: true}];\n }\n\n if (!streamConstraints) {\n return constraintCandidates;\n }\n\n const baseConstraints: MediaStreamConstraints = {};\n\n baseConstraints.audio = typeof streamConstraints.audio === 'boolean' ? streamConstraints.audio : undefined;\n\n if (!streamConstraints.video) {\n return [baseConstraints];\n }\n\n baseConstraints.video = {\n facingMode: 'environment',\n frameRate: {ideal: 15, max: 30}\n };\n\n const deviceId = get(this._groupedDevices, 'video.deviceId');\n\n if (deviceId) {\n baseConstraints.video.deviceId = deviceId;\n }\n\n const assignConstraint = (videoResolution: VideoStreamResolution): void => {\n const [width, height] = videoResolution.resolution.split('x');\n const constraintCandidate = assign({}, baseConstraints);\n\n constraintCandidate.video = assign({}, baseConstraints.video, {\n width: _constraintByType(width, videoResolution.constraintType),\n height: _constraintByType(height, videoResolution.constraintType)\n });\n constraintCandidates.push(constraintCandidate);\n };\n\n if ((baseConstraints.video && typeof streamConstraints.video === 'boolean') ||\n !((streamConstraints.video as LocalVideoStreamConstraints).videoResolution instanceof Array)) {\n\n const defaultResolution: VideoStreamResolution = {\n resolution: DEFAULT_VIDEO_RESOLUTION,\n constraintType: DEFAULT_VIDEO_CONSTRAINT_TYPE\n };\n\n assignConstraint(defaultResolution);\n\n return constraintCandidates;\n }\n\n (streamConstraints.video as any).videoResolution.forEach(assignConstraint);\n\n return constraintCandidates;\n }\n\n private parseMediaErrorThenThrow(error: any): MediaRequestFailResult {\n if (error && error.errorCode) {\n throw error;\n }\n\n trace.error('Get media stream error.', error);\n const errorName = error && error.name ? error.name : '';\n\n const permissionErrorNames = [\n 'NotAllowedError',\n 'PermissionDismissedError',\n 'PermissionDeniedError'\n\n ];\n\n // const generalError = [\n // 'NotFoundError',\n // 'DevicesNotFoundError',\n // 'NotReadableError',\n // 'TrackStartError'\n // ];\n\n const constraintsErrors = [\n 'OverconstrainedError',\n 'ConstraintNotSatisfiedError'\n\n ];\n\n const isErrorOfType = (errorsArr: string[]) => errorsArr.filter((err: string) => err === errorName).length > 0;\n\n if (isErrorOfType(permissionErrorNames)) {\n throw {errorCode: MediaRequestErrorCode.PermissionDenied, message: errorName};\n }\n\n if (isErrorOfType(constraintsErrors)) {\n throw {errorCode: MediaRequestErrorCode.Overconstrained, message: errorName};\n }\n\n throw {errorCode: MediaRequestErrorCode.GeneralError, message: errorName};\n }\n}\n\nfunction _constraintByType(value: any, type: ConstraintType): any {\n switch (type) {\n case ConstraintType.MIN:\n return {min: value};\n default:\n return {ideal: value};\n }\n}\n"]}
@@ -18,7 +18,7 @@ var __importDefault = undefined && undefined.__importDefault || function (mod) {
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
19
  var assign_1 = __importDefault(require("lodash/assign"));
20
20
  var get_1 = __importDefault(require("lodash/get"));
21
- var isEmpty_1 = __importDefault(require("lodash/isEmpty"));
21
+ var last_1 = __importDefault(require("lodash/last"));
22
22
  var bluebird_1 = require("bluebird");
23
23
  var MediaConstants_1 = require("./MediaConstants");
24
24
  window.latestUserMediaStream = null;
@@ -29,6 +29,7 @@ var MediaTracer_1 = require("./MediaUtils/MediaTracer");
29
29
  var trace = MediaTracer_1.getMediaTracer('LocalStreamManager');
30
30
  var LocalStreamManager = /** @class */function () {
31
31
  function LocalStreamManager(environment) {
32
+ this._groupedDevices = { video: null, audio: null };
32
33
  this.environment = environment;
33
34
  this.parseMediaErrorThenThrow = this.parseMediaErrorThenThrow.bind(this);
34
35
  this.clearAllStreams = this.clearAllStreams.bind(this);
@@ -70,6 +71,7 @@ var LocalStreamManager = /** @class */function () {
70
71
  if (desktopMediaPromise) {
71
72
  return desktopMediaPromise;
72
73
  }
74
+ trace.info('getDesktopMediaStream', constraints);
73
75
  if (window.latestDesktopMediaStream) {
74
76
  var track = window.latestDesktopMediaStream.mediaStream.getVideoTracks();
75
77
  if (track.length > 0 && track[0].readyState === 'live') {
@@ -103,7 +105,7 @@ var LocalStreamManager = /** @class */function () {
103
105
  var streamResult = window.latestUserMediaStream;
104
106
  window.latestUserMediaStream = null;
105
107
  userMediaPromise = null;
106
- if (streamResult) {
108
+ if (streamResult && streamResult.mediaStream) {
107
109
  streamResult.mediaStream.getTracks().forEach(function (track) {
108
110
  track.stop();
109
111
  });
@@ -114,7 +116,7 @@ var LocalStreamManager = /** @class */function () {
114
116
  var streamResult = window.latestDesktopMediaStream;
115
117
  window.latestDesktopMediaStream = null;
116
118
  desktopMediaPromise = null;
117
- if (streamResult) {
119
+ if (streamResult && streamResult.mediaStream) {
118
120
  streamResult.mediaStream.getTracks().forEach(function (track) {
119
121
  track.stop();
120
122
  });
@@ -130,6 +132,7 @@ var LocalStreamManager = /** @class */function () {
130
132
  LocalStreamManager.prototype.getHighestResolutionStream = function (isDesktopMedia, constraints) {
131
133
  var _this = this;
132
134
  var constraintsCandidates = this.getParsedConstraints(isDesktopMedia, constraints);
135
+ trace.info('getHighestResolutionStream - constraintsCandidates:', constraintsCandidates);
133
136
  if (constraintsCandidates.length === 0) {
134
137
  return bluebird_1.Promise.reject(new Error('No constraints to retrieve the stream'));
135
138
  }
@@ -172,24 +175,58 @@ var LocalStreamManager = /** @class */function () {
172
175
  });
173
176
  });
174
177
  };
178
+ LocalStreamManager.prototype.getUserMediaStreamMediaDevice = function (constraints, isDesktopMedia) {
179
+ var streamPromise = null;
180
+ if (!isDesktopMedia) {
181
+ streamPromise = navigator.mediaDevices.getUserMedia(constraints);
182
+ } else {
183
+ //@ts-ignore
184
+ streamPromise = navigator.mediaDevices.getDisplayMedia
185
+ //@ts-ignore
186
+ ? navigator.mediaDevices.getDisplayMedia(constraints) : navigator.getDisplayMedia(constraints);
187
+ }
188
+ return streamPromise;
189
+ };
175
190
  //@ts-ignore
176
191
  LocalStreamManager.prototype.getStreamPromiseByParsedConstraints = function (constraints, isDesktopMedia) {
177
- var streamPromise = null;
192
+ var _this = this;
178
193
  trace.info('getStreamPromiseByParsedConstraints', constraints);
179
194
  try {
180
- if (!isDesktopMedia) {
181
- streamPromise = navigator.mediaDevices.getUserMedia(constraints);
182
- } else {
183
- //@ts-ignore
184
- streamPromise = navigator.mediaDevices.getDisplayMedia
185
- //@ts-ignore
186
- ? navigator.mediaDevices.getDisplayMedia(constraints) : navigator.getDisplayMedia(constraints);
187
- }
188
- return streamPromise.catch(this.parseMediaErrorThenThrow);
195
+ return this.getUserMediaStreamMediaDevice(constraints, isDesktopMedia).catch(function (err) {
196
+ var streamPromise = null;
197
+ trace.info('getStreamPromiseByParsedConstraints - get user stream error', err.name);
198
+ // Android (Galaxy esp.) have a bug that when using facingMode it might cause NotReadableError. So
199
+ // we should try again but without facingMode. The exception to the rule is when we don't have specific
200
+ // device to use (like in IOS13 bug, as can be seen in MediaServiceBase.ts), in that case, we might end
201
+ // up using the front camera, which is a privacy concern and the preference is to fallback from video
202
+ if (err && err.name === 'NotReadableError' && get_1.default(constraints, 'video.facingMode') && get_1.default(_this._groupedDevices, 'video.deviceId')) {
203
+ var newConstraints = constraints;
204
+ trace.info('getStreamPromiseByParsedConstraints - NotReadableError - Failed to get video user media stream with facingMode=environment', err.name);
205
+ // @ts-ignore
206
+ delete newConstraints.video.facingMode;
207
+ streamPromise = _this.getStreamPromiseByParsedConstraints(newConstraints, isDesktopMedia);
208
+ } else if (err && err.name && constraints.audio && !constraints.video) {
209
+ trace.info('getStreamPromiseByParsedConstraints - audioStreamFailed - Failed to get audio user media stream', err.name);
210
+ return _this.parseMediaErrorThenThrow({ name: 'audioStreamFailed' });
211
+ } else if (err && err.name && constraints.audio) {
212
+ var newConstraints = constraints;
213
+ trace.info('getStreamPromiseByParsedConstraints - Failed to get video and audio user media stream, try to get video media stream only', err.name);
214
+ newConstraints.audio = false;
215
+ streamPromise = _this.getStreamPromiseByParsedConstraints(newConstraints, isDesktopMedia);
216
+ } else if (err && !streamPromise) {
217
+ trace.info('getStreamPromiseByParsedConstraints - Failed to get video user media stream', err && err.name);
218
+ streamPromise = bluebird_1.Promise.reject(err);
219
+ }
220
+ return streamPromise && streamPromise.catch(_this.parseMediaErrorThenThrow);
221
+ });
189
222
  } catch (e) {
190
223
  this.parseMediaErrorThenThrow(e);
191
224
  }
192
225
  };
226
+ LocalStreamManager.prototype.setGroupedDevices = function (groupedDevices) {
227
+ trace.info('setGroupedDevices', groupedDevices);
228
+ this._groupedDevices = { video: last_1.default(groupedDevices.video) || null, audio: last_1.default(groupedDevices.audio) || null };
229
+ };
193
230
  LocalStreamManager.prototype.getParsedConstraints = function (isDesktopMedia, streamConstraints) {
194
231
  var constraintCandidates = [];
195
232
  //TODO - Alex: need to understand which constraints not compatible with screen share
@@ -200,7 +237,7 @@ var LocalStreamManager = /** @class */function () {
200
237
  return constraintCandidates;
201
238
  }
202
239
  var baseConstraints = {};
203
- baseConstraints.audio = !isEmpty_1.default(streamConstraints.audio) ? streamConstraints.audio : undefined;
240
+ baseConstraints.audio = typeof streamConstraints.audio === 'boolean' ? streamConstraints.audio : undefined;
204
241
  if (!streamConstraints.video) {
205
242
  return [baseConstraints];
206
243
  }
@@ -208,6 +245,10 @@ var LocalStreamManager = /** @class */function () {
208
245
  facingMode: 'environment',
209
246
  frameRate: { ideal: 15, max: 30 }
210
247
  };
248
+ var deviceId = get_1.default(this._groupedDevices, 'video.deviceId');
249
+ if (deviceId) {
250
+ baseConstraints.video.deviceId = deviceId;
251
+ }
211
252
  var assignConstraint = function assignConstraint(videoResolution) {
212
253
  var _a = videoResolution.resolution.split('x'),
213
254
  width = _a[0],
@@ -231,6 +272,9 @@ var LocalStreamManager = /** @class */function () {
231
272
  return constraintCandidates;
232
273
  };
233
274
  LocalStreamManager.prototype.parseMediaErrorThenThrow = function (error) {
275
+ if (error && error.errorCode) {
276
+ throw error;
277
+ }
234
278
  trace.error('Get media stream error.', error);
235
279
  var errorName = error && error.name ? error.name : '';
236
280
  var permissionErrorNames = ['NotAllowedError', 'PermissionDismissedError', 'PermissionDeniedError'];
@@ -1 +1 @@
1
- {"version":3,"sources":["LocalStreamManager.js","../src/LocalStreamManager.ts"],"names":["__assign","Object","assign","t","s","i","n","arguments","length","p","prototype","hasOwnProperty","call","apply","__importDefault","mod","__esModule","defineProperty","exports","value","assign_1","require","get_1","isEmpty_1","bluebird_1","MediaConstants_1","window","latestUserMediaStream","userMediaPromise","latestDesktopMediaStream","desktopMediaPromise","MediaTracer_1","trace","getMediaTracer","LocalStreamManager","environment","parseMediaErrorThenThrow","bind","clearAllStreams","getUserMediaStream","constraints","_this","info","videoTrack","mediaStream","getVideoTracks","readyState","Promise","resolve","isNew","destroyUserMediaStream","reject","catchHandler","err","error","getHighestResolutionStream","then","streamResult","catch","getDesktopMediaStream","track","destroyDesktopMediaStream","mediaCatchHandler","video","audio","getTracks","forEach","stop","all","undefined","isDesktopMedia","constraintsCandidates","getParsedConstraints","Error","lastSuccessfulResult","lastFailedResult","isStreamRequestFulfilled","reduce","total","candidate","constraintType","default","getStreamPromiseByParsedConstraints","stream","constraint","failResult","errorCode","MediaRequestErrorCode","PermissionDenied","GeneralError","message","streamPromise","navigator","mediaDevices","getUserMedia","getDisplayMedia","e","streamConstraints","constraintCandidates","baseConstraints","facingMode","frameRate","ideal","max","assignConstraint","videoResolution","_a","resolution","split","width","height","constraintCandidate","_constraintByType","push","Array","defaultResolution","DEFAULT_VIDEO_RESOLUTION","DEFAULT_VIDEO_CONSTRAINT_TYPE","errorName","name","permissionErrorNames","constraintsErrors","isErrorOfType","errorsArr","filter","Overconstrained","type","ConstraintType","MIN","min"],"mappings":"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","file":"LocalStreamManager.js","sourcesContent":["\"use strict\";\nvar __assign = (this && this.__assign) || function () {\n __assign = Object.assign || function(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\n t[p] = s[p];\n }\n return t;\n };\n return __assign.apply(this, arguments);\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar assign_1 = __importDefault(require(\"lodash/assign\"));\nvar get_1 = __importDefault(require(\"lodash/get\"));\nvar isEmpty_1 = __importDefault(require(\"lodash/isEmpty\"));\nvar bluebird_1 = require(\"bluebird\");\nvar MediaConstants_1 = require(\"./MediaConstants\");\nwindow.latestUserMediaStream = null;\nvar userMediaPromise = null;\nwindow.latestDesktopMediaStream = null;\nvar desktopMediaPromise = null;\nvar MediaTracer_1 = require(\"./MediaUtils/MediaTracer\");\nvar trace = MediaTracer_1.getMediaTracer('LocalStreamManager');\nvar LocalStreamManager = /** @class */ (function () {\n function LocalStreamManager(environment) {\n this.environment = environment;\n this.parseMediaErrorThenThrow = this.parseMediaErrorThenThrow.bind(this);\n this.clearAllStreams = this.clearAllStreams.bind(this);\n }\n LocalStreamManager.prototype.getUserMediaStream = function (constraints) {\n var _this = this;\n trace.info('getUserMediaStream', constraints);\n if (userMediaPromise) {\n return userMediaPromise;\n }\n if (window.latestUserMediaStream) {\n var videoTrack = window.latestUserMediaStream.mediaStream.getVideoTracks();\n if (videoTrack.length > 0 && videoTrack[0].readyState === 'live') {\n return bluebird_1.Promise.resolve(__assign({}, window.latestUserMediaStream, { isNew: false }));\n }\n this.destroyUserMediaStream();\n }\n userMediaPromise = new bluebird_1.Promise(function (resolve, reject) {\n var catchHandler = function (err) {\n userMediaPromise = null;\n window.latestUserMediaStream = null;\n trace.error('getUserMedia error', err);\n reject(err);\n };\n try {\n _this.getHighestResolutionStream(false, constraints)\n .then(function (streamResult) {\n userMediaPromise = null;\n window.latestUserMediaStream = streamResult;\n resolve(__assign({}, window.latestUserMediaStream, { isNew: true }));\n })\n .catch(catchHandler);\n }\n catch (err) {\n catchHandler(err);\n }\n });\n return userMediaPromise;\n };\n LocalStreamManager.prototype.getDesktopMediaStream = function (constraints) {\n var _this = this;\n if (desktopMediaPromise) {\n return desktopMediaPromise;\n }\n if (window.latestDesktopMediaStream) {\n var track = window.latestDesktopMediaStream.mediaStream.getVideoTracks();\n if (track.length > 0 && track[0].readyState === 'live') {\n //return Promise.resolve();\n return bluebird_1.Promise.resolve(__assign({}, window.latestDesktopMediaStream, { isNew: false }));\n }\n this.destroyDesktopMediaStream().catch(function (error) {\n trace.error('Error destroying desktop media stream', error);\n });\n }\n desktopMediaPromise = new bluebird_1.Promise(function (resolve, reject) {\n var mediaCatchHandler = function (err) {\n desktopMediaPromise = null;\n window.latestDesktopMediaStream = null;\n trace.error('getDisplayMedia error', err);\n reject(err);\n };\n try {\n _this.getHighestResolutionStream(true, { video: constraints, audio: false })\n .then(function (streamResult) {\n desktopMediaPromise = null;\n window.latestDesktopMediaStream = streamResult;\n resolve(__assign({}, window.latestDesktopMediaStream, { isNew: true }));\n }).catch(mediaCatchHandler);\n }\n catch (err) {\n mediaCatchHandler(err);\n }\n });\n return desktopMediaPromise;\n };\n LocalStreamManager.prototype.destroyUserMediaStream = function () {\n var streamResult = window.latestUserMediaStream;\n window.latestUserMediaStream = null;\n userMediaPromise = null;\n if (streamResult) {\n streamResult.mediaStream.getTracks().forEach(function (track) {\n track.stop();\n });\n }\n return bluebird_1.Promise.resolve();\n };\n LocalStreamManager.prototype.destroyDesktopMediaStream = function () {\n var streamResult = window.latestDesktopMediaStream;\n window.latestDesktopMediaStream = null;\n desktopMediaPromise = null;\n if (streamResult) {\n streamResult.mediaStream.getTracks().forEach(function (track) {\n track.stop();\n });\n }\n return bluebird_1.Promise.resolve();\n };\n LocalStreamManager.prototype.clearAllStreams = function () {\n trace.info('LocalStreamManager Clearing all streams');\n return bluebird_1.Promise.all([\n this.destroyDesktopMediaStream(),\n this.destroyUserMediaStream()\n ]).then(function () { return undefined; });\n };\n LocalStreamManager.prototype.getHighestResolutionStream = function (isDesktopMedia, constraints) {\n var _this = this;\n var constraintsCandidates = this.getParsedConstraints(isDesktopMedia, constraints);\n if (constraintsCandidates.length === 0) {\n return bluebird_1.Promise.reject(new Error('No constraints to retrieve the stream'));\n }\n return new bluebird_1.Promise(function (resolve, reject) {\n var lastSuccessfulResult = null;\n var lastFailedResult = null;\n var isStreamRequestFulfilled = false;\n bluebird_1.Promise.reduce(constraintsCandidates, function (total, candidate) {\n if (isStreamRequestFulfilled) {\n return;\n }\n var constraintType = get_1.default(constraints, 'video.videoResolution.constraintType') || get_1.default(constraints, 'video.videoResolution[0].constraintType');\n return _this.getStreamPromiseByParsedConstraints(candidate, isDesktopMedia)\n .then(function (stream) {\n lastSuccessfulResult = {\n mediaStream: stream,\n constraint: candidate,\n constraintType: constraintType,\n isNew: true\n };\n trace.info('getHighestResolutionStream Success', lastSuccessfulResult);\n isStreamRequestFulfilled = true;\n resolve(lastSuccessfulResult);\n })\n .catch(function (failResult) {\n lastFailedResult = failResult;\n if (lastFailedResult.errorCode === MediaConstants_1.MediaRequestErrorCode.PermissionDenied) {\n isStreamRequestFulfilled = true;\n reject(lastFailedResult);\n }\n });\n }, 0)\n .then(function () {\n if (!isStreamRequestFulfilled) {\n if (!lastFailedResult) {\n lastFailedResult = {\n errorCode: MediaConstants_1.MediaRequestErrorCode.GeneralError,\n message: 'Suitable stream cannot be created'\n };\n }\n reject(lastFailedResult);\n }\n });\n });\n };\n //@ts-ignore\n LocalStreamManager.prototype.getStreamPromiseByParsedConstraints = function (constraints, isDesktopMedia) {\n var streamPromise = null;\n trace.info('getStreamPromiseByParsedConstraints', constraints);\n try {\n if (!isDesktopMedia) {\n streamPromise = navigator.mediaDevices.getUserMedia(constraints);\n }\n else {\n //@ts-ignore\n streamPromise = navigator.mediaDevices.getDisplayMedia\n //@ts-ignore\n ? navigator.mediaDevices.getDisplayMedia(constraints)\n : navigator.getDisplayMedia(constraints);\n }\n return streamPromise.catch(this.parseMediaErrorThenThrow);\n }\n catch (e) {\n this.parseMediaErrorThenThrow(e);\n }\n };\n LocalStreamManager.prototype.getParsedConstraints = function (isDesktopMedia, streamConstraints) {\n var constraintCandidates = [];\n //TODO - Alex: need to understand which constraints not compatible with screen share\n if (isDesktopMedia) {\n return [{ video: true }];\n }\n if (!streamConstraints) {\n return constraintCandidates;\n }\n var baseConstraints = {};\n baseConstraints.audio = !isEmpty_1.default(streamConstraints.audio) ? streamConstraints.audio : undefined;\n if (!streamConstraints.video) {\n return [baseConstraints];\n }\n baseConstraints.video = {\n facingMode: 'environment',\n frameRate: { ideal: 15, max: 30 }\n };\n var assignConstraint = function (videoResolution) {\n var _a = videoResolution.resolution.split('x'), width = _a[0], height = _a[1];\n var constraintCandidate = assign_1.default({}, baseConstraints);\n constraintCandidate.video = assign_1.default({}, baseConstraints.video, {\n width: _constraintByType(width, videoResolution.constraintType),\n height: _constraintByType(height, videoResolution.constraintType)\n });\n constraintCandidates.push(constraintCandidate);\n };\n if ((baseConstraints.video && typeof streamConstraints.video === 'boolean') ||\n !(streamConstraints.video.videoResolution instanceof Array)) {\n var defaultResolution = {\n resolution: MediaConstants_1.DEFAULT_VIDEO_RESOLUTION,\n constraintType: MediaConstants_1.DEFAULT_VIDEO_CONSTRAINT_TYPE\n };\n assignConstraint(defaultResolution);\n return constraintCandidates;\n }\n streamConstraints.video.videoResolution.forEach(assignConstraint);\n return constraintCandidates;\n };\n LocalStreamManager.prototype.parseMediaErrorThenThrow = function (error) {\n trace.error('Get media stream error.', error);\n var errorName = error && error.name ? error.name : '';\n var permissionErrorNames = [\n 'NotAllowedError',\n 'PermissionDismissedError',\n 'PermissionDeniedError'\n ];\n // const generalError = [\n // 'NotFoundError',\n // 'DevicesNotFoundError',\n // 'NotReadableError',\n // 'TrackStartError'\n // ];\n var constraintsErrors = [\n 'OverconstrainedError',\n 'ConstraintNotSatisfiedError'\n ];\n var isErrorOfType = function (errorsArr) { return errorsArr.filter(function (err) { return err === errorName; }).length > 0; };\n if (isErrorOfType(permissionErrorNames)) {\n throw { errorCode: MediaConstants_1.MediaRequestErrorCode.PermissionDenied, message: errorName };\n }\n if (isErrorOfType(constraintsErrors)) {\n throw { errorCode: MediaConstants_1.MediaRequestErrorCode.Overconstrained, message: errorName };\n }\n throw { errorCode: MediaConstants_1.MediaRequestErrorCode.GeneralError, message: errorName };\n };\n return LocalStreamManager;\n}());\nexports.LocalStreamManager = LocalStreamManager;\nfunction _constraintByType(value, type) {\n switch (type) {\n case MediaConstants_1.ConstraintType.MIN:\n return { min: value };\n default:\n return { ideal: value };\n }\n}\n\n//# sourceMappingURL=LocalStreamManager.js.map\n","import assign from 'lodash/assign';\nimport get from 'lodash/get';\nimport isEmpty from 'lodash/isEmpty';\nimport {Promise} from 'bluebird';\n\nimport {Nullable} from '@techsee/techsee-common';\n\nimport {\n VideoStreamResolution,\n LocalMediaConstraints,\n LocalVideoStreamConstraints,\n MediaRequestFailResult,\n MediaRequestSuccessResult,\n IMediaEnvironment\n} from './MediaContracts';\n\nimport {\n ConstraintType,\n DEFAULT_VIDEO_CONSTRAINT_TYPE,\n DEFAULT_VIDEO_RESOLUTION,\n MediaRequestErrorCode\n} from './MediaConstants';\n\ndeclare global {\n interface Window {\n latestUserMediaStream: Nullable<MediaRequestSuccessResult>;\n latestDesktopMediaStream: Nullable<MediaRequestSuccessResult>;\n }\n}\n\ndeclare const window: Window;\n\nwindow.latestUserMediaStream = null;\nlet userMediaPromise: Nullable<Promise<MediaRequestSuccessResult>> = null;\n\nwindow.latestDesktopMediaStream = null;\nlet desktopMediaPromise: Nullable<Promise<MediaRequestSuccessResult>> = null;\n\nimport {getMediaTracer} from './MediaUtils/MediaTracer';\n\nconst trace = getMediaTracer('LocalStreamManager');\n\nexport class LocalStreamManager {\n private environment: IMediaEnvironment;\n\n constructor(environment: IMediaEnvironment) {\n this.environment = environment;\n\n this.parseMediaErrorThenThrow = this.parseMediaErrorThenThrow.bind(this);\n this.clearAllStreams = this.clearAllStreams.bind(this);\n }\n\n getUserMediaStream(constraints: LocalMediaConstraints): Promise<MediaRequestSuccessResult> {\n trace.info('getUserMediaStream', constraints);\n if (userMediaPromise) {\n return userMediaPromise;\n }\n\n if (window.latestUserMediaStream) {\n const videoTrack = window.latestUserMediaStream.mediaStream.getVideoTracks();\n\n if (videoTrack.length > 0 && videoTrack[0].readyState === 'live') {\n return Promise.resolve({...window.latestUserMediaStream, isNew: false});\n }\n this.destroyUserMediaStream();\n\n }\n\n\n userMediaPromise = new Promise((resolve, reject) => {\n const catchHandler = (err: any): void => {\n userMediaPromise = null;\n window.latestUserMediaStream = null;\n trace.error('getUserMedia error', err);\n reject(err);\n };\n\n try {\n this.getHighestResolutionStream(false, constraints)\n .then((streamResult: MediaRequestSuccessResult) => {\n userMediaPromise = null;\n window.latestUserMediaStream = streamResult;\n resolve({...window.latestUserMediaStream, isNew: true});\n })\n .catch(catchHandler);\n } catch (err) {\n catchHandler(err);\n }\n });\n\n return userMediaPromise;\n }\n\n getDesktopMediaStream(constraints: LocalVideoStreamConstraints): Promise<MediaRequestSuccessResult> {\n if (desktopMediaPromise) {\n return desktopMediaPromise;\n }\n\n if (window.latestDesktopMediaStream) {\n const track = window.latestDesktopMediaStream.mediaStream.getVideoTracks();\n\n if (track.length > 0 && track[0].readyState === 'live') {\n //return Promise.resolve();\n return Promise.resolve({...window.latestDesktopMediaStream, isNew: false});\n }\n this.destroyDesktopMediaStream().catch((error: any) => {\n trace.error('Error destroying desktop media stream', error);\n });\n\n }\n\n desktopMediaPromise = new Promise((resolve, reject) => {\n const mediaCatchHandler = (err: any): void => {\n desktopMediaPromise = null;\n window.latestDesktopMediaStream = null;\n trace.error('getDisplayMedia error', err);\n reject(err);\n };\n\n try {\n this.getHighestResolutionStream(true, {video: constraints, audio: false})\n .then((streamResult: MediaRequestSuccessResult) => {\n desktopMediaPromise = null;\n window.latestDesktopMediaStream = streamResult;\n\n resolve({...window.latestDesktopMediaStream, isNew: true});\n }).catch(mediaCatchHandler);\n } catch (err) {\n mediaCatchHandler(err);\n }\n });\n\n return desktopMediaPromise;\n }\n\n destroyUserMediaStream(): Promise<void> {\n const streamResult = window.latestUserMediaStream;\n\n window.latestUserMediaStream = null;\n userMediaPromise = null;\n\n if (streamResult) {\n streamResult.mediaStream.getTracks().forEach((track: MediaStreamTrack) => {\n track.stop();\n });\n }\n\n return Promise.resolve();\n }\n\n destroyDesktopMediaStream(): Promise<void> {\n const streamResult = window.latestDesktopMediaStream;\n\n window.latestDesktopMediaStream = null;\n desktopMediaPromise = null;\n\n if (streamResult) {\n streamResult.mediaStream.getTracks().forEach((track: MediaStreamTrack) => {\n track.stop();\n });\n }\n\n return Promise.resolve();\n }\n\n clearAllStreams(): Promise<void> {\n trace.info('LocalStreamManager Clearing all streams');\n\n return Promise.all([\n this.destroyDesktopMediaStream(),\n this.destroyUserMediaStream()\n ]).then(() => undefined);\n }\n\n private getHighestResolutionStream(isDesktopMedia: boolean, constraints?: LocalMediaConstraints): Promise<MediaRequestSuccessResult> {\n const constraintsCandidates = this.getParsedConstraints(isDesktopMedia, constraints);\n\n if (constraintsCandidates.length === 0) {\n return Promise.reject(new Error('No constraints to retrieve the stream'));\n }\n\n return new Promise((resolve, reject) => {\n let lastSuccessfulResult: Nullable<MediaRequestSuccessResult> = null;\n let lastFailedResult: Nullable<MediaRequestFailResult> = null;\n let isStreamRequestFulfilled = false;\n\n (Promise as any).reduce(constraintsCandidates, (total: any, candidate: MediaStreamConstraints) => {\n if (isStreamRequestFulfilled) {\n return;\n }\n const constraintType = get(constraints, 'video.videoResolution.constraintType') || get(constraints, 'video.videoResolution[0].constraintType');\n\n return this.getStreamPromiseByParsedConstraints(candidate, isDesktopMedia)\n .then((stream: MediaStream) => {\n lastSuccessfulResult = {\n mediaStream: stream,\n constraint: candidate,\n constraintType,\n isNew: true\n };\n trace.info('getHighestResolutionStream Success', lastSuccessfulResult);\n isStreamRequestFulfilled = true;\n resolve(lastSuccessfulResult);\n })\n .catch((failResult: MediaRequestFailResult) => {\n lastFailedResult = failResult;\n if (lastFailedResult.errorCode === MediaRequestErrorCode.PermissionDenied) {\n isStreamRequestFulfilled = true;\n reject(lastFailedResult);\n }\n });\n }, 0)\n .then(() => {\n if (!isStreamRequestFulfilled) {\n if (!lastFailedResult) {\n lastFailedResult = {\n errorCode: MediaRequestErrorCode.GeneralError,\n message: 'Suitable stream cannot be created'\n };\n }\n reject(lastFailedResult);\n }\n });\n });\n }\n\n //@ts-ignore\n private getStreamPromiseByParsedConstraints(constraints: MediaStreamConstraints, isDesktopMedia: boolean): Promise<MediaStream> {\n let streamPromise = null;\n\n trace.info('getStreamPromiseByParsedConstraints', constraints);\n\n try {\n if (!isDesktopMedia) {\n streamPromise = navigator.mediaDevices.getUserMedia(constraints);\n } else {\n //@ts-ignore\n streamPromise = navigator.mediaDevices.getDisplayMedia\n //@ts-ignore\n ? navigator.mediaDevices.getDisplayMedia(constraints)\n : navigator.getDisplayMedia(constraints);\n }\n\n return streamPromise.catch(this.parseMediaErrorThenThrow);\n } catch (e) {\n this.parseMediaErrorThenThrow(e);\n }\n }\n\n private getParsedConstraints(isDesktopMedia: boolean, streamConstraints?: LocalMediaConstraints): MediaStreamConstraints[] {\n const constraintCandidates: MediaStreamConstraints[] = [];\n\n //TODO - Alex: need to understand which constraints not compatible with screen share\n if (isDesktopMedia) {\n return [{video: true}];\n }\n\n if (!streamConstraints) {\n return constraintCandidates;\n }\n\n const baseConstraints: MediaStreamConstraints = {};\n\n baseConstraints.audio = !isEmpty(streamConstraints.audio) ? streamConstraints.audio : undefined;\n\n if (!streamConstraints.video) {\n return [baseConstraints];\n }\n\n baseConstraints.video = {\n facingMode: 'environment',\n frameRate: {ideal: 15, max: 30}\n };\n\n const assignConstraint = (videoResolution: VideoStreamResolution): void => {\n const [width, height] = videoResolution.resolution.split('x');\n const constraintCandidate = assign({}, baseConstraints);\n\n constraintCandidate.video = assign({}, baseConstraints.video, {\n width: _constraintByType(width, videoResolution.constraintType),\n height: _constraintByType(height, videoResolution.constraintType)\n });\n constraintCandidates.push(constraintCandidate);\n };\n\n if ((baseConstraints.video && typeof streamConstraints.video === 'boolean') ||\n !((streamConstraints.video as LocalVideoStreamConstraints).videoResolution instanceof Array)) {\n\n const defaultResolution: VideoStreamResolution = {\n resolution: DEFAULT_VIDEO_RESOLUTION,\n constraintType: DEFAULT_VIDEO_CONSTRAINT_TYPE\n };\n\n assignConstraint(defaultResolution);\n\n return constraintCandidates;\n }\n\n (streamConstraints.video as any).videoResolution.forEach(assignConstraint);\n\n return constraintCandidates;\n }\n\n private parseMediaErrorThenThrow(error: any): MediaRequestFailResult {\n trace.error('Get media stream error.', error);\n const errorName = error && error.name ? error.name : '';\n\n const permissionErrorNames = [\n 'NotAllowedError',\n 'PermissionDismissedError',\n 'PermissionDeniedError'\n\n ];\n\n // const generalError = [\n // 'NotFoundError',\n // 'DevicesNotFoundError',\n // 'NotReadableError',\n // 'TrackStartError'\n // ];\n\n const constraintsErrors = [\n 'OverconstrainedError',\n 'ConstraintNotSatisfiedError'\n\n ];\n\n const isErrorOfType = (errorsArr: string[]) => errorsArr.filter((err: string) => err === errorName).length > 0;\n\n if (isErrorOfType(permissionErrorNames)) {\n throw {errorCode: MediaRequestErrorCode.PermissionDenied, message: errorName};\n }\n\n if (isErrorOfType(constraintsErrors)) {\n throw {errorCode: MediaRequestErrorCode.Overconstrained, message: errorName};\n }\n\n throw {errorCode: MediaRequestErrorCode.GeneralError, message: errorName};\n }\n}\n\nfunction _constraintByType(value: any, type: ConstraintType): any {\n switch (type) {\n case ConstraintType.MIN:\n return {min: value};\n default:\n return {ideal: value};\n }\n}\n"]}
1
+ {"version":3,"sources":["LocalStreamManager.js","../src/LocalStreamManager.ts"],"names":["__assign","Object","assign","t","s","i","n","arguments","length","p","prototype","hasOwnProperty","call","apply","__importDefault","mod","__esModule","defineProperty","exports","value","assign_1","require","get_1","last_1","bluebird_1","MediaConstants_1","window","latestUserMediaStream","userMediaPromise","latestDesktopMediaStream","desktopMediaPromise","MediaTracer_1","trace","getMediaTracer","LocalStreamManager","environment","_groupedDevices","video","audio","parseMediaErrorThenThrow","bind","clearAllStreams","getUserMediaStream","constraints","_this","info","videoTrack","mediaStream","getVideoTracks","readyState","Promise","resolve","isNew","destroyUserMediaStream","reject","catchHandler","err","error","getHighestResolutionStream","then","streamResult","catch","getDesktopMediaStream","track","destroyDesktopMediaStream","mediaCatchHandler","getTracks","forEach","stop","all","undefined","isDesktopMedia","constraintsCandidates","getParsedConstraints","Error","lastSuccessfulResult","lastFailedResult","isStreamRequestFulfilled","reduce","total","candidate","constraintType","default","getStreamPromiseByParsedConstraints","stream","constraint","failResult","errorCode","MediaRequestErrorCode","PermissionDenied","GeneralError","message","getUserMediaStreamMediaDevice","streamPromise","navigator","mediaDevices","getUserMedia","getDisplayMedia","name","newConstraints","facingMode","e","setGroupedDevices","groupedDevices","streamConstraints","constraintCandidates","baseConstraints","frameRate","ideal","max","deviceId","assignConstraint","videoResolution","_a","resolution","split","width","height","constraintCandidate","_constraintByType","push","Array","defaultResolution","DEFAULT_VIDEO_RESOLUTION","DEFAULT_VIDEO_CONSTRAINT_TYPE","errorName","permissionErrorNames","constraintsErrors","isErrorOfType","errorsArr","filter","Overconstrained","type","ConstraintType","MIN","min"],"mappings":"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","file":"LocalStreamManager.js","sourcesContent":["\"use strict\";\nvar __assign = (this && this.__assign) || function () {\n __assign = Object.assign || function(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\n t[p] = s[p];\n }\n return t;\n };\n return __assign.apply(this, arguments);\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar assign_1 = __importDefault(require(\"lodash/assign\"));\nvar get_1 = __importDefault(require(\"lodash/get\"));\nvar last_1 = __importDefault(require(\"lodash/last\"));\nvar bluebird_1 = require(\"bluebird\");\nvar MediaConstants_1 = require(\"./MediaConstants\");\nwindow.latestUserMediaStream = null;\nvar userMediaPromise = null;\nwindow.latestDesktopMediaStream = null;\nvar desktopMediaPromise = null;\nvar MediaTracer_1 = require(\"./MediaUtils/MediaTracer\");\nvar trace = MediaTracer_1.getMediaTracer('LocalStreamManager');\nvar LocalStreamManager = /** @class */ (function () {\n function LocalStreamManager(environment) {\n this._groupedDevices = { video: null, audio: null };\n this.environment = environment;\n this.parseMediaErrorThenThrow = this.parseMediaErrorThenThrow.bind(this);\n this.clearAllStreams = this.clearAllStreams.bind(this);\n }\n LocalStreamManager.prototype.getUserMediaStream = function (constraints) {\n var _this = this;\n trace.info('getUserMediaStream', constraints);\n if (userMediaPromise) {\n return userMediaPromise;\n }\n if (window.latestUserMediaStream) {\n var videoTrack = window.latestUserMediaStream.mediaStream.getVideoTracks();\n if (videoTrack.length > 0 && videoTrack[0].readyState === 'live') {\n return bluebird_1.Promise.resolve(__assign({}, window.latestUserMediaStream, { isNew: false }));\n }\n this.destroyUserMediaStream();\n }\n userMediaPromise = new bluebird_1.Promise(function (resolve, reject) {\n var catchHandler = function (err) {\n userMediaPromise = null;\n window.latestUserMediaStream = null;\n trace.error('getUserMedia error', err);\n reject(err);\n };\n try {\n _this.getHighestResolutionStream(false, constraints)\n .then(function (streamResult) {\n userMediaPromise = null;\n window.latestUserMediaStream = streamResult;\n resolve(__assign({}, window.latestUserMediaStream, { isNew: true }));\n })\n .catch(catchHandler);\n }\n catch (err) {\n catchHandler(err);\n }\n });\n return userMediaPromise;\n };\n LocalStreamManager.prototype.getDesktopMediaStream = function (constraints) {\n var _this = this;\n if (desktopMediaPromise) {\n return desktopMediaPromise;\n }\n trace.info('getDesktopMediaStream', constraints);\n if (window.latestDesktopMediaStream) {\n var track = window.latestDesktopMediaStream.mediaStream.getVideoTracks();\n if (track.length > 0 && track[0].readyState === 'live') {\n //return Promise.resolve();\n return bluebird_1.Promise.resolve(__assign({}, window.latestDesktopMediaStream, { isNew: false }));\n }\n this.destroyDesktopMediaStream().catch(function (error) {\n trace.error('Error destroying desktop media stream', error);\n });\n }\n desktopMediaPromise = new bluebird_1.Promise(function (resolve, reject) {\n var mediaCatchHandler = function (err) {\n desktopMediaPromise = null;\n window.latestDesktopMediaStream = null;\n trace.error('getDisplayMedia error', err);\n reject(err);\n };\n try {\n _this.getHighestResolutionStream(true, { video: constraints, audio: false })\n .then(function (streamResult) {\n desktopMediaPromise = null;\n window.latestDesktopMediaStream = streamResult;\n resolve(__assign({}, window.latestDesktopMediaStream, { isNew: true }));\n }).catch(mediaCatchHandler);\n }\n catch (err) {\n mediaCatchHandler(err);\n }\n });\n return desktopMediaPromise;\n };\n LocalStreamManager.prototype.destroyUserMediaStream = function () {\n var streamResult = window.latestUserMediaStream;\n window.latestUserMediaStream = null;\n userMediaPromise = null;\n if (streamResult && streamResult.mediaStream) {\n streamResult.mediaStream.getTracks().forEach(function (track) {\n track.stop();\n });\n }\n return bluebird_1.Promise.resolve();\n };\n LocalStreamManager.prototype.destroyDesktopMediaStream = function () {\n var streamResult = window.latestDesktopMediaStream;\n window.latestDesktopMediaStream = null;\n desktopMediaPromise = null;\n if (streamResult && streamResult.mediaStream) {\n streamResult.mediaStream.getTracks().forEach(function (track) {\n track.stop();\n });\n }\n return bluebird_1.Promise.resolve();\n };\n LocalStreamManager.prototype.clearAllStreams = function () {\n trace.info('LocalStreamManager Clearing all streams');\n return bluebird_1.Promise.all([\n this.destroyDesktopMediaStream(),\n this.destroyUserMediaStream()\n ]).then(function () { return undefined; });\n };\n LocalStreamManager.prototype.getHighestResolutionStream = function (isDesktopMedia, constraints) {\n var _this = this;\n var constraintsCandidates = this.getParsedConstraints(isDesktopMedia, constraints);\n trace.info('getHighestResolutionStream - constraintsCandidates:', constraintsCandidates);\n if (constraintsCandidates.length === 0) {\n return bluebird_1.Promise.reject(new Error('No constraints to retrieve the stream'));\n }\n return new bluebird_1.Promise(function (resolve, reject) {\n var lastSuccessfulResult = null;\n var lastFailedResult = null;\n var isStreamRequestFulfilled = false;\n bluebird_1.Promise.reduce(constraintsCandidates, function (total, candidate) {\n if (isStreamRequestFulfilled) {\n return;\n }\n var constraintType = get_1.default(constraints, 'video.videoResolution.constraintType') || get_1.default(constraints, 'video.videoResolution[0].constraintType');\n return _this.getStreamPromiseByParsedConstraints(candidate, isDesktopMedia)\n .then(function (stream) {\n lastSuccessfulResult = {\n mediaStream: stream,\n constraint: candidate,\n constraintType: constraintType,\n isNew: true\n };\n trace.info('getHighestResolutionStream Success', lastSuccessfulResult);\n isStreamRequestFulfilled = true;\n resolve(lastSuccessfulResult);\n })\n .catch(function (failResult) {\n lastFailedResult = failResult;\n if (lastFailedResult.errorCode === MediaConstants_1.MediaRequestErrorCode.PermissionDenied) {\n isStreamRequestFulfilled = true;\n reject(lastFailedResult);\n }\n });\n }, 0)\n .then(function () {\n if (!isStreamRequestFulfilled) {\n if (!lastFailedResult) {\n lastFailedResult = {\n errorCode: MediaConstants_1.MediaRequestErrorCode.GeneralError,\n message: 'Suitable stream cannot be created'\n };\n }\n reject(lastFailedResult);\n }\n });\n });\n };\n LocalStreamManager.prototype.getUserMediaStreamMediaDevice = function (constraints, isDesktopMedia) {\n var streamPromise = null;\n if (!isDesktopMedia) {\n streamPromise = navigator.mediaDevices.getUserMedia(constraints);\n }\n else {\n //@ts-ignore\n streamPromise = navigator.mediaDevices.getDisplayMedia\n //@ts-ignore\n ? navigator.mediaDevices.getDisplayMedia(constraints)\n : navigator.getDisplayMedia(constraints);\n }\n return streamPromise;\n };\n //@ts-ignore\n LocalStreamManager.prototype.getStreamPromiseByParsedConstraints = function (constraints, isDesktopMedia) {\n var _this = this;\n trace.info('getStreamPromiseByParsedConstraints', constraints);\n try {\n return this.getUserMediaStreamMediaDevice(constraints, isDesktopMedia).catch(function (err) {\n var streamPromise = null;\n trace.info('getStreamPromiseByParsedConstraints - get user stream error', err.name);\n // Android (Galaxy esp.) have a bug that when using facingMode it might cause NotReadableError. So\n // we should try again but without facingMode. The exception to the rule is when we don't have specific\n // device to use (like in IOS13 bug, as can be seen in MediaServiceBase.ts), in that case, we might end\n // up using the front camera, which is a privacy concern and the preference is to fallback from video\n if (err && (err.name === 'NotReadableError') && get_1.default(constraints, 'video.facingMode') &&\n get_1.default(_this._groupedDevices, 'video.deviceId')) {\n var newConstraints = constraints;\n trace.info('getStreamPromiseByParsedConstraints - NotReadableError - Failed to get video user media stream with facingMode=environment', err.name);\n // @ts-ignore\n delete newConstraints.video.facingMode;\n streamPromise = _this.getStreamPromiseByParsedConstraints(newConstraints, isDesktopMedia);\n }\n else if (err && err.name && constraints.audio && !constraints.video) {\n trace.info('getStreamPromiseByParsedConstraints - audioStreamFailed - Failed to get audio user media stream', err.name);\n return _this.parseMediaErrorThenThrow({ name: 'audioStreamFailed' });\n }\n else if (err && err.name && constraints.audio) {\n var newConstraints = constraints;\n trace.info('getStreamPromiseByParsedConstraints - Failed to get video and audio user media stream, try to get video media stream only', err.name);\n newConstraints.audio = false;\n streamPromise = _this.getStreamPromiseByParsedConstraints(newConstraints, isDesktopMedia);\n }\n else if (err && !streamPromise) {\n trace.info('getStreamPromiseByParsedConstraints - Failed to get video user media stream', err && err.name);\n streamPromise = bluebird_1.Promise.reject(err);\n }\n return streamPromise && streamPromise.catch(_this.parseMediaErrorThenThrow);\n });\n }\n catch (e) {\n this.parseMediaErrorThenThrow(e);\n }\n };\n LocalStreamManager.prototype.setGroupedDevices = function (groupedDevices) {\n trace.info('setGroupedDevices', groupedDevices);\n this._groupedDevices = { video: last_1.default(groupedDevices.video) || null, audio: last_1.default(groupedDevices.audio) || null };\n };\n LocalStreamManager.prototype.getParsedConstraints = function (isDesktopMedia, streamConstraints) {\n var constraintCandidates = [];\n //TODO - Alex: need to understand which constraints not compatible with screen share\n if (isDesktopMedia) {\n return [{ video: true }];\n }\n if (!streamConstraints) {\n return constraintCandidates;\n }\n var baseConstraints = {};\n baseConstraints.audio = typeof streamConstraints.audio === 'boolean' ? streamConstraints.audio : undefined;\n if (!streamConstraints.video) {\n return [baseConstraints];\n }\n baseConstraints.video = {\n facingMode: 'environment',\n frameRate: { ideal: 15, max: 30 }\n };\n var deviceId = get_1.default(this._groupedDevices, 'video.deviceId');\n if (deviceId) {\n baseConstraints.video.deviceId = deviceId;\n }\n var assignConstraint = function (videoResolution) {\n var _a = videoResolution.resolution.split('x'), width = _a[0], height = _a[1];\n var constraintCandidate = assign_1.default({}, baseConstraints);\n constraintCandidate.video = assign_1.default({}, baseConstraints.video, {\n width: _constraintByType(width, videoResolution.constraintType),\n height: _constraintByType(height, videoResolution.constraintType)\n });\n constraintCandidates.push(constraintCandidate);\n };\n if ((baseConstraints.video && typeof streamConstraints.video === 'boolean') ||\n !(streamConstraints.video.videoResolution instanceof Array)) {\n var defaultResolution = {\n resolution: MediaConstants_1.DEFAULT_VIDEO_RESOLUTION,\n constraintType: MediaConstants_1.DEFAULT_VIDEO_CONSTRAINT_TYPE\n };\n assignConstraint(defaultResolution);\n return constraintCandidates;\n }\n streamConstraints.video.videoResolution.forEach(assignConstraint);\n return constraintCandidates;\n };\n LocalStreamManager.prototype.parseMediaErrorThenThrow = function (error) {\n if (error && error.errorCode) {\n throw error;\n }\n trace.error('Get media stream error.', error);\n var errorName = error && error.name ? error.name : '';\n var permissionErrorNames = [\n 'NotAllowedError',\n 'PermissionDismissedError',\n 'PermissionDeniedError'\n ];\n // const generalError = [\n // 'NotFoundError',\n // 'DevicesNotFoundError',\n // 'NotReadableError',\n // 'TrackStartError'\n // ];\n var constraintsErrors = [\n 'OverconstrainedError',\n 'ConstraintNotSatisfiedError'\n ];\n var isErrorOfType = function (errorsArr) { return errorsArr.filter(function (err) { return err === errorName; }).length > 0; };\n if (isErrorOfType(permissionErrorNames)) {\n throw { errorCode: MediaConstants_1.MediaRequestErrorCode.PermissionDenied, message: errorName };\n }\n if (isErrorOfType(constraintsErrors)) {\n throw { errorCode: MediaConstants_1.MediaRequestErrorCode.Overconstrained, message: errorName };\n }\n throw { errorCode: MediaConstants_1.MediaRequestErrorCode.GeneralError, message: errorName };\n };\n return LocalStreamManager;\n}());\nexports.LocalStreamManager = LocalStreamManager;\nfunction _constraintByType(value, type) {\n switch (type) {\n case MediaConstants_1.ConstraintType.MIN:\n return { min: value };\n default:\n return { ideal: value };\n }\n}\n\n//# sourceMappingURL=LocalStreamManager.js.map\n","import assign from 'lodash/assign';\nimport get from 'lodash/get';\nimport last from 'lodash/last';\nimport {Promise} from 'bluebird';\n\nimport {Nullable} from '@techsee/techsee-common';\n\nimport {\n VideoStreamResolution,\n LocalMediaConstraints,\n LocalVideoStreamConstraints,\n MediaRequestFailResult,\n MediaRequestSuccessResult,\n IMediaEnvironment\n} from './MediaContracts';\n\nimport {\n ConstraintType,\n DEFAULT_VIDEO_CONSTRAINT_TYPE,\n DEFAULT_VIDEO_RESOLUTION,\n MediaRequestErrorCode\n} from './MediaConstants';\n\ndeclare global {\n interface Window {\n latestUserMediaStream: Nullable<MediaRequestSuccessResult>;\n latestDesktopMediaStream: Nullable<MediaRequestSuccessResult>;\n }\n}\n\ndeclare const window: Window;\n\nwindow.latestUserMediaStream = null;\nlet userMediaPromise: Nullable<Promise<MediaRequestSuccessResult>> = null;\n\nwindow.latestDesktopMediaStream = null;\nlet desktopMediaPromise: Nullable<Promise<MediaRequestSuccessResult>> = null;\n\nimport {getMediaTracer} from './MediaUtils/MediaTracer';\n\nconst trace = getMediaTracer('LocalStreamManager');\n\nexport class LocalStreamManager {\n private environment: IMediaEnvironment;\n private _groupedDevices: {video: Nullable<MediaDeviceInfo>; audio: Nullable<MediaDeviceInfo>} = {video: null, audio: null};\n\n constructor(environment: IMediaEnvironment) {\n this.environment = environment;\n\n this.parseMediaErrorThenThrow = this.parseMediaErrorThenThrow.bind(this);\n this.clearAllStreams = this.clearAllStreams.bind(this);\n }\n\n getUserMediaStream(constraints: LocalMediaConstraints): Promise<MediaRequestSuccessResult> {\n trace.info('getUserMediaStream', constraints);\n if (userMediaPromise) {\n return userMediaPromise;\n }\n\n if (window.latestUserMediaStream) {\n const videoTrack = window.latestUserMediaStream.mediaStream.getVideoTracks();\n\n if (videoTrack.length > 0 && videoTrack[0].readyState === 'live') {\n return Promise.resolve({...window.latestUserMediaStream, isNew: false});\n }\n\n this.destroyUserMediaStream();\n }\n\n userMediaPromise = new Promise((resolve, reject) => {\n const catchHandler = (err: any): void => {\n userMediaPromise = null;\n window.latestUserMediaStream = null;\n trace.error('getUserMedia error', err);\n reject(err);\n };\n\n try {\n this.getHighestResolutionStream(false, constraints)\n .then((streamResult: MediaRequestSuccessResult) => {\n userMediaPromise = null;\n window.latestUserMediaStream = streamResult;\n resolve({...window.latestUserMediaStream, isNew: true});\n })\n .catch(catchHandler);\n } catch (err) {\n catchHandler(err);\n }\n });\n\n return userMediaPromise;\n }\n\n getDesktopMediaStream(constraints: LocalVideoStreamConstraints): Promise<MediaRequestSuccessResult> {\n if (desktopMediaPromise) {\n return desktopMediaPromise;\n }\n\n trace.info('getDesktopMediaStream', constraints);\n\n if (window.latestDesktopMediaStream) {\n const track = window.latestDesktopMediaStream.mediaStream.getVideoTracks();\n\n if (track.length > 0 && track[0].readyState === 'live') {\n //return Promise.resolve();\n return Promise.resolve({...window.latestDesktopMediaStream, isNew: false});\n }\n this.destroyDesktopMediaStream().catch((error: any) => {\n trace.error('Error destroying desktop media stream', error);\n });\n\n }\n\n desktopMediaPromise = new Promise((resolve, reject) => {\n const mediaCatchHandler = (err: any): void => {\n desktopMediaPromise = null;\n window.latestDesktopMediaStream = null;\n trace.error('getDisplayMedia error', err);\n reject(err);\n };\n\n try {\n this.getHighestResolutionStream(true, {video: constraints, audio: false})\n .then((streamResult: MediaRequestSuccessResult) => {\n desktopMediaPromise = null;\n window.latestDesktopMediaStream = streamResult;\n\n resolve({...window.latestDesktopMediaStream, isNew: true});\n }).catch(mediaCatchHandler);\n } catch (err) {\n mediaCatchHandler(err);\n }\n });\n\n return desktopMediaPromise;\n }\n\n destroyUserMediaStream(): Promise<void> {\n const streamResult = window.latestUserMediaStream;\n\n window.latestUserMediaStream = null;\n userMediaPromise = null;\n\n if (streamResult && streamResult.mediaStream) {\n streamResult.mediaStream.getTracks().forEach((track: MediaStreamTrack) => {\n track.stop();\n });\n }\n\n return Promise.resolve();\n }\n\n destroyDesktopMediaStream(): Promise<void> {\n const streamResult = window.latestDesktopMediaStream;\n\n window.latestDesktopMediaStream = null;\n desktopMediaPromise = null;\n\n if (streamResult && streamResult.mediaStream) {\n streamResult.mediaStream.getTracks().forEach((track: MediaStreamTrack) => {\n track.stop();\n });\n }\n\n return Promise.resolve();\n }\n\n clearAllStreams(): Promise<void> {\n trace.info('LocalStreamManager Clearing all streams');\n\n return Promise.all([\n this.destroyDesktopMediaStream(),\n this.destroyUserMediaStream()\n ]).then(() => undefined);\n }\n\n private getHighestResolutionStream(isDesktopMedia: boolean, constraints?: LocalMediaConstraints): Promise<MediaRequestSuccessResult> {\n const constraintsCandidates = this.getParsedConstraints(isDesktopMedia, constraints);\n\n trace.info('getHighestResolutionStream - constraintsCandidates:', constraintsCandidates);\n\n if (constraintsCandidates.length === 0) {\n return Promise.reject(new Error('No constraints to retrieve the stream'));\n }\n\n return new Promise((resolve, reject) => {\n let lastSuccessfulResult: Nullable<MediaRequestSuccessResult> = null;\n let lastFailedResult: Nullable<MediaRequestFailResult> = null;\n let isStreamRequestFulfilled = false;\n\n (Promise as any).reduce(constraintsCandidates, (total: any, candidate: MediaStreamConstraints) => {\n if (isStreamRequestFulfilled) {\n return;\n }\n\n const constraintType = get(constraints, 'video.videoResolution.constraintType') || get(constraints, 'video.videoResolution[0].constraintType');\n\n return this.getStreamPromiseByParsedConstraints(candidate, isDesktopMedia)\n .then((stream: MediaStream) => {\n lastSuccessfulResult = {\n mediaStream: stream,\n constraint: candidate,\n constraintType,\n isNew: true\n };\n trace.info('getHighestResolutionStream Success', lastSuccessfulResult);\n isStreamRequestFulfilled = true;\n resolve(lastSuccessfulResult);\n })\n .catch((failResult: MediaRequestFailResult) => {\n lastFailedResult = failResult;\n\n if (lastFailedResult.errorCode === MediaRequestErrorCode.PermissionDenied) {\n isStreamRequestFulfilled = true;\n reject(lastFailedResult);\n }\n });\n }, 0)\n .then(() => {\n if (!isStreamRequestFulfilled) {\n if (!lastFailedResult) {\n lastFailedResult = {\n errorCode: MediaRequestErrorCode.GeneralError,\n message: 'Suitable stream cannot be created'\n };\n }\n reject(lastFailedResult);\n }\n });\n });\n }\n\n private getUserMediaStreamMediaDevice(constraints: MediaStreamConstraints, isDesktopMedia: boolean) {\n let streamPromise = null;\n\n if (!isDesktopMedia) {\n streamPromise = navigator.mediaDevices.getUserMedia(constraints);\n } else {\n //@ts-ignore\n streamPromise = navigator.mediaDevices.getDisplayMedia\n //@ts-ignore\n ? navigator.mediaDevices.getDisplayMedia(constraints)\n : navigator.getDisplayMedia(constraints);\n }\n\n return streamPromise;\n }\n\n //@ts-ignore\n private getStreamPromiseByParsedConstraints(constraints: MediaStreamConstraints, isDesktopMedia: boolean): Promise<MediaStream> {\n trace.info('getStreamPromiseByParsedConstraints', constraints);\n\n try {\n return this.getUserMediaStreamMediaDevice(constraints, isDesktopMedia).catch((err: any) => {\n let streamPromise = null;\n\n trace.info('getStreamPromiseByParsedConstraints - get user stream error', err.name);\n\n // Android (Galaxy esp.) have a bug that when using facingMode it might cause NotReadableError. So\n // we should try again but without facingMode. The exception to the rule is when we don't have specific\n // device to use (like in IOS13 bug, as can be seen in MediaServiceBase.ts), in that case, we might end\n // up using the front camera, which is a privacy concern and the preference is to fallback from video\n if (err && (err.name === 'NotReadableError') && get(constraints, 'video.facingMode') &&\n get(this._groupedDevices, 'video.deviceId')) {\n\n const newConstraints = constraints;\n\n trace.info('getStreamPromiseByParsedConstraints - NotReadableError - Failed to get video user media stream with facingMode=environment', err.name);\n\n // @ts-ignore\n delete newConstraints.video.facingMode;\n\n streamPromise = this.getStreamPromiseByParsedConstraints(newConstraints, isDesktopMedia);\n } else if (err && err.name && constraints.audio && !constraints.video) {\n trace.info('getStreamPromiseByParsedConstraints - audioStreamFailed - Failed to get audio user media stream', err.name);\n\n return this.parseMediaErrorThenThrow({name: 'audioStreamFailed'});\n } else if (err && err.name && constraints.audio) {\n const newConstraints = constraints;\n\n trace.info('getStreamPromiseByParsedConstraints - Failed to get video and audio user media stream, try to get video media stream only', err.name);\n\n newConstraints.audio = false;\n streamPromise = this.getStreamPromiseByParsedConstraints(newConstraints, isDesktopMedia);\n } else if (err && !streamPromise) {\n trace.info('getStreamPromiseByParsedConstraints - Failed to get video user media stream', err && err.name);\n\n streamPromise = Promise.reject(err);\n }\n\n return streamPromise && streamPromise.catch(this.parseMediaErrorThenThrow);\n });\n } catch (e) {\n this.parseMediaErrorThenThrow(e);\n }\n }\n\n setGroupedDevices(groupedDevices: {video: MediaDeviceInfo[]; audio: MediaDeviceInfo[]}) {\n trace.info('setGroupedDevices', groupedDevices);\n this._groupedDevices = {video: last(groupedDevices.video) || null, audio: last(groupedDevices.audio) || null};\n }\n\n private getParsedConstraints(isDesktopMedia: boolean, streamConstraints?: LocalMediaConstraints): MediaStreamConstraints[] {\n const constraintCandidates: MediaStreamConstraints[] = [];\n\n //TODO - Alex: need to understand which constraints not compatible with screen share\n if (isDesktopMedia) {\n return [{video: true}];\n }\n\n if (!streamConstraints) {\n return constraintCandidates;\n }\n\n const baseConstraints: MediaStreamConstraints = {};\n\n baseConstraints.audio = typeof streamConstraints.audio === 'boolean' ? streamConstraints.audio : undefined;\n\n if (!streamConstraints.video) {\n return [baseConstraints];\n }\n\n baseConstraints.video = {\n facingMode: 'environment',\n frameRate: {ideal: 15, max: 30}\n };\n\n const deviceId = get(this._groupedDevices, 'video.deviceId');\n\n if (deviceId) {\n baseConstraints.video.deviceId = deviceId;\n }\n\n const assignConstraint = (videoResolution: VideoStreamResolution): void => {\n const [width, height] = videoResolution.resolution.split('x');\n const constraintCandidate = assign({}, baseConstraints);\n\n constraintCandidate.video = assign({}, baseConstraints.video, {\n width: _constraintByType(width, videoResolution.constraintType),\n height: _constraintByType(height, videoResolution.constraintType)\n });\n constraintCandidates.push(constraintCandidate);\n };\n\n if ((baseConstraints.video && typeof streamConstraints.video === 'boolean') ||\n !((streamConstraints.video as LocalVideoStreamConstraints).videoResolution instanceof Array)) {\n\n const defaultResolution: VideoStreamResolution = {\n resolution: DEFAULT_VIDEO_RESOLUTION,\n constraintType: DEFAULT_VIDEO_CONSTRAINT_TYPE\n };\n\n assignConstraint(defaultResolution);\n\n return constraintCandidates;\n }\n\n (streamConstraints.video as any).videoResolution.forEach(assignConstraint);\n\n return constraintCandidates;\n }\n\n private parseMediaErrorThenThrow(error: any): MediaRequestFailResult {\n if (error && error.errorCode) {\n throw error;\n }\n\n trace.error('Get media stream error.', error);\n const errorName = error && error.name ? error.name : '';\n\n const permissionErrorNames = [\n 'NotAllowedError',\n 'PermissionDismissedError',\n 'PermissionDeniedError'\n\n ];\n\n // const generalError = [\n // 'NotFoundError',\n // 'DevicesNotFoundError',\n // 'NotReadableError',\n // 'TrackStartError'\n // ];\n\n const constraintsErrors = [\n 'OverconstrainedError',\n 'ConstraintNotSatisfiedError'\n\n ];\n\n const isErrorOfType = (errorsArr: string[]) => errorsArr.filter((err: string) => err === errorName).length > 0;\n\n if (isErrorOfType(permissionErrorNames)) {\n throw {errorCode: MediaRequestErrorCode.PermissionDenied, message: errorName};\n }\n\n if (isErrorOfType(constraintsErrors)) {\n throw {errorCode: MediaRequestErrorCode.Overconstrained, message: errorName};\n }\n\n throw {errorCode: MediaRequestErrorCode.GeneralError, message: errorName};\n }\n}\n\nfunction _constraintByType(value: any, type: ConstraintType): any {\n switch (type) {\n case ConstraintType.MIN:\n return {min: value};\n default:\n return {ideal: value};\n }\n}\n"]}
@@ -7,7 +7,7 @@ export interface IMediaEnvironment {
7
7
  import { ConstraintType, KnownMediaStream, LocalVideoSourceType, MediaRequestErrorCode, MediaServiceType, MediaSessionDisconnectReason, MediaStreamUnregisterReason, SessionClientRole, SessionClientType } from './MediaConstants';
8
8
  export interface LocalMediaConstraints {
9
9
  video: boolean | LocalVideoStreamConstraints;
10
- audio?: any;
10
+ audio?: boolean;
11
11
  }
12
12
  export declare type LocalMediaSourceInfo = LocalMediaConstraints & {
13
13
  mediaSourceType: LocalVideoSourceType;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/MediaContracts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,yBAAyB,CAAC;AAEjD,MAAM,WAAW,iBAAiB;IAC9B,KAAK,EAAE,MAAM,OAAO,CAAC;IACrB,MAAM,EAAE,MAAM,OAAO,CAAC;IACtB,YAAY,EAAE,MAAM,MAAM,CAAC;CAC9B;AAED,OAAO,EACH,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACpB,qBAAqB,EACrB,gBAAgB,EAChB,4BAA4B,EAC5B,2BAA2B,EAC3B,iBAAiB,EACjB,iBAAiB,EACpB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,qBAAqB;IAClC,KAAK,EAAE,OAAO,GAAG,2BAA2B,CAAC;IAC7C,KAAK,CAAC,EAAE,GAAG,CAAC;CACf;AAED,oBAAY,oBAAoB,GAAG,qBAAqB,GAAG;IACvD,eAAe,EAAE,oBAAoB,CAAC;CACzC,CAAA;AAED,MAAM,WAAW,qBAAqB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,cAAc,CAAC;CAClC;AAED,MAAM,WAAW,2BAA2B;IACxC,eAAe,CAAC,EAAE,MAAM,GAAG,qBAAqB,EAAE,CAAC;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,yBAAyB;IACtC,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,sBAAsB,CAAC;IACnC,cAAc,EAAE,cAAc,CAAC;IAC/B,KAAK,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,sBAAsB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,qBAAqB,CAAC;CACpC;AAED,MAAM,WAAW,sBAAsB;IACnC,qBAAqB,CAAC,eAAe,EAAE,iBAAiB,GAAG,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC;IAE1F,mBAAmB,CAAC,UAAU,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjE,gBAAgB,CAAC,UAAU,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjE;AAED,MAAM,WAAW,mBAAmB;IAChC,gBAAgB,EAAE,gBAAgB,CAAC;IAEnC,8BAA8B,CAAC,EAAE,MAAM,CAAC;IAGxC,8BAA8B,CAAC,EAAE,MAAM,CAAC;CAC3C;AAED,MAAM,WAAW,kBAAkB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,iBAAiB,CAAC;IAC9B,UAAU,EAAE,iBAAiB,CAAC;IAC9B,WAAW,EAAE,0BAA0B,CAAC;CAC3C;AAED,MAAM,WAAW,yBAAyB;IAEtC,8BAA8B,EAAE,MAAM,CAAC;CAC1C;AAED,MAAM,WAAW,qBAAqB;IAClC,SAAS,EAAE,cAAc,CAAC;IAC1B,UAAU,EAAE,gBAAgB,CAAC;CAChC;AAED,MAAM,WAAW,oBAAoB;IACjC,WAAW,EAAE,gBAAgB,EAAE,CAAC;IAChC,eAAe,EAAE,iBAAiB,CAAC;CACtC;AAED,MAAM,WAAW,gBAAgB;IAC7B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,6BAA6B,EAAE,OAAO,CAAC;IACvC,iCAAiC,EAAE,OAAO,CAAC;IAC3C,uBAAuB,EAAE,OAAO,CAAC;IACjC,2BAA2B,EAAE,OAAO,CAAC;CACxC;AAED,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC;IACtC,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC;IACnC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,gBAAgB,CAAC,CAAC;IAClD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAE9B,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IAElC,cAAc,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAE3C,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;CACzC;AAED,oBAAY,0BAA0B,GAAG,GAAG,CAAC;AAE7C,MAAM,WAAW,oBAAoB;IACjC,qBAAqB,EAAE,+BAA+B,CAAC;CAC1D;AAED,oBAAY,+BAA+B,GAAG,CAAC,MAAM,EAAE,4BAA4B,KAAK,IAAI,CAAA;AAE5F,MAAM,WAAW,iBAAiB;IAC9B,iBAAiB,EAAE,gBAAgB,CAAC;IACpC,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,GAAG,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAE1B,OAAO,CAAC,WAAW,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9C,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5B,mBAAmB,CAAC,UAAU,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAE7E,sBAAsB,CAAC,UAAU,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAErE,oBAAoB,CAAC,UAAU,EAAE,iBAAiB,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChG;AAED,MAAM,WAAW,gBAAgB;IAC7B,UAAU,EAAE,gBAAgB,CAAC;IAC7B,SAAS,EAAE,gBAAgB,CAAC;IAC5B,YAAY,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,CAAC,CAAC,EAAE,GAAG,CAAC;IACR,CAAC,CAAC,EAAE,GAAG,CAAC;IACR,CAAC,CAAC,EAAE,GAAG,CAAC;IACR,CAAC,CAAC,EAAE,GAAG,CAAC;CACX;AAED,MAAM,WAAW,wBAAwB;IACrC,UAAU,EAAE,gBAAgB,CAAC;IAC7B,MAAM,EAAE,2BAA2B,CAAC;CACvC;AAED,MAAM,WAAW,sBAAsB;IACnC,UAAU,EAAE,gBAAgB,CAAC;CAChC","file":"MediaContracts.d.ts","sourcesContent":["import {Nullable} from '@techsee/techsee-common';\n\nexport interface IMediaEnvironment {\n isIOS: () => boolean;\n isIE11: () => boolean;\n majorVersion: () => number;\n}\n\nimport {\n ConstraintType,\n KnownMediaStream,\n LocalVideoSourceType,\n MediaRequestErrorCode,\n MediaServiceType,\n MediaSessionDisconnectReason,\n MediaStreamUnregisterReason,\n SessionClientRole,\n SessionClientType\n} from './MediaConstants';\n\nexport interface LocalMediaConstraints {\n video: boolean | LocalVideoStreamConstraints;\n audio?: any;\n}\n\nexport type LocalMediaSourceInfo = LocalMediaConstraints & {\n mediaSourceType: LocalVideoSourceType;\n}\n\nexport interface VideoStreamResolution {\n resolution: string;\n constraintType: ConstraintType;\n}\n\nexport interface LocalVideoStreamConstraints {\n videoResolution?: string | VideoStreamResolution[];\n facingMode?: string;\n}\n\nexport interface MediaRequestSuccessResult {\n mediaStream: MediaStream;\n constraint: MediaStreamConstraints;\n constraintType: ConstraintType;\n isNew: boolean;\n}\n\nexport interface MediaRequestFailResult {\n message: string;\n errorCode: MediaRequestErrorCode;\n}\n\nexport interface ISessionStreamsManager {\n getMediaStreamForRole(destinationRole: SessionClientRole): Promise<Nullable<MediaStream>>;\n\n addRemoteMediaTrack(mediaTrack: RemoteMediaTrack): Promise<void>;\n\n removeMediaTrack(mediaTrack: MediaStreamTrack): Promise<void>;\n}\n\nexport interface MediaServiceOptions {\n mediaServiceType: MediaServiceType;\n //How much to wait until raise \"peerConnectionTimeout\" if WebRTC connection events not arriving\n peerConnectivityTimeoutSeconds?: number;\n\n //How much to wait totally for video stream to arrive, before making fallback to image upload\n videoNotReceivedTimeoutSeconds?: number;\n}\n\nexport interface MediaSessionParams {\n sessionId: string;\n clientType: SessionClientType;\n clientRole: SessionClientRole;\n credentials: MediaSessionIceCredentials;\n}\n\nexport interface MediaSessionConfiguration {\n //How much to wait until raise \"peerConnectionTimeout\" if WebRTC connection events not arriving\n peerConnectivityTimeoutSeconds: number;\n}\n\nexport interface MediaSubscriberParams {\n container: HTMLDivElement;\n streamType: KnownMediaStream;\n}\n\nexport interface MediaPublisherParams {\n streamTypes: KnownMediaStream[];\n destinationRole: SessionClientRole;\n}\n\nexport interface ClientWebRtcInfo {\n isWebRTCSupported: boolean;\n isWebsiteHasWebcamPermissions: boolean;\n isWebsiteHasMicrophonePermissions: boolean;\n isGetUserMediaSupported: boolean;\n isApplyConstraintsSupported: boolean;\n}\n\nexport interface IMediaSubscriber {\n readonly streamType: KnownMediaStream;\n readonly container: HTMLDivElement;\n readonly isPlaying: boolean;\n readonly isSoundMuted: boolean;\n readonly hasAudio: boolean;\n readonly hasVideo: boolean;\n readonly mediaElement: Nullable<HTMLVideoElement>;\n readonly videoWidth: number;\n readonly videoHeight: number;\n readonly renderWidth: number;\n readonly renderHeight: number;\n\n muteSound(isMuted: boolean): void;\n\n onStateChanged(callback: () => void): void;\n\n onDispose(callback: () => void): void;\n}\n\nexport type MediaSessionIceCredentials = any;//TODO - Define type for credentials\n\nexport interface MediaSessionHandlers {\n onDisconnectedHandler: MediaSessionDisconnectedHandler;\n}\n\nexport type MediaSessionDisconnectedHandler = (reason: MediaSessionDisconnectReason) => void\n\nexport interface DeviceSupportInfo {\n webRtcSupportInfo: ClientWebRtcInfo;\n hasCamera: boolean;\n hasMicrophone: boolean;\n videoPlayback: boolean;\n}\n\nexport interface RemoteTrackStats {\n trackId: string;\n trackStats: any;\n}\n\nexport interface IMediaSession {\n //Boolean parameter is used for supporting \"RTC Test\" application\n connect(connectOnly?: boolean): Promise<void>;\n\n disconnect(): Promise<void>;\n\n getRemoteTrackStats(mediaTrack: MediaStreamTrack): Promise<RemoteTrackStats>;\n\n onMediaStreamDestroyed(clientRole: SessionClientRole): Promise<void>;\n\n onMediaStreamRenewed(clientRole: SessionClientRole, mediaStream: MediaStream): Promise<void>;\n}\n\nexport interface RemoteMediaTrack {\n mediaTrack: MediaStreamTrack;\n trackType: KnownMediaStream;\n isRegistered: boolean;\n}\n\nexport interface SnapshotResult {\n base64img: string;\n objectUrl: string;\n imageBlob: Blob;\n mimeType: string;\n}\n\nexport interface SnapshotOptions {\n format?: string;\n quality?: number;\n x?: any;\n y?: any;\n w?: any;\n h?: any;\n}\n\nexport interface StreamDestroyedEventArgs {\n streamType: KnownMediaStream;\n reason: MediaStreamUnregisterReason;\n}\n\nexport interface StreamCreatedEventArgs {\n streamType: KnownMediaStream;\n}\n"]}
1
+ {"version":3,"sources":["../src/MediaContracts.ts"],"names":[],"mappings":"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","file":"MediaContracts.d.ts","sourcesContent":["import {Nullable} from '@techsee/techsee-common';\n\nexport interface IMediaEnvironment {\n isIOS: () => boolean;\n isIE11: () => boolean;\n majorVersion: () => number;\n}\n\nimport {\n ConstraintType,\n KnownMediaStream,\n LocalVideoSourceType,\n MediaRequestErrorCode,\n MediaServiceType,\n MediaSessionDisconnectReason,\n MediaStreamUnregisterReason,\n SessionClientRole,\n SessionClientType\n} from './MediaConstants';\n\nexport interface LocalMediaConstraints {\n video: boolean | LocalVideoStreamConstraints;\n audio?: boolean;\n}\n\nexport type LocalMediaSourceInfo = LocalMediaConstraints & {\n mediaSourceType: LocalVideoSourceType;\n}\n\nexport interface VideoStreamResolution {\n resolution: string;\n constraintType: ConstraintType;\n}\n\nexport interface LocalVideoStreamConstraints {\n videoResolution?: string | VideoStreamResolution[];\n facingMode?: string;\n}\n\nexport interface MediaRequestSuccessResult {\n mediaStream: MediaStream;\n constraint: MediaStreamConstraints;\n constraintType: ConstraintType;\n isNew: boolean;\n}\n\nexport interface MediaRequestFailResult {\n message: string;\n errorCode: MediaRequestErrorCode;\n}\n\nexport interface ISessionStreamsManager {\n getMediaStreamForRole(destinationRole: SessionClientRole): Promise<Nullable<MediaStream>>;\n\n addRemoteMediaTrack(mediaTrack: RemoteMediaTrack): Promise<void>;\n\n removeMediaTrack(mediaTrack: MediaStreamTrack): Promise<void>;\n}\n\nexport interface MediaServiceOptions {\n mediaServiceType: MediaServiceType;\n //How much to wait until raise \"peerConnectionTimeout\" if WebRTC connection events not arriving\n peerConnectivityTimeoutSeconds?: number;\n\n //How much to wait totally for video stream to arrive, before making fallback to image upload\n videoNotReceivedTimeoutSeconds?: number;\n}\n\nexport interface MediaSessionParams {\n sessionId: string;\n clientType: SessionClientType;\n clientRole: SessionClientRole;\n credentials: MediaSessionIceCredentials;\n}\n\nexport interface MediaSessionConfiguration {\n //How much to wait until raise \"peerConnectionTimeout\" if WebRTC connection events not arriving\n peerConnectivityTimeoutSeconds: number;\n}\n\nexport interface MediaSubscriberParams {\n container: HTMLDivElement;\n streamType: KnownMediaStream;\n}\n\nexport interface MediaPublisherParams {\n streamTypes: KnownMediaStream[];\n destinationRole: SessionClientRole;\n}\n\nexport interface ClientWebRtcInfo {\n isWebRTCSupported: boolean;\n isWebsiteHasWebcamPermissions: boolean;\n isWebsiteHasMicrophonePermissions: boolean;\n isGetUserMediaSupported: boolean;\n isApplyConstraintsSupported: boolean;\n}\n\nexport interface IMediaSubscriber {\n readonly streamType: KnownMediaStream;\n readonly container: HTMLDivElement;\n readonly isPlaying: boolean;\n readonly isSoundMuted: boolean;\n readonly hasAudio: boolean;\n readonly hasVideo: boolean;\n readonly mediaElement: Nullable<HTMLVideoElement>;\n readonly videoWidth: number;\n readonly videoHeight: number;\n readonly renderWidth: number;\n readonly renderHeight: number;\n\n muteSound(isMuted: boolean): void;\n\n onStateChanged(callback: () => void): void;\n\n onDispose(callback: () => void): void;\n}\n\nexport type MediaSessionIceCredentials = any;//TODO - Define type for credentials\n\nexport interface MediaSessionHandlers {\n onDisconnectedHandler: MediaSessionDisconnectedHandler;\n}\n\nexport type MediaSessionDisconnectedHandler = (reason: MediaSessionDisconnectReason) => void\n\nexport interface DeviceSupportInfo {\n webRtcSupportInfo: ClientWebRtcInfo;\n hasCamera: boolean;\n hasMicrophone: boolean;\n videoPlayback: boolean;\n}\n\nexport interface RemoteTrackStats {\n trackId: string;\n trackStats: any;\n}\n\nexport interface IMediaSession {\n //Boolean parameter is used for supporting \"RTC Test\" application\n connect(connectOnly?: boolean): Promise<void>;\n\n disconnect(): Promise<void>;\n\n getRemoteTrackStats(mediaTrack: MediaStreamTrack): Promise<RemoteTrackStats>;\n\n onMediaStreamDestroyed(clientRole: SessionClientRole): Promise<void>;\n\n onMediaStreamRenewed(clientRole: SessionClientRole, mediaStream: MediaStream): Promise<void>;\n}\n\nexport interface RemoteMediaTrack {\n mediaTrack: MediaStreamTrack;\n trackType: KnownMediaStream;\n isRegistered: boolean;\n}\n\nexport interface SnapshotResult {\n base64img: string;\n objectUrl: string;\n imageBlob: Blob;\n mimeType: string;\n}\n\nexport interface SnapshotOptions {\n format?: string;\n quality?: number;\n x?: any;\n y?: any;\n w?: any;\n h?: any;\n}\n\nexport interface StreamDestroyedEventArgs {\n streamType: KnownMediaStream;\n reason: MediaStreamUnregisterReason;\n}\n\nexport interface StreamCreatedEventArgs {\n streamType: KnownMediaStream;\n}\n"]}