sip-connector 15.1.0 → 15.2.0

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.
Files changed (61) hide show
  1. package/README.md +160 -11
  2. package/dist/{@SipConnector-G96OmJEP.js → @SipConnector-BEZk1hmx.js} +548 -267
  3. package/dist/@SipConnector-hpySQIBa.cjs +1 -0
  4. package/dist/SipConnector/@SipConnector.d.ts +2 -0
  5. package/dist/SipConnector/eventNames.d.ts +1 -1
  6. package/dist/SipConnectorFacade/SipConnectorFacade.d.ts +3 -0
  7. package/dist/StatsManager/@StatsManager.d.ts +19 -0
  8. package/dist/StatsManager/eventNames.d.ts +2 -0
  9. package/dist/StatsManager/index.d.ts +2 -0
  10. package/dist/StatsPeerConnection/StatsPeerConnection.d.ts +20 -0
  11. package/dist/StatsPeerConnection/__fixtures__/callStaticsState.d.ts +3923 -0
  12. package/dist/StatsPeerConnection/constants.d.ts +14 -0
  13. package/dist/StatsPeerConnection/eventNames.d.ts +10 -0
  14. package/dist/StatsPeerConnection/index.d.ts +4 -0
  15. package/dist/StatsPeerConnection/parseStatsReports.d.ts +14 -0
  16. package/dist/StatsPeerConnection/requestAllStatistics.d.ts +11 -0
  17. package/dist/StatsPeerConnection/typings.d.ts +194 -0
  18. package/dist/StatsPeerConnection/utils/hasAvailableStats.d.ts +2 -0
  19. package/dist/StatsPeerConnection/utils/index.d.ts +3 -0
  20. package/dist/StatsPeerConnection/utils/now.d.ts +2 -0
  21. package/dist/StatsPeerConnection/utils/statsReportToObject.d.ts +4 -0
  22. package/dist/{videoSendingBalancer → VideoSendingBalancer}/ParametersSetterWithQueue.d.ts +2 -2
  23. package/dist/{videoSendingBalancer → VideoSendingBalancer}/SenderBalancer.d.ts +2 -2
  24. package/dist/{videoSendingBalancer → VideoSendingBalancer}/VideoSendingBalancer.d.ts +2 -2
  25. package/dist/{videoSendingBalancer → VideoSendingBalancer}/types.d.ts +2 -2
  26. package/dist/doMock.cjs +1 -1
  27. package/dist/doMock.js +4 -4
  28. package/dist/index.cjs +1 -1
  29. package/dist/index.d.ts +2 -2
  30. package/dist/index.js +270 -255
  31. package/dist/tools/createUaParser/createUaParser.d.ts +4 -0
  32. package/dist/tools/createUaParser/index.d.ts +1 -0
  33. package/dist/tools/createUaParser/isElectronEnvironment.d.ts +2 -0
  34. package/dist/tools/index.d.ts +4 -0
  35. package/dist/{setParametersToSender → tools/setParametersToSender}/configureDegradationPreference.d.ts +1 -1
  36. package/dist/{setParametersToSender → tools/setParametersToSender}/configureEncodings.d.ts +1 -1
  37. package/dist/{setParametersToSender → tools/setParametersToSender}/index.d.ts +1 -1
  38. package/dist/{setParametersToSender → tools/setParametersToSender}/setEncodingsToSender.d.ts +2 -2
  39. package/dist/{setParametersToSender → tools/setParametersToSender}/setMaxBitrateToSender.d.ts +1 -1
  40. package/dist/tools/setParametersToSender/setParametersToSender.d.ts +4 -0
  41. package/dist/{setParametersToSender → tools/setParametersToSender}/types.d.ts +1 -1
  42. package/package.json +7 -13
  43. package/dist/@SipConnector-BBhQzo-W.cjs +0 -1
  44. package/dist/setParametersToSender/setParametersToSender.d.ts +0 -4
  45. /package/dist/{videoSendingBalancer → VideoSendingBalancer}/CodecProvider.d.ts +0 -0
  46. /package/dist/{videoSendingBalancer → VideoSendingBalancer}/SenderFinder.d.ts +0 -0
  47. /package/dist/{videoSendingBalancer → VideoSendingBalancer}/TaskQueue.d.ts +0 -0
  48. /package/dist/{videoSendingBalancer → VideoSendingBalancer}/VideoSendingEventHandler.d.ts +0 -0
  49. /package/dist/{videoSendingBalancer → VideoSendingBalancer}/calcBitrate/calcMaxBitrateByWidth.d.ts +0 -0
  50. /package/dist/{videoSendingBalancer → VideoSendingBalancer}/calcBitrate/calcMaxBitrateByWidthAndCodec.d.ts +0 -0
  51. /package/dist/{videoSendingBalancer → VideoSendingBalancer}/calcBitrate/hasAv1Codec.d.ts +0 -0
  52. /package/dist/{videoSendingBalancer → VideoSendingBalancer}/calcBitrate/index.d.ts +0 -0
  53. /package/dist/{videoSendingBalancer → VideoSendingBalancer}/calcBitrate/scaleBitrateByCodec.d.ts +0 -0
  54. /package/dist/{videoSendingBalancer → VideoSendingBalancer}/calcResolution/calcScaleResolutionDownBy.d.ts +0 -0
  55. /package/dist/{videoSendingBalancer → VideoSendingBalancer}/calcResolution/index.d.ts +0 -0
  56. /package/dist/{videoSendingBalancer → VideoSendingBalancer}/index.d.ts +0 -0
  57. /package/dist/{setParametersToSender → tools/setParametersToSender}/configureEmptyEncodings.d.ts +0 -0
  58. /package/dist/{setParametersToSender → tools/setParametersToSender}/configureMaxBitrate.d.ts +0 -0
  59. /package/dist/{setParametersToSender → tools/setParametersToSender}/configureScaleResolutionDownBy.d.ts +0 -0
  60. /package/dist/{setParametersToSender → tools/setParametersToSender}/hasChangedRTCRtpSendParameters.d.ts +0 -0
  61. /package/dist/{setParametersToSender → tools/setParametersToSender}/resolveHasNeedToUpdateItemEncoding.d.ts +0 -0
@@ -0,0 +1,14 @@
1
+ export declare const INTERVAL_COLLECT_STATISTICS = 1000;
2
+ export declare enum EStatsTypes {
3
+ INBOUND_RTP = "inbound-rtp",
4
+ REMOTE_OUTBOUND_RTP = "remote-outbound-rtp",
5
+ MEDIA_SOURCE = "media-source",
6
+ OUTBOUND_RTP = "outbound-rtp",
7
+ REMOTE_INBOUND_RTP = "remote-inbound-rtp",
8
+ CODEC = "codec",
9
+ CANDIDATE_PAIR = "candidate-pair",
10
+ CERTIFICATE = "certificate",
11
+ TRANSPORT = "transport",
12
+ LOCAL_CANDIDATE = "local-candidate",
13
+ REMOTE_CANDIDATE = "remote-candidate"
14
+ }
@@ -0,0 +1,10 @@
1
+ import { TypedEvents } from 'events-constructor';
2
+ import { TInbound, TOutbound } from './typings';
3
+ export type TEventMap = {
4
+ collected: {
5
+ outbound: TOutbound;
6
+ inbound: TInbound;
7
+ };
8
+ };
9
+ export declare const EVENT_NAMES: readonly ["collected"];
10
+ export type TEvents = TypedEvents<TEventMap>;
@@ -0,0 +1,4 @@
1
+ export { EStatsTypes } from './constants';
2
+ export type { TEventMap } from './eventNames';
3
+ export { default as StatsPeerConnection } from './StatsPeerConnection';
4
+ export { default as hasAvailableStats } from './utils/hasAvailableStats';
@@ -0,0 +1,14 @@
1
+ import { TInbound, TOutbound, TSynchronizationSources } from './typings';
2
+ declare const parseStatsReports: ({ audioSenderStats, videoSenderFirstStats, videoSenderSecondStats, audioReceiverStats, videoReceiverFirstStats, videoReceiverSecondStats, synchronizationSources, }: {
3
+ audioSenderStats?: RTCStatsReport;
4
+ videoSenderFirstStats?: RTCStatsReport;
5
+ videoSenderSecondStats?: RTCStatsReport;
6
+ audioReceiverStats?: RTCStatsReport;
7
+ videoReceiverFirstStats?: RTCStatsReport;
8
+ videoReceiverSecondStats?: RTCStatsReport;
9
+ synchronizationSources: TSynchronizationSources;
10
+ }) => {
11
+ inbound: TInbound;
12
+ outbound: TOutbound;
13
+ };
14
+ export default parseStatsReports;
@@ -0,0 +1,11 @@
1
+ import { TSynchronizationSources } from './typings';
2
+ declare const requestAllStatistics: (peerConnection: RTCPeerConnection) => Promise<{
3
+ synchronizationSources: TSynchronizationSources;
4
+ audioSenderStats: RTCStatsReport | undefined;
5
+ videoSenderFirstStats: RTCStatsReport | undefined;
6
+ videoSenderSecondStats: RTCStatsReport | undefined;
7
+ audioReceiverStats: RTCStatsReport | undefined;
8
+ videoReceiverFirstStats: RTCStatsReport | undefined;
9
+ videoReceiverSecondStats: RTCStatsReport | undefined;
10
+ }>;
11
+ export default requestAllStatistics;
@@ -0,0 +1,194 @@
1
+ import { EStatsTypes } from './constants';
2
+ export type TMedia = {
3
+ trackIdentifier?: string;
4
+ item?: RTCRtpSynchronizationSource;
5
+ };
6
+ export type TSynchronizationSources = {
7
+ audio: TMedia;
8
+ video: TMedia;
9
+ };
10
+ export type TCandidatePair = RTCIceCandidatePairStats & {
11
+ consentRequestsSent?: number;
12
+ nominated?: boolean;
13
+ packetsDiscardedOnSend?: number;
14
+ packetsSent?: number;
15
+ priority?: number;
16
+ writable?: boolean;
17
+ };
18
+ export type TCandidate = {
19
+ candidateType?: string;
20
+ ip?: string;
21
+ networkType?: string;
22
+ isRemote?: boolean;
23
+ address?: string;
24
+ component?: RTCIceComponent;
25
+ foundation?: string;
26
+ port?: number;
27
+ priority?: number;
28
+ protocol?: RTCIceProtocol;
29
+ relatedAddress?: string;
30
+ relatedPort?: number;
31
+ sdpMLineIndex?: number;
32
+ sdpMid?: string;
33
+ tcpType?: string;
34
+ usernameFragment?: string;
35
+ };
36
+ export type TOutboundRtp = RTCOutboundRtpStreamStats & {
37
+ active?: boolean;
38
+ encoderImplementation?: string;
39
+ frameHeight?: number;
40
+ contentType?: string;
41
+ frameWidth?: number;
42
+ framesPerSecond?: number;
43
+ framesSent?: number;
44
+ hugeFramesSent?: number;
45
+ keyFramesEncoded?: number;
46
+ headerBytesSent?: number;
47
+ qualityLimitationDurations?: {
48
+ bandwidth?: number;
49
+ cpu?: number;
50
+ none?: number;
51
+ other?: number;
52
+ };
53
+ qualityLimitationReason?: string;
54
+ qualityLimitationResolutionChanges?: number;
55
+ mediaSourceId?: string;
56
+ mediaType?: string;
57
+ mid?: string;
58
+ retransmittedBytesSent?: number;
59
+ retransmittedPacketsSent?: number;
60
+ totalEncodeTime?: number;
61
+ totalEncodedBytesTarget?: number;
62
+ totalPacketSendDelay?: number;
63
+ targetBitrate?: number;
64
+ trackId?: string;
65
+ };
66
+ export type TTransport = RTCTransportStats & {
67
+ dtlsRole?: string;
68
+ iceLocalUsernameFragment?: string;
69
+ iceRole?: string;
70
+ iceState?: string;
71
+ packetsSent?: number;
72
+ remoteCertificateId?: string;
73
+ selectedCandidatePairChanges?: number;
74
+ };
75
+ export type TInboundRtp = RTCInboundRtpStreamStats & {
76
+ audioLevel?: number;
77
+ bytesReceived?: number;
78
+ decoderImplementation?: string;
79
+ framesDropped?: number;
80
+ framesReceived?: number;
81
+ headerBytesReceived?: number;
82
+ jitterBufferDelay?: number;
83
+ jitterBufferEmittedCount?: number;
84
+ keyFramesDecoded?: number;
85
+ fecPacketsDiscarded?: number;
86
+ fecPacketsReceived?: number;
87
+ jitterBufferMinimumDelay?: number;
88
+ jitterBufferTargetDelay?: number;
89
+ lastPacketReceivedTimestamp?: number;
90
+ totalSamplesReceived?: number;
91
+ };
92
+ export type TMediaSource = {
93
+ audioLevel?: number;
94
+ frames?: number;
95
+ framesPerSecond?: number;
96
+ height?: number;
97
+ width?: number;
98
+ totalAudioEnergy?: number;
99
+ totalSamplesDuration?: number;
100
+ trackIdentifier?: string;
101
+ };
102
+ export type TCertificate = {
103
+ base64Certificate?: string;
104
+ fingerprint?: string;
105
+ fingerprintAlgorithm?: string;
106
+ };
107
+ export type TRemoteInboundRtp = {
108
+ codecId?: string;
109
+ fractionLost?: number;
110
+ jitter?: number;
111
+ localId?: string;
112
+ packetsLost?: number;
113
+ roundTripTime?: number;
114
+ roundTripTimeMeasurements?: number;
115
+ ssrc?: number;
116
+ totalRoundTripTime?: number;
117
+ transportId?: string;
118
+ };
119
+ export type TRemoteOutboundRtp = {
120
+ bytesSent?: number;
121
+ codecId?: string;
122
+ localId?: string;
123
+ packetsSent?: number;
124
+ remoteTimestamp?: number;
125
+ reportsSent?: number;
126
+ roundTripTimeMeasurements?: number;
127
+ ssrc?: number;
128
+ totalRoundTripTime?: number;
129
+ transportId?: string;
130
+ };
131
+ export type TOutboundVideo = {
132
+ outboundRtp?: TOutboundRtp;
133
+ mediaSource?: TMediaSource;
134
+ codec?: RTCRtpCodecParameters;
135
+ remoteInboundRtp?: TRemoteInboundRtp;
136
+ };
137
+ export type TOutboundAudio = {
138
+ outboundRtp?: TOutboundRtp;
139
+ mediaSource?: TMediaSource;
140
+ codec?: RTCRtpCodecParameters;
141
+ remoteInboundRtp?: TRemoteInboundRtp;
142
+ };
143
+ export type TAdditional = {
144
+ candidatePair?: TCandidatePair;
145
+ certificate?: TCertificate;
146
+ localCandidate?: TCandidate;
147
+ remoteCandidate?: TCandidate;
148
+ transport?: TTransport;
149
+ };
150
+ export type TInboundVideo = {
151
+ inboundRtp?: TInboundRtp;
152
+ codec?: RTCRtpCodecParameters;
153
+ synchronizationSources?: TMedia;
154
+ };
155
+ export type TInboundAudio = {
156
+ inboundRtp?: TInboundRtp;
157
+ codec?: RTCRtpCodecParameters;
158
+ remoteOutboundRtp?: TRemoteOutboundRtp;
159
+ synchronizationSources?: TMedia;
160
+ };
161
+ export type TInbound = {
162
+ video: TInboundVideo;
163
+ secondVideo: TInboundVideo;
164
+ audio: TInboundAudio;
165
+ additional: TAdditional;
166
+ };
167
+ export type TOutbound = {
168
+ video: TOutboundVideo;
169
+ secondVideo: TOutboundVideo;
170
+ audio: TOutboundAudio;
171
+ additional: TAdditional;
172
+ };
173
+ export type TAudioStatistics = {
174
+ [EStatsTypes.OUTBOUND_RTP]?: TOutboundRtp;
175
+ [EStatsTypes.CODEC]?: RTCRtpCodecParameters;
176
+ [EStatsTypes.MEDIA_SOURCE]?: TMediaSource;
177
+ [EStatsTypes.REMOTE_INBOUND_RTP]?: TRemoteInboundRtp;
178
+ [EStatsTypes.INBOUND_RTP]?: TInboundRtp;
179
+ [EStatsTypes.REMOTE_OUTBOUND_RTP]?: TRemoteOutboundRtp;
180
+ };
181
+ export type TVideoStatistics = {
182
+ [EStatsTypes.OUTBOUND_RTP]?: TOutboundRtp;
183
+ [EStatsTypes.CODEC]?: RTCRtpCodecParameters;
184
+ [EStatsTypes.MEDIA_SOURCE]?: TMediaSource;
185
+ [EStatsTypes.REMOTE_INBOUND_RTP]?: TRemoteInboundRtp;
186
+ [EStatsTypes.INBOUND_RTP]?: TInboundRtp;
187
+ };
188
+ export type TParsedStatistics = {
189
+ [EStatsTypes.CANDIDATE_PAIR]?: TCandidatePair;
190
+ [EStatsTypes.CERTIFICATE]?: TCertificate;
191
+ [EStatsTypes.LOCAL_CANDIDATE]?: TCandidate;
192
+ [EStatsTypes.REMOTE_CANDIDATE]?: TCandidate;
193
+ [EStatsTypes.TRANSPORT]?: TTransport;
194
+ };
@@ -0,0 +1,2 @@
1
+ declare const hasAvailableStats: () => boolean;
2
+ export default hasAvailableStats;
@@ -0,0 +1,3 @@
1
+ export { default as hasAvailableStats } from './hasAvailableStats';
2
+ export { default as now } from './now';
3
+ export { default as statsReportToObject } from './statsReportToObject';
@@ -0,0 +1,2 @@
1
+ declare const now: () => number;
2
+ export default now;
@@ -0,0 +1,4 @@
1
+ declare const statsReportToObject: (results: ReadonlyMap<string, {
2
+ type: string;
3
+ }>) => {};
4
+ export default statsReportToObject;
@@ -1,4 +1,4 @@
1
- import { TOnSetParameters, TResult } from '../setParametersToSender';
1
+ import { TOnSetParameters, TResultSetParametersToSender } from '../tools';
2
2
  import { IEncodingParameters, IParametersSetter } from './types';
3
3
  /**
4
4
  * Обёртка для ParametersSetter с использованием TaskQueue
@@ -7,6 +7,6 @@ export declare class ParametersSetterWithQueue implements IParametersSetter {
7
7
  private readonly taskQueue;
8
8
  private readonly onSetParameters?;
9
9
  constructor(onSetParameters?: TOnSetParameters);
10
- setEncodingsToSender(sender: RTCRtpSender, parameters: IEncodingParameters): Promise<TResult>;
10
+ setEncodingsToSender(sender: RTCRtpSender, parameters: IEncodingParameters): Promise<TResultSetParametersToSender>;
11
11
  stop(): void;
12
12
  }
@@ -1,4 +1,4 @@
1
- import { TResult } from '../setParametersToSender';
1
+ import { TResultSetParametersToSender } from '../tools';
2
2
  import { ICodecProvider, IMainCamHeaders, IParametersSetter, ISenderFinder } from './types';
3
3
  /**
4
4
  * Бизнес-логика балансировки отправителей
@@ -23,7 +23,7 @@ export declare class SenderBalancer {
23
23
  * @param headers - Заголовки от сервера с командами управления
24
24
  * @returns Promise с результатом балансировки
25
25
  */
26
- balance(connection: RTCPeerConnection, headers?: IMainCamHeaders): Promise<TResult>;
26
+ balance(connection: RTCPeerConnection, headers?: IMainCamHeaders): Promise<TResultSetParametersToSender>;
27
27
  /**
28
28
  * Обрабатывает отправитель в зависимости от команды управления
29
29
  * @param context - Контекст балансировки
@@ -1,5 +1,5 @@
1
- import { TResult } from '../setParametersToSender';
2
1
  import { SipConnector } from '../SipConnector';
2
+ import { TResultSetParametersToSender } from '../tools';
3
3
  import { IBalancerOptions } from './types';
4
4
  /**
5
5
  * Контроллер/фасад для балансировки видеопотоков
@@ -27,7 +27,7 @@ declare class VideoSendingBalancer {
27
27
  * Перебалансирует текущее состояние
28
28
  * @returns Promise с результатом балансировки
29
29
  */
30
- reBalance(): Promise<TResult>;
30
+ reBalance(): Promise<TResultSetParametersToSender>;
31
31
  /**
32
32
  * Выполняет балансировку на основе текущего состояния
33
33
  * @returns Promise с результатом балансировки
@@ -1,5 +1,5 @@
1
1
  import { EEventsMainCAM } from '../ApiManager';
2
- import { TOnSetParameters, TResult } from '../setParametersToSender';
2
+ import { TOnSetParameters, TResultSetParametersToSender } from '../tools';
3
3
  export interface IBalancerOptions {
4
4
  ignoreForCodec?: string;
5
5
  onSetParameters?: TOnSetParameters;
@@ -24,7 +24,7 @@ export interface IEncodingParameters {
24
24
  maxBitrate: number;
25
25
  }
26
26
  export interface IParametersSetter {
27
- setEncodingsToSender: (sender: RTCRtpSender, parameters: IEncodingParameters, onSetParameters?: TOnSetParameters) => Promise<TResult>;
27
+ setEncodingsToSender: (sender: RTCRtpSender, parameters: IEncodingParameters, onSetParameters?: TOnSetParameters) => Promise<TResultSetParametersToSender>;
28
28
  }
29
29
  export interface IEventHandler {
30
30
  subscribe: (handler: (headers: IMainCamHeaders) => void) => void;
package/dist/doMock.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const b=require("node:events"),V=require("@krivega/jssip/lib/NameAddrHeader"),k=require("@krivega/jssip/lib/URI"),U=require("@krivega/jssip/lib/SIPMessage"),a=require("@krivega/jssip"),f=require("webrtc-mock"),S=require("events-constructor"),P=require("./@SipConnector-BBhQzo-W.cjs");class N extends U.IncomingRequest{headers;constructor(e){super(),this.headers=new Headers(e)}getHeader(e){return this.headers.get(e)??""}}const H="incomingCall",q="declinedIncomingCall",G="failedIncomingCall",x="terminatedIncomingCall",v="connecting",z="connected",j="disconnected",Y="newRTCSession",B="registered",K="unregistered",J="registrationFailed",$="newMessage",Q="sipEvent",X="availableSecondRemoteStream",Z="notAvailableSecondRemoteStream",ee="mustStopPresentation",te="shareState",re="enterRoom",ne="useLicense",oe="peerconnection:confirmed",se="peerconnection:ontrack",ie="channels",ae="channels:notify",ce="ended:fromserver",de="main-cam-control",Ee="admin-stop-main-cam",he="admin-start-main-cam",ue="admin-stop-mic",me="admin-start-mic",le="admin-force-sync-media-state",pe="participant:added-to-list-moderators",ge="participant:removed-from-list-moderators",_e="participant:move-request-to-stream",Te="participant:move-request-to-spectators",Ie="participant:move-request-to-participants",Se="participation:accepting-word-request",Ne="participation:cancelling-word-request",we="webcast:started",Ce="webcast:stopped",Re="account:changed",fe="account:deleted",Ae="conference:participant-token-issued",Me="ended",Oe="sending",Pe="reinvite",ve="replaces",De="refer",ye="progress",Le="accepted",Fe="confirmed",We="peerconnection",be="failed",Ve="muted",ke="unmuted",Ue="newDTMF",He="newInfo",qe="hold",Ge="unhold",xe="update",ze="sdp",je="icecandidate",Ye="getusermediafailed",Be="peerconnection:createofferfailed",Ke="peerconnection:createanswerfailed",Je="peerconnection:setlocaldescriptionfailed",$e="peerconnection:setremotedescriptionfailed",Qe="presentation:start",Xe="presentation:started",Ze="presentation:end",et="presentation:ended",tt="presentation:failed",rt=[H,q,x,G,Se,Ne,_e,ae,Ae,Re,fe,we,Ce,pe,ge],D=[v,z,j,Y,B,K,J,$,Q],nt=[X,Z,ee,te,re,ne,oe,se,ie,ce,de,he,Ee,ue,me,le,Te,Ie],_=[Me,v,Oe,Pe,ve,De,ye,Le,Fe,We,be,Ve,ke,Ue,He,qe,Ge,xe,ze,je,Ye,Be,Ke,Je,$e,Qe,Xe,Ze,et,tt];[...D,...rt];[..._,...nt];class ot{originator;connection;events;remote_identity;mutedOptions={audio:!1,video:!1};constructor({originator:e="local",eventHandlers:t,remoteIdentity:r}){this.originator=e,this.events=new S.Events(_),this.initEvents(t),this.remote_identity=r}get contact(){throw new Error("Method not implemented.")}get direction(){throw new Error("Method not implemented.")}get local_identity(){throw new Error("Method not implemented.")}get start_time(){throw new Error("Method not implemented.")}get end_time(){throw new Error("Method not implemented.")}get status(){throw new Error("Method not implemented.")}get C(){throw new Error("Method not implemented.")}get causes(){throw new Error("Method not implemented.")}get id(){throw new Error("Method not implemented.")}get data(){throw new Error("Method not implemented.")}set data(e){throw new Error("Method not implemented.")}isInProgress(){throw new Error("Method not implemented.")}isEnded(){throw new Error("Method not implemented.")}isReadyToReOffer(){throw new Error("Method not implemented.")}answer(e){throw new Error("Method not implemented.")}terminate(e){throw new Error("Method not implemented.")}async sendInfo(e,t,r){throw new Error("Method not implemented.")}hold(e,t){throw new Error("Method not implemented.")}unhold(e,t){throw new Error("Method not implemented.")}async renegotiate(e,t){throw new Error("Method not implemented.")}isOnHold(){throw new Error("Method not implemented.")}mute(e){throw new Error("Method not implemented.")}unmute(e){throw new Error("Method not implemented.")}isMuted(){throw new Error("Method not implemented.")}refer(e,t){throw new Error("Method not implemented.")}resetLocalMedia(){throw new Error("Method not implemented.")}async replaceMediaStream(e,t){throw new Error("Method not implemented.")}addListener(e,t){throw new Error("Method not implemented.")}once(e,t){throw new Error("Method not implemented.")}removeListener(e,t){throw new Error("Method not implemented.")}off(e,t){return this.events.off(e,t),this}removeAllListeners(e){return console.warn("Method not implemented. Event:",e),this}setMaxListeners(e){throw new Error("Method not implemented.")}getMaxListeners(){throw new Error("Method not implemented.")}listeners(e){throw new Error("Method not implemented.")}rawListeners(e){throw new Error("Method not implemented.")}emit(e,...t){throw new Error("Method not implemented.")}listenerCount(e){throw new Error("Method not implemented.")}prependListener(e,t){throw new Error("Method not implemented.")}prependOnceListener(e,t){throw new Error("Method not implemented.")}eventNames(){throw new Error("Method not implemented.")}initEvents(e){e&&Object.entries(e).forEach(([t,r])=>{this.on(t,r)})}on(e,t){return _.includes(e)&&this.events.on(e,t),this}trigger(e,t){this.events.trigger(e,t)}sendDTMF(){this.trigger("newDTMF",{originator:this.originator})}async startPresentation(e){return this.trigger("presentation:start",e),this.trigger("presentation:started",e),e}async stopPresentation(e){return this.trigger("presentation:end",e),this.trigger("presentation:ended",e),e}isEstablished(){return!0}}class st{stats=new Map().set("codec",{mimeType:"video/h264"});dtmf=null;track=null;transport=null;transform=null;parameters={encodings:[{}],transactionId:"0",codecs:[],headerExtensions:[],rtcp:{}};parametersGets;constructor({track:e}={}){this.track=e??null}async getStats(){return this.stats}async replaceTrack(e){this.track=e??null}async setParameters(e){if(e!==this.parametersGets)throw new Error("Failed to execute 'setParameters' on 'RTCRtpSender': Read-only field modified in setParameters().");const{transactionId:t}=this.parameters;this.parameters={...this.parameters,...e,transactionId:`${Number(t)+1}`}}getParameters(){return this.parametersGets={...this.parameters},this.parametersGets}setStreams(){throw new Error("Method not implemented.")}}const it=["track"];class at{senders=[];receivers=[];canTrickleIceCandidates;connectionState;currentLocalDescription;currentRemoteDescription;iceConnectionState;iceGatheringState;idpErrorInfo;idpLoginUrl;localDescription;onconnectionstatechange;ondatachannel;onicecandidate;onicecandidateerror=null;oniceconnectionstatechange;onicegatheringstatechange;onnegotiationneeded;onsignalingstatechange;ontrack;peerIdentity=void 0;pendingLocalDescription;pendingRemoteDescription;remoteDescription;sctp=null;signalingState;events;constructor(e,t){this.events=new S.Events(it),this.receivers=t.map(r=>({track:r}))}getRemoteStreams(){throw new Error("Method not implemented.")}async addIceCandidate(e){throw new Error("Method not implemented.")}addTransceiver(e,t){throw new Error("Method not implemented.")}close(){throw new Error("Method not implemented.")}restartIce(){throw new Error("Method not implemented.")}async createAnswer(e,t){throw new Error("Method not implemented.")}createDataChannel(e,t){throw new Error("Method not implemented.")}async createOffer(e,t,r){throw new Error("Method not implemented.")}getConfiguration(){throw new Error("Method not implemented.")}async getIdentityAssertion(){throw new Error("Method not implemented.")}async getStats(e){throw new Error("Method not implemented.")}getTransceivers(){throw new Error("Method not implemented.")}removeTrack(e){throw new Error("Method not implemented.")}setConfiguration(e){throw new Error("Method not implemented.")}async setLocalDescription(e){throw new Error("Method not implemented.")}async setRemoteDescription(e){throw new Error("Method not implemented.")}addEventListener(e,t,r){this.events.on(e,t)}removeEventListener(e,t,r){this.events.off(e,t)}dispatchEvent(e){throw new Error("Method not implemented.")}getReceivers=()=>this.receivers;getSenders=()=>this.senders;addTrack=e=>{const t=new st({track:e});return this.senders.push(t),this.events.trigger("track",{track:e}),t}}function ct(n){const e=n.match(/(purgatory)|[\d.]+/g);if(!e)throw new Error("wrong sip url");return e[0]}const A=400,y="777",dt=n=>n.getVideoTracks().length>0;class i extends ot{static presentationError;static startPresentationError;static countStartPresentationError=Number.POSITIVE_INFINITY;static countStartsPresentation=0;url;status_code;answer=jest.fn(({mediaStream:e})=>{if(this.originator!=="remote")throw new Error("answer available only for remote sessions");this.initPeerconnection(e),setTimeout(()=>{this.trigger("connecting"),setTimeout(()=>{this.trigger("accepted")},100),setTimeout(()=>{this.trigger("confirmed")},200)},A)});replaceMediaStream=jest.fn(async e=>{});isEndedInner=!1;constructor({eventHandlers:e,originator:t,remoteIdentity:r=new a.NameAddrHeader(new a.URI("sip","caller1","test1.com",5060),"Test Caller 1")}){super({originator:t,eventHandlers:e,remoteIdentity:r})}static setPresentationError(e){this.presentationError=e}static resetPresentationError(){this.presentationError=void 0}static setStartPresentationError(e,{count:t=Number.POSITIVE_INFINITY}={}){this.startPresentationError=e,this.countStartPresentationError=t}static resetStartPresentationError(){this.startPresentationError=void 0,this.countStartPresentationError=Number.POSITIVE_INFINITY,this.countStartsPresentation=0}startPresentation=async e=>{if(i.countStartsPresentation+=1,i.presentationError)throw this.trigger("presentation:start",e),this.trigger("presentation:failed",e),i.presentationError;if(i.startPresentationError&&i.countStartsPresentation<i.countStartPresentationError)throw this.trigger("presentation:start",e),this.trigger("presentation:failed",e),i.startPresentationError;return super.startPresentation(e)};stopPresentation=async e=>{if(i.presentationError)throw this.trigger("presentation:end",e),this.trigger("presentation:failed",e),i.presentationError;return super.stopPresentation(e)};initPeerconnection(e){return e?(this.createPeerconnection(e),!0):!1}createPeerconnection(e){const t=f.createAudioMediaStreamTrackMock();t.id="mainaudio1";const r=[t];if(dt(e)){const c=f.createVideoMediaStreamTrackMock();c.id="mainvideo1",r.push(c)}this.connection=new at(void 0,r),this.addStream(e),this.trigger("peerconnection",{peerconnection:this.connection})}connect(e,{mediaStream:t}={}){const r=ct(e);return this.initPeerconnection(t),setTimeout(()=>{e.includes(y)?this.trigger("failed",{originator:"remote",message:"IncomingResponse",cause:"Rejected"}):(this.trigger("connecting"),setTimeout(()=>{this.newInfo({originator:P.Originator.REMOTE,request:{getHeader:s=>s==="content-type"?"application/vinteo.webrtc.roomname":s==="x-webrtc-enter-room"?r:s==="x-webrtc-participant-name"?"Test Caller 1":""}})},100),setTimeout(()=>{this.trigger("accepted")},200),setTimeout(()=>{this.trigger("confirmed")},300))},A),this.connection}terminate({status_code:e,cause:t}={}){return this.status_code=e,this.trigger("ended",{status_code:e,cause:t,originator:"local"}),this.isEndedInner=!1,this}async terminateAsync({status_code:e,cause:t}={}){this.terminate({status_code:e,cause:t})}terminateRemote({status_code:e}={}){return this.status_code=e,this.trigger("ended",{status_code:e,originator:"remote"}),this}addStream(e,t="getTracks"){e[t]().forEach(r=>this.connection.addTrack(r))}forEachSenders(e){const t=this.connection.getSenders();for(const r of t)e(r);return t}toggleMuteAudio(e){this.forEachSenders(({track:t})=>{t&&t.kind==="audio"&&(t.enabled=!e)})}toggleMuteVideo(e){this.forEachSenders(({track:t})=>{t&&t.kind==="video"&&(t.enabled=!e)})}mute(e){e.audio&&(this.mutedOptions.audio=!0,this.toggleMuteAudio(this.mutedOptions.audio)),e.video&&(this.mutedOptions.video=!0,this.toggleMuteVideo(this.mutedOptions.video)),this.onmute(e)}unmute(e){e.audio&&(this.mutedOptions.audio=!1),e.video&&(this.mutedOptions.video=!1),this.trigger("unmuted",e)}isMuted(){return this.mutedOptions}onmute({audio:e,video:t}){this.trigger("muted",{audio:e,video:t})}async sendInfo(){}isEnded(){return this.isEndedInner}newInfo(e){this.trigger("newInfo",e)}}class Et{extraHeaders=[];setExtraHeaders(e){this.extraHeaders=e}setExtraContactParams(){}}const d="PASSWORD_CORRECT",T="PASSWORD_CORRECT_2",L="NAME_INCORRECT",h=400,g={url:"wss://sipServerUrl/webrtc/wss/",sip_uri:"sip:sipServerUrl;transport=ws",via_transport:"WSS"},M={status_code:200,reason_phrase:"OK"},O={status_code:401,reason_phrase:"Unauthorized"};class o{static isAvailableTelephony=!0;static startError;static countStartError=Number.POSITIVE_INFINITY;static countStarts=0;events;registratorInner;call=jest.fn((e,t)=>{const{mediaStream:r,eventHandlers:s}=t;return this.session=new i({eventHandlers:s,originator:"local"}),this.session.connect(e,{mediaStream:r}),this.session});sendOptions=jest.fn((e,t,r)=>{console.log("sendOptions",e,t,r)});start=jest.fn(()=>{if(o.countStarts+=1,o.startError&&o.countStarts<o.countStartError){this.trigger("disconnected",o.startError);return}this.register()});stop=jest.fn(()=>{this.startedTimeout&&clearTimeout(this.startedTimeout),this.stopedTimeout&&clearTimeout(this.stopedTimeout),this.unregister(),this.isStarted()?this.stopedTimeout=setTimeout(()=>{this.trigger("disconnected",{error:!0,socket:g})},h):this.trigger("disconnected",{error:!0,socket:g})});removeAllListeners=jest.fn(()=>(this.events.removeEventHandlers(),this));once=jest.fn((e,t)=>(this.events.once(e,t),this));startedTimeout;stopedTimeout;session;isRegisteredInner;isConnectedInner;configuration;constructor(e){this.events=new S.Events(D);const[t,r]=e.uri.split(":"),[s,c]=r.split("@"),p={...e,uri:new a.URI(t,s,c)};this.configuration=p,this.registratorInner=new Et}static setStartError(e,{count:t=Number.POSITIVE_INFINITY}={}){o.startError=e,o.countStartError=t}static resetStartError(){o.startError=void 0,o.countStartError=Number.POSITIVE_INFINITY,o.countStarts=0}static setAvailableTelephony(){o.isAvailableTelephony=!0}static setNotAvailableTelephony(){o.isAvailableTelephony=!1}static reset(){o.resetStartError(),o.setAvailableTelephony()}on(e,t){return this.events.on(e,t),this}off(e,t){return this.events.off(e,t),this}trigger(e,t){this.events.trigger(e,t)}terminateSessions(){this.session?.terminate()}set(e,t){return this.configuration[e]=t,!0}register(){this.startedTimeout&&clearTimeout(this.startedTimeout);const{password:e,register:t,uri:r}=this.configuration;t===!0&&r.user.includes(L)?(this.isRegisteredInner=!1,this.isConnectedInner=!1,this.startedTimeout=setTimeout(()=>{this.trigger("registrationFailed",{response:O,cause:a.C.causes.REJECTED})},h)):!this.isRegistered()&&t===!0&&(e===d||e===T)?(this.isRegisteredInner=!0,this.startedTimeout=setTimeout(()=>{this.trigger("registered",{response:M})},h)):t===!0&&e!==d&&e!==T&&(this.isRegisteredInner=!1,this.isConnectedInner=!1,this.startedTimeout=setTimeout(()=>{this.trigger("registrationFailed",{response:O,cause:a.C.causes.REJECTED})},h)),o.isAvailableTelephony?(this.trigger("connected",{socket:g}),this.isConnectedInner=!0):this.stop()}unregister(){this.isRegisteredInner=!1,this.isConnectedInner=!1,this.trigger("unregistered",{response:M})}isRegistered(){return this.isRegisteredInner===!0}isConnected(){return this.isConnectedInner===!0}isStarted(){return this.configuration.register===!0&&this.isRegisteredInner===!0||this.configuration.register!==!0&&this.isConnectedInner===!0}newSipEvent(e){this.trigger("sipEvent",e)}registrator(){return this.registratorInner}}class ht{url;constructor(e){this.url=e}}class ut extends b.EventEmitter{contentType;body;constructor(e,t){super(),this.contentType=e,this.body=t}}const I="remote",mt=(n,e)=>{const t=new N(e),r={originator:I,request:t,info:new ut("","")};n.newInfo(r)},lt=(n,e)=>{const r={event:"sipEvent",request:new N(e)};n.newSipEvent(r)},pt=(n,{incomingNumber:e="1234",displayName:t,host:r})=>{const s=new i({originator:I,eventHandlers:{}}),c=new k("sip",e,r);s.remote_identity=new V(c,t);const p=new N([]);n.trigger("newRTCSession",{originator:I,session:s,request:p})},gt=(n,e)=>{e?n.trigger("failed",e):n.trigger("failed",n)},w={triggerNewInfo:mt,triggerNewSipEvent:lt,triggerIncomingSession:pt,triggerFailIncomingSession:gt,WebSocketInterface:ht,UA:o,C:{INVITE:"INVITE"}},u="user",E="displayName",m="SIP_SERVER_URL",C="SIP_WEB_SOCKET_SERVER_URL",_t=new w.WebSocketInterface(C),R={userAgent:"Chrome",sipServerUrl:m,sipWebSocketServerURL:C},Tt={...R},F={...R,user:u,password:d,register:!0},It={...F,displayName:E},St={...R,displayName:E,register:!1},l={session_timers:!1,sockets:[_t],user_agent:"Chrome",sdpSemantics:"unified-plan",register_expires:300,connection_recovery_max_interval:6,connection_recovery_min_interval:2},Nt={...l,password:d,uri:new a.URI("sip",u,m),display_name:"",register:!0},wt={...l,password:d,uri:new a.URI("sip",u,m),display_name:E,register:!0},Ct={...l,display_name:E,register:!1},Rt={...l,display_name:"",register:!1},W="10.10.10.10",ft=[`X-Vinteo-Remote: ${W}`],At=()=>new P.SipConnector({JsSIP:w});exports.FAILED_CONFERENCE_NUMBER=y;exports.JsSIP=w;exports.NAME_INCORRECT=L;exports.PASSWORD_CORRECT=d;exports.PASSWORD_CORRECT_2=T;exports.SIP_SERVER_URL=m;exports.SIP_WEB_SOCKET_SERVER_URL=C;exports.dataForConnectionWithAuthorization=F;exports.dataForConnectionWithAuthorizationWithDisplayName=It;exports.dataForConnectionWithoutAuthorization=St;exports.dataForConnectionWithoutAuthorizationWithoutDisplayName=Tt;exports.displayName=E;exports.doMockSipConnector=At;exports.extraHeadersRemoteAddress=ft;exports.remoteAddress=W;exports.uaConfigurationWithAuthorization=Nt;exports.uaConfigurationWithAuthorizationWithDisplayName=wt;exports.uaConfigurationWithoutAuthorization=Ct;exports.uaConfigurationWithoutAuthorizationWithoutDisplayName=Rt;exports.user=u;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const b=require("node:events"),V=require("@krivega/jssip/lib/NameAddrHeader"),k=require("@krivega/jssip/lib/URI"),U=require("@krivega/jssip/lib/SIPMessage"),a=require("@krivega/jssip"),f=require("webrtc-mock"),S=require("events-constructor"),P=require("./@SipConnector-hpySQIBa.cjs");class N extends U.IncomingRequest{headers;constructor(e){super(),this.headers=new Headers(e)}getHeader(e){return this.headers.get(e)??""}}const H="incomingCall",q="declinedIncomingCall",G="failedIncomingCall",x="terminatedIncomingCall",v="connecting",z="connected",j="disconnected",Y="newRTCSession",B="registered",K="unregistered",J="registrationFailed",$="newMessage",Q="sipEvent",X="availableSecondRemoteStream",Z="notAvailableSecondRemoteStream",ee="mustStopPresentation",te="shareState",re="enterRoom",ne="useLicense",oe="peerconnection:confirmed",se="peerconnection:ontrack",ie="channels",ae="channels:notify",ce="ended:fromserver",de="main-cam-control",Ee="admin-stop-main-cam",he="admin-start-main-cam",ue="admin-stop-mic",me="admin-start-mic",le="admin-force-sync-media-state",pe="participant:added-to-list-moderators",ge="participant:removed-from-list-moderators",_e="participant:move-request-to-stream",Te="participant:move-request-to-spectators",Ie="participant:move-request-to-participants",Se="participation:accepting-word-request",Ne="participation:cancelling-word-request",we="webcast:started",Ce="webcast:stopped",Re="account:changed",fe="account:deleted",Ae="conference:participant-token-issued",Me="ended",Oe="sending",Pe="reinvite",ve="replaces",De="refer",ye="progress",Le="accepted",Fe="confirmed",We="peerconnection",be="failed",Ve="muted",ke="unmuted",Ue="newDTMF",He="newInfo",qe="hold",Ge="unhold",xe="update",ze="sdp",je="icecandidate",Ye="getusermediafailed",Be="peerconnection:createofferfailed",Ke="peerconnection:createanswerfailed",Je="peerconnection:setlocaldescriptionfailed",$e="peerconnection:setremotedescriptionfailed",Qe="presentation:start",Xe="presentation:started",Ze="presentation:end",et="presentation:ended",tt="presentation:failed",rt=[H,q,x,G,Se,Ne,_e,ae,Ae,Re,fe,we,Ce,pe,ge],D=[v,z,j,Y,B,K,J,$,Q],nt=[X,Z,ee,te,re,ne,oe,se,ie,ce,de,he,Ee,ue,me,le,Te,Ie],_=[Me,v,Oe,Pe,ve,De,ye,Le,Fe,We,be,Ve,ke,Ue,He,qe,Ge,xe,ze,je,Ye,Be,Ke,Je,$e,Qe,Xe,Ze,et,tt];[...D,...rt];[..._,...nt];class ot{originator;connection;events;remote_identity;mutedOptions={audio:!1,video:!1};constructor({originator:e="local",eventHandlers:t,remoteIdentity:r}){this.originator=e,this.events=new S.Events(_),this.initEvents(t),this.remote_identity=r}get contact(){throw new Error("Method not implemented.")}get direction(){throw new Error("Method not implemented.")}get local_identity(){throw new Error("Method not implemented.")}get start_time(){throw new Error("Method not implemented.")}get end_time(){throw new Error("Method not implemented.")}get status(){throw new Error("Method not implemented.")}get C(){throw new Error("Method not implemented.")}get causes(){throw new Error("Method not implemented.")}get id(){throw new Error("Method not implemented.")}get data(){throw new Error("Method not implemented.")}set data(e){throw new Error("Method not implemented.")}isInProgress(){throw new Error("Method not implemented.")}isEnded(){throw new Error("Method not implemented.")}isReadyToReOffer(){throw new Error("Method not implemented.")}answer(e){throw new Error("Method not implemented.")}terminate(e){throw new Error("Method not implemented.")}async sendInfo(e,t,r){throw new Error("Method not implemented.")}hold(e,t){throw new Error("Method not implemented.")}unhold(e,t){throw new Error("Method not implemented.")}async renegotiate(e,t){throw new Error("Method not implemented.")}isOnHold(){throw new Error("Method not implemented.")}mute(e){throw new Error("Method not implemented.")}unmute(e){throw new Error("Method not implemented.")}isMuted(){throw new Error("Method not implemented.")}refer(e,t){throw new Error("Method not implemented.")}resetLocalMedia(){throw new Error("Method not implemented.")}async replaceMediaStream(e,t){throw new Error("Method not implemented.")}addListener(e,t){throw new Error("Method not implemented.")}once(e,t){throw new Error("Method not implemented.")}removeListener(e,t){throw new Error("Method not implemented.")}off(e,t){return this.events.off(e,t),this}removeAllListeners(e){return console.warn("Method not implemented. Event:",e),this}setMaxListeners(e){throw new Error("Method not implemented.")}getMaxListeners(){throw new Error("Method not implemented.")}listeners(e){throw new Error("Method not implemented.")}rawListeners(e){throw new Error("Method not implemented.")}emit(e,...t){throw new Error("Method not implemented.")}listenerCount(e){throw new Error("Method not implemented.")}prependListener(e,t){throw new Error("Method not implemented.")}prependOnceListener(e,t){throw new Error("Method not implemented.")}eventNames(){throw new Error("Method not implemented.")}initEvents(e){e&&Object.entries(e).forEach(([t,r])=>{this.on(t,r)})}on(e,t){return _.includes(e)&&this.events.on(e,t),this}trigger(e,t){this.events.trigger(e,t)}sendDTMF(){this.trigger("newDTMF",{originator:this.originator})}async startPresentation(e){return this.trigger("presentation:start",e),this.trigger("presentation:started",e),e}async stopPresentation(e){return this.trigger("presentation:end",e),this.trigger("presentation:ended",e),e}isEstablished(){return!0}}class st{stats=new Map().set("codec",{mimeType:"video/h264"});dtmf=null;track=null;transport=null;transform=null;parameters={encodings:[{}],transactionId:"0",codecs:[],headerExtensions:[],rtcp:{}};parametersGets;constructor({track:e}={}){this.track=e??null}async getStats(){return this.stats}async replaceTrack(e){this.track=e??null}async setParameters(e){if(e!==this.parametersGets)throw new Error("Failed to execute 'setParameters' on 'RTCRtpSender': Read-only field modified in setParameters().");const{transactionId:t}=this.parameters;this.parameters={...this.parameters,...e,transactionId:`${Number(t)+1}`}}getParameters(){return this.parametersGets={...this.parameters},this.parametersGets}setStreams(){throw new Error("Method not implemented.")}}const it=["track"];class at{senders=[];receivers=[];canTrickleIceCandidates;connectionState;currentLocalDescription;currentRemoteDescription;iceConnectionState;iceGatheringState;idpErrorInfo;idpLoginUrl;localDescription;onconnectionstatechange;ondatachannel;onicecandidate;onicecandidateerror=null;oniceconnectionstatechange;onicegatheringstatechange;onnegotiationneeded;onsignalingstatechange;ontrack;peerIdentity=void 0;pendingLocalDescription;pendingRemoteDescription;remoteDescription;sctp=null;signalingState;events;constructor(e,t){this.events=new S.Events(it),this.receivers=t.map(r=>({track:r}))}getRemoteStreams(){throw new Error("Method not implemented.")}async addIceCandidate(e){throw new Error("Method not implemented.")}addTransceiver(e,t){throw new Error("Method not implemented.")}close(){throw new Error("Method not implemented.")}restartIce(){throw new Error("Method not implemented.")}async createAnswer(e,t){throw new Error("Method not implemented.")}createDataChannel(e,t){throw new Error("Method not implemented.")}async createOffer(e,t,r){throw new Error("Method not implemented.")}getConfiguration(){throw new Error("Method not implemented.")}async getIdentityAssertion(){throw new Error("Method not implemented.")}async getStats(e){throw new Error("Method not implemented.")}getTransceivers(){throw new Error("Method not implemented.")}removeTrack(e){throw new Error("Method not implemented.")}setConfiguration(e){throw new Error("Method not implemented.")}async setLocalDescription(e){throw new Error("Method not implemented.")}async setRemoteDescription(e){throw new Error("Method not implemented.")}addEventListener(e,t,r){this.events.on(e,t)}removeEventListener(e,t,r){this.events.off(e,t)}dispatchEvent(e){throw new Error("Method not implemented.")}getReceivers=()=>this.receivers;getSenders=()=>this.senders;addTrack=e=>{const t=new st({track:e});return this.senders.push(t),this.events.trigger("track",{track:e}),t}}function ct(n){const e=n.match(/(purgatory)|[\d.]+/g);if(!e)throw new Error("wrong sip url");return e[0]}const A=400,y="777",dt=n=>n.getVideoTracks().length>0;class i extends ot{static presentationError;static startPresentationError;static countStartPresentationError=Number.POSITIVE_INFINITY;static countStartsPresentation=0;url;status_code;answer=jest.fn(({mediaStream:e})=>{if(this.originator!=="remote")throw new Error("answer available only for remote sessions");this.initPeerconnection(e),setTimeout(()=>{this.trigger("connecting"),setTimeout(()=>{this.trigger("accepted")},100),setTimeout(()=>{this.trigger("confirmed")},200)},A)});replaceMediaStream=jest.fn(async e=>{});isEndedInner=!1;constructor({eventHandlers:e,originator:t,remoteIdentity:r=new a.NameAddrHeader(new a.URI("sip","caller1","test1.com",5060),"Test Caller 1")}){super({originator:t,eventHandlers:e,remoteIdentity:r})}static setPresentationError(e){this.presentationError=e}static resetPresentationError(){this.presentationError=void 0}static setStartPresentationError(e,{count:t=Number.POSITIVE_INFINITY}={}){this.startPresentationError=e,this.countStartPresentationError=t}static resetStartPresentationError(){this.startPresentationError=void 0,this.countStartPresentationError=Number.POSITIVE_INFINITY,this.countStartsPresentation=0}startPresentation=async e=>{if(i.countStartsPresentation+=1,i.presentationError)throw this.trigger("presentation:start",e),this.trigger("presentation:failed",e),i.presentationError;if(i.startPresentationError&&i.countStartsPresentation<i.countStartPresentationError)throw this.trigger("presentation:start",e),this.trigger("presentation:failed",e),i.startPresentationError;return super.startPresentation(e)};stopPresentation=async e=>{if(i.presentationError)throw this.trigger("presentation:end",e),this.trigger("presentation:failed",e),i.presentationError;return super.stopPresentation(e)};initPeerconnection(e){return e?(this.createPeerconnection(e),!0):!1}createPeerconnection(e){const t=f.createAudioMediaStreamTrackMock();t.id="mainaudio1";const r=[t];if(dt(e)){const c=f.createVideoMediaStreamTrackMock();c.id="mainvideo1",r.push(c)}this.connection=new at(void 0,r),this.addStream(e),this.trigger("peerconnection",{peerconnection:this.connection})}connect(e,{mediaStream:t}={}){const r=ct(e);return this.initPeerconnection(t),setTimeout(()=>{e.includes(y)?this.trigger("failed",{originator:"remote",message:"IncomingResponse",cause:"Rejected"}):(this.trigger("connecting"),setTimeout(()=>{this.newInfo({originator:P.Originator.REMOTE,request:{getHeader:s=>s==="content-type"?"application/vinteo.webrtc.roomname":s==="x-webrtc-enter-room"?r:s==="x-webrtc-participant-name"?"Test Caller 1":""}})},100),setTimeout(()=>{this.trigger("accepted")},200),setTimeout(()=>{this.trigger("confirmed")},300))},A),this.connection}terminate({status_code:e,cause:t}={}){return this.status_code=e,this.trigger("ended",{status_code:e,cause:t,originator:"local"}),this.isEndedInner=!1,this}async terminateAsync({status_code:e,cause:t}={}){this.terminate({status_code:e,cause:t})}terminateRemote({status_code:e}={}){return this.status_code=e,this.trigger("ended",{status_code:e,originator:"remote"}),this}addStream(e,t="getTracks"){e[t]().forEach(r=>this.connection.addTrack(r))}forEachSenders(e){const t=this.connection.getSenders();for(const r of t)e(r);return t}toggleMuteAudio(e){this.forEachSenders(({track:t})=>{t&&t.kind==="audio"&&(t.enabled=!e)})}toggleMuteVideo(e){this.forEachSenders(({track:t})=>{t&&t.kind==="video"&&(t.enabled=!e)})}mute(e){e.audio&&(this.mutedOptions.audio=!0,this.toggleMuteAudio(this.mutedOptions.audio)),e.video&&(this.mutedOptions.video=!0,this.toggleMuteVideo(this.mutedOptions.video)),this.onmute(e)}unmute(e){e.audio&&(this.mutedOptions.audio=!1),e.video&&(this.mutedOptions.video=!1),this.trigger("unmuted",e)}isMuted(){return this.mutedOptions}onmute({audio:e,video:t}){this.trigger("muted",{audio:e,video:t})}async sendInfo(){}isEnded(){return this.isEndedInner}newInfo(e){this.trigger("newInfo",e)}}class Et{extraHeaders=[];setExtraHeaders(e){this.extraHeaders=e}setExtraContactParams(){}}const d="PASSWORD_CORRECT",T="PASSWORD_CORRECT_2",L="NAME_INCORRECT",h=400,g={url:"wss://sipServerUrl/webrtc/wss/",sip_uri:"sip:sipServerUrl;transport=ws",via_transport:"WSS"},M={status_code:200,reason_phrase:"OK"},O={status_code:401,reason_phrase:"Unauthorized"};class o{static isAvailableTelephony=!0;static startError;static countStartError=Number.POSITIVE_INFINITY;static countStarts=0;events;registratorInner;call=jest.fn((e,t)=>{const{mediaStream:r,eventHandlers:s}=t;return this.session=new i({eventHandlers:s,originator:"local"}),this.session.connect(e,{mediaStream:r}),this.session});sendOptions=jest.fn((e,t,r)=>{console.log("sendOptions",e,t,r)});start=jest.fn(()=>{if(o.countStarts+=1,o.startError&&o.countStarts<o.countStartError){this.trigger("disconnected",o.startError);return}this.register()});stop=jest.fn(()=>{this.startedTimeout&&clearTimeout(this.startedTimeout),this.stopedTimeout&&clearTimeout(this.stopedTimeout),this.unregister(),this.isStarted()?this.stopedTimeout=setTimeout(()=>{this.trigger("disconnected",{error:!0,socket:g})},h):this.trigger("disconnected",{error:!0,socket:g})});removeAllListeners=jest.fn(()=>(this.events.removeEventHandlers(),this));once=jest.fn((e,t)=>(this.events.once(e,t),this));startedTimeout;stopedTimeout;session;isRegisteredInner;isConnectedInner;configuration;constructor(e){this.events=new S.Events(D);const[t,r]=e.uri.split(":"),[s,c]=r.split("@"),p={...e,uri:new a.URI(t,s,c)};this.configuration=p,this.registratorInner=new Et}static setStartError(e,{count:t=Number.POSITIVE_INFINITY}={}){o.startError=e,o.countStartError=t}static resetStartError(){o.startError=void 0,o.countStartError=Number.POSITIVE_INFINITY,o.countStarts=0}static setAvailableTelephony(){o.isAvailableTelephony=!0}static setNotAvailableTelephony(){o.isAvailableTelephony=!1}static reset(){o.resetStartError(),o.setAvailableTelephony()}on(e,t){return this.events.on(e,t),this}off(e,t){return this.events.off(e,t),this}trigger(e,t){this.events.trigger(e,t)}terminateSessions(){this.session?.terminate()}set(e,t){return this.configuration[e]=t,!0}register(){this.startedTimeout&&clearTimeout(this.startedTimeout);const{password:e,register:t,uri:r}=this.configuration;t===!0&&r.user.includes(L)?(this.isRegisteredInner=!1,this.isConnectedInner=!1,this.startedTimeout=setTimeout(()=>{this.trigger("registrationFailed",{response:O,cause:a.C.causes.REJECTED})},h)):!this.isRegistered()&&t===!0&&(e===d||e===T)?(this.isRegisteredInner=!0,this.startedTimeout=setTimeout(()=>{this.trigger("registered",{response:M})},h)):t===!0&&e!==d&&e!==T&&(this.isRegisteredInner=!1,this.isConnectedInner=!1,this.startedTimeout=setTimeout(()=>{this.trigger("registrationFailed",{response:O,cause:a.C.causes.REJECTED})},h)),o.isAvailableTelephony?(this.trigger("connected",{socket:g}),this.isConnectedInner=!0):this.stop()}unregister(){this.isRegisteredInner=!1,this.isConnectedInner=!1,this.trigger("unregistered",{response:M})}isRegistered(){return this.isRegisteredInner===!0}isConnected(){return this.isConnectedInner===!0}isStarted(){return this.configuration.register===!0&&this.isRegisteredInner===!0||this.configuration.register!==!0&&this.isConnectedInner===!0}newSipEvent(e){this.trigger("sipEvent",e)}registrator(){return this.registratorInner}}class ht{url;constructor(e){this.url=e}}class ut extends b.EventEmitter{contentType;body;constructor(e,t){super(),this.contentType=e,this.body=t}}const I="remote",mt=(n,e)=>{const t=new N(e),r={originator:I,request:t,info:new ut("","")};n.newInfo(r)},lt=(n,e)=>{const r={event:"sipEvent",request:new N(e)};n.newSipEvent(r)},pt=(n,{incomingNumber:e="1234",displayName:t,host:r})=>{const s=new i({originator:I,eventHandlers:{}}),c=new k("sip",e,r);s.remote_identity=new V(c,t);const p=new N([]);n.trigger("newRTCSession",{originator:I,session:s,request:p})},gt=(n,e)=>{e?n.trigger("failed",e):n.trigger("failed",n)},w={triggerNewInfo:mt,triggerNewSipEvent:lt,triggerIncomingSession:pt,triggerFailIncomingSession:gt,WebSocketInterface:ht,UA:o,C:{INVITE:"INVITE"}},u="user",E="displayName",m="SIP_SERVER_URL",C="SIP_WEB_SOCKET_SERVER_URL",_t=new w.WebSocketInterface(C),R={userAgent:"Chrome",sipServerUrl:m,sipWebSocketServerURL:C},Tt={...R},F={...R,user:u,password:d,register:!0},It={...F,displayName:E},St={...R,displayName:E,register:!1},l={session_timers:!1,sockets:[_t],user_agent:"Chrome",sdpSemantics:"unified-plan",register_expires:300,connection_recovery_max_interval:6,connection_recovery_min_interval:2},Nt={...l,password:d,uri:new a.URI("sip",u,m),display_name:"",register:!0},wt={...l,password:d,uri:new a.URI("sip",u,m),display_name:E,register:!0},Ct={...l,display_name:E,register:!1},Rt={...l,display_name:"",register:!1},W="10.10.10.10",ft=[`X-Vinteo-Remote: ${W}`],At=()=>new P.SipConnector({JsSIP:w});exports.FAILED_CONFERENCE_NUMBER=y;exports.JsSIP=w;exports.NAME_INCORRECT=L;exports.PASSWORD_CORRECT=d;exports.PASSWORD_CORRECT_2=T;exports.SIP_SERVER_URL=m;exports.SIP_WEB_SOCKET_SERVER_URL=C;exports.dataForConnectionWithAuthorization=F;exports.dataForConnectionWithAuthorizationWithDisplayName=It;exports.dataForConnectionWithoutAuthorization=St;exports.dataForConnectionWithoutAuthorizationWithoutDisplayName=Tt;exports.displayName=E;exports.doMockSipConnector=At;exports.extraHeadersRemoteAddress=ft;exports.remoteAddress=W;exports.uaConfigurationWithAuthorization=Nt;exports.uaConfigurationWithAuthorizationWithDisplayName=wt;exports.uaConfigurationWithoutAuthorization=Ct;exports.uaConfigurationWithoutAuthorizationWithoutDisplayName=Rt;exports.user=u;
package/dist/doMock.js CHANGED
@@ -5,7 +5,7 @@ import { IncomingRequest as F } from "@krivega/jssip/lib/SIPMessage";
5
5
  import { NameAddrHeader as b, URI as E, C as N } from "@krivega/jssip";
6
6
  import { createAudioMediaStreamTrackMock as V, createVideoMediaStreamTrackMock as k } from "webrtc-mock";
7
7
  import { Events as _ } from "events-constructor";
8
- import { O as W, S as U } from "./@SipConnector-G96OmJEP.js";
8
+ import { O as W, S as U } from "./@SipConnector-BEZk1hmx.js";
9
9
  class T extends F {
10
10
  headers;
11
11
  constructor(e) {
@@ -306,7 +306,7 @@ class st {
306
306
  getParameters() {
307
307
  return this.parametersGets = { ...this.parameters }, this.parametersGets;
308
308
  }
309
- // eslint-disable-next-line class-methods-use-this
309
+ // eslint-disable-next-line @typescript-eslint/class-methods-use-this
310
310
  setStreams() {
311
311
  throw new Error("Method not implemented.");
312
312
  }
@@ -564,7 +564,7 @@ class i extends ot {
564
564
  video: t
565
565
  });
566
566
  }
567
- // eslint-disable-next-line @typescript-eslint/no-empty-function, class-methods-use-this
567
+ // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/class-methods-use-this
568
568
  async sendInfo() {
569
569
  }
570
570
  isEnded() {
@@ -580,7 +580,7 @@ class ht {
580
580
  setExtraHeaders(e) {
581
581
  this.extraHeaders = e;
582
582
  }
583
- // eslint-disable-next-line class-methods-use-this
583
+ // eslint-disable-next-line @typescript-eslint/class-methods-use-this
584
584
  setExtraContactParams() {
585
585
  }
586
586
  }
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require("events-constructor");const o=require("./@SipConnector-BBhQzo-W.cjs"),j=require("@krivega/cancelable-promise"),ce=require("repeated-calls"),ae=require("ts-debounce"),de=require("stack-promises"),B=require("debug"),ue=require("sequent-promises"),le=n=>n instanceof Object&&("originator"in n||"cause"in n),ge=n=>{if(j.isCanceledError(n))return!0;if(!le(n))return!1;const{originator:e,cause:t}=n;return typeof t=="string"?t===o.ECallCause.REQUEST_TIMEOUT||t===o.ECallCause.REJECTED||e===o.Originator.LOCAL&&(t===o.ECallCause.CANCELED||t===o.ECallCause.BYE):!1},he=(n,e)=>(n.degradationPreference=e.degradationPreference,n),Ce=(n,e)=>{n.encodings??=[];for(let t=n.encodings.length;t<e;t+=1)n.encodings.push({});return n},G=n=>(e,t)=>t!==void 0&&e!==t||t===void 0&&e!==n,Se=G(),fe=(n,e)=>{if(Se(n,e))return n},me=(n,e)=>{const t=n.maxBitrate,r=fe(e,t);return r!==void 0&&(n.maxBitrate=r),n},K=1,pe=G(K),Re=(n,e)=>{const t=n===void 0?void 0:Math.max(n,K);if(t!==void 0&&pe(t,e))return t},ye=(n,e)=>{const t=n.scaleResolutionDownBy,r=Re(e,t);return r!==void 0&&(n.scaleResolutionDownBy=r),n},Ee=(n,e)=>{const t=e.encodings?.length??0;return Ce(n,t),n.encodings.forEach((r,s)=>{const i=(e?.encodings??[])[s],c=i?.maxBitrate,a=i?.scaleResolutionDownBy;me(r,c),ye(r,a)}),n},ve=(n,e)=>{if(n.codecs?.length!==e.codecs?.length)return!0;for(let t=0;t<(n.codecs?.length??0);t++)if(JSON.stringify(n.codecs[t])!==JSON.stringify(e.codecs[t]))return!0;if(n.headerExtensions?.length!==e.headerExtensions?.length)return!0;for(let t=0;t<(n.headerExtensions?.length??0);t++)if(JSON.stringify(n.headerExtensions[t])!==JSON.stringify(e.headerExtensions[t]))return!0;if(n.encodings?.length!==e.encodings?.length)return!0;for(let t=0;t<(n.encodings?.length??0);t++)if(JSON.stringify(n.encodings[t])!==JSON.stringify(e.encodings[t]))return!0;return n.rtcp?.cname!==e.rtcp?.cname||n.rtcp?.reducedSize!==e.rtcp?.reducedSize||n.degradationPreference!==e.degradationPreference},$=async(n,e)=>{const t=n.getParameters(),r=JSON.parse(JSON.stringify(t));Ee(t,e),he(t,e);const s=ve(r,t);return s&&await n.setParameters(t),{parameters:t,isChanged:s}},Te=async(n,e,t)=>{const{isChanged:r,parameters:s}=await $(n,{encodings:[{scaleResolutionDownBy:e.scaleResolutionDownBy,maxBitrate:e.maxBitrate}]});return r&&t&&t(s),{isChanged:r,parameters:s}},Me=n=>n.getVideoTracks()[0],be=1e6,S=n=>n*be,Y=S(.06),z=S(4),Be=n=>n<=64?Y:n<=128?S(.12):n<=256?S(.25):n<=384?S(.32):n<=426?S(.38):n<=640?S(.5):n<=848?S(.7):n<=1280?S(1):n<=1920?S(2):z,Z=(n,e)=>n!==void 0&&e!==void 0&&n.toLowerCase().includes(e.toLowerCase()),_e="av1",Ae=n=>Z(n,_e),Pe=.6,W=(n,e)=>Ae(e)?n*Pe:n,Ne=n=>W(Y,n),Oe=n=>W(z,n),q=(n,e)=>{const t=Be(n);return W(t,e)},L=1,ee=({videoTrack:n,targetSize:e})=>{const t=n.getSettings(),r=t.width,s=t.height,i=r===void 0?L:r/e.width,c=s===void 0?L:s/e.height;return Math.max(i,c,L)},we=n=>[...n.keys()].map(e=>n.get(e)),De=(n,e)=>we(n).find(t=>t?.type===e),ne=async n=>n.getStats().then(e=>De(e,"codec")?.mimeType);class ke{async getCodecFromSender(e){return await ne(e)??""}}class Fe{stackPromises=de.createStackPromises({noRunIsNotActual:!0});async add(e){return this.stackPromises.add(e),this.run()}stop(){this.stackPromises.stop()}async run(){return this.stackPromises().catch(e=>{o.logger("TaskQueue: error",e)})}}class Ie{taskQueue;onSetParameters;constructor(e){this.onSetParameters=e,this.taskQueue=new Fe}async setEncodingsToSender(e,t){return this.taskQueue.add(async()=>Te(e,t,this.onSetParameters))}stop(){this.taskQueue.stop()}}class xe{ignoreForCodec;senderFinder;codecProvider;parametersSetter;resultNoChanged={isChanged:!1,parameters:{encodings:[{}],transactionId:"0",codecs:[],headerExtensions:[],rtcp:{}}};constructor({senderFinder:e,codecProvider:t,parametersSetter:r},s){this.senderFinder=e,this.codecProvider=t,this.parametersSetter=r,this.ignoreForCodec=s.ignoreForCodec}async balance(e,t){const r=e.getSenders(),s=this.senderFinder.findVideoSender(r);if(!s?.track)return this.resultNoChanged;const i=await this.codecProvider.getCodecFromSender(s);if(Z(i,this.ignoreForCodec))return this.resultNoChanged;const{mainCam:c,resolutionMainCam:a}=t??{};return this.processSender({mainCam:c,resolutionMainCam:a},{sender:s,codec:i,videoTrack:s.track})}async processSender(e,t){const{mainCam:r,resolutionMainCam:s}=e;switch(r){case o.EEventsMainCAM.PAUSE_MAIN_CAM:return this.downgradeResolutionSender(t);case o.EEventsMainCAM.RESUME_MAIN_CAM:return this.setBitrateByTrackResolution(t);case o.EEventsMainCAM.MAX_MAIN_CAM_RESOLUTION:return s!==void 0?this.setResolutionSender(s,t):this.setBitrateByTrackResolution(t);case o.EEventsMainCAM.ADMIN_STOP_MAIN_CAM:case o.EEventsMainCAM.ADMIN_START_MAIN_CAM:case void 0:return this.setBitrateByTrackResolution(t);default:return this.setBitrateByTrackResolution(t)}}async downgradeResolutionSender(e){const{sender:t,codec:r}=e,s={scaleResolutionDownBy:200,maxBitrate:Ne(r)};return this.parametersSetter.setEncodingsToSender(t,s)}async setBitrateByTrackResolution(e){const{sender:t,videoTrack:r,codec:s}=e,c=r.getSettings().width,a=c===void 0?Oe(s):q(c,s);return this.parametersSetter.setEncodingsToSender(t,{scaleResolutionDownBy:1,maxBitrate:a})}async setResolutionSender(e,t){const[r,s]=e.split("x"),{sender:i,videoTrack:c,codec:a}=t,d={width:Number(r),height:Number(s)},l=ee({videoTrack:c,targetSize:d}),h=q(d.width,a),g={scaleResolutionDownBy:l,maxBitrate:h};return this.parametersSetter.setEncodingsToSender(i,g)}}const Ue=n=>n.find(e=>e.track?.kind==="video");class Ve{findVideoSender(e){return Ue(e)}}class Le{sipConnector;currentHandler;constructor(e){this.sipConnector=e}subscribe(e){this.currentHandler=e,this.sipConnector.on("api:main-cam-control",e)}unsubscribe(){this.currentHandler&&(this.sipConnector.off("api:main-cam-control",this.currentHandler),this.currentHandler=void 0)}getConnection(){return this.sipConnector.connection}}class te{eventHandler;senderBalancer;parametersSetterWithQueue;serverHeaders;constructor(e,{ignoreForCodec:t,onSetParameters:r}={}){this.eventHandler=new Le(e),this.parametersSetterWithQueue=new Ie(r),this.senderBalancer=new xe({senderFinder:new Ve,codecProvider:new ke,parametersSetter:this.parametersSetterWithQueue},{ignoreForCodec:t})}subscribe(){this.eventHandler.subscribe(this.handleMainCamControl)}unsubscribe(){this.eventHandler.unsubscribe(),this.parametersSetterWithQueue.stop(),this.reset()}reset(){delete this.serverHeaders}async reBalance(){return this.balanceByTrack()}async balanceByTrack(){const e=this.eventHandler.getConnection();if(!e)throw new Error("connection is not exist");return this.senderBalancer.balance(e,this.serverHeaders)}handleMainCamControl=e=>{this.serverHeaders=e,this.balanceByTrack().catch(B)}}const He=(n,e={})=>new te(n,e),qe=({videoTrack:n,targetSize:e,codec:t})=>{const r=ee({videoTrack:n,targetSize:e}),s=q(e.width,t);return{scaleResolutionDownBy:r,maxBitrate:s}},O=({mediaStream:n,simulcastEncodings:e,sendEncodings:t})=>{if(e&&e.length>0){const r=t??[],s=Me(n);if(s===void 0)throw new Error("No video track");return e.forEach((i,c)=>{const a=r[c]??{};a.active=!0,i.rid!==void 0&&(a.rid=i.rid),i.scalabilityMode!==void 0&&(a.scalabilityMode=i.scalabilityMode);const{maxBitrate:d,scaleResolutionDownBy:l}=qe({videoTrack:s,targetSize:{width:i.width,height:i.height}});a.maxBitrate=d,a.scaleResolutionDownBy=l,r[c]=a}),r}return t},re="purgatory",F=n=>n===re,$e=(n,e)=>n.filter(r=>e.some(s=>s.clockRate===r.clockRate&&s.mimeType===r.mimeType&&s.channels===r.channels&&s.sdpFmtpLine===r.sdpFmtpLine)),We=n=>{const e=RTCRtpSender.getCapabilities(n),t=RTCRtpReceiver.getCapabilities(n),r=e===null?[]:e.codecs,s=t===null?[]:t.codecs;return $e(r,s)},Qe=(n,e)=>e===void 0||e.length===0?n:n.sort((t,r)=>{const s=e.indexOf(t.mimeType),i=e.indexOf(r.mimeType),c=s===-1?Number.MAX_VALUE:s,a=i===-1?Number.MAX_VALUE:i;return c-a}),Je=(n,e)=>e===void 0||e.length===0?n:n.filter(t=>!e.includes(t.mimeType)),Xe=(n,{preferredMimeTypesVideoCodecs:e,excludeMimeTypesVideoCodecs:t})=>{if(typeof n.setCodecPreferences=="function"&&n.sender.track?.kind==="video"&&(e!==void 0&&e.length>0||t!==void 0&&t.length>0)){const r=We("video"),s=Je(r,t),i=Qe(s,e);n.setCodecPreferences(i)}},w=(n,{preferredMimeTypesVideoCodecs:e,excludeMimeTypesVideoCodecs:t})=>async r=>{try{Xe(r,{preferredMimeTypesVideoCodecs:e,excludeMimeTypesVideoCodecs:t}),Object.values(n).filter(i=>i!=null).length>0&&(o.logger("updateTransceiver setParametersToSender",n),await $(r.sender,n))}catch(s){o.logger("updateTransceiver error",s)}},H=n=>{if(!j.isCanceledError(n)&&!ce.hasCanceledError(n))throw n;return{isSuccessful:!1}},je=({kind:n,readyState:e})=>n==="video"&&e==="live",Q=(n,e,{onEnterPurgatory:t,onEnterConference:r})=>{F(n)?t&&t():r&&r({isSuccessProgressCall:e})},J=(n,e)=>{n(),e&&e()},X=(n,e,t)=>{throw n&&n(),e(),t},Ge=new Set(["on","once","onceRace","wait","off","sendDTMF","hangUp","declineToIncomingCall","sendChannels","checkTelephony","waitChannels","ping","connection","isConfigured","isRegistered"]);class Ke{on;once;onceRace;wait;off;sendDTMF;hangUp;declineToIncomingCall;sendChannels;checkTelephony;waitChannels;ping;connection;isConfigured;isRegistered;sipConnector;preferredMimeTypesVideoCodecs;excludeMimeTypesVideoCodecs;constructor(e,{preferredMimeTypesVideoCodecs:t,excludeMimeTypesVideoCodecs:r}={}){return this.preferredMimeTypesVideoCodecs=t,this.excludeMimeTypesVideoCodecs=r,this.sipConnector=e,new Proxy(this,{get:(s,i,c)=>{if(typeof i=="string"&&Ge.has(i)&&i in this.sipConnector){const d=Reflect.get(this.sipConnector,i,this.sipConnector);return typeof d=="function"?d.bind(this.sipConnector):d}const a=Reflect.get(s,i,c);return typeof a=="function"?a.bind(s):a}})}connectToServer=async e=>{const{userAgent:t,sipWebSocketServerURL:r,sipServerUrl:s,remoteAddress:i,displayName:c,name:a,password:d,isRegisteredUser:l,isDisconnectOnFail:h}=e;return o.logger("connectToServer",e),this.sipConnector.connect({userAgent:t,sipWebSocketServerURL:r,sipServerUrl:s,remoteAddress:i,displayName:c,password:d,user:a,register:l}).then(g=>(o.logger("connectToServer then"),{ua:g,isSuccessful:!0})).catch(async g=>(o.logger("connectToServer catch: error",g),h===!0?this.sipConnector.disconnect().then(()=>H(g)).catch(()=>H(g)):H(g)))};callToServer=async e=>{const{conference:t,mediaStream:r,extraHeaders:s,iceServers:i,contentHint:c,simulcastEncodings:a,degradationPreference:d,sendEncodings:l,offerToReceiveAudio:h,offerToReceiveVideo:g,directionVideo:D,directionAudio:k,setRemoteStreams:C,onBeforeProgressCall:f,onSuccessProgressCall:m,onEnterPurgatory:p,onEnterConference:R,onFailProgressCall:v,onFinishProgressCall:T,onEndedCall:M}=e,b=this.resolveHandleReadyRemoteStreamsDebounced({onReadyRemoteStreams:C}),_=this.resolveHandleReadyRemoteStreams({onReadyRemoteStreams:()=>{b().catch(B)}}),A=w({degradationPreference:d},{preferredMimeTypesVideoCodecs:this.preferredMimeTypesVideoCodecs,excludeMimeTypesVideoCodecs:this.excludeMimeTypesVideoCodecs});o.logger("callToServer",e);const P=async()=>(o.logger("startCall"),this.sipConnector.call({mediaStream:r,extraHeaders:s,iceServers:i,contentHint:c,offerToReceiveAudio:h,offerToReceiveVideo:g,directionVideo:D,directionAudio:k,sendEncodings:O({mediaStream:r,simulcastEncodings:a,sendEncodings:l}),number:t,onAddedTransceiver:A,ontrack:_}));let y=!1,E;const N=(o.logger("subscribeEnterConference: onEnterConference",R),this.sipConnector.on("api:enterRoom",({room:u})=>{o.logger("enterRoom",{_room:u,isSuccessProgressCall:y}),E=u,(p??R)&&Q(E,y,{onEnterPurgatory:p,onEnterConference:R})})),x=u=>(o.logger("onSuccess"),y=!0,b().catch(B),m&&m({isPurgatory:F(E)}),this.sipConnector.onceRace(["call:ended","call:failed"],()=>{J(N,M)}),u),U=u=>(o.logger("onFail"),X(v,N,u)),V=()=>{o.logger("onFinish"),T&&T()};return o.logger("onBeforeProgressCall"),f&&f(t),P().then(x).catch(u=>U(u)).finally(V)};disconnectFromServer=async()=>this.sipConnector.disconnect().then(()=>(o.logger("disconnectFromServer: then"),{isSuccessful:!0})).catch(e=>(o.logger("disconnectFromServer: catch",e),{isSuccessful:!1}));answerToIncomingCall=async e=>{const{mediaStream:t,extraHeaders:r,iceServers:s,contentHint:i,simulcastEncodings:c,degradationPreference:a,sendEncodings:d,offerToReceiveAudio:l,offerToReceiveVideo:h,directionVideo:g,directionAudio:D,setRemoteStreams:k,onBeforeProgressCall:C,onSuccessProgressCall:f,onEnterPurgatory:m,onEnterConference:p,onFailProgressCall:R,onFinishProgressCall:v,onEndedCall:T}=e,M=this.resolveHandleReadyRemoteStreamsDebounced({onReadyRemoteStreams:k}),b=this.resolveHandleReadyRemoteStreams({onReadyRemoteStreams:()=>{M().catch(B)}}),_=w({degradationPreference:a},{preferredMimeTypesVideoCodecs:this.preferredMimeTypesVideoCodecs,excludeMimeTypesVideoCodecs:this.excludeMimeTypesVideoCodecs});o.logger("answerToIncomingCall",e);const A=async()=>this.sipConnector.answerToIncomingCall({mediaStream:t,extraHeaders:r,iceServers:s,contentHint:i,offerToReceiveAudio:l,offerToReceiveVideo:h,directionVideo:g,directionAudio:D,sendEncodings:O({mediaStream:t,simulcastEncodings:c,sendEncodings:d}),onAddedTransceiver:_,ontrack:b}),P=()=>{const{remoteCallerData:u}=this.sipConnector;return u.incomingNumber};let y=!1,E;const N=(o.logger("subscribeEnterConference: onEnterConference",p),this.sipConnector.on("api:enterRoom",u=>{o.logger("enterRoom",{_room:u,isSuccessProgressCall:y}),E=u,(m??p)&&Q(E,y,{onEnterPurgatory:m,onEnterConference:p})})),x=u=>(o.logger("onSuccess"),y=!0,M().catch(B),f&&f({isPurgatory:F(E)}),this.sipConnector.onceRace(["call:ended","call:failed"],()=>{J(N,T)}),u),U=u=>(o.logger("onFail"),X(R,N,u)),V=()=>{o.logger("onFinish"),v&&v()};if(o.logger("onBeforeProgressCall"),C){const u=P();C(u)}return A().then(x).catch(u=>U(u)).finally(V)};updatePresentation=async({mediaStream:e,isP2P:t,maxBitrate:r,contentHint:s,simulcastEncodings:i,degradationPreference:c,sendEncodings:a,preferredMimeTypesVideoCodecs:d,excludeMimeTypesVideoCodecs:l})=>{const h=w({degradationPreference:c},{preferredMimeTypesVideoCodecs:d,excludeMimeTypesVideoCodecs:l});return o.logger("updatePresentation"),this.sipConnector.updatePresentation(e,{isP2P:t,maxBitrate:r,contentHint:s,sendEncodings:O({mediaStream:e,simulcastEncodings:i,sendEncodings:a}),onAddedTransceiver:h})};startPresentation=async({mediaStream:e,isP2P:t,maxBitrate:r,contentHint:s,simulcastEncodings:i,degradationPreference:c,sendEncodings:a,preferredMimeTypesVideoCodecs:d,excludeMimeTypesVideoCodecs:l,callLimit:h})=>{const g=w({degradationPreference:c},{preferredMimeTypesVideoCodecs:d,excludeMimeTypesVideoCodecs:l});return o.logger("startPresentation"),this.sipConnector.startPresentation(e,{isP2P:t,maxBitrate:r,contentHint:s,callLimit:h,sendEncodings:O({mediaStream:e,simulcastEncodings:i,sendEncodings:a}),onAddedTransceiver:g})};stopShareSipConnector=async({isP2P:e=!1}={})=>(o.logger("stopShareSipConnector"),this.sipConnector.stopPresentation({isP2P:e}).catch(t=>{o.logger(t)}));sendRefusalToTurnOnMic=async()=>{o.logger("sendRefusalToTurnOnMic"),await this.sipConnector.sendRefusalToTurnOnMic().catch(e=>{o.logger("sendRefusalToTurnOnMic: error",e)})};sendRefusalToTurnOnCam=async()=>{o.logger("sendRefusalToTurnOnCam"),await this.sipConnector.sendRefusalToTurnOnCam().catch(e=>{o.logger("sendRefusalToTurnOnCam: error",e)})};sendMediaState=async({isEnabledCam:e,isEnabledMic:t})=>{o.logger("sendMediaState"),await this.sipConnector.sendMediaState({cam:e,mic:t})};replaceMediaStream=async(e,{deleteExisting:t,addMissing:r,forceRenegotiation:s,contentHint:i,simulcastEncodings:c,degradationPreference:a,sendEncodings:d})=>{const l=w({degradationPreference:a},{preferredMimeTypesVideoCodecs:this.preferredMimeTypesVideoCodecs,excludeMimeTypesVideoCodecs:this.excludeMimeTypesVideoCodecs});return o.logger("replaceMediaStream"),this.sipConnector.replaceMediaStream(e,{deleteExisting:t,addMissing:r,forceRenegotiation:s,contentHint:i,sendEncodings:O({mediaStream:e,simulcastEncodings:c,sendEncodings:d}),onAddedTransceiver:l})};askPermissionToEnableCam=async()=>{o.logger("askPermissionToEnableCam"),await this.sipConnector.askPermissionToEnableCam()};resolveHandleReadyRemoteStreamsDebounced=({onReadyRemoteStreams:e})=>ae.debounce(()=>{const t=this.sipConnector.getRemoteStreams();o.logger("remoteStreams",t),t&&e(t)},200);resolveHandleReadyRemoteStreams=({onReadyRemoteStreams:e})=>({track:t})=>{je(t)&&e()};getRemoteStreams=()=>(o.logger("getRemoteStreams"),this.sipConnector.getRemoteStreams());onUseLicense=e=>(o.logger("onUseLicense"),this.sipConnector.on("api:useLicense",e));onMustStopPresentation=e=>(o.logger("onMustStopPresentation"),this.sipConnector.on("api:mustStopPresentation",e));onMoveToSpectators=e=>(o.logger("onMoveToSpectators"),this.sipConnector.on("api:participant:move-request-to-spectators",e));onMoveToParticipants=e=>(o.logger("onMoveToParticipants"),this.sipConnector.on("api:participant:move-request-to-participants",e))}const I=n=>{const{url:e,cause:t}=n;let r=e;return(t===o.ECallCause.BAD_MEDIA_DESCRIPTION||t===o.ECallCause.NOT_FOUND)&&(r=`${n.message.to.uri.user}@${n.message.to.uri.host}`),r};var se=(n=>(n.CONNECT_SERVER_FAILED="CONNECT_SERVER_FAILED",n.WRONG_USER_OR_PASSWORD="WRONG_USER_OR_PASSWORD",n.BAD_MEDIA_ERROR="BAD_MEDIA_ERROR",n.NOT_FOUND_ERROR="NOT_FOUND_ERROR",n.WS_CONNECTION_FAILED="WS_CONNECTION_FAILED",n.CONNECT_SERVER_FAILED_BY_LINK="CONNECT_SERVER_FAILED_BY_LINK",n))(se||{});const Ye=new Error("Unknown error"),ze=(n=Ye)=>{const{cause:e,socket:t}=n;let r="CONNECT_SERVER_FAILED";switch(e){case"Forbidden":{r="WRONG_USER_OR_PASSWORD";break}case o.ECallCause.BAD_MEDIA_DESCRIPTION:{r="BAD_MEDIA_ERROR";break}case o.ECallCause.NOT_FOUND:{r="NOT_FOUND_ERROR";break}default:t!==void 0&&t._ws?.readyState===3?r="WS_CONNECTION_FAILED":I(n)!==void 0&&I(n)!==""&&(r="CONNECT_SERVER_FAILED_BY_LINK")}return r},Ze=n=>{let e="";try{e=JSON.stringify(n)}catch(t){o.logger("failed to stringify message",t)}return e},en=new Error("Unknown error"),nn=(n=en)=>{const{code:e,cause:t,message:r}=n,s=I(n),i={code:"",cause:"",message:""};return typeof r=="object"&&r!==null?i.message=Ze(r):r&&(i.message=String(r)),s!==void 0&&s!==""&&(i.link=s),e!==void 0&&e!==""&&(i.code=e),t!==void 0&&t!==""&&(i.cause=t),i},tn=Object.freeze(Object.defineProperty({__proto__:null,EErrorTypes:se,getLinkError:I,getTypeFromError:ze,getValuesFromError:nn},Symbol.toStringTag,{value:"Module"})),rn=({sessionId:n,remoteAddress:e,isMutedAudio:t,isMutedVideo:r,isRegistered:s,isPresentationCall:i})=>{const c=[],a=t?"0":"1",d=r?"0":"1";return c.push(`X-Vinteo-Mic-State: ${a}`,`X-Vinteo-MainCam-State: ${d}`),(s===!1||s===void 0)&&c.push("X-Vinteo-Purgatory-Call: yes"),n!==void 0&&n!==""&&c.push(`X-Vinteo-Session: ${n}`),i===!0&&c.push("X-Vinteo-Presentation-Call: yes"),e!==void 0&&e!==""&&c.push(`X-Vinteo-Remote: ${e}`),c},sn="[@*!|]",on="_",cn=n=>{let e=n;return e=e.replaceAll(new RegExp(sn,"g"),on),e},an=({appName:n,appVersion:e,browserName:t,browserVersion:r})=>{const i=`${cn(n)} ${e}`;return`ChromeNew - ${t===void 0?i:`${t} ${r}, ${i}`}`},dn=({isUnifiedSdpSemantic:n,appVersion:e,browserName:t,browserVersion:r,appName:s})=>n?an({appVersion:e,browserName:t,browserVersion:r,appName:s}):"Chrome",un=n=>e=>[...e].map(r=>async()=>n(r)),ln=async({accumulatedKeys:n,sendKey:e,canRunTask:t})=>{const s=un(e)(n);return ue.sequentPromises(s,t)},gn=n=>t=>(o.logger("onStartMainCam"),n.on("api:admin-start-main-cam",t)),hn=n=>t=>(o.logger("onStartMic"),n.on("api:admin-start-mic",t)),Cn=n=>t=>(o.logger("onStopMainCam"),n.on("api:admin-stop-main-cam",t)),Sn=n=>t=>(o.logger("onStopMic"),n.on("api:admin-stop-mic",t)),fn=({sipConnector:n})=>{const e=(C,f)=>({isSyncForced:m})=>{if(m===!0){C();return}f()},t=gn(n),r=Cn(n),s=hn(n),i=Sn(n);let c,a,d,l;const h=({onStartMainCamForced:C,onStartMainCamNotForced:f,onStopMainCamForced:m,onStopMainCamNotForced:p,onStartMicForced:R,onStartMicNotForced:v,onStopMicForced:T,onStopMicNotForced:M})=>{const b=e(C,f);c=t(b);const _=e(m,p);a=r(_);const A=e(R,v);d=s(A);const P=e(T,M);l=i(P)},g=()=>{c?.(),a?.(),d?.(),l?.()};return{start:C=>{h(C)},stop:()=>{g()}}},mn=Object.freeze(Object.defineProperty({__proto__:null,PURGATORY_CONFERENCE_NUMBER:re,createSyncMediaState:fn,error:tn,getExtraHeaders:rn,getUserAgent:dn,hasPurgatory:F,sendDtmfAccumulated:ln},Symbol.toStringTag,{value:"Module"}));var oe=(n=>(n.VP8="video/VP8",n.VP9="video/VP9",n.H264="video/H264",n.AV1="video/AV1",n.rtx="video/rtx",n.red="video/red",n.flexfec03="video/flexfec-03",n))(oe||{});exports.ECallCause=o.ECallCause;exports.EUseLicense=o.EUseLicense;exports.SipConnector=o.SipConnector;exports.disableDebug=o.disableDebug;exports.enableDebug=o.enableDebug;exports.hasCanceledStartPresentationError=o.hasCanceledStartPresentationError;exports.debug=B;exports.EMimeTypesVideoCodecs=oe;exports.SipConnectorFacade=Ke;exports.VideoSendingBalancer=te;exports.getCodecFromSender=ne;exports.hasCanceledCallError=ge;exports.resolveVideoSendingBalancer=He;exports.setParametersToSender=$;exports.tools=mn;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require("events-constructor");const o=require("./@SipConnector-hpySQIBa.cjs"),j=require("@krivega/cancelable-promise"),de=require("repeated-calls"),ue=require("ts-debounce"),le=require("ua-parser-js"),ge=require("sequent-promises"),he=require("stack-promises"),B=require("debug"),Ce=n=>n instanceof Object&&("originator"in n||"cause"in n),Se=n=>{if(j.isCanceledError(n))return!0;if(!Ce(n))return!1;const{originator:e,cause:t}=n;return typeof t=="string"?t===o.ECallCause.REQUEST_TIMEOUT||t===o.ECallCause.REJECTED||e===o.Originator.LOCAL&&(t===o.ECallCause.CANCELED||t===o.ECallCause.BYE):!1},fe=()=>globalThis.process?.versions?.electron!==void 0,G=()=>{const n=new le.UAParser,{name:e}=n.getBrowser(),t=fe();return{isChrome:e==="Chrome"||t}},F=n=>{const{url:e,cause:t}=n;let r=e;return(t===o.ECallCause.BAD_MEDIA_DESCRIPTION||t===o.ECallCause.NOT_FOUND)&&(r=`${n.message.to.uri.user}@${n.message.to.uri.host}`),r};var K=(n=>(n.CONNECT_SERVER_FAILED="CONNECT_SERVER_FAILED",n.WRONG_USER_OR_PASSWORD="WRONG_USER_OR_PASSWORD",n.BAD_MEDIA_ERROR="BAD_MEDIA_ERROR",n.NOT_FOUND_ERROR="NOT_FOUND_ERROR",n.WS_CONNECTION_FAILED="WS_CONNECTION_FAILED",n.CONNECT_SERVER_FAILED_BY_LINK="CONNECT_SERVER_FAILED_BY_LINK",n))(K||{});const me=new Error("Unknown error"),pe=(n=me)=>{const{cause:e,socket:t}=n;let r="CONNECT_SERVER_FAILED";switch(e){case"Forbidden":{r="WRONG_USER_OR_PASSWORD";break}case o.ECallCause.BAD_MEDIA_DESCRIPTION:{r="BAD_MEDIA_ERROR";break}case o.ECallCause.NOT_FOUND:{r="NOT_FOUND_ERROR";break}default:t!==void 0&&t._ws?.readyState===3?r="WS_CONNECTION_FAILED":F(n)!==void 0&&F(n)!==""&&(r="CONNECT_SERVER_FAILED_BY_LINK")}return r},Re=n=>{let e="";try{e=JSON.stringify(n)}catch(t){o.logger("failed to stringify message",t)}return e},Ee=new Error("Unknown error"),ye=(n=Ee)=>{const{code:e,cause:t,message:r}=n,s=F(n),i={code:"",cause:"",message:""};return typeof r=="object"&&r!==null?i.message=Re(r):r&&(i.message=String(r)),s!==void 0&&s!==""&&(i.link=s),e!==void 0&&e!==""&&(i.code=e),t!==void 0&&t!==""&&(i.cause=t),i},ve=Object.freeze(Object.defineProperty({__proto__:null,EErrorTypes:K,getLinkError:F,getTypeFromError:pe,getValuesFromError:ye},Symbol.toStringTag,{value:"Module"})),Te=({sessionId:n,remoteAddress:e,isMutedAudio:t,isMutedVideo:r,isRegistered:s,isPresentationCall:i})=>{const c=[],a=t?"0":"1",d=r?"0":"1";return c.push(`X-Vinteo-Mic-State: ${a}`,`X-Vinteo-MainCam-State: ${d}`),(s===!1||s===void 0)&&c.push("X-Vinteo-Purgatory-Call: yes"),n!==void 0&&n!==""&&c.push(`X-Vinteo-Session: ${n}`),i===!0&&c.push("X-Vinteo-Presentation-Call: yes"),e!==void 0&&e!==""&&c.push(`X-Vinteo-Remote: ${e}`),c},Me="[@*!|]",be="_",Be=n=>{let e=n;return e=e.replaceAll(new RegExp(Me,"g"),be),e},Pe=({appName:n,appVersion:e,browserName:t,browserVersion:r})=>{const i=`${Be(n)} ${e}`;return`ChromeNew - ${t===void 0?i:`${t} ${r}, ${i}`}`},Ae=({isUnifiedSdpSemantic:n,appVersion:e,browserName:t,browserVersion:r,appName:s})=>n?Pe({appVersion:e,browserName:t,browserVersion:r,appName:s}):"Chrome",Y="purgatory",I=n=>n===Y,_e=n=>e=>[...e].map(r=>async()=>n(r)),Ne=async({accumulatedKeys:n,sendKey:e,canRunTask:t})=>{const s=_e(e)(n);return ge.sequentPromises(s,t)},Oe=(n,e)=>(n.degradationPreference=e.degradationPreference,n),we=(n,e)=>{n.encodings??=[];for(let t=n.encodings.length;t<e;t+=1)n.encodings.push({});return n},z=n=>(e,t)=>t!==void 0&&e!==t||t===void 0&&e!==n,De=z(),ke=(n,e)=>{if(De(n,e))return n},Fe=(n,e)=>{const t=n.maxBitrate,r=ke(e,t);return r!==void 0&&(n.maxBitrate=r),n},Z=1,Ie=z(Z),xe=(n,e)=>{const t=n===void 0?void 0:Math.max(n,Z);if(t!==void 0&&Ie(t,e))return t},Ue=(n,e)=>{const t=n.scaleResolutionDownBy,r=xe(e,t);return r!==void 0&&(n.scaleResolutionDownBy=r),n},Ve=(n,e)=>{const t=e.encodings?.length??0;return we(n,t),n.encodings.forEach((r,s)=>{const i=(e?.encodings??[])[s],c=i?.maxBitrate,a=i?.scaleResolutionDownBy;Fe(r,c),Ue(r,a)}),n},Le=(n,e)=>{if(n.codecs?.length!==e.codecs?.length)return!0;for(let t=0;t<(n.codecs?.length??0);t++)if(JSON.stringify(n.codecs[t])!==JSON.stringify(e.codecs[t]))return!0;if(n.headerExtensions?.length!==e.headerExtensions?.length)return!0;for(let t=0;t<(n.headerExtensions?.length??0);t++)if(JSON.stringify(n.headerExtensions[t])!==JSON.stringify(e.headerExtensions[t]))return!0;if(n.encodings?.length!==e.encodings?.length)return!0;for(let t=0;t<(n.encodings?.length??0);t++)if(JSON.stringify(n.encodings[t])!==JSON.stringify(e.encodings[t]))return!0;return n.rtcp?.cname!==e.rtcp?.cname||n.rtcp?.reducedSize!==e.rtcp?.reducedSize||n.degradationPreference!==e.degradationPreference},$=async(n,e)=>{const t=n.getParameters(),r=JSON.parse(JSON.stringify(t));Ve(t,e),Oe(t,e);const s=Le(r,t);return s&&await n.setParameters(t),{parameters:t,isChanged:s}},ee=async(n,e,t)=>{const{isChanged:r,parameters:s}=await $(n,{encodings:[{scaleResolutionDownBy:e.scaleResolutionDownBy,maxBitrate:e.maxBitrate}]});return r&&t&&t(s),{isChanged:r,parameters:s}},He=n=>t=>(o.logger("onStartMainCam"),n.on("api:admin-start-main-cam",t)),qe=n=>t=>(o.logger("onStartMic"),n.on("api:admin-start-mic",t)),$e=n=>t=>(o.logger("onStopMainCam"),n.on("api:admin-stop-main-cam",t)),We=n=>t=>(o.logger("onStopMic"),n.on("api:admin-stop-mic",t)),Qe=({sipConnector:n})=>{const e=(C,f)=>({isSyncForced:m})=>{if(m===!0){C();return}f()},t=He(n),r=$e(n),s=qe(n),i=We(n);let c,a,d,l;const h=({onStartMainCamForced:C,onStartMainCamNotForced:f,onStopMainCamForced:m,onStopMainCamNotForced:p,onStartMicForced:R,onStartMicNotForced:v,onStopMicForced:T,onStopMicNotForced:M})=>{const b=e(C,f);c=t(b);const P=e(m,p);a=r(P);const A=e(R,v);d=s(A);const _=e(T,M);l=i(_)},g=()=>{c?.(),a?.(),d?.(),l?.()};return{start:C=>{h(C)},stop:()=>{g()}}},Je=Object.freeze(Object.defineProperty({__proto__:null,PURGATORY_CONFERENCE_NUMBER:Y,createSyncMediaState:Qe,createUaParser:G,error:ve,getExtraHeaders:Te,getUserAgent:Ae,hasPurgatory:I,prepareMediaStream:o.prepareMediaStream,sendDtmfAccumulated:Ne,setEncodingsToSender:ee,setParametersToSender:$},Symbol.toStringTag,{value:"Module"})),Xe=()=>G().isChrome,je=n=>n.getVideoTracks()[0],Ge=1e6,S=n=>n*Ge,ne=S(.06),te=S(4),Ke=n=>n<=64?ne:n<=128?S(.12):n<=256?S(.25):n<=384?S(.32):n<=426?S(.38):n<=640?S(.5):n<=848?S(.7):n<=1280?S(1):n<=1920?S(2):te,re=(n,e)=>n!==void 0&&e!==void 0&&n.toLowerCase().includes(e.toLowerCase()),Ye="av1",ze=n=>re(n,Ye),Ze=.6,W=(n,e)=>ze(e)?n*Ze:n,en=n=>W(ne,n),nn=n=>W(te,n),q=(n,e)=>{const t=Ke(n);return W(t,e)},L=1,se=({videoTrack:n,targetSize:e})=>{const t=n.getSettings(),r=t.width,s=t.height,i=r===void 0?L:r/e.width,c=s===void 0?L:s/e.height;return Math.max(i,c,L)},tn=n=>[...n.keys()].map(e=>n.get(e)),rn=(n,e)=>tn(n).find(t=>t?.type===e),oe=async n=>n.getStats().then(e=>rn(e,"codec")?.mimeType);class sn{async getCodecFromSender(e){return await oe(e)??""}}class on{stackPromises=he.createStackPromises({noRunIsNotActual:!0});async add(e){return this.stackPromises.add(e),this.run()}stop(){this.stackPromises.stop()}async run(){return this.stackPromises().catch(e=>{o.logger("TaskQueue: error",e)})}}class cn{taskQueue;onSetParameters;constructor(e){this.onSetParameters=e,this.taskQueue=new on}async setEncodingsToSender(e,t){return this.taskQueue.add(async()=>ee(e,t,this.onSetParameters))}stop(){this.taskQueue.stop()}}class an{ignoreForCodec;senderFinder;codecProvider;parametersSetter;resultNoChanged={isChanged:!1,parameters:{encodings:[{}],transactionId:"0",codecs:[],headerExtensions:[],rtcp:{}}};constructor({senderFinder:e,codecProvider:t,parametersSetter:r},s){this.senderFinder=e,this.codecProvider=t,this.parametersSetter=r,this.ignoreForCodec=s.ignoreForCodec}async balance(e,t){const r=e.getSenders(),s=this.senderFinder.findVideoSender(r);if(!s?.track)return this.resultNoChanged;const i=await this.codecProvider.getCodecFromSender(s);if(re(i,this.ignoreForCodec))return this.resultNoChanged;const{mainCam:c,resolutionMainCam:a}=t??{};return this.processSender({mainCam:c,resolutionMainCam:a},{sender:s,codec:i,videoTrack:s.track})}async processSender(e,t){const{mainCam:r,resolutionMainCam:s}=e;switch(r){case o.EEventsMainCAM.PAUSE_MAIN_CAM:return this.downgradeResolutionSender(t);case o.EEventsMainCAM.RESUME_MAIN_CAM:return this.setBitrateByTrackResolution(t);case o.EEventsMainCAM.MAX_MAIN_CAM_RESOLUTION:return s!==void 0?this.setResolutionSender(s,t):this.setBitrateByTrackResolution(t);case o.EEventsMainCAM.ADMIN_STOP_MAIN_CAM:case o.EEventsMainCAM.ADMIN_START_MAIN_CAM:case void 0:return this.setBitrateByTrackResolution(t);default:return this.setBitrateByTrackResolution(t)}}async downgradeResolutionSender(e){const{sender:t,codec:r}=e,s={scaleResolutionDownBy:200,maxBitrate:en(r)};return this.parametersSetter.setEncodingsToSender(t,s)}async setBitrateByTrackResolution(e){const{sender:t,videoTrack:r,codec:s}=e,c=r.getSettings().width,a=c===void 0?nn(s):q(c,s);return this.parametersSetter.setEncodingsToSender(t,{scaleResolutionDownBy:1,maxBitrate:a})}async setResolutionSender(e,t){const[r,s]=e.split("x"),{sender:i,videoTrack:c,codec:a}=t,d={width:Number(r),height:Number(s)},l=se({videoTrack:c,targetSize:d}),h=q(d.width,a),g={scaleResolutionDownBy:l,maxBitrate:h};return this.parametersSetter.setEncodingsToSender(i,g)}}const dn=n=>n.find(e=>e.track?.kind==="video");class un{findVideoSender(e){return dn(e)}}class ln{sipConnector;currentHandler;constructor(e){this.sipConnector=e}subscribe(e){this.currentHandler=e,this.sipConnector.on("api:main-cam-control",e)}unsubscribe(){this.currentHandler&&(this.sipConnector.off("api:main-cam-control",this.currentHandler),this.currentHandler=void 0)}getConnection(){return this.sipConnector.connection}}class ie{eventHandler;senderBalancer;parametersSetterWithQueue;serverHeaders;constructor(e,{ignoreForCodec:t,onSetParameters:r}={}){this.eventHandler=new ln(e),this.parametersSetterWithQueue=new cn(r),this.senderBalancer=new an({senderFinder:new un,codecProvider:new sn,parametersSetter:this.parametersSetterWithQueue},{ignoreForCodec:t})}subscribe(){this.eventHandler.subscribe(this.handleMainCamControl)}unsubscribe(){this.eventHandler.unsubscribe(),this.parametersSetterWithQueue.stop(),this.reset()}reset(){delete this.serverHeaders}async reBalance(){return this.balanceByTrack()}async balanceByTrack(){const e=this.eventHandler.getConnection();if(!e)throw new Error("connection is not exist");return this.senderBalancer.balance(e,this.serverHeaders)}handleMainCamControl=e=>{this.serverHeaders=e,this.balanceByTrack().catch(B)}}const gn=(n,e={})=>new ie(n,e),hn=({videoTrack:n,targetSize:e,codec:t})=>{const r=se({videoTrack:n,targetSize:e}),s=q(e.width,t);return{scaleResolutionDownBy:r,maxBitrate:s}},O=({mediaStream:n,simulcastEncodings:e,sendEncodings:t})=>{if(e&&e.length>0){const r=t??[],s=je(n);if(s===void 0)throw new Error("No video track");return e.forEach((i,c)=>{const a=r[c]??{};a.active=!0,i.rid!==void 0&&(a.rid=i.rid),i.scalabilityMode!==void 0&&(a.scalabilityMode=i.scalabilityMode);const{maxBitrate:d,scaleResolutionDownBy:l}=hn({videoTrack:s,targetSize:{width:i.width,height:i.height}});a.maxBitrate=d,a.scaleResolutionDownBy=l,r[c]=a}),r}return t},Cn=(n,e)=>n.filter(r=>e.some(s=>s.clockRate===r.clockRate&&s.mimeType===r.mimeType&&s.channels===r.channels&&s.sdpFmtpLine===r.sdpFmtpLine)),Sn=n=>{const e=RTCRtpSender.getCapabilities(n),t=RTCRtpReceiver.getCapabilities(n),r=e===null?[]:e.codecs,s=t===null?[]:t.codecs;return Cn(r,s)},fn=(n,e)=>e===void 0||e.length===0?n:n.sort((t,r)=>{const s=e.indexOf(t.mimeType),i=e.indexOf(r.mimeType),c=s===-1?Number.MAX_VALUE:s,a=i===-1?Number.MAX_VALUE:i;return c-a}),mn=(n,e)=>e===void 0||e.length===0?n:n.filter(t=>!e.includes(t.mimeType)),pn=(n,{preferredMimeTypesVideoCodecs:e,excludeMimeTypesVideoCodecs:t})=>{if(typeof n.setCodecPreferences=="function"&&n.sender.track?.kind==="video"&&(e!==void 0&&e.length>0||t!==void 0&&t.length>0)){const r=Sn("video"),s=mn(r,t),i=fn(s,e);n.setCodecPreferences(i)}},w=(n,{preferredMimeTypesVideoCodecs:e,excludeMimeTypesVideoCodecs:t})=>async r=>{try{pn(r,{preferredMimeTypesVideoCodecs:e,excludeMimeTypesVideoCodecs:t}),Object.values(n).filter(i=>i!=null).length>0&&(o.logger("updateTransceiver setParametersToSender",n),await $(r.sender,n))}catch(s){o.logger("updateTransceiver error",s)}},H=n=>{if(!j.isCanceledError(n)&&!de.hasCanceledError(n))throw n;return{isSuccessful:!1}},Rn=({kind:n,readyState:e})=>n==="video"&&e==="live",Q=(n,e,{onEnterPurgatory:t,onEnterConference:r})=>{I(n)?t&&t():r&&r({isSuccessProgressCall:e})},J=(n,e)=>{n(),e&&e()},X=(n,e,t)=>{throw n&&n(),e(),t},En=new Set(["on","once","onceRace","wait","off","sendDTMF","hangUp","declineToIncomingCall","sendChannels","checkTelephony","waitChannels","ping","connection","isConfigured","isRegistered"]);class yn{on;once;onceRace;wait;off;sendDTMF;hangUp;declineToIncomingCall;sendChannels;checkTelephony;waitChannels;ping;connection;isConfigured;isRegistered;sipConnector;preferredMimeTypesVideoCodecs;excludeMimeTypesVideoCodecs;constructor(e,{preferredMimeTypesVideoCodecs:t,excludeMimeTypesVideoCodecs:r}={}){return this.preferredMimeTypesVideoCodecs=t,this.excludeMimeTypesVideoCodecs=r,this.sipConnector=e,new Proxy(this,{get:(s,i,c)=>{if(typeof i=="string"&&En.has(i)&&i in this.sipConnector){const d=Reflect.get(this.sipConnector,i,this.sipConnector);return typeof d=="function"?d.bind(this.sipConnector):d}const a=Reflect.get(s,i,c);return typeof a=="function"?a.bind(s):a}})}connectToServer=async e=>{const{userAgent:t,sipWebSocketServerURL:r,sipServerUrl:s,remoteAddress:i,displayName:c,name:a,password:d,isRegisteredUser:l,isDisconnectOnFail:h}=e;return o.logger("connectToServer",e),this.sipConnector.connect({userAgent:t,sipWebSocketServerURL:r,sipServerUrl:s,remoteAddress:i,displayName:c,password:d,user:a,register:l}).then(g=>(o.logger("connectToServer then"),{ua:g,isSuccessful:!0})).catch(async g=>(o.logger("connectToServer catch: error",g),h===!0?this.sipConnector.disconnect().then(()=>H(g)).catch(()=>H(g)):H(g)))};callToServer=async e=>{const{conference:t,mediaStream:r,extraHeaders:s,iceServers:i,contentHint:c,simulcastEncodings:a,degradationPreference:d,sendEncodings:l,offerToReceiveAudio:h,offerToReceiveVideo:g,directionVideo:D,directionAudio:k,setRemoteStreams:C,onBeforeProgressCall:f,onSuccessProgressCall:m,onEnterPurgatory:p,onEnterConference:R,onFailProgressCall:v,onFinishProgressCall:T,onEndedCall:M}=e,b=this.resolveHandleReadyRemoteStreamsDebounced({onReadyRemoteStreams:C}),P=this.resolveHandleReadyRemoteStreams({onReadyRemoteStreams:()=>{b().catch(B)}}),A=w({degradationPreference:d},{preferredMimeTypesVideoCodecs:this.preferredMimeTypesVideoCodecs,excludeMimeTypesVideoCodecs:this.excludeMimeTypesVideoCodecs});o.logger("callToServer",e);const _=async()=>(o.logger("startCall"),this.sipConnector.call({mediaStream:r,extraHeaders:s,iceServers:i,contentHint:c,offerToReceiveAudio:h,offerToReceiveVideo:g,directionVideo:D,directionAudio:k,sendEncodings:O({mediaStream:r,simulcastEncodings:a,sendEncodings:l}),number:t,onAddedTransceiver:A,ontrack:P}));let E=!1,y;const N=(o.logger("subscribeEnterConference: onEnterConference",R),this.sipConnector.on("api:enterRoom",({room:u})=>{o.logger("enterRoom",{_room:u,isSuccessProgressCall:E}),y=u,(p??R)&&Q(y,E,{onEnterPurgatory:p,onEnterConference:R})})),x=u=>(o.logger("onSuccess"),E=!0,b().catch(B),m&&m({isPurgatory:I(y)}),this.sipConnector.onceRace(["call:ended","call:failed"],()=>{J(N,M)}),u),U=u=>(o.logger("onFail"),X(v,N,u)),V=()=>{o.logger("onFinish"),T&&T()};return o.logger("onBeforeProgressCall"),f&&f(t),_().then(x).catch(u=>U(u)).finally(V)};disconnectFromServer=async()=>this.sipConnector.disconnect().then(()=>(o.logger("disconnectFromServer: then"),{isSuccessful:!0})).catch(e=>(o.logger("disconnectFromServer: catch",e),{isSuccessful:!1}));answerToIncomingCall=async e=>{const{mediaStream:t,extraHeaders:r,iceServers:s,contentHint:i,simulcastEncodings:c,degradationPreference:a,sendEncodings:d,offerToReceiveAudio:l,offerToReceiveVideo:h,directionVideo:g,directionAudio:D,setRemoteStreams:k,onBeforeProgressCall:C,onSuccessProgressCall:f,onEnterPurgatory:m,onEnterConference:p,onFailProgressCall:R,onFinishProgressCall:v,onEndedCall:T}=e,M=this.resolveHandleReadyRemoteStreamsDebounced({onReadyRemoteStreams:k}),b=this.resolveHandleReadyRemoteStreams({onReadyRemoteStreams:()=>{M().catch(B)}}),P=w({degradationPreference:a},{preferredMimeTypesVideoCodecs:this.preferredMimeTypesVideoCodecs,excludeMimeTypesVideoCodecs:this.excludeMimeTypesVideoCodecs});o.logger("answerToIncomingCall",e);const A=async()=>this.sipConnector.answerToIncomingCall({mediaStream:t,extraHeaders:r,iceServers:s,contentHint:i,offerToReceiveAudio:l,offerToReceiveVideo:h,directionVideo:g,directionAudio:D,sendEncodings:O({mediaStream:t,simulcastEncodings:c,sendEncodings:d}),onAddedTransceiver:P,ontrack:b}),_=()=>{const{remoteCallerData:u}=this.sipConnector;return u.incomingNumber};let E=!1,y;const N=(o.logger("subscribeEnterConference: onEnterConference",p),this.sipConnector.on("api:enterRoom",u=>{o.logger("enterRoom",{_room:u,isSuccessProgressCall:E}),y=u,(m??p)&&Q(y,E,{onEnterPurgatory:m,onEnterConference:p})})),x=u=>(o.logger("onSuccess"),E=!0,M().catch(B),f&&f({isPurgatory:I(y)}),this.sipConnector.onceRace(["call:ended","call:failed"],()=>{J(N,T)}),u),U=u=>(o.logger("onFail"),X(R,N,u)),V=()=>{o.logger("onFinish"),v&&v()};if(o.logger("onBeforeProgressCall"),C){const u=_();C(u)}return A().then(x).catch(u=>U(u)).finally(V)};updatePresentation=async({mediaStream:e,isP2P:t,maxBitrate:r,contentHint:s,simulcastEncodings:i,degradationPreference:c,sendEncodings:a,preferredMimeTypesVideoCodecs:d,excludeMimeTypesVideoCodecs:l})=>{const h=w({degradationPreference:c},{preferredMimeTypesVideoCodecs:d,excludeMimeTypesVideoCodecs:l});return o.logger("updatePresentation"),this.sipConnector.updatePresentation(e,{isP2P:t,maxBitrate:r,contentHint:s,sendEncodings:O({mediaStream:e,simulcastEncodings:i,sendEncodings:a}),onAddedTransceiver:h})};startPresentation=async({mediaStream:e,isP2P:t,maxBitrate:r,contentHint:s,simulcastEncodings:i,degradationPreference:c,sendEncodings:a,preferredMimeTypesVideoCodecs:d,excludeMimeTypesVideoCodecs:l,callLimit:h})=>{const g=w({degradationPreference:c},{preferredMimeTypesVideoCodecs:d,excludeMimeTypesVideoCodecs:l});return o.logger("startPresentation"),this.sipConnector.startPresentation(e,{isP2P:t,maxBitrate:r,contentHint:s,callLimit:h,sendEncodings:O({mediaStream:e,simulcastEncodings:i,sendEncodings:a}),onAddedTransceiver:g})};stopShareSipConnector=async({isP2P:e=!1}={})=>(o.logger("stopShareSipConnector"),this.sipConnector.stopPresentation({isP2P:e}).catch(t=>{o.logger(t)}));sendRefusalToTurnOnMic=async()=>{o.logger("sendRefusalToTurnOnMic"),await this.sipConnector.sendRefusalToTurnOnMic().catch(e=>{o.logger("sendRefusalToTurnOnMic: error",e)})};sendRefusalToTurnOnCam=async()=>{o.logger("sendRefusalToTurnOnCam"),await this.sipConnector.sendRefusalToTurnOnCam().catch(e=>{o.logger("sendRefusalToTurnOnCam: error",e)})};sendMediaState=async({isEnabledCam:e,isEnabledMic:t})=>{o.logger("sendMediaState"),await this.sipConnector.sendMediaState({cam:e,mic:t})};replaceMediaStream=async(e,{deleteExisting:t,addMissing:r,forceRenegotiation:s,contentHint:i,simulcastEncodings:c,degradationPreference:a,sendEncodings:d})=>{const l=w({degradationPreference:a},{preferredMimeTypesVideoCodecs:this.preferredMimeTypesVideoCodecs,excludeMimeTypesVideoCodecs:this.excludeMimeTypesVideoCodecs});return o.logger("replaceMediaStream"),this.sipConnector.replaceMediaStream(e,{deleteExisting:t,addMissing:r,forceRenegotiation:s,contentHint:i,sendEncodings:O({mediaStream:e,simulcastEncodings:c,sendEncodings:d}),onAddedTransceiver:l})};askPermissionToEnableCam=async()=>{o.logger("askPermissionToEnableCam"),await this.sipConnector.askPermissionToEnableCam()};resolveHandleReadyRemoteStreamsDebounced=({onReadyRemoteStreams:e})=>ue.debounce(()=>{const t=this.sipConnector.getRemoteStreams();o.logger("remoteStreams",t),t&&e(t)},200);resolveHandleReadyRemoteStreams=({onReadyRemoteStreams:e})=>({track:t})=>{Rn(t)&&e()};getRemoteStreams=()=>(o.logger("getRemoteStreams"),this.sipConnector.getRemoteStreams());onUseLicense=e=>(o.logger("onUseLicense"),this.sipConnector.on("api:useLicense",e));onMustStopPresentation=e=>(o.logger("onMustStopPresentation"),this.sipConnector.on("api:mustStopPresentation",e));onMoveToSpectators=e=>(o.logger("onMoveToSpectators"),this.sipConnector.on("api:participant:move-request-to-spectators",e));onMoveToParticipants=e=>(o.logger("onMoveToParticipants"),this.sipConnector.on("api:participant:move-request-to-participants",e));onStats=e=>(o.logger("onStats"),this.sipConnector.on("stats:collected",e));offStats=e=>{o.logger("offStats"),this.sipConnector.off("stats:collected",e)}}var ce=(n=>(n.VP8="video/VP8",n.VP9="video/VP9",n.H264="video/H264",n.AV1="video/AV1",n.rtx="video/rtx",n.red="video/red",n.flexfec03="video/flexfec-03",n))(ce||{});exports.ECallCause=o.ECallCause;exports.EStatsTypes=o.EStatsTypes;exports.EUseLicense=o.EUseLicense;exports.SipConnector=o.SipConnector;exports.StatsPeerConnection=o.StatsPeerConnection;exports.disableDebug=o.disableDebug;exports.enableDebug=o.enableDebug;exports.hasCanceledStartPresentationError=o.hasCanceledStartPresentationError;exports.debug=B;exports.EMimeTypesVideoCodecs=ce;exports.SipConnectorFacade=yn;exports.VideoSendingBalancer=ie;exports.getCodecFromSender=oe;exports.hasAvailableStats=Xe;exports.hasCanceledCallError=Se;exports.resolveVideoSendingBalancer=gn;exports.tools=Je;
package/dist/index.d.ts CHANGED
@@ -4,11 +4,11 @@ export type { TCustomError } from './CallManager';
4
4
  export { debug, disableDebug, enableDebug } from './logger';
5
5
  export { hasCanceledStartPresentationError } from './PresentationManager';
6
6
  export type { TContentHint } from './PresentationManager';
7
- export { setParametersToSender } from './setParametersToSender';
8
7
  export { SipConnector } from './SipConnector';
9
8
  export { SipConnectorFacade } from './SipConnectorFacade';
9
+ export { EStatsTypes, hasAvailableStats, StatsPeerConnection } from './StatsPeerConnection';
10
10
  export * as tools from './tools';
11
11
  export { EMimeTypesVideoCodecs } from './types';
12
12
  export type { TJsSIP } from './types';
13
13
  export { default as getCodecFromSender } from './utils/getCodecFromSender';
14
- export { resolveVideoSendingBalancer, VideoSendingBalancer } from './videoSendingBalancer';
14
+ export { resolveVideoSendingBalancer, VideoSendingBalancer } from './VideoSendingBalancer';