sip-connector 19.8.3 → 20.0.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.
- package/README.md +131 -138
- package/dist/@SipConnector-CZiURTVf.cjs +1 -0
- package/dist/{@SipConnector-BmkeKEDD.js → @SipConnector-D4DfiZRM.js} +1117 -977
- package/dist/ApiManager/@ApiManager.d.ts +0 -1
- package/dist/ApiManager/constants.d.ts +3 -8
- package/dist/ApiManager/eventNames.d.ts +15 -6
- package/dist/ApiManager/index.d.ts +0 -1
- package/dist/ApiManager/types.d.ts +0 -6
- package/dist/CallManager/@CallManager.d.ts +44 -15
- package/dist/CallManager/MCUSession.d.ts +0 -2
- package/dist/CallManager/RecvSession.d.ts +29 -0
- package/dist/CallManager/RemoteStreamsManager.d.ts +20 -5
- package/dist/CallManager/RoleManager.d.ts +31 -0
- package/dist/CallManager/eventNames.d.ts +9 -2
- package/dist/CallManager/index.d.ts +1 -2
- package/dist/CallManager/types.d.ts +29 -35
- package/dist/ConnectionManager/@ConnectionManager.d.ts +2 -2
- package/dist/ConnectionManager/ConfigurationManager.d.ts +6 -1
- package/dist/ConnectionManager/ConnectionFlow.d.ts +5 -4
- package/dist/ConnectionManager/SipOperations.d.ts +2 -2
- package/dist/ConnectionManager/UAFactory.d.ts +4 -4
- package/dist/SipConnector/@SipConnector.d.ts +4 -4
- package/dist/SipConnector/eventNames.d.ts +1 -1
- package/dist/SipConnectorFacade/@SipConnectorFacade.d.ts +0 -2
- package/dist/VideoSendingBalancer/__fixtures__/createMockTrack.d.ts +1 -1
- package/dist/__fixtures__/RTCPeerConnectionMock.d.ts +14 -18
- package/dist/__fixtures__/index.d.ts +4 -4
- package/dist/doMock.cjs +1 -1
- package/dist/doMock.js +134 -131
- package/dist/index.cjs +1 -1
- package/dist/index.js +156 -171
- package/dist/tools/__fixtures__/connectToServer.d.ts +15 -15
- package/dist/tools/__fixtures__/permissions.d.ts +2 -2
- package/dist/tools/__fixtures__/processRequest.d.ts +2 -2
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/sendOffer.d.ts +39 -0
- package/dist/utils/utils.d.ts +1 -1
- package/package.json +13 -5
- package/dist/@SipConnector-BHakZWEK.cjs +0 -1
- package/dist/CallManager/AbstractCallStrategy.d.ts +0 -54
- package/dist/CallManager/MCUCallStrategy.d.ts +0 -31
- package/dist/TransceiverManager/@TransceiverManager.d.ts +0 -70
- package/dist/TransceiverManager/index.d.ts +0 -1
- package/dist/TransceiverManager/types.d.ts +0 -11
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
type TQuality = 'low' | 'medium' | 'high';
|
|
2
|
+
type TSendOfferParams = {
|
|
3
|
+
/**
|
|
4
|
+
* Базовый endpoint без номера конференции.
|
|
5
|
+
* Например: "dev.vinteo.com".
|
|
6
|
+
*/
|
|
7
|
+
serverUrl: string;
|
|
8
|
+
/**
|
|
9
|
+
* Номер конференции.
|
|
10
|
+
* Например: "1008".
|
|
11
|
+
*/
|
|
12
|
+
conferenceNumber: string;
|
|
13
|
+
/**
|
|
14
|
+
* Качество потока: low | medium | high.
|
|
15
|
+
*/
|
|
16
|
+
quality: TQuality;
|
|
17
|
+
/**
|
|
18
|
+
* Идентификатор аудиоканала.
|
|
19
|
+
* В примере из ТЗ соответствует query-параметру audio.
|
|
20
|
+
*/
|
|
21
|
+
audio: string | number;
|
|
22
|
+
/**
|
|
23
|
+
* SDP-offer, который нужно отправить на сервер.
|
|
24
|
+
*/
|
|
25
|
+
offer: RTCSessionDescriptionInit;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Отправляет SDP-offer на MCU и возвращает SDP-answer.
|
|
29
|
+
*
|
|
30
|
+
* Формат запроса:
|
|
31
|
+
* POST {endpoint}/{conferenceNumber}?quality={quality}&audio={audio}
|
|
32
|
+
* Пример:
|
|
33
|
+
* https://dev.vinteo.com/api/v2/rtp2webrtc/offer/1008?quality=medium&audio=0
|
|
34
|
+
*
|
|
35
|
+
* Ожидается, что сервер вернёт JSON с полями { type, sdp }.
|
|
36
|
+
*/
|
|
37
|
+
declare const sendOffer: ({ serverUrl, conferenceNumber, quality, audio, offer, }: TSendOfferParams) => Promise<RTCSessionDescription>;
|
|
38
|
+
export type { TSendOfferParams, TQuality };
|
|
39
|
+
export default sendOffer;
|
package/dist/utils/utils.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare function
|
|
1
|
+
export declare function resolveGetUri(sipServerIp: string): (string: string) => string;
|
|
2
2
|
export declare const parseDisplayName: (displayName: string) => string;
|
|
3
3
|
export declare const generateUserId: () => number;
|
|
4
4
|
export declare const hasVideoTracks: (remoteTracks: MediaStreamTrack[]) => boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sip-connector",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "20.0.0",
|
|
4
4
|
"description": "Module for connect to Vinteo server",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"webrtc",
|
|
@@ -39,8 +39,12 @@
|
|
|
39
39
|
],
|
|
40
40
|
"scripts": {
|
|
41
41
|
"build": "vite build",
|
|
42
|
+
"build:demo": "vite build --config vite.demo.config.ts",
|
|
43
|
+
"cert": "rm -rf .cert && mkdir -p .cert && mkcert -key-file ./.cert/key.pem -cert-file ./.cert/cert.pem 'localhost'",
|
|
42
44
|
"lint": "yarn lint:ts && yarn lint:js",
|
|
43
|
-
"lint:js": "
|
|
45
|
+
"lint:js": "yarn lint:js:src && yarn lint:js:demo",
|
|
46
|
+
"lint:js:demo": "eslint demo --ext ts,tsx --report-unused-disable-directives --max-warnings 0 --cache --cache-strategy=content",
|
|
47
|
+
"lint:js:src": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0 --cache --cache-strategy=content",
|
|
44
48
|
"lint:ts": "tsc",
|
|
45
49
|
"prepare": "husky",
|
|
46
50
|
"prepublishOnly": "yarn build",
|
|
@@ -50,6 +54,8 @@
|
|
|
50
54
|
"release:major": "standard-version --release-as major && npm run release:publish && npm publish --access=public --registry=https://registry.npmjs.org/",
|
|
51
55
|
"release:pre": "standard-version --prerelease && npm run release:publish && npm publish --tag prerelease --registry=https://registry.npmjs.org/",
|
|
52
56
|
"release:publish": "git push --follow-tags",
|
|
57
|
+
"start": "vite --config vite.demo.config.ts",
|
|
58
|
+
"start:builded": "yarn build:demo && http-server demoDist -c-1 -o --cors",
|
|
53
59
|
"test": "jest",
|
|
54
60
|
"test:ci": "cross-env CI=true jest",
|
|
55
61
|
"test:coverage": "yarn test:ci --no-cache --coverage",
|
|
@@ -74,11 +80,12 @@
|
|
|
74
80
|
"@commitlint/cli": "^20.2.0",
|
|
75
81
|
"@commitlint/config-conventional": "^20.2.0",
|
|
76
82
|
"@eslint/compat": "^2.0.0",
|
|
77
|
-
"@krivega/eslint-config": "^1.1.
|
|
83
|
+
"@krivega/eslint-config": "^1.1.3",
|
|
78
84
|
"@types/debug": "^4.1.12",
|
|
79
85
|
"@types/dom-mediacapture-transform": "^0.1.11",
|
|
80
86
|
"@types/jest": "^30.0.0",
|
|
81
87
|
"cross-env": "^10.1.0",
|
|
88
|
+
"http-server": "^14.1.1",
|
|
82
89
|
"husky": "^9.1.7",
|
|
83
90
|
"jest": "^30.2.0",
|
|
84
91
|
"jest-environment-jsdom": "^30.2.0",
|
|
@@ -91,9 +98,10 @@
|
|
|
91
98
|
"ts-node": "^10.9.2",
|
|
92
99
|
"tsc-files": "^1.1.4",
|
|
93
100
|
"typescript": "^5.9.3",
|
|
94
|
-
"vite": "^7.
|
|
101
|
+
"vite": "^7.3.0",
|
|
95
102
|
"vite-plugin-dts": "^4.5.4",
|
|
96
|
-
"vite-tsconfig-paths": "^
|
|
103
|
+
"vite-tsconfig-paths": "^6.0.3",
|
|
104
|
+
"webrtc-adapter": "^9.0.3"
|
|
97
105
|
},
|
|
98
106
|
"peerDependencies": {
|
|
99
107
|
"@krivega/cancelable-promise": "^1.1.4",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";const y=require("events-constructor"),G=require("debug"),k=require("@krivega/cancelable-promise"),D=require("@krivega/timeout-requester"),Q=require("repeated-calls"),re=require("xstate"),Y=require("stack-promises");require("ua-parser-js");require("sequent-promises");const z="sip-connector",c=G(z),ye=()=>{G.enable(z)},be=()=>{G.enable(`-${z}`)},De="Error decline with 603",we=1006,Ue=n=>typeof n=="object"&&n!==null&&"code"in n&&n.code===we,Le=n=>n.message===De;var u=(n=>(n.CONTENT_TYPE="content-type",n.CONTENT_ENTER_ROOM="x-webrtc-enter-room",n.CONTENT_USE_LICENSE="X-WEBRTC-USE-LICENSE",n.PARTICIPANT_NAME="X-WEBRTC-PARTICIPANT-NAME",n.INPUT_CHANNELS="X-WEBRTC-INPUT-CHANNELS",n.OUTPUT_CHANNELS="X-WEBRTC-OUTPUT-CHANNELS",n.MAIN_CAM="X-WEBRTC-MAINCAM",n.MIC="X-WEBRTC-MIC",n.MEDIA_SYNC="X-WEBRTC-SYNC",n.MAIN_CAM_RESOLUTION="X-WEBRTC-MAINCAM-RESOLUTION",n.MEDIA_STATE="X-WEBRTC-MEDIA-STATE",n.MEDIA_TYPE="X-Vinteo-Media-Type",n.MAIN_CAM_STATE="X-Vinteo-MainCam-State",n.MIC_STATE="X-Vinteo-Mic-State",n.CONTENT_PARTICIPANT_STATE="X-WEBRTC-PARTSTATE",n.NOTIFY="X-VINTEO-NOTIFY",n.CONTENT_ENABLE_MEDIA_DEVICE="X-WEBRTC-REQUEST-ENABLE-MEDIA-DEVICE",n.CONTENT_SHARE_STATE="x-webrtc-share-state",n.MUST_STOP_PRESENTATION_P2P="x-webrtc-share-state: YOUMUSTSTOPSENDCONTENT",n.START_PRESENTATION_P2P="x-webrtc-share-state: YOUCANRECEIVECONTENT",n.STOP_PRESENTATION_P2P="x-webrtc-share-state: CONTENTEND",n.STOP_PRESENTATION="x-webrtc-share-state: STOPPRESENTATION",n.START_PRESENTATION="x-webrtc-share-state: LETMESTARTPRESENTATION",n.ENABLE_MAIN_CAM="X-WEBRTC-REQUEST-ENABLE-MEDIA-DEVICE: LETMESTARTMAINCAM",n.AVAILABLE_INCOMING_BITRATE="X-WEBRTC-AVAILABLE-INCOMING-BITRATE",n.AUDIO_TRACK_COUNT="X-WEBRTC-AUDIO-TRACK-COUNT",n.VIDEO_TRACK_COUNT="X-WEBRTC-VIDEO-TRACK-COUNT",n.TRACKS_DIRECTION="X-WEBRTC-TRACKS-DIRECTION",n))(u||{}),F=(n=>(n.AVAILABLE_SECOND_REMOTE_STREAM="YOUCANRECEIVECONTENT",n.NOT_AVAILABLE_SECOND_REMOTE_STREAM="CONTENTEND",n.MUST_STOP_PRESENTATION="YOUMUSTSTOPSENDCONTENT",n))(F||{}),H=(n=>(n.SPECTATOR="SPECTATOR",n.PARTICIPANT="PARTICIPANT",n))(H||{}),P=(n=>(n.ENTER_ROOM="application/vinteo.webrtc.roomname",n.MIC="application/vinteo.webrtc.mic",n.USE_LICENSE="application/vinteo.webrtc.uselic",n.PARTICIPANT_STATE="application/vinteo.webrtc.partstate",n.NOTIFY="application/vinteo.webrtc.notify",n.SHARE_STATE="application/vinteo.webrtc.sharedesktop",n.MAIN_CAM="application/vinteo.webrtc.maincam",n.RESTART="application/vinteo.webrtc.restart",n))(P||{}),I=(n=>(n.CHANNELS="application/vinteo.webrtc.channels",n.MEDIA_STATE="application/vinteo.webrtc.mediastate",n.REFUSAL="application/vinteo.webrtc.refusal",n.SHARE_STATE="application/vinteo.webrtc.sharedesktop",n.MAIN_CAM="application/vinteo.webrtc.maincam",n.STATS="application/vinteo.webrtc.stats",n))(I||{}),f=(n=>(n.PAUSE_MAIN_CAM="PAUSEMAINCAM",n.RESUME_MAIN_CAM="RESUMEMAINCAM",n.MAX_MAIN_CAM_RESOLUTION="MAXMAINCAMRESOLUTION",n.ADMIN_STOP_MAIN_CAM="ADMINSTOPMAINCAM",n.ADMIN_START_MAIN_CAM="ADMINSTARTMAINCAM",n))(f||{}),W=(n=>(n.ADMIN_STOP_MIC="ADMINSTOPMIC",n.ADMIN_START_MIC="ADMINSTARTMIC",n))(W||{}),x=(n=>(n.ADMIN_SYNC_FORCED="1",n.ADMIN_SYNC_NOT_FORCED="0",n))(x||{}),ie=(n=>(n.AUDIO="AUDIO",n.VIDEO="VIDEO",n.AUDIOPLUSPRESENTATION="AUDIOPLUSPRESENTATION",n))(ie||{}),g=(n=>(n.CHANNELS_NOTIFY="channels:notify",n.PARTICIPANT_ADDED_TO_LIST_MODERATORS="participant:added-to-list-moderators",n.PARTICIPANT_REMOVED_FROM_LIST_MODERATORS="participant:removed-from-list-moderators",n.PARTICIPANT_MOVE_REQUEST_TO_STREAM="participant:move-request-to-stream",n.PARTICIPANT_MOVE_REQUEST_TO_SPECTATORS="participant:move-request-to-spectators",n.PARTICIPANT_MOVE_REQUEST_TO_PARTICIPANTS="participant:move-request-to-participants",n.PARTICIPATION_ACCEPTING_WORD_REQUEST="participation:accepting-word-request",n.PARTICIPATION_CANCELLING_WORD_REQUEST="participation:cancelling-word-request",n.WEBCAST_STARTED="webcast:started",n.WEBCAST_STOPPED="webcast:stopped",n.ACCOUNT_CHANGED="account:changed",n.ACCOUNT_DELETED="account:deleted",n.CONFERENCE_PARTICIPANT_TOKEN_ISSUED="conference:participant-token-issued",n.CHANNELS="channels",n.ENTER_ROOM="enterRoom",n.SHARE_STATE="shareState",n.MAIN_CAM_CONTROL="main-cam-control",n.USE_LICENSE="useLicense",n.ADMIN_START_MAIN_CAM="admin-start-main-cam",n.ADMIN_STOP_MAIN_CAM="admin-stop-main-cam",n.ADMIN_START_MIC="admin-start-mic",n.ADMIN_STOP_MIC="admin-stop-mic",n.ADMIN_FORCE_SYNC_MEDIA_STATE="admin-force-sync-media-state",n.AVAILABLE_SECOND_REMOTE_STREAM="availableSecondRemoteStream",n.NOT_AVAILABLE_SECOND_REMOTE_STREAM="notAvailableSecondRemoteStream",n.MUST_STOP_PRESENTATION="mustStopPresentation",n.NEW_DTMF="newDTMF",n.RESTART="restart",n))(g||{});const ae=["participation:accepting-word-request","participation:cancelling-word-request","participant:move-request-to-stream","channels:notify","conference:participant-token-issued","account:changed","account:deleted","webcast:started","webcast:stopped","participant:added-to-list-moderators","participant:removed-from-list-moderators","participant:move-request-to-spectators","participant:move-request-to-participants","channels","enterRoom","shareState","main-cam-control","useLicense","admin-start-main-cam","admin-stop-main-cam","admin-start-mic","admin-stop-mic","admin-force-sync-media-state","availableSecondRemoteStream","notAvailableSecondRemoteStream","mustStopPresentation","newDTMF","restart"];var m=(n=>(n.CHANNELS="channels",n.WEBCAST_STARTED="WebcastStarted",n.WEBCAST_STOPPED="WebcastStopped",n.ACCOUNT_CHANGED="accountChanged",n.ACCOUNT_DELETED="accountDeleted",n.ADDED_TO_LIST_MODERATORS="addedToListModerators",n.REMOVED_FROM_LIST_MODERATORS="removedFromListModerators",n.ACCEPTING_WORD_REQUEST="ParticipationRequestAccepted",n.CANCELLING_WORD_REQUEST="ParticipationRequestRejected",n.MOVE_REQUEST_TO_STREAM="ParticipantMovedToWebcast",n.CONFERENCE_PARTICIPANT_TOKEN_ISSUED="ConferenceParticipantTokenIssued",n))(m||{});class Be{events;connectionManager;callManager;constructor({connectionManager:e,callManager:t}){this.connectionManager=e,this.callManager=t,this.events=new y.TypedEvents(ae),this.subscribe()}async waitChannels(){return this.wait(g.CHANNELS)}async waitSyncMediaState(){return this.wait(g.ADMIN_FORCE_SYNC_MEDIA_STATE)}async sendDTMF(e){return new Promise((t,s)=>{let r;try{r=this.getEstablishedRTCSessionProtected()}catch(i){s(i)}r&&(this.callManager.once("newDTMF",({originator:i})=>{i==="local"&&t()}),r.sendDTMF(e,{duration:120,interToneGap:600}))})}async sendChannels({inputChannels:e,outputChannels:t}){const s=this.getEstablishedRTCSessionProtected(),r=`${u.INPUT_CHANNELS}: ${e}`,i=`${u.OUTPUT_CHANNELS}: ${t}`,a=[r,i];return s.sendInfo(I.CHANNELS,void 0,{extraHeaders:a})}async sendMediaState({cam:e,mic:t},s={}){const r=this.getEstablishedRTCSessionProtected(),i=`${u.MEDIA_STATE}: currentstate`,a=`${u.MAIN_CAM_STATE}: ${Number(e)}`,o=`${u.MIC_STATE}: ${Number(t)}`,h=[i,a,o];return r.sendInfo(I.MEDIA_STATE,void 0,{noTerminateWhenError:!0,...s,extraHeaders:h})}async sendStats({availableIncomingBitrate:e}){const t=this.getEstablishedRTCSessionProtected(),r=[`${u.AVAILABLE_INCOMING_BITRATE}: ${e}`];return t.sendInfo(I.STATS,void 0,{noTerminateWhenError:!0,extraHeaders:r})}async sendRefusalToTurnOn(e,t={}){const s=this.getEstablishedRTCSessionProtected(),a=e==="mic"?0:1,h=[`${u.MEDIA_TYPE}: ${a}`];return s.sendInfo(I.REFUSAL,void 0,{noTerminateWhenError:!0,...t,extraHeaders:h})}async sendRefusalToTurnOnMic(e={}){return this.sendRefusalToTurnOn("mic",{noTerminateWhenError:!0,...e})}async sendRefusalToTurnOnCam(e={}){return this.sendRefusalToTurnOn("cam",{noTerminateWhenError:!0,...e})}async sendMustStopPresentationP2P(){await this.getEstablishedRTCSessionProtected().sendInfo(I.SHARE_STATE,void 0,{extraHeaders:[u.MUST_STOP_PRESENTATION_P2P]})}async sendStoppedPresentationP2P(){await this.getEstablishedRTCSessionProtected().sendInfo(I.SHARE_STATE,void 0,{extraHeaders:[u.STOP_PRESENTATION_P2P]})}async sendStoppedPresentation(){await this.getEstablishedRTCSessionProtected().sendInfo(I.SHARE_STATE,void 0,{extraHeaders:[u.STOP_PRESENTATION]})}async askPermissionToStartPresentationP2P(){await this.getEstablishedRTCSessionProtected().sendInfo(I.SHARE_STATE,void 0,{extraHeaders:[u.START_PRESENTATION_P2P]})}async askPermissionToStartPresentation(){await this.getEstablishedRTCSessionProtected().sendInfo(I.SHARE_STATE,void 0,{extraHeaders:[u.START_PRESENTATION]})}async askPermissionToEnableCam(e={}){const t=this.getEstablishedRTCSessionProtected(),s=[u.ENABLE_MAIN_CAM];return t.sendInfo(I.MAIN_CAM,void 0,{noTerminateWhenError:!0,...e,extraHeaders:s}).catch(r=>{if(Le(r))throw r})}on(e,t){return this.events.on(e,t)}once(e,t){return this.events.once(e,t)}onceRace(e,t){return this.events.onceRace(e,t)}async wait(e){return this.events.wait(e)}off(e,t){this.events.off(e,t)}getEstablishedRTCSessionProtected=()=>{const e=this.callManager.getEstablishedRTCSession();if(!e)throw new Error("No rtcSession established");return e};subscribe(){this.connectionManager.on("sipEvent",this.handleSipEvent),this.callManager.on("newInfo",this.handleNewInfo),this.callManager.on("newDTMF",e=>{this.events.trigger("newDTMF",e)})}handleSipEvent=({request:e})=>{this.maybeHandleNotify(e)};maybeHandleNotify=e=>{try{const t=e.getHeader(u.NOTIFY);if(t){const s=JSON.parse(t);this.handleNotify(s)}}catch(t){c("error parse notify",t)}};handleNotify=e=>{switch(e.cmd){case m.CHANNELS:{const t=e;this.triggerChannelsNotify(t);break}case m.WEBCAST_STARTED:{const t=e;this.triggerWebcastStartedNotify(t);break}case m.WEBCAST_STOPPED:{const t=e;this.triggerWebcastStoppedNotify(t);break}case m.ADDED_TO_LIST_MODERATORS:{const t=e;this.triggerAddedToListModeratorsNotify(t);break}case m.REMOVED_FROM_LIST_MODERATORS:{const t=e;this.triggerRemovedFromListModeratorsNotify(t);break}case m.ACCEPTING_WORD_REQUEST:{const t=e;this.triggerParticipationAcceptingWordRequest(t);break}case m.CANCELLING_WORD_REQUEST:{const t=e;this.triggerParticipationCancellingWordRequest(t);break}case m.MOVE_REQUEST_TO_STREAM:{const t=e;this.triggerParticipantMoveRequestToStream(t);break}case m.ACCOUNT_CHANGED:{this.triggerAccountChangedNotify();break}case m.ACCOUNT_DELETED:{this.triggerAccountDeletedNotify();break}case m.CONFERENCE_PARTICIPANT_TOKEN_ISSUED:{const t=e;this.triggerConferenceParticipantTokenIssued(t);break}default:c("unknown cmd",e)}};handleNewInfo=e=>{const{originator:t}=e;if(t!=="remote")return;const{request:s}=e,r=s,i=r.getHeader(u.CONTENT_TYPE);if(i!==void 0)switch(i){case P.ENTER_ROOM:{this.triggerEnterRoom(r),this.maybeTriggerChannels(r);break}case P.NOTIFY:{this.maybeHandleNotify(r);break}case P.SHARE_STATE:{this.triggerShareState(r);break}case P.MAIN_CAM:{this.triggerMainCamControl(r);break}case P.MIC:{this.triggerMicControl(r);break}case P.USE_LICENSE:{this.triggerUseLicense(r);break}case P.PARTICIPANT_STATE:{this.maybeTriggerParticipantMoveRequest(r);break}case P.RESTART:{this.triggerRestart(r);break}}};triggerChannelsNotify=e=>{const t=e.input,s=e.output,r={inputChannels:t,outputChannels:s};this.events.trigger(g.CHANNELS_NOTIFY,r)};triggerWebcastStartedNotify=({body:{conference:e,type:t}})=>{const s={conference:e,type:t};this.events.trigger(g.WEBCAST_STARTED,s)};triggerWebcastStoppedNotify=({body:{conference:e,type:t}})=>{const s={conference:e,type:t};this.events.trigger(g.WEBCAST_STOPPED,s)};triggerAddedToListModeratorsNotify=({conference:e})=>{const t={conference:e};this.events.trigger(g.PARTICIPANT_ADDED_TO_LIST_MODERATORS,t)};triggerRemovedFromListModeratorsNotify=({conference:e})=>{const t={conference:e};this.events.trigger(g.PARTICIPANT_REMOVED_FROM_LIST_MODERATORS,t)};triggerParticipationAcceptingWordRequest=({body:{conference:e}})=>{const t={conference:e};this.events.trigger(g.PARTICIPATION_ACCEPTING_WORD_REQUEST,t)};triggerParticipationCancellingWordRequest=({body:{conference:e}})=>{const t={conference:e};this.events.trigger(g.PARTICIPATION_CANCELLING_WORD_REQUEST,t)};triggerParticipantMoveRequestToStream=({body:{conference:e}})=>{const t={conference:e};this.events.trigger(g.PARTICIPANT_MOVE_REQUEST_TO_STREAM,t)};triggerAccountChangedNotify=()=>{this.events.trigger(g.ACCOUNT_CHANGED,{})};triggerAccountDeletedNotify=()=>{this.events.trigger(g.ACCOUNT_DELETED,{})};triggerConferenceParticipantTokenIssued=({body:{conference:e,participant:t,jwt:s}})=>{const r={conference:e,participant:t,jwt:s};this.events.trigger(g.CONFERENCE_PARTICIPANT_TOKEN_ISSUED,r)};maybeTriggerChannels=e=>{const t=e.getHeader(u.INPUT_CHANNELS),s=e.getHeader(u.OUTPUT_CHANNELS);if(t&&s){const r={inputChannels:t,outputChannels:s};this.events.trigger(g.CHANNELS,r)}};triggerEnterRoom=e=>{const t=e.getHeader(u.CONTENT_ENTER_ROOM),s=e.getHeader(u.PARTICIPANT_NAME);this.events.trigger(g.ENTER_ROOM,{room:t,participantName:s})};triggerShareState=e=>{const t=e.getHeader(u.CONTENT_SHARE_STATE);if(t!==void 0)switch(t){case F.AVAILABLE_SECOND_REMOTE_STREAM:{this.events.trigger(g.AVAILABLE_SECOND_REMOTE_STREAM,{});break}case F.NOT_AVAILABLE_SECOND_REMOTE_STREAM:{this.events.trigger(g.NOT_AVAILABLE_SECOND_REMOTE_STREAM,{});break}case F.MUST_STOP_PRESENTATION:{this.events.trigger(g.MUST_STOP_PRESENTATION,{});break}}};maybeTriggerParticipantMoveRequest=e=>{const t=e.getHeader(u.CONTENT_PARTICIPANT_STATE);t===H.SPECTATOR&&this.events.trigger(g.PARTICIPANT_MOVE_REQUEST_TO_SPECTATORS,{}),t===H.PARTICIPANT&&this.events.trigger(g.PARTICIPANT_MOVE_REQUEST_TO_PARTICIPANTS,{})};triggerMainCamControl=e=>{const t=e.getHeader(u.MAIN_CAM),s=e.getHeader(u.MEDIA_SYNC),r=s===x.ADMIN_SYNC_FORCED;if(t===f.ADMIN_START_MAIN_CAM){this.events.trigger(g.ADMIN_START_MAIN_CAM,{isSyncForced:r});return}if(t===f.ADMIN_STOP_MAIN_CAM){this.events.trigger(g.ADMIN_STOP_MAIN_CAM,{isSyncForced:r});return}(t===f.RESUME_MAIN_CAM||t===f.PAUSE_MAIN_CAM)&&s!==void 0&&this.events.trigger(g.ADMIN_FORCE_SYNC_MEDIA_STATE,{isSyncForced:r});const i=e.getHeader(u.MAIN_CAM_RESOLUTION);this.events.trigger(g.MAIN_CAM_CONTROL,{mainCam:t,resolutionMainCam:i})};triggerMicControl=e=>{const t=e.getHeader(u.MIC),r=e.getHeader(u.MEDIA_SYNC)===x.ADMIN_SYNC_FORCED;t===W.ADMIN_START_MIC?this.events.trigger(g.ADMIN_START_MIC,{isSyncForced:r}):t===W.ADMIN_STOP_MIC&&this.events.trigger(g.ADMIN_STOP_MIC,{isSyncForced:r})};triggerUseLicense=e=>{const t=e.getHeader(u.CONTENT_USE_LICENSE);this.events.trigger(g.USE_LICENSE,t)};triggerRestart=e=>{const t=e.getHeader(u.TRACKS_DIRECTION),s=Number(e.getHeader(u.AUDIO_TRACK_COUNT)),r=Number(e.getHeader(u.VIDEO_TRACK_COUNT)),i={tracksDirection:t,audioTrackCount:s,videoTrackCount:r};this.events.trigger(g.RESTART,i)}}var R=(n=>(n.PEER_CONNECTION="peerconnection",n.CONNECTING="connecting",n.SENDING="sending",n.PROGRESS="progress",n.ACCEPTED="accepted",n.CONFIRMED="confirmed",n.ENDED="ended",n.FAILED="failed",n.NEW_DTMF="newDTMF",n.NEW_INFO="newInfo",n.HOLD="hold",n.UNHOLD="unhold",n.MUTED="muted",n.UNMUTED="unmuted",n.REINVITE="reinvite",n.UPDATE="update",n.REFER="refer",n.REPLACES="replaces",n.SDP="sdp",n.ICE_CANDIDATE="icecandidate",n.GET_USER_MEDIA_FAILED="getusermediafailed",n.PEER_CONNECTION_CREATE_OFFER_FAILED="peerconnection:createofferfailed",n.PEER_CONNECTION_CREATE_ANSWER_FAILED="peerconnection:createanswerfailed",n.PEER_CONNECTION_SET_LOCAL_DESCRIPTION_FAILED="peerconnection:setlocaldescriptionfailed",n.PEER_CONNECTION_SET_REMOTE_DESCRIPTION_FAILED="peerconnection:setremotedescriptionfailed",n.START_PRESENTATION="presentation:start",n.STARTED_PRESENTATION="presentation:started",n.END_PRESENTATION="presentation:end",n.ENDED_PRESENTATION="presentation:ended",n.FAILED_PRESENTATION="presentation:failed",n.PEER_CONNECTION_CONFIRMED="peerconnection:confirmed",n.PEER_CONNECTION_ONTRACK="peerconnection:ontrack",n.ENDED_FROM_SERVER="ended:fromserver",n.CALL_STATUS_CHANGED="call-status-changed",n))(R||{}),oe=(n=>(n.LOCAL="local",n.REMOTE="remote",n.SYSTEM="system",n))(oe||{});const ce=["peerconnection","connecting","sending","progress","accepted","confirmed","ended","failed","newInfo","newDTMF","presentation:start","presentation:started","presentation:end","presentation:ended","presentation:failed","reinvite","update","refer","replaces","sdp","icecandidate","getusermediafailed","peerconnection:createofferfailed","peerconnection:createanswerfailed","peerconnection:setlocaldescriptionfailed","peerconnection:setremotedescriptionfailed"],Fe=["peerconnection:confirmed","peerconnection:ontrack","ended:fromserver","call-status-changed"],he=[...ce,...Fe];function ke(n){return e=>`sip:${e}@${n}`}const $e=(n,e)=>()=>Math.floor(Math.random()*(e-n))+n,de=n=>n.trim().replaceAll(" ","_"),qe=$e(1e5,99999999),Ve=n=>n.some(t=>{const{kind:s}=t;return s==="video"});class He{isPendingCall=!1;isPendingAnswer=!1;rtcSession;remoteStreams={};events;callConfiguration={};constructor(e){this.events=e}}const We=(n,e)=>{n.getVideoTracks().forEach(s=>{"contentHint"in s&&s.contentHint!==e&&(s.contentHint=e)})},L=(n,{directionVideo:e,directionAudio:t,contentHint:s}={})=>{if(!n||e==="recvonly"&&t==="recvonly")return;const r=t==="recvonly"?[]:n.getAudioTracks(),i=e==="recvonly"?[]:n.getVideoTracks(),a=[...r,...i],o=new MediaStream(a);return o.getTracks=()=>[...o.getAudioTracks(),...o.getVideoTracks()],s&&s!=="none"&&We(o,s),o};var X=(n=>(n.BYE="Terminated",n.WEBRTC_ERROR="WebRTC Error",n.CANCELED="Canceled",n.REQUEST_TIMEOUT="Request Timeout",n.REJECTED="Rejected",n.REDIRECTED="Redirected",n.UNAVAILABLE="Unavailable",n.NOT_FOUND="Not Found",n.ADDRESS_INCOMPLETE="Address Incomplete",n.INCOMPATIBLE_SDP="Incompatible SDP",n.BAD_MEDIA_DESCRIPTION="Bad Media Description",n))(X||{});class xe{events;rtcSession;disposers=new Set;onReset;constructor(e,{onReset:t}){this.events=e,this.onReset=t,e.on(R.FAILED,this.handleEnded),e.on(R.ENDED,this.handleEnded)}get connection(){return this.rtcSession?.connection}get isCallActive(){return this.rtcSession?.isEstablished()===!0}getEstablishedRTCSession=()=>this.rtcSession?.isEstablished()===!0?this.rtcSession:void 0;startCall=async(e,t,{number:s,mediaStream:r,extraHeaders:i=[],ontrack:a,iceServers:o,directionVideo:h,directionAudio:d,contentHint:T,offerToReceiveAudio:S=!0,offerToReceiveVideo:l=!0,degradationPreference:A,sendEncodings:p,onAddedTransceiver:N})=>new Promise((M,$)=>{this.handleCall({ontrack:a}).then(M).catch(q=>{$(q)}),this.rtcSession=e.call(t(s),{mediaStream:L(r,{directionVideo:h,directionAudio:d,contentHint:T}),pcConfig:{iceServers:o},rtcOfferConstraints:{offerToReceiveAudio:S,offerToReceiveVideo:l},eventHandlers:this.events.triggers,extraHeaders:i,directionVideo:h,directionAudio:d,degradationPreference:A,sendEncodings:p,onAddedTransceiver:N})});async endCall(){const{rtcSession:e}=this;if(e&&!e.isEnded())return e.terminateAsync({cause:X.CANCELED}).finally(()=>{this.reset()});this.reset()}answerToIncomingCall=async(e,{mediaStream:t,ontrack:s,extraHeaders:r=[],iceServers:i,directionVideo:a,directionAudio:o,offerToReceiveAudio:h,offerToReceiveVideo:d,contentHint:T,degradationPreference:S,sendEncodings:l,onAddedTransceiver:A})=>new Promise((p,N)=>{try{this.rtcSession=e,this.subscribeToSessionEvents(e),this.handleCall({ontrack:s}).then(p).catch(M=>{N(M)}),e.answer({pcConfig:{iceServers:i},rtcOfferConstraints:{offerToReceiveAudio:h,offerToReceiveVideo:d},mediaStream:L(t,{directionVideo:a,directionAudio:o,contentHint:T}),extraHeaders:r,directionVideo:a,directionAudio:o,degradationPreference:S,sendEncodings:l,onAddedTransceiver:A})}catch(M){N(M)}});getRemoteTracks(){return this.connection?this.connection.getReceivers().map(({track:s})=>s):void 0}async replaceMediaStream(e,t){if(!this.rtcSession)throw new Error("No rtcSession established");const{contentHint:s}=t??{},r=L(e,{contentHint:s});if(r===void 0)throw new Error("No preparedMediaStream");return this.rtcSession.replaceMediaStream(r,t)}async restartIce(e){if(!this.rtcSession)throw new Error("No rtcSession established");return this.rtcSession.restartIce(e)}async addTransceiver(e,t){if(!this.rtcSession)throw new Error("No rtcSession established");return this.rtcSession.addTransceiver(e,t)}handleCall=async({ontrack:e})=>new Promise((t,s)=>{const r=()=>{this.events.on(R.PEER_CONNECTION,T),this.events.on(R.CONFIRMED,S)},i=()=>{this.events.off(R.PEER_CONNECTION,T),this.events.off(R.CONFIRMED,S)},a=()=>{this.events.on(R.FAILED,h),this.events.on(R.ENDED,h)},o=()=>{this.events.off(R.FAILED,h),this.events.off(R.ENDED,h)},h=l=>{i(),o(),s(l)};let d;const T=({peerconnection:l})=>{d=l;const A=p=>{this.events.trigger(R.PEER_CONNECTION_ONTRACK,p),e&&e(p)};l.addEventListener("track",A),this.disposers.add(()=>{l.removeEventListener("track",A)})},S=()=>{d!==void 0&&this.events.trigger(R.PEER_CONNECTION_CONFIRMED,d),i(),o(),t(d)};r(),a()});subscribeToSessionEvents(e){this.events.eachTriggers((t,s)=>{const r=ce.find(i=>i===s);r&&(e.on(r,t),this.disposers.add(()=>{e.off(r,t)}))})}unsubscribeFromSessionEvents(){this.disposers.forEach(e=>{e()}),this.disposers.clear()}handleEnded=e=>{const{originator:t}=e;t==="remote"&&this.events.trigger(R.ENDED_FROM_SERVER,e),this.reset()};reset=()=>{delete this.rtcSession,this.unsubscribeFromSessionEvents(),this.onReset()}}class Ge{remoteStreams={};reset(){this.remoteStreams={}}generateStream(e,t){const{id:s}=e,r=this.remoteStreams[s]??new MediaStream;return t&&r.addTrack(t),r.addTrack(e),this.remoteStreams[s]=r,r}generateAudioStream(e){const{id:t}=e,s=this.remoteStreams[t]??new MediaStream;return s.addTrack(e),this.remoteStreams[t]=s,s}generateStreams(e){const t=[];return e.forEach((s,r)=>{if(s.kind==="audio")return;const i=s,a=e[r-1];let o;a?.kind==="audio"&&(o=a);const h=this.generateStream(i,o);t.push(h)}),t}generateAudioStreams(e){return e.map(t=>this.generateAudioStream(t))}}class Qe extends He{remoteStreamsManager=new Ge;mcuSession;constructor(e){super(e),this.mcuSession=new xe(e,{onReset:this.reset})}get requested(){return this.isPendingCall||this.isPendingAnswer}get connection(){return this.mcuSession.connection}get isCallActive(){return this.mcuSession.isCallActive}getEstablishedRTCSession=()=>this.mcuSession.getEstablishedRTCSession();startCall=async(e,t,s)=>(this.isPendingCall=!0,this.callConfiguration.number=s.number,this.callConfiguration.answer=!1,this.mcuSession.startCall(e,t,s).finally(()=>{this.isPendingCall=!1}));async endCall(){return this.mcuSession.endCall()}answerToIncomingCall=async(e,t)=>{this.isPendingAnswer=!0;const s=e();return this.callConfiguration.answer=!0,this.callConfiguration.number=s.remote_identity.uri.user,this.mcuSession.answerToIncomingCall(s,t).finally(()=>{this.isPendingAnswer=!1})};getCallConfiguration(){return{...this.callConfiguration}}getRemoteStreams(){const e=this.mcuSession.getRemoteTracks();if(e)return Ve(e)?this.remoteStreamsManager.generateStreams(e):this.remoteStreamsManager.generateAudioStreams(e)}async replaceMediaStream(e,t){return this.mcuSession.replaceMediaStream(e,t)}async restartIce(e){return this.mcuSession.restartIce(e)}async addTransceiver(e,t){return this.mcuSession.addTransceiver(e,t)}reset=()=>{this.remoteStreamsManager.reset(),this.callConfiguration.number=void 0,this.callConfiguration.answer=!1}}class Ye{events;strategy;constructor(e){this.events=new y.TypedEvents(he),this.strategy=e??new Qe(this.events),this.subscribeCallStatusChange()}get requested(){return this.strategy.requested}get connection(){return this.strategy.connection}get isCallActive(){return this.strategy.isCallActive}getEstablishedRTCSession=()=>this.strategy.getEstablishedRTCSession();on(e,t){return this.events.on(e,t)}onRace(e,t){return this.events.onRace(e,t)}once(e,t){return this.events.once(e,t)}onceRace(e,t){return this.events.onceRace(e,t)}async wait(e){return this.events.wait(e)}off(e,t){this.events.off(e,t)}setStrategy(e){this.strategy=e}startCall=async(...e)=>this.strategy.startCall(...e);endCall=async()=>this.strategy.endCall();answerToIncomingCall=async(...e)=>this.strategy.answerToIncomingCall(...e);getCallConfiguration=()=>this.strategy.getCallConfiguration();getRemoteStreams=()=>this.strategy.getRemoteStreams();addTransceiver=async(...e)=>this.strategy.addTransceiver(...e);replaceMediaStream=async(...e)=>this.strategy.replaceMediaStream(...e);restartIce=async e=>this.strategy.restartIce(e);subscribeCallStatusChange(){let{isCallActive:e}=this;const{ACCEPTED:t,CONFIRMED:s,ENDED:r,FAILED:i}=R;this.onRace([t,s,r,i],()=>{e=this.maybeTriggerCallStatus(e)})}maybeTriggerCallStatus(e){const t=this.isCallActive;return t!==e&&this.events.trigger(R.CALL_STATUS_CHANGED,{isCallActive:t}),t}}const ze=(n,e)=>(n.degradationPreference=e.degradationPreference,n),Xe=(n,e)=>{n.encodings??=[];for(let t=n.encodings.length;t<e;t+=1)n.encodings.push({});return n},le=n=>(e,t)=>t!==void 0&&e!==t||t===void 0&&e!==n,Je=le(),Ke=(n,e)=>{if(Je(n,e))return n},je=(n,e)=>{const t=n.maxBitrate,s=Ke(e,t);return s!==void 0&&(n.maxBitrate=s),n},ue=1,Ze=le(ue),et=(n,e)=>{const t=n===void 0?void 0:Math.max(n,ue);if(t!==void 0&&Ze(t,e))return t},tt=(n,e)=>{const t=n.scaleResolutionDownBy,s=et(e,t);return s!==void 0&&(n.scaleResolutionDownBy=s),n},nt=(n,e)=>{const t=e.encodings?.length??0;return Xe(n,t),n.encodings.forEach((s,r)=>{const i=(e?.encodings??[])[r],a=i?.maxBitrate,o=i?.scaleResolutionDownBy;je(s,a),tt(s,o)}),n},st=(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},ge=async(n,e)=>{const t=n.getParameters(),s=JSON.parse(JSON.stringify(t));nt(t,e),ze(t,e);const r=st(s,t);return r&&await n.setParameters(t),{parameters:t,isChanged:r}},J=async(n,e,t)=>{const{isChanged:s,parameters:r}=await ge(n,{encodings:[{scaleResolutionDownBy:e.scaleResolutionDownBy,maxBitrate:e.maxBitrate}]});return s&&t&&t(r),{isChanged:s,parameters:r}},rt=(n,e)=>n.find(t=>t.track!==null&&e.getTracks().includes(t.track)),it=async(n,e,t)=>{const s=rt(n,e);if(s)return J(s,{maxBitrate:t})};var O=(n=>(n.START_PRESENTATION="presentation:start",n.STARTED_PRESENTATION="presentation:started",n.END_PRESENTATION="presentation:end",n.ENDED_PRESENTATION="presentation:ended",n.FAILED_PRESENTATION="presentation:failed",n))(O||{});const Te=["presentation:start","presentation:started","presentation:end","presentation:ended","presentation:failed"],at=1,ot=n=>Q.hasCanceledError(n);class ct{events;promisePendingStartPresentation;promisePendingStopPresentation;streamPresentationCurrent;maxBitrate;cancelableSendPresentationWithRepeatedCalls;callManager;constructor({callManager:e,maxBitrate:t}){this.callManager=e,this.maxBitrate=t,this.events=new y.TypedEvents(Te),this.subscribe()}get isPendingPresentation(){return!!this.promisePendingStartPresentation||!!this.promisePendingStopPresentation}async startPresentation(e,t,{isNeedReinvite:s,contentHint:r,sendEncodings:i,onAddedTransceiver:a}={},o){const h=this.getRtcSessionProtected();if(this.streamPresentationCurrent)throw new Error("Presentation is already started");return this.sendPresentationWithDuplicatedCalls(e,{rtcSession:h,stream:t,presentationOptions:{isNeedReinvite:s,contentHint:r,sendEncodings:i,onAddedTransceiver:a},options:o})}async stopPresentation(e){this.cancelSendPresentationWithRepeatedCalls();const t=this.streamPresentationCurrent;let s=this.promisePendingStartPresentation??Promise.resolve(void 0);this.promisePendingStartPresentation&&await this.promisePendingStartPresentation.catch(()=>{});const r=this.callManager.getEstablishedRTCSession();return r&&t?s=e().then(async()=>r.stopPresentation(t)).catch(i=>{const a=i instanceof Error?i:new Error(String(i));throw this.events.trigger(O.FAILED_PRESENTATION,a),i}):t&&this.events.trigger(O.ENDED_PRESENTATION,t),this.promisePendingStopPresentation=s,s.finally(()=>{this.resetPresentation()})}async updatePresentation(e,t,{contentHint:s,sendEncodings:r,onAddedTransceiver:i}={}){const a=this.getRtcSessionProtected();if(!this.streamPresentationCurrent)throw new Error("Presentation has not started yet");return this.promisePendingStartPresentation&&await this.promisePendingStartPresentation,this.sendPresentation(e,a,t,{contentHint:s,isNeedReinvite:!1,sendEncodings:r,onAddedTransceiver:i}).then(async o=>(await this.setMaxBitrate(),o))}cancelSendPresentationWithRepeatedCalls(){this.cancelableSendPresentationWithRepeatedCalls?.stopRepeatedCalls()}on(e,t){return this.events.on(e,t)}once(e,t){return this.events.once(e,t)}onceRace(e,t){return this.events.onceRace(e,t)}async wait(e){return this.events.wait(e)}off(e,t){this.events.off(e,t)}subscribe(){this.callManager.on("presentation:start",e=>{this.events.trigger(O.START_PRESENTATION,e)}),this.callManager.on("presentation:started",e=>{this.events.trigger(O.STARTED_PRESENTATION,e)}),this.callManager.on("presentation:end",e=>{this.events.trigger(O.END_PRESENTATION,e)}),this.callManager.on("presentation:ended",e=>{this.events.trigger(O.ENDED_PRESENTATION,e)}),this.callManager.on("presentation:failed",e=>{this.events.trigger(O.FAILED_PRESENTATION,e)}),this.callManager.on("failed",this.handleEnded),this.callManager.on("ended",this.handleEnded)}async sendPresentationWithDuplicatedCalls(e,{rtcSession:t,stream:s,presentationOptions:r,options:i={callLimit:at}}){const a=async()=>this.sendPresentation(e,t,s,r),o=()=>!!this.streamPresentationCurrent;return this.cancelableSendPresentationWithRepeatedCalls=Q.repeatedCallsAsync({targetFunction:a,isComplete:o,isRejectAsValid:!0,...i}),this.cancelableSendPresentationWithRepeatedCalls.then(h=>h)}async sendPresentation(e,t,s,{isNeedReinvite:r=!0,contentHint:i="detail",degradationPreference:a,sendEncodings:o,onAddedTransceiver:h}){const d=L(s,{contentHint:i});if(d===void 0)throw new Error("No streamPresentationTarget");this.streamPresentationCurrent=d;const T=e().then(async()=>t.startPresentation(d,r,{degradationPreference:a,sendEncodings:o,onAddedTransceiver:h})).then(this.setMaxBitrate).then(()=>s).catch(S=>{this.removeStreamPresentationCurrent();const l=S instanceof Error?S:new Error(String(S));throw this.events.trigger(O.FAILED_PRESENTATION,l),S});return this.promisePendingStartPresentation=T,T.finally(()=>{this.promisePendingStartPresentation=void 0})}setMaxBitrate=async()=>{const{connection:e}=this.callManager,{streamPresentationCurrent:t}=this,{maxBitrate:s}=this;if(!e||!t||s===void 0)return;const r=e.getSenders();await it(r,t,s)};getRtcSessionProtected=()=>{const e=this.callManager.getEstablishedRTCSession();if(!e)throw new Error("No rtcSession established");return e};handleEnded=()=>{this.reset()};reset(){this.cancelSendPresentationWithRepeatedCalls(),this.resetPresentation()}resetPresentation(){this.removeStreamPresentationCurrent(),this.promisePendingStartPresentation=void 0,this.promisePendingStopPresentation=void 0}removeStreamPresentationCurrent(){delete this.streamPresentationCurrent}}class ht{data;getUa;constructor(e){this.getUa=e.getUa}isConfigured(){return this.getUa()!==void 0}get(){if(this.data!==void 0)return{...this.data}}set(e){if(e===void 0){this.data=void 0;return}this.data={...e}}update(e,t){if(this.data===void 0)throw new Error("data is not exist");this.data[e]=t}clear(){this.data=void 0}isRegister(){return this.data?.register===!0}getSipServerUrl(){return this.data?.sipServerUrl}getDisplayName(){return this.data?.displayName}getUser(){return this.data?.user}getPassword(){return this.data?.password}isRegisterEnabled(){return this.data?.register===!0}}var C=(n=>(n.CONNECTING="connecting",n.CONNECTED="connected",n.DISCONNECTED="disconnected",n.DISCONNECTING="disconnecting",n.NEW_RTC_SESSION="newRTCSession",n.REGISTERED="registered",n.UNREGISTERED="unregistered",n.REGISTRATION_FAILED="registrationFailed",n.NEW_MESSAGE="newMessage",n.SIP_EVENT="sipEvent",n.CONNECT_STARTED="connect-started",n.CONNECT_SUCCEEDED="connect-succeeded",n.CONNECT_FAILED="connect-failed",n.CONNECT_PARAMETERS_RESOLVE_SUCCESS="connect-parameters-resolve-success",n.CONNECT_PARAMETERS_RESOLVE_FAILED="connect-parameters-resolve-failed",n.CONNECTED_WITH_CONFIGURATION="connected-with-configuration",n))(C||{});const Se=["connecting","connected","disconnected","newRTCSession","registered","unregistered","registrationFailed","newMessage","sipEvent"],dt=["disconnecting","connect-started","connect-succeeded","connect-failed","connect-parameters-resolve-success","connect-parameters-resolve-failed","connected-with-configuration"],Ce=[...Se,...dt],lt=3;class ut{cancelableConnectWithRepeatedCalls;JsSIP;events;uaFactory;stateMachine;registrationManager;getUa;setUa;getConnectionConfiguration;setConnectionConfiguration;updateConnectionConfiguration;setSipServerUrl;setSocket;constructor(e){this.JsSIP=e.JsSIP,this.events=e.events,this.uaFactory=e.uaFactory,this.stateMachine=e.stateMachine,this.registrationManager=e.registrationManager,this.getUa=e.getUa,this.setUa=e.setUa,this.getConnectionConfiguration=e.getConnectionConfiguration,this.setConnectionConfiguration=e.setConnectionConfiguration,this.updateConnectionConfiguration=e.updateConnectionConfiguration,this.setSipServerUrl=e.setSipServerUrl,this.setSocket=e.setSocket,this.proxyEvents()}connect=async(e,t)=>(this.cancelRequests(),this.connectWithDuplicatedCalls(e,t));set=async({displayName:e})=>new Promise((t,s)=>{const r=this.getUa();if(!r){s(new Error("this.ua is not initialized"));return}let i=!1;const a=this.getConnectionConfiguration();e!==void 0&&e!==a?.displayName&&(i=r.set("display_name",de(e)),this.updateConnectionConfiguration("displayName",e));const o=i;o?t(o):s(new Error("nothing changed"))});disconnect=async()=>{this.events.trigger(C.DISCONNECTING,{});const e=new Promise(s=>{this.events.once(C.DISCONNECTED,()=>{s()})}),t=this.getUa();return t?t.stop():this.events.trigger(C.DISCONNECTED,{socket:{},error:!1}),e.finally(()=>{this.setUa(void 0),this.stateMachine.reset()})};cancelRequests(){this.cancelConnectWithRepeatedCalls()}connectWithDuplicatedCalls=async(e,{callLimit:t=lt}={})=>{const s=async()=>this.connectInner(e),r=i=>{const h=this.getUa()?.isConnected()===!0&&this.hasEqualConnectionConfiguration(e),d=i!=null&&!Ue(i);return h||d};return this.stateMachine.startConnect(),this.cancelableConnectWithRepeatedCalls=Q.repeatedCallsAsync({targetFunction:s,isComplete:r,callLimit:t,isRejectAsValid:!0,isCheckBeforeCall:!1}),this.cancelableConnectWithRepeatedCalls.then(i=>{if("ua"in i&&i.ua instanceof this.JsSIP.UA)return i;throw i})};hasEqualConnectionConfiguration(e){const{configuration:t}=this.uaFactory.createConfiguration(e),r=this.getUa()?.configuration;return r?r.password===t.password&&r.register===t.register&&r.uri.toString()===t.uri&&r.display_name===t.display_name&&r.user_agent===t.user_agent&&r.sockets===t.sockets&&r.session_timers===t.session_timers&&r.register_expires===t.register_expires&&r.connection_recovery_min_interval===t.connection_recovery_min_interval&&r.connection_recovery_max_interval===t.connection_recovery_max_interval:!1}connectInner=async e=>this.initUa(e).then(async()=>this.start()).then(t=>{const s=this.getConnectionConfiguration();if(s===void 0)throw new Error("connectionConfiguration has not defined");return{...s,ua:t}});initUa=async({user:e,password:t,sipServerUrl:s,sipWebSocketServerURL:r,remoteAddress:i,sessionTimers:a,registerExpires:o,connectionRecoveryMinInterval:h,connectionRecoveryMaxInterval:d,userAgent:T,displayName:S="",register:l=!1,extraHeaders:A=[]})=>{this.stateMachine.startInitUa(),this.setConnectionConfiguration({sipServerUrl:s,displayName:S,register:l,user:e,password:t}),this.getUa()&&await this.disconnect();const{ua:N,helpers:M}=this.uaFactory.createUAWithConfiguration({user:e,password:t,sipServerUrl:s,sipWebSocketServerURL:r,displayName:S,register:l,sessionTimers:a,registerExpires:o,connectionRecoveryMinInterval:h,connectionRecoveryMaxInterval:d,userAgent:T,remoteAddress:i,extraHeaders:A},this.events);return this.setUa(N),this.setSipServerUrl(M.getSipServerUrl),this.setSocket(M.socket),N};start=async()=>new Promise((e,t)=>{const s=this.getUa();if(!s){t(new Error("this.ua is not initialized"));return}let r;r=((h,d)=>{if(this.getConnectionConfiguration()?.register===!0)return this.registrationManager.subscribeToStartEvents(h,d);const S=C.CONNECTED,l=[C.DISCONNECTED];return this.events.on(S,h),l.forEach(A=>{this.events.on(A,d)}),()=>{this.events.off(S,h),l.forEach(A=>{this.events.off(A,d)})}})(()=>{r?.(),e(s)},h=>{r?.(),t(h)}),s.start()});cancelConnectWithRepeatedCalls(){this.cancelableConnectWithRepeatedCalls?.cancel()}proxyEvents(){this.events.on(C.CONNECTED,()=>{const e=this.getConnectionConfiguration(),t=this.getUa();e!==void 0&&t!==void 0&&this.events.trigger(C.CONNECTED_WITH_CONFIGURATION,{...e,ua:t})})}}var Ee=(n=>(n.START_CONNECT="START_CONNECT",n.START_INIT_UA="START_INIT_UA",n.UA_CONNECTED="UA_CONNECTED",n.UA_REGISTERED="UA_REGISTERED",n.UA_UNREGISTERED="UA_UNREGISTERED",n.UA_DISCONNECTED="UA_DISCONNECTED",n.CONNECTION_FAILED="CONNECTION_FAILED",n.RESET="RESET",n))(Ee||{});const gt=re.setup({types:{context:{},events:{}},actions:{logTransition:(n,e)=>{c(`State transition: ${e.from} -> ${e.to} (${e.event})`)},logStateChange:(n,e)=>{c("ConnectionStateMachine state changed",e.state)}}}).createMachine({id:"connection",initial:"idle",context:{},states:{idle:{entry:{type:"logStateChange",params:{state:"idle"}},on:{START_CONNECT:{target:"connecting",actions:{type:"logTransition",params:{from:"idle",to:"connecting",event:"START_CONNECT"}}}}},connecting:{entry:{type:"logStateChange",params:{state:"connecting"}},on:{START_INIT_UA:{target:"initializing",actions:{type:"logTransition",params:{from:"connecting",to:"initializing",event:"START_INIT_UA"}}},UA_DISCONNECTED:{target:"disconnected",actions:{type:"logTransition",params:{from:"connecting",to:"disconnected",event:"UA_DISCONNECTED"}}},CONNECTION_FAILED:{target:"failed",actions:{type:"logTransition",params:{from:"connecting",to:"failed",event:"CONNECTION_FAILED"}}}}},initializing:{entry:{type:"logStateChange",params:{state:"initializing"}},on:{UA_CONNECTED:{target:"connected",actions:{type:"logTransition",params:{from:"initializing",to:"connected",event:"UA_CONNECTED"}}},UA_REGISTERED:{target:"registered",actions:{type:"logTransition",params:{from:"initializing",to:"registered",event:"UA_REGISTERED"}}},UA_DISCONNECTED:{target:"disconnected",actions:{type:"logTransition",params:{from:"initializing",to:"disconnected",event:"UA_DISCONNECTED"}}},CONNECTION_FAILED:{target:"failed",actions:{type:"logTransition",params:{from:"initializing",to:"failed",event:"CONNECTION_FAILED"}}}}},connected:{entry:{type:"logStateChange",params:{state:"connected"}},on:{UA_REGISTERED:{target:"registered",actions:{type:"logTransition",params:{from:"connected",to:"registered",event:"UA_REGISTERED"}}},UA_DISCONNECTED:{target:"disconnected",actions:{type:"logTransition",params:{from:"connected",to:"disconnected",event:"UA_DISCONNECTED"}}},CONNECTION_FAILED:{target:"failed",actions:{type:"logTransition",params:{from:"connected",to:"failed",event:"CONNECTION_FAILED"}}}}},registered:{entry:{type:"logStateChange",params:{state:"registered"}},on:{UA_UNREGISTERED:{target:"connected",actions:{type:"logTransition",params:{from:"registered",to:"connected",event:"UA_UNREGISTERED"}}},UA_DISCONNECTED:{target:"disconnected",actions:{type:"logTransition",params:{from:"registered",to:"disconnected",event:"UA_DISCONNECTED"}}},CONNECTION_FAILED:{target:"failed",actions:{type:"logTransition",params:{from:"registered",to:"failed",event:"CONNECTION_FAILED"}}}}},disconnected:{entry:{type:"logStateChange",params:{state:"disconnected"}},on:{RESET:{target:"idle",actions:{type:"logTransition",params:{from:"disconnected",to:"idle",event:"RESET"}}},START_CONNECT:{target:"connecting",actions:{type:"logTransition",params:{from:"disconnected",to:"connecting",event:"START_CONNECT"}}}}},failed:{entry:{type:"logStateChange",params:{state:"failed"}},on:{RESET:{target:"idle",actions:{type:"logTransition",params:{from:"failed",to:"idle",event:"RESET"}}},START_CONNECT:{target:"connecting",actions:{type:"logTransition",params:{from:"failed",to:"connecting",event:"START_CONNECT"}}}}}}});class Tt{actor;stateChangeListeners=new Set;events;unsubscribeFromEvents;actorSubscription;constructor(e){this.events=e,this.actor=re.createActor(gt),this.actorSubscription=this.actor.subscribe(t=>{const s=t.value;this.stateChangeListeners.forEach(r=>{r(s)})}),this.actor.start(),this.subscribeToEvents()}get state(){return this.actor.getSnapshot().value}get isIdle(){return this.hasState("idle")}get isConnecting(){return this.hasState("connecting")}get isInitializing(){return this.hasState("initializing")}get isConnected(){return this.hasState("connected")}get isRegistered(){return this.hasState("registered")}get isDisconnected(){return this.hasState("disconnected")}get isFailed(){return this.hasState("failed")}get isPending(){return this.isConnecting||this.isInitializing}get isPendingConnect(){return this.isConnecting}get isPendingInitUa(){return this.isInitializing}get isActiveConnection(){return this.isConnected||this.isRegistered}startConnect(){this.toStartConnect()}startInitUa(){this.toStartInitUa()}reset(){this.toIdle()}destroy(){this.unsubscribeFromEvents?.(),this.actorSubscription?.unsubscribe(),this.actor.stop()}onStateChange(e){return this.stateChangeListeners.add(e),()=>{this.stateChangeListeners.delete(e)}}canTransition(e){return this.actor.getSnapshot().can({type:e})}getValidEvents(){return Object.values(Ee).filter(e=>this.canTransition(e))}hasState(e){return this.actor.getSnapshot().matches(e)}sendEvent(e){const t=this.actor.getSnapshot(),s={type:e};if(!t.can(s)){c(`Invalid transition: ${s.type} from ${this.state}. Event cannot be processed in current state.`);return}this.actor.send(s)}toStartConnect=()=>{this.sendEvent("START_CONNECT")};toStartInitUa=()=>{this.sendEvent("START_INIT_UA")};toConnected=()=>{this.sendEvent("UA_CONNECTED")};toRegistered=()=>{this.sendEvent("UA_REGISTERED")};toUnregistered=()=>{this.sendEvent("UA_UNREGISTERED")};toDisconnected=()=>{this.sendEvent("UA_DISCONNECTED")};toFailed=()=>{this.sendEvent("CONNECTION_FAILED")};toIdle=()=>{this.sendEvent("RESET")};subscribeToEvents(){this.events.on("connected",this.toConnected),this.events.on("registered",this.toRegistered),this.events.on("unregistered",this.toUnregistered),this.events.on("disconnected",this.toDisconnected),this.events.on("registrationFailed",this.toFailed),this.unsubscribeFromEvents=()=>{this.events.off("connected",this.toConnected),this.events.off("registered",this.toRegistered),this.events.off("unregistered",this.toUnregistered),this.events.off("disconnected",this.toDisconnected),this.events.off("registrationFailed",this.toFailed)}}}class St{events;getUaProtected;constructor(e){this.events=e.events,this.getUaProtected=e.getUaProtected}async register(){const e=this.getUaProtected();return new Promise((t,s)=>{e.on(C.REGISTERED,t),e.on(C.REGISTRATION_FAILED,s),e.register()})}async unregister(){const e=this.getUaProtected();return new Promise(t=>{e.on(C.UNREGISTERED,t),e.unregister()})}async tryRegister(){try{await this.unregister()}catch(e){c("tryRegister",e)}return this.register()}subscribeToStartEvents(e,t){const s=C.REGISTERED,r=[C.REGISTRATION_FAILED,C.DISCONNECTED];return this.events.on(s,e),r.forEach(i=>{this.events.on(i,t)}),()=>{this.events.off(s,e),r.forEach(i=>{this.events.off(i,t)})}}}class Ct{uaFactory;getUaProtected;constructor(e){this.uaFactory=e.uaFactory,this.getUaProtected=e.getUaProtected}async sendOptions(e,t,s){const r=this.getUaProtected();return new Promise((i,a)=>{try{r.sendOptions(e,t,{extraHeaders:s,eventHandlers:{succeeded:()=>{i()},failed:a}})}catch(o){a(o)}})}async ping(e,t){const r=this.getUaProtected().configuration.uri;return this.sendOptions(r,e,t)}async checkTelephony({userAgent:e,displayName:t,sipServerUrl:s,sipWebSocketServerURL:r,remoteAddress:i,extraHeaders:a}){return new Promise((o,h)=>{const{configuration:d}=this.uaFactory.createConfiguration({sipWebSocketServerURL:r,displayName:t,userAgent:e,sipServerUrl:s}),T=this.uaFactory.createUA({...d,remoteAddress:i,extraHeaders:a}),S=()=>{const A=new Error("Telephony is not available");h(A)};T.once(C.DISCONNECTED,S);const l=()=>{T.removeAllListeners(),T.once(C.DISCONNECTED,()=>{o()}),T.stop()};T.once(C.CONNECTED,l),T.start()})}}const Et=n=>{const e=[];return n!==void 0&&n!==""&&e.push(`X-Vinteo-Remote: ${n}`),e};class b{JsSIP;constructor(e){this.JsSIP=e}static isRegisteredUA(e){return!!e&&e.isRegistered()}static validateParametersConnection({register:e,password:t,user:s,sipServerUrl:r,sipWebSocketServerURL:i}){if(!r)throw new Error("sipServerUrl is required");if(!i)throw new Error("sipWebSocketServerURL is required");if(e&&(t===void 0||t===""))throw new Error("password is required for authorized connection");if(e&&(s===void 0||s===""))throw new Error("user is required for authorized connection")}static resolveAuthorizationUser(e,t){return e&&t!==void 0&&t.trim()!==""?t.trim():`${qe()}`}static buildExtraHeaders(e,t){const s=e!==void 0&&e!==""?Et(e):[];return t===void 0?s:[...s,...t]}createConfiguration({user:e,password:t,sipWebSocketServerURL:s,displayName:r="",sipServerUrl:i,register:a=!1,sessionTimers:o=!1,registerExpires:h=300,connectionRecoveryMinInterval:d=2,connectionRecoveryMaxInterval:T=6,userAgent:S}){b.validateParametersConnection({register:a,password:t,user:e,sipServerUrl:i,sipWebSocketServerURL:s});const l=b.resolveAuthorizationUser(a,e),A=ke(i),p=A(l),N=new this.JsSIP.WebSocketInterface(s);return{configuration:{password:t,register:a,uri:p,display_name:de(r),user_agent:S,sdpSemantics:"unified-plan",sockets:[N],session_timers:o,register_expires:h,connection_recovery_min_interval:d,connection_recovery_max_interval:T},helpers:{socket:N,getSipServerUrl:A}}}createUA({remoteAddress:e,extraHeaders:t,...s}){const r=new this.JsSIP.UA(s),i=b.buildExtraHeaders(e,t);return i.length>0&&r.registrator().setExtraHeaders(i),r}createUAWithConfiguration(e,t){const{configuration:s,helpers:r}=this.createConfiguration(e),i=this.createUA({...s,remoteAddress:e.remoteAddress,extraHeaders:e.extraHeaders});return t.eachTriggers((a,o)=>{const h=Se.find(d=>d===o);h&&i.on(h,a)}),{ua:i,helpers:r}}}const Ae="Not ready for connection",Re=n=>n instanceof Error&&n.message===Ae,At=()=>new Error(Ae),Rt=async n=>typeof n=="function"?n():n;class Nt{events;ua;socket;uaFactory;registrationManager;stateMachine;connectionFlow;sipOperations;configurationManager;JsSIP;constructor({JsSIP:e}){this.JsSIP=e,this.events=new y.TypedEvents(Ce),this.uaFactory=new b(e),this.registrationManager=new St({events:this.events,getUaProtected:this.getUaProtected}),this.stateMachine=new Tt(this.events),this.configurationManager=new ht({getUa:this.getUa}),this.sipOperations=new Ct({uaFactory:this.uaFactory,getUaProtected:this.getUaProtected}),this.connectionFlow=new ut({JsSIP:this.JsSIP,events:this.events,uaFactory:this.uaFactory,stateMachine:this.stateMachine,registrationManager:this.registrationManager,getUa:this.getUa,getConnectionConfiguration:this.getConnectionConfiguration,setConnectionConfiguration:t=>{this.configurationManager.set(t)},updateConnectionConfiguration:(t,s)=>{this.configurationManager.update(t,s)},setUa:t=>{this.ua=t},setSipServerUrl:t=>{this.getSipServerUrl=t},setSocket:t=>{this.socket=t}})}get requested(){return this.stateMachine.isPending}get isPendingConnect(){return this.stateMachine.isPendingConnect}get isPendingInitUa(){return this.stateMachine.isPendingInitUa}get isIdle(){return this.stateMachine.isIdle}get isDisconnected(){return this.stateMachine.isDisconnected}get isFailed(){return this.stateMachine.isFailed}get connectionState(){return this.stateMachine.state}get isRegistered(){return b.isRegisteredUA(this.ua)}get isRegisterConfig(){return this.configurationManager.isRegister()}connect=async(e,t)=>this.disconnect().catch(s=>{c("connect: disconnect error",s)}).then(async()=>this.connectWithProcessError(e,t));set=async({displayName:e})=>this.connectionFlow.set({displayName:e});disconnect=async()=>{if(this.isConfigured())return this.connectionFlow.disconnect()};async register(){return this.registrationManager.register()}async unregister(){return this.registrationManager.unregister()}tryRegister=async()=>this.registrationManager.tryRegister();sendOptions=async(e,t,s)=>this.sipOperations.sendOptions(e,t,s);ping=async(e,t)=>this.sipOperations.ping(e,t);checkTelephony=async e=>this.sipOperations.checkTelephony(e);on(e,t){return this.events.on(e,t)}once(e,t){return this.events.once(e,t)}onceRace(e,t){return this.events.onceRace(e,t)}async wait(e){return this.events.wait(e)}off(e,t){this.events.off(e,t)}isConfigured(){return this.configurationManager.isConfigured()}getConnectionConfiguration=()=>this.configurationManager.get();destroy(){this.stateMachine.destroy()}getSipServerUrl=e=>e;getUaProtected=()=>{if(!this.ua)throw new Error("UA not initialized");return this.ua};getUa=()=>this.ua;connectWithProcessError=async(e,t)=>{if(!(t?.hasReadyForConnection?.()??!0))throw At();return this.processConnect(e,t).catch(async r=>{const i=r;return this.disconnect().then(()=>{throw i}).catch(()=>{throw i})})};processConnect=async(e,t)=>(this.events.trigger(C.CONNECT_STARTED,{}),Rt(e).then(s=>(this.events.trigger(C.CONNECT_PARAMETERS_RESOLVE_SUCCESS,s),s)).catch(s=>{throw this.events.trigger(C.CONNECT_PARAMETERS_RESOLVE_FAILED,s),s}).then(async s=>this.connectionFlow.connect(s,t)).then(s=>(this.events.trigger(C.CONNECT_SUCCEEDED,{...s}),s)).catch(s=>{const r=s??new Error("Failed to connect to server");throw this.events.trigger(C.CONNECT_FAILED,r),r}))}class mt{connectionManager;stackPromises=Y.createStackPromises({noRunIsNotActual:!0});constructor({connectionManager:e}){this.connectionManager=e}connect=async(...e)=>this.stackPromises.run(async()=>this.connectionManager.connect(...e));disconnect=async()=>this.stackPromises.run(async()=>this.connectionManager.disconnect());stop(){this.stackPromises.stop()}}const j=0,pt=30;class It{countInner=j;initialCount=j;limitInner=pt;isInProgress=!1;onStatusChange;constructor({onStatusChange:e}){this.onStatusChange=e}get count(){return this.countInner}get limit(){return this.limitInner}get isAttemptInProgress(){return this.isInProgress}hasLimitReached(){return this.countInner>=this.limitInner}startAttempt(){this.isInProgress||(this.isInProgress=!0,this.onStatusChange({isInProgress:this.isInProgress}))}finishAttempt(){this.isInProgress&&(this.isInProgress=!1,this.onStatusChange({isInProgress:this.isInProgress}))}increment(){this.count<this.limit&&(this.countInner+=1)}reset(){this.countInner=this.initialCount,this.finishAttempt()}}class _t{connectionManager;interval;checkTelephonyByTimeout=void 0;cancelableBeforeRequest=void 0;constructor({connectionManager:e,interval:t}){this.connectionManager=e,this.interval=t}start({onBeforeRequest:e,onSuccessRequest:t,onFailRequest:s}){this.stop(),this.cancelableBeforeRequest=new k.CancelableRequest(e),this.checkTelephonyByTimeout=D.resolveRequesterByTimeout({isDontStopOnFail:!0,requestInterval:this.interval,request:async()=>{if(!this.cancelableBeforeRequest)throw new Error("cancelableBeforeRequest is not defined");const r=await this.cancelableBeforeRequest.request();return this.connectionManager.checkTelephony(r)}}),this.checkTelephonyByTimeout.start(void 0,{onFailRequest:s,onSuccessRequest:()=>{this.stop(),t()}})}stop(){this.checkTelephonyByTimeout?.stop(),this.checkTelephonyByTimeout=void 0,this.cancelableBeforeRequest?.cancelRequest(),this.cancelableBeforeRequest=void 0}}var _=(n=>(n.BEFORE_ATTEMPT="before-attempt",n.SUCCESS="success",n.FAILED_ALL_ATTEMPTS="failed-all-attempts",n.CANCELLED_ATTEMPTS="cancelled-attempts",n.CHANGED_ATTEMPT_STATUS="changed-attempt-status",n.STOP_ATTEMPTS_BY_ERROR="stop-attempts-by-error",n.LIMIT_REACHED_ATTEMPTS="limit-reached-attempts",n))(_||{});const Ne=["before-attempt","success","failed-all-attempts","cancelled-attempts","changed-attempt-status","stop-attempts-by-error","limit-reached-attempts"],Mt=15e3,vt=2;class ft{connectionManager;pingServerByTimeoutWithFailCalls;constructor({connectionManager:e}){this.connectionManager=e,this.pingServerByTimeoutWithFailCalls=D.requesterByTimeoutsWithFailCalls(vt,{whenPossibleRequest:async()=>{},requestInterval:Mt,request:async()=>(c("ping"),this.connectionManager.ping().then(()=>{c("ping success")}))})}start({onFailRequest:e}){this.pingServerByTimeoutWithFailCalls.start(void 0,{onFailRequest:e}).catch(c)}stop(){this.pingServerByTimeoutWithFailCalls.stop()}}class Pt{callManager;pingServerRequester;disposeCallStatusChange;constructor({connectionManager:e,callManager:t}){this.callManager=t,this.pingServerRequester=new ft({connectionManager:e})}start({onFailRequest:e}){c("start"),this.disposeCallStatusChange=this.callManager.on("call-status-changed",()=>{this.handleCallStatusChange({onFailRequest:e})}),this.handleCallStatusChange({onFailRequest:e})}stop(){c("stop"),this.pingServerRequester.stop(),this.unsubscribeCallStatusChange()}unsubscribeCallStatusChange(){this.disposeCallStatusChange?.(),this.disposeCallStatusChange=void 0}handleCallStatusChange({onFailRequest:e}){this.callManager.isCallActive?this.pingServerRequester.stop():this.pingServerRequester.start({onFailRequest:e})}}class Ot{connectionManager;callManager;isRegistrationFailed=!1;disposers=[];constructor({connectionManager:e,callManager:t}){this.connectionManager=e,this.callManager=t}subscribe(e){this.unsubscribe(),this.disposers.push(this.connectionManager.on("registrationFailed",()=>{this.setIsRegistrationFailed()})),this.disposers.push(this.callManager.on("call-status-changed",({isCallActive:t})=>{!t&&this.isRegistrationFailed&&e()}))}unsubscribe(){this.disposers.forEach(e=>{e()}),this.disposers=[],this.resetIsRegistrationFailed()}setIsRegistrationFailed(){this.isRegistrationFailed=!0}resetIsRegistrationFailed(){this.isRegistrationFailed=!1}}const yt=3e3,bt=15e3,Z={LIMIT_REACHED:"Limit reached",FAILED_TO_RECONNECT:"Failed to reconnect"},Dt=async()=>{},wt=n=>!0;class Ut{events;connectionManager;connectionQueueManager;checkTelephonyRequester;pingServerIfNotActiveCallRequester;registrationFailedOutOfCallSubscriber;attemptsState;delayBetweenAttempts;cancelableRequestBeforeRetry;onBeforeRetry;canRetryOnError;networkInterfacesSubscriber;resumeFromSleepModeSubscriber;constructor({connectionQueueManager:e,connectionManager:t,callManager:s},r){const i=r?.onBeforeRetry??Dt,a=r?.canRetryOnError??wt;this.connectionQueueManager=e,this.connectionManager=t,this.onBeforeRetry=i,this.canRetryOnError=a,this.networkInterfacesSubscriber=r?.networkInterfacesSubscriber,this.resumeFromSleepModeSubscriber=r?.resumeFromSleepModeSubscriber,this.events=new y.TypedEvents(Ne),this.checkTelephonyRequester=new _t({connectionManager:t,interval:r?.checkTelephonyRequestInterval??bt}),this.pingServerIfNotActiveCallRequester=new Pt({connectionManager:t,callManager:s}),this.registrationFailedOutOfCallSubscriber=new Ot({connectionManager:t,callManager:s}),this.attemptsState=new It({onStatusChange:this.emitStatusChange}),this.cancelableRequestBeforeRetry=new k.CancelableRequest(i),this.delayBetweenAttempts=new D.DelayRequester(r?.timeoutBetweenAttempts??yt)}start(e){c("auto connector start"),this.restartConnectionAttempts(e),this.subscribeToHardwareTriggers(e)}stop(){c("auto connector stop"),this.unsubscribeFromHardwareTriggers(),this.stopConnectionFlow().catch(e=>{c("auto connector stop from stop method: error",e)})}on(e,t){return this.events.on(e,t)}once(e,t){return this.events.once(e,t)}onceRace(e,t){return this.events.onceRace(e,t)}async wait(e){return this.events.wait(e)}off(e,t){this.events.off(e,t)}restartConnectionAttempts(e){c("auto connector restart connection attempts"),this.stopConnectionFlow().then(async()=>this.attemptConnection(e)).catch(t=>{c("auto connector failed to restart connection attempts:",t)})}async stopConnectionFlow(){c("stopConnectionFlow"),this.stopAttempts(),this.stopConnectTriggers(),await this.connectionQueueManager.disconnect()}stopAttempts(){this.attemptsState.isAttemptInProgress&&this.connectionQueueManager.stop(),this.delayBetweenAttempts.cancelRequest(),this.cancelableRequestBeforeRetry.cancelRequest(),this.attemptsState.reset()}stopConnectTriggers(){c("stopConnectTriggers"),this.stopPingRequester(),this.checkTelephonyRequester.stop(),this.registrationFailedOutOfCallSubscriber.unsubscribe()}startCheckTelephony(e){c("startCheckTelephony"),this.checkTelephonyRequester.start({onBeforeRequest:async()=>(await this.onBeforeRetry(),e.getParameters()),onSuccessRequest:()=>{c("startCheckTelephony: onSuccessRequest"),this.connectIfDisconnected(e)},onFailRequest:t=>{c("startCheckTelephony: onFailRequest",t.message)}})}async attemptConnection(e){if(c("attemptConnection: attempts.count",this.attemptsState.count),this.events.trigger(_.BEFORE_ATTEMPT,{}),this.stopConnectTriggers(),this.attemptsState.hasLimitReached()){c("attemptConnection: limit reached"),this.handleLimitReached(e);return}return this.attemptsState.startAttempt(),this.attemptsState.increment(),this.executeConnectionAttempt(e)}async executeConnectionAttempt(e){try{await this.connectionQueueManager.connect(e.getParameters,e.options),c("executeConnectionAttempt: success"),this.handleSucceededAttempt(e)}catch(t){this.handleConnectionError(t,e)}}handleConnectionError(e,t){if(Re(e)){this.attemptsState.finishAttempt(),this.events.trigger(_.STOP_ATTEMPTS_BY_ERROR,e);return}if(!this.canRetryOnError(e)){c("executeConnectionAttempt: error does not allow retry",e),this.attemptsState.finishAttempt(),this.events.trigger(_.STOP_ATTEMPTS_BY_ERROR,e);return}if(Y.isPromiseIsNotActualError(e)){c("executeConnectionAttempt: not actual error",e),this.attemptsState.finishAttempt(),this.events.trigger(_.CANCELLED_ATTEMPTS,e);return}c("executeConnectionAttempt: error",e),this.scheduleReconnect(t)}handleLimitReached(e){this.attemptsState.finishAttempt(),this.events.trigger(_.LIMIT_REACHED_ATTEMPTS,new Error(Z.LIMIT_REACHED)),this.startCheckTelephony(e)}handleSucceededAttempt(e){c("handleSucceededAttempt"),this.subscribeToConnectTriggers(e),this.events.trigger(_.SUCCESS)}subscribeToConnectTriggers(e){this.startPingRequester(e),this.registrationFailedOutOfCallSubscriber.subscribe(()=>{c("registrationFailedOutOfCallListener callback"),this.restartConnectionAttempts(e)})}subscribeToHardwareTriggers(e){this.unsubscribeFromHardwareTriggers(),c("subscribeToHardwareTriggers"),this.networkInterfacesSubscriber?.subscribe({onChange:()=>{c("networkInterfacesSubscriber onChange"),this.restartConnectionAttempts(e)},onUnavailable:()=>{c("networkInterfacesSubscriber onUnavailable"),this.stopConnectionFlow().catch(t=>{c("auto connector stop from networkInterfacesSubscriber onUnavailable: error",t)})}}),this.resumeFromSleepModeSubscriber?.subscribe({onResume:()=>{c("resumeFromSleepModeSubscriber onResume"),this.restartConnectionAttempts(e)}})}unsubscribeFromHardwareTriggers(){c("unsubscribeFromHardwareTriggers"),this.networkInterfacesSubscriber?.unsubscribe(),this.resumeFromSleepModeSubscriber?.unsubscribe()}stopPingRequester(){this.pingServerIfNotActiveCallRequester.stop()}startPingRequester(e){this.pingServerIfNotActiveCallRequester.start({onFailRequest:()=>{c("pingRequester: onFailRequest"),this.restartConnectionAttempts(e)}})}connectIfDisconnected(e){const t=this.isConnectionUnavailable();c("connectIfDisconnected: isUnavailable",t),t?this.restartConnectionAttempts(e):(this.stopConnectTriggers(),this.events.trigger(_.SUCCESS))}scheduleReconnect(e){c("scheduleReconnect"),this.delayBetweenAttempts.request().then(async()=>(c("scheduleReconnect: delayBetweenAttempts success"),this.cancelableRequestBeforeRetry.request())).then(async()=>(c("scheduleReconnect: onBeforeRetry success"),this.attemptConnection(e))).catch(t=>{const s=t instanceof Error?t:new Error(Z.FAILED_TO_RECONNECT);this.attemptsState.finishAttempt(),k.isCanceledError(t)||D.hasCanceledError(t)?this.events.trigger(_.CANCELLED_ATTEMPTS,s):this.events.trigger(_.FAILED_ALL_ATTEMPTS,s),c("scheduleReconnect: error",t)})}isConnectionUnavailable(){const{isFailed:e,isDisconnected:t,isIdle:s}=this.connectionManager;return e||t||s}emitStatusChange=({isInProgress:e})=>{this.events.trigger(_.CHANGED_ATTEMPT_STATUS,{isInProgress:e})}}var U=(n=>(n.INCOMING_CALL="incomingCall",n.DECLINED_INCOMING_CALL="declinedIncomingCall",n.TERMINATED_INCOMING_CALL="terminatedIncomingCall",n.FAILED_INCOMING_CALL="failedIncomingCall",n))(U||{});const me=["incomingCall","declinedIncomingCall","terminatedIncomingCall","failedIncomingCall"],Lt=486,Bt=487;class Ft{events;incomingRTCSession;connectionManager;constructor(e){this.connectionManager=e,this.events=new y.TypedEvents(me),this.start()}get remoteCallerData(){return{displayName:this.incomingRTCSession?.remote_identity.display_name,host:this.incomingRTCSession?.remote_identity.uri.host,incomingNumber:this.incomingRTCSession?.remote_identity.uri.user,rtcSession:this.incomingRTCSession}}get isAvailableIncomingCall(){return!!this.incomingRTCSession}start(){this.subscribe()}stop(){this.unsubscribe(),this.removeIncomingSession()}getIncomingRTCSession=()=>{const{incomingRTCSession:e}=this;if(!e)throw new Error("No incomingRTCSession");return e};extractIncomingRTCSession=()=>{const e=this.getIncomingRTCSession();return this.removeIncomingSession(),e};async declineToIncomingCall({statusCode:e=Bt}={}){return new Promise((t,s)=>{try{const r=this.getIncomingRTCSession(),i=this.remoteCallerData;this.removeIncomingSession(),this.events.trigger(U.DECLINED_INCOMING_CALL,i),r.terminate({status_code:e}),t()}catch(r){s(r)}})}async busyIncomingCall(){return this.declineToIncomingCall({statusCode:Lt})}on(e,t){return this.events.on(e,t)}once(e,t){return this.events.once(e,t)}onceRace(e,t){return this.events.onceRace(e,t)}async wait(e){return this.events.wait(e)}off(e,t){this.events.off(e,t)}subscribe(){this.connectionManager.on("newRTCSession",this.handleNewRTCSession)}unsubscribe(){this.connectionManager.off("newRTCSession",this.handleNewRTCSession)}handleNewRTCSession=({originator:e,session:t})=>{e==="remote"&&this.setIncomingSession(t)};setIncomingSession(e){this.incomingRTCSession=e;const t=this.remoteCallerData;e.on("failed",s=>{this.removeIncomingSession(),s.originator==="local"?this.events.trigger(U.TERMINATED_INCOMING_CALL,t):this.events.trigger(U.FAILED_INCOMING_CALL,t)}),this.events.trigger(U.INCOMING_CALL,t)}removeIncomingSession(){delete this.incomingRTCSession}}const w=1e3;var E=(n=>(n.INBOUND_RTP="inbound-rtp",n.REMOTE_OUTBOUND_RTP="remote-outbound-rtp",n.MEDIA_SOURCE="media-source",n.OUTBOUND_RTP="outbound-rtp",n.REMOTE_INBOUND_RTP="remote-inbound-rtp",n.CODEC="codec",n.CANDIDATE_PAIR="candidate-pair",n.CERTIFICATE="certificate",n.TRANSPORT="transport",n.LOCAL_CANDIDATE="local-candidate",n.REMOTE_CANDIDATE="remote-candidate",n))(E||{});const pe=["collected"],ee=()=>"performance"in window?performance.now():Date.now(),B=n=>[...n.keys()].reduce((e,t)=>{const s=n.get(t);return s===void 0?e:{...e,[s.type]:s}},{}),kt=n=>{if(!n)return{outboundRtp:void 0,codec:void 0,mediaSource:void 0,remoteInboundRtp:void 0};const e=B(n);return{outboundRtp:e[E.OUTBOUND_RTP],codec:e[E.CODEC],mediaSource:e[E.MEDIA_SOURCE],remoteInboundRtp:e[E.REMOTE_INBOUND_RTP]}},te=n=>{if(!n)return{outboundRtp:void 0,codec:void 0,mediaSource:void 0,remoteInboundRtp:void 0};const e=B(n);return{outboundRtp:e[E.OUTBOUND_RTP],codec:e[E.CODEC],mediaSource:e[E.MEDIA_SOURCE],remoteInboundRtp:e[E.REMOTE_INBOUND_RTP]}},ne=({videoReceiversStats:n,synchronizationSourcesVideo:e})=>{if(!n)return{inboundRtp:void 0,codec:void 0,synchronizationSources:e};const t=B(n);return{inboundRtp:t[E.INBOUND_RTP],codec:t[E.CODEC],synchronizationSources:e}},$t=({audioReceiverStats:n,synchronizationSourcesAudio:e})=>{if(!n)return{inboundRtp:void 0,codec:void 0,remoteOutboundRtp:void 0,synchronizationSources:e};const t=B(n);return{inboundRtp:t[E.INBOUND_RTP],codec:t[E.CODEC],remoteOutboundRtp:t[E.REMOTE_OUTBOUND_RTP],synchronizationSources:e}},Ie=n=>{if(!n)return{candidatePair:void 0,certificate:void 0,localCandidate:void 0,remoteCandidate:void 0,transport:void 0};const e=B(n);return{candidatePair:e[E.CANDIDATE_PAIR],certificate:e[E.CERTIFICATE],localCandidate:e[E.LOCAL_CANDIDATE],remoteCandidate:e[E.REMOTE_CANDIDATE],transport:e[E.TRANSPORT]}},qt=({audioSenderStats:n,videoSenderFirstStats:e,videoSenderSecondStats:t})=>({video:te(e),secondVideo:te(t),audio:kt(n),additional:Ie(n??e??t)}),Vt=({audioReceiverStats:n,videoReceiverFirstStats:e,videoReceiverSecondStats:t,synchronizationSources:s})=>({video:ne({videoReceiversStats:e,synchronizationSourcesVideo:s.video}),secondVideo:ne({videoReceiversStats:t,synchronizationSourcesVideo:s.video}),audio:$t({audioReceiverStats:n,synchronizationSourcesAudio:s.audio}),additional:Ie(n??e??t)}),Ht=({audioSenderStats:n,videoSenderFirstStats:e,videoSenderSecondStats:t,audioReceiverStats:s,videoReceiverFirstStats:r,videoReceiverSecondStats:i,synchronizationSources:a})=>{const o=qt({audioSenderStats:n,videoSenderFirstStats:e,videoSenderSecondStats:t}),h=Vt({audioReceiverStats:s,videoReceiverFirstStats:r,videoReceiverSecondStats:i,synchronizationSources:a});return{outbound:o,inbound:h}},Wt=async n=>{const e="audio",t="video",s=n.getSenders(),r=s.find(l=>l.track?.kind===e),i=s.filter(l=>l.track?.kind===t),a=n.getReceivers(),o=a.find(l=>l.track.kind===e),h=a.filter(l=>l.track.kind===t),d={trackIdentifier:o?.track.id,item:o?.getSynchronizationSources()[0]},T={trackIdentifier:h[0]?.track.id,item:h[0]?.getSynchronizationSources()[0]},S={audio:d,video:T};return Promise.all([r?.getStats()??Promise.resolve(void 0),i[0]?.getStats()??Promise.resolve(void 0),i[1]?.getStats()??Promise.resolve(void 0),o?.getStats()??Promise.resolve(void 0),h[0]?.getStats()??Promise.resolve(void 0),h[1]?.getStats()??Promise.resolve(void 0)]).then(l=>{const[A,p,N,M,$,q]=l;return{synchronizationSources:S,audioSenderStats:A,videoSenderFirstStats:p,videoSenderSecondStats:N,audioReceiverStats:M,videoReceiverFirstStats:$,videoReceiverSecondStats:q}})},xt=n=>{c(String(n))};class _e{events;setTimeoutRequest;requesterAllStatistics=new k.CancelableRequest(Wt);constructor(){this.events=new y.TypedEvents(pe),this.setTimeoutRequest=new D.SetTimeoutRequest}get requested(){return this.setTimeoutRequest.requested}start(e,{interval:t=w,onError:s=xt}={}){this.stop(),this.setTimeoutRequest.request(()=>{this.collectStatistics(e,{onError:s})},t)}stop(){this.setTimeoutRequest.cancelRequest(),this.requesterAllStatistics.cancelRequest()}on(e,t){return this.events.on(e,t)}once(e,t){return this.events.once(e,t)}onceRace(e,t){return this.events.onceRace(e,t)}async wait(e){return this.events.wait(e)}off(e,t){this.events.off(e,t)}collectStatistics=(e,{onError:t})=>{const s=ee();this.requesterAllStatistics.request(e).then(r=>{this.events.trigger("collected",Ht(r));const a=ee()-s;let o=w;a>48?o=w*4:a>32?o=w*3:a>16&&(o=w*2),this.start(e,{onError:t,interval:o})}).catch(r=>{t&&t(r)})}}class Gt{availableIncomingBitrate;statsPeerConnection;callManager;apiManager;previousAvailableIncomingBitrate;constructor({callManager:e,apiManager:t}){this.callManager=e,this.apiManager=t,this.statsPeerConnection=new _e,this.subscribe()}get events(){return this.statsPeerConnection.events}on(e,t){return this.statsPeerConnection.on(e,t)}once(e,t){return this.statsPeerConnection.once(e,t)}onceRace(e,t){return this.statsPeerConnection.onceRace(e,t)}async wait(e){return this.statsPeerConnection.wait(e)}off(e,t){this.statsPeerConnection.off(e,t)}hasAvailableIncomingBitrateChangedQuarter(){const e=this.previousAvailableIncomingBitrate,t=this.availableIncomingBitrate;return e===void 0||t===void 0?!1:e===0?t>0:Math.abs(t-e)/e>=.25}subscribe(){this.callManager.on("peerconnection:confirmed",this.handleStarted),this.callManager.on("failed",this.handleEnded),this.callManager.on("ended",this.handleEnded),this.statsPeerConnection.on("collected",this.handleStatsCollected)}handleStatsCollected=e=>{this.previousAvailableIncomingBitrate=this.availableIncomingBitrate,this.availableIncomingBitrate=e.inbound.additional.candidatePair?.availableIncomingBitrate,this.maybeSendStats()};handleStarted=e=>{this.statsPeerConnection.start(e)};handleEnded=()=>{this.statsPeerConnection.stop(),this.availableIncomingBitrate=void 0,this.previousAvailableIncomingBitrate=void 0};maybeSendStats(){this.availableIncomingBitrate!==void 0&&this.hasAvailableIncomingBitrateChangedQuarter()&&this.apiManager.sendStats({availableIncomingBitrate:this.availableIncomingBitrate}).catch(e=>{c("Failed to send stats",e)})}}const Qt=(n,e)=>n.filter(s=>e.some(r=>r.clockRate===s.clockRate&&r.mimeType===s.mimeType&&r.channels===s.channels&&r.sdpFmtpLine===s.sdpFmtpLine)),Yt=n=>{const e=RTCRtpSender.getCapabilities(n),t=RTCRtpReceiver.getCapabilities(n),s=e===null?[]:e.codecs,r=t===null?[]:t.codecs;return Qt(s,r)},zt=(n,e)=>e===void 0||e.length===0?n:n.sort((t,s)=>{const r=e.indexOf(t.mimeType),i=e.indexOf(s.mimeType),a=r===-1?Number.MAX_VALUE:r,o=i===-1?Number.MAX_VALUE:i;return a-o}),Xt=(n,e)=>e===void 0||e.length===0?n:n.filter(t=>!e.includes(t.mimeType)),Jt=(n,{preferredMimeTypesVideoCodecs:e,excludeMimeTypesVideoCodecs:t})=>{try{if(typeof n.setCodecPreferences=="function"&&n.sender.track?.kind==="video"&&(e!==void 0&&e.length>0||t!==void 0&&t.length>0)){const s=Yt("video"),r=Xt(s,t),i=zt(r,e);n.setCodecPreferences(i)}}catch(s){c("setCodecPreferences error",s)}};class Kt{transceivers={};callManager;apiManager;constructor({callManager:e,apiManager:t}){this.callManager=e,this.apiManager=t,this.subscribe()}storeTransceiver(e,t){const{kind:s}=t;if(s==="audio")this.transceivers.mainAudio??=e;else{const{mid:r}=e;r==="2"?this.transceivers.presentationVideo??=e:this.transceivers.mainVideo??=e}}getTransceivers(){return{...this.transceivers}}getMainAudioTransceiver(){return this.transceivers.mainAudio}getMainVideoTransceiver(){return this.transceivers.mainVideo}getPresentationVideoTransceiver(){return this.transceivers.presentationVideo}hasTransceiver(e){return this.transceivers[e]!==void 0}clear(){this.transceivers.mainVideo=void 0,this.transceivers.mainAudio=void 0,this.transceivers.presentationVideo=void 0}getCount(){let e=0;return this.transceivers.mainAudio&&(e+=1),this.transceivers.mainVideo&&(e+=1),this.transceivers.presentationVideo&&(e+=1),e}isEmpty(){return this.getCount()===0}handleRestart=e=>{this.updateTransceivers(e).catch(t=>{c("Failed to update transceivers",t)}).finally(()=>{this.callManager.restartIce().catch(t=>{c("Failed to restart ICE",t)})})};updateTransceivers=async e=>{const{videoTrackCount:t}=e;t===2&&(this.getTransceivers().presentationVideo!==void 0||await this.callManager.addTransceiver("video",{direction:"recvonly"}).catch(i=>{c("Failed to add presentation video transceiver",i)}))};subscribe(){this.callManager.on("peerconnection:ontrack",this.handleTrack),this.callManager.on("failed",this.handleEnded),this.callManager.on("ended",this.handleEnded),this.apiManager.on("restart",this.handleRestart)}handleTrack=e=>{this.storeTransceiver(e.transceiver,e.track)};handleEnded=()=>{this.clear()}}const jt=n=>[...n.keys()].map(e=>n.get(e)),Zt=(n,e)=>jt(n).find(t=>t?.type===e),Me=async n=>n.getStats().then(e=>Zt(e,"codec")?.mimeType);class en{async getCodecFromSender(e){return await Me(e)??""}}class tn{stackPromises=Y.createStackPromises({noRunIsNotActual:!0});async add(e){return this.stackPromises.add(e),this.run()}stop(){this.stackPromises.stop()}async run(){return this.stackPromises().catch(e=>{c("TaskQueue: error",e)})}}class nn{taskQueue;onSetParameters;constructor(e){this.onSetParameters=e,this.taskQueue=new tn}async setEncodingsToSender(e,t){return this.taskQueue.add(async()=>J(e,t,this.onSetParameters))}stop(){this.taskQueue.stop()}}const ve=(n,e)=>n!==void 0&&e!==void 0&&n.toLowerCase().includes(e.toLowerCase()),sn=1e6,v=n=>n*sn,fe=v(.06),Pe=v(4),rn=n=>n<=64?fe:n<=128?v(.12):n<=256?v(.25):n<=384?v(.32):n<=426?v(.38):n<=640?v(.5):n<=848?v(.7):n<=1280?v(1):n<=1920?v(2):Pe,an="av1",on=n=>ve(n,an),cn=.6,K=(n,e)=>on(e)?n*cn:n,hn=n=>K(fe,n),dn=n=>K(Pe,n),se=(n,e)=>{const t=rn(n);return K(t,e)},V=1,ln=({videoTrack:n,targetSize:e})=>{const t=n.getSettings(),s=t.width,r=t.height,i=s===void 0?V:s/e.width,a=r===void 0?V:r/e.height;return Math.max(i,a,V)};class un{ignoreForCodec;senderFinder;codecProvider;parametersSetter;resultNoChanged={isChanged:!1,parameters:{encodings:[{}],transactionId:"0",codecs:[],headerExtensions:[],rtcp:{}}};constructor({senderFinder:e,codecProvider:t,parametersSetter:s},r){this.senderFinder=e,this.codecProvider=t,this.parametersSetter=s,this.ignoreForCodec=r.ignoreForCodec}async balance(e,t){const s=e.getSenders(),r=this.senderFinder.findVideoSender(s);if(!r?.track)return{...this.resultNoChanged,sender:r};const i=await this.codecProvider.getCodecFromSender(r);if(ve(i,this.ignoreForCodec))return{...this.resultNoChanged,sender:r};const{mainCam:a,resolutionMainCam:o}=t??{};return this.processSender({mainCam:a,resolutionMainCam:o},{sender:r,codec:i,videoTrack:r.track}).then(h=>({...h,sender:r}))}async processSender(e,t){const{mainCam:s,resolutionMainCam:r}=e;switch(s){case f.PAUSE_MAIN_CAM:return this.downgradeResolutionSender(t);case f.RESUME_MAIN_CAM:return this.setBitrateByTrackResolution(t);case f.MAX_MAIN_CAM_RESOLUTION:return r!==void 0?this.setResolutionSender(r,t):this.setBitrateByTrackResolution(t);case f.ADMIN_STOP_MAIN_CAM:case f.ADMIN_START_MAIN_CAM:case void 0:return this.setBitrateByTrackResolution(t);default:return this.setBitrateByTrackResolution(t)}}async downgradeResolutionSender(e){const{sender:t,codec:s}=e,r={scaleResolutionDownBy:200,maxBitrate:hn(s)};return this.parametersSetter.setEncodingsToSender(t,r)}async setBitrateByTrackResolution(e){const{sender:t,videoTrack:s,codec:r}=e,a=s.getSettings().width,o=a===void 0?dn(r):se(a,r);return this.parametersSetter.setEncodingsToSender(t,{scaleResolutionDownBy:1,maxBitrate:o})}async setResolutionSender(e,t){const[s,r]=e.split("x"),{sender:i,videoTrack:a,codec:o}=t,h={width:Number(s),height:Number(r)},d=ln({videoTrack:a,targetSize:h}),T=se(h.width,o),S={scaleResolutionDownBy:d,maxBitrate:T};return this.parametersSetter.setEncodingsToSender(i,S)}}const gn=n=>n.find(e=>e.track?.kind==="video");class Tn{findVideoSender(e){return gn(e)}}class Sn{currentSender;originalReplaceTrack;lastWidth;lastHeight;maxPollIntervalMs;currentPollIntervalMs;pollIntervalMs;setTimeoutRequest;constructor({pollIntervalMs:e=1e3,maxPollIntervalMs:t}){this.pollIntervalMs=e,this.maxPollIntervalMs=t??e*16,this.currentPollIntervalMs=this.pollIntervalMs,this.setTimeoutRequest=new D.SetTimeoutRequest}subscribe(e,t){if(!e){this.detachSender();return}this.currentSender!==e&&(this.detachSender(),this.attachSender(e,t))}unsubscribe(){this.detachSender()}attachSender(e,t){this.currentSender=e;const s=e.replaceTrack.bind(e);this.originalReplaceTrack=s,e.replaceTrack=async r=>{await s(r),this.attachTrack(t,r??void 0),t()},this.attachTrack(t,e.track)}detachSender(){this.currentSender&&this.originalReplaceTrack&&(this.currentSender.replaceTrack=this.originalReplaceTrack),this.originalReplaceTrack=void 0,this.currentSender=void 0,this.detachTrack()}attachTrack(e,t){if(this.detachTrack(),!t)return;const{width:s,height:r}=t.getSettings();this.lastWidth=s,this.lastHeight=r,this.currentPollIntervalMs=this.pollIntervalMs,this.schedulePoll(t,e)}schedulePoll(e,t){const s=()=>{const{width:r,height:i}=e.getSettings();r!==this.lastWidth||i!==this.lastHeight?(this.lastWidth=r,this.lastHeight=i,this.currentPollIntervalMs=this.pollIntervalMs,t()):this.currentPollIntervalMs=Math.min(this.currentPollIntervalMs*2,this.maxPollIntervalMs),this.setTimeoutRequest.request(s,this.currentPollIntervalMs)};this.setTimeoutRequest.request(s,this.currentPollIntervalMs)}detachTrack(){this.setTimeoutRequest.cancelRequest(),this.lastWidth=void 0,this.lastHeight=void 0}}class Cn{apiManager;currentHandler;constructor(e){this.apiManager=e}subscribe(e){this.currentHandler=e,this.apiManager.on("main-cam-control",e)}unsubscribe(){this.currentHandler&&(this.apiManager.off("main-cam-control",this.currentHandler),this.currentHandler=void 0)}}class En{eventHandler;senderBalancer;parametersSetterWithQueue;getConnection;serverHeaders;trackMonitor;constructor(e,t,{ignoreForCodec:s,onSetParameters:r,pollIntervalMs:i}={}){this.getConnection=t,this.eventHandler=new Cn(e),this.parametersSetterWithQueue=new nn(r),this.senderBalancer=new un({senderFinder:new Tn,codecProvider:new en,parametersSetter:this.parametersSetterWithQueue},{ignoreForCodec:s}),this.trackMonitor=new Sn({pollIntervalMs:i})}subscribe(){this.eventHandler.subscribe(this.handleMainCamControl)}unsubscribe(){this.eventHandler.unsubscribe(),this.parametersSetterWithQueue.stop(),this.reset()}reset(){delete this.serverHeaders,this.trackMonitor.unsubscribe()}async balance(){const e=this.getConnection();if(!e)throw new Error("connection is not exist");const t=await this.senderBalancer.balance(e,this.serverHeaders);return this.trackMonitor.subscribe(t.sender,()=>{this.balance().catch(s=>{c("balance on track change: error",s)})}),t}handleMainCamControl=e=>{this.serverHeaders=e,this.balance().catch(t=>{c("handleMainCamControl: error",t)})}}const Oe=["balancing-scheduled","balancing-started","balancing-stopped","parameters-updated"];class An{isBalancingActive=!1;events;callManager;balancingStartDelay;videoSendingBalancer;startBalancingTimer;constructor(e,t,s={}){this.events=new y.TypedEvents(Oe),this.callManager=e,this.balancingStartDelay=s.balancingStartDelay??1e4,this.videoSendingBalancer=new En(t,()=>e.connection,{...s,onSetParameters:r=>{this.events.trigger("parameters-updated",r),s.onSetParameters?.(r)}}),this.subscribe()}get isBalancingScheduled(){return this.startBalancingTimer!==void 0}async startBalancing(){this.isBalancingActive||(this.clearStartTimer(),await this.videoSendingBalancer.balance(),this.videoSendingBalancer.subscribe(),this.isBalancingActive=!0,this.events.trigger("balancing-started",{delay:this.balancingStartDelay}))}stopBalancing(){this.clearStartTimer(),this.videoSendingBalancer.unsubscribe(),this.isBalancingActive=!1,this.events.trigger("balancing-stopped",{})}async balance(){return this.videoSendingBalancer.balance()}on(e,t){return this.events.on(e,t)}once(e,t){return this.events.once(e,t)}onceRace(e,t){return this.events.onceRace(e,t)}async wait(e){return this.events.wait(e)}off(e,t){this.events.off(e,t)}subscribe(){this.callManager.on("peerconnection:confirmed",this.handleCallStarted),this.callManager.on("ended",this.handleCallEnded),this.callManager.on("failed",this.handleCallEnded)}handleCallStarted=()=>{this.scheduleBalancingStart()};handleCallEnded=()=>{this.stopBalancing()};scheduleBalancingStart(){this.clearStartTimer(),this.startBalancingTimer=setTimeout(()=>{this.startBalancingTimer=void 0,this.startBalancing().catch(e=>{c("startBalancing: error",e)})},this.balancingStartDelay),this.events.trigger("balancing-scheduled",{delay:this.balancingStartDelay})}clearStartTimer(){this.startBalancingTimer&&(clearTimeout(this.startBalancingTimer),this.startBalancingTimer=void 0)}}const Rn=1e6,Nn=Ne.map(n=>`auto-connect:${n}`),mn=Ce.map(n=>`connection:${n}`),pn=he.map(n=>`call:${n}`),In=ae.map(n=>`api:${n}`),_n=me.map(n=>`incoming-call:${n}`),Mn=Te.map(n=>`presentation:${n}`),vn=pe.map(n=>`stats:${n}`),fn=Oe.map(n=>`video-balancer:${n}`),Pn=[...Nn,...mn,...pn,...In,..._n,...Mn,...vn,...fn];class On{events;connectionManager;connectionQueueManager;callManager;autoConnectorManager;apiManager;incomingCallManager;presentationManager;statsManager;videoSendingBalancerManager;transceiverManager;preferredMimeTypesVideoCodecs;excludeMimeTypesVideoCodecs;constructor({JsSIP:e},{preferredMimeTypesVideoCodecs:t,excludeMimeTypesVideoCodecs:s,videoBalancerOptions:r,autoConnectorOptions:i}={}){this.preferredMimeTypesVideoCodecs=t,this.excludeMimeTypesVideoCodecs=s,this.events=new y.TypedEvents(Pn),this.connectionManager=new Nt({JsSIP:e}),this.connectionQueueManager=new mt({connectionManager:this.connectionManager}),this.callManager=new Ye,this.apiManager=new Be({connectionManager:this.connectionManager,callManager:this.callManager}),this.incomingCallManager=new Ft(this.connectionManager),this.presentationManager=new ct({callManager:this.callManager,maxBitrate:Rn}),this.statsManager=new Gt({callManager:this.callManager,apiManager:this.apiManager}),this.autoConnectorManager=new Ut({connectionQueueManager:this.connectionQueueManager,connectionManager:this.connectionManager,callManager:this.callManager},i),this.transceiverManager=new Kt({callManager:this.callManager,apiManager:this.apiManager}),this.videoSendingBalancerManager=new An(this.callManager,this.apiManager,r),this.subscribe()}get requestedConnection(){return this.connectionManager.requested}get isPendingConnect(){return this.connectionManager.isPendingConnect}get isPendingInitUa(){return this.connectionManager.isPendingInitUa}get connectionState(){return this.connectionManager.connectionState}get isRegistered(){return this.connectionManager.isRegistered}get isRegisterConfig(){return this.connectionManager.isRegisterConfig}get socket(){return this.connectionManager.socket}get requestedCall(){return this.callManager.requested}get connection(){return this.callManager.connection}get isCallActive(){return this.callManager.isCallActive}get remoteCallerData(){return this.incomingCallManager.remoteCallerData}get isAvailableIncomingCall(){return this.incomingCallManager.isAvailableIncomingCall}on(e,t){return this.events.on(e,t)}once(e,t){return this.events.once(e,t)}onceRace(e,t){return this.events.onceRace(e,t)}async wait(e){return this.events.wait(e)}off(e,t){this.events.off(e,t)}connect=async(...e)=>this.connectionQueueManager.connect(...e);disconnect=async()=>this.connectionQueueManager.disconnect();register=async()=>this.connectionManager.register();unregister=async()=>this.connectionManager.unregister();tryRegister=async()=>this.connectionManager.tryRegister();set=async(...e)=>this.connectionManager.set(...e);sendOptions=async(e,t,s)=>this.connectionManager.sendOptions(e,t,s);ping=async(e,t)=>this.connectionManager.ping(e,t);checkTelephony=async e=>this.connectionManager.checkTelephony(e);isConfigured=()=>this.connectionManager.isConfigured();getConnectionConfiguration=()=>this.connectionManager.getConnectionConfiguration();getSipServerUrl=e=>this.connectionManager.getSipServerUrl(e);startAutoConnect=(...e)=>{this.autoConnectorManager.start(...e)};stopAutoConnect=()=>{this.autoConnectorManager.stop()};call=async e=>{const{onAddedTransceiver:t,...s}=e;return this.callManager.startCall(this.connectionManager.getUaProtected(),this.getSipServerUrl,{...s,onAddedTransceiver:this.resolveHandleAddTransceiver(t)})};hangUp=async()=>this.callManager.endCall();answerToIncomingCall=async e=>{const{onAddedTransceiver:t,...s}=e;return this.callManager.answerToIncomingCall(this.incomingCallManager.extractIncomingRTCSession,{...s,onAddedTransceiver:this.resolveHandleAddTransceiver(t)})};declineToIncomingCall=async(...e)=>this.incomingCallManager.declineToIncomingCall(...e);getEstablishedRTCSession=()=>this.callManager.getEstablishedRTCSession();getCallConfiguration=()=>this.callManager.getCallConfiguration();getRemoteStreams=()=>this.callManager.getRemoteStreams();replaceMediaStream=async(...e)=>this.callManager.replaceMediaStream(...e);async startPresentation(e,t={}){const{isP2P:s,callLimit:r,onAddedTransceiver:i,...a}=t;return this.presentationManager.startPresentation(async()=>{s===!0?(await this.apiManager.sendMustStopPresentationP2P(),await this.apiManager.askPermissionToStartPresentationP2P()):await this.apiManager.askPermissionToStartPresentation()},e,{...a,onAddedTransceiver:this.resolveHandleAddTransceiver(i)},r===void 0?void 0:{callLimit:r})}async stopPresentation(e={}){const{isP2P:t}=e;return this.presentationManager.stopPresentation(async()=>{await(t===!0?this.apiManager.sendMustStopPresentationP2P():this.apiManager.sendStoppedPresentation())})}async updatePresentation(e,t={}){const{isP2P:s,onAddedTransceiver:r,...i}=t;return this.presentationManager.updatePresentation(async()=>{s===!0?(await this.apiManager.sendMustStopPresentationP2P(),await this.apiManager.askPermissionToStartPresentationP2P()):await this.apiManager.askPermissionToStartPresentation()},e,{...i,onAddedTransceiver:this.resolveHandleAddTransceiver(r)})}async waitChannels(...e){return this.apiManager.waitChannels(...e)}async waitSyncMediaState(...e){return this.apiManager.waitSyncMediaState(...e)}async sendDTMF(...e){return this.apiManager.sendDTMF(...e)}async sendChannels(...e){return this.apiManager.sendChannels(...e)}async sendMediaState(...e){return this.apiManager.sendMediaState(...e)}async sendRefusalToTurnOn(...e){return this.apiManager.sendRefusalToTurnOn(...e)}async sendRefusalToTurnOnMic(...e){return this.apiManager.sendRefusalToTurnOnMic(...e)}async sendRefusalToTurnOnCam(...e){return this.apiManager.sendRefusalToTurnOnCam(...e)}async sendMustStopPresentationP2P(...e){return this.apiManager.sendMustStopPresentationP2P(...e)}async sendStoppedPresentationP2P(...e){return this.apiManager.sendStoppedPresentationP2P(...e)}async sendStoppedPresentation(...e){return this.apiManager.sendStoppedPresentation(...e)}async askPermissionToStartPresentationP2P(...e){return this.apiManager.askPermissionToStartPresentationP2P(...e)}async askPermissionToStartPresentation(...e){return this.apiManager.askPermissionToStartPresentation(...e)}async askPermissionToEnableCam(...e){return this.apiManager.askPermissionToEnableCam(...e)}setCodecPreferences(e){Jt(e,{preferredMimeTypesVideoCodecs:this.preferredMimeTypesVideoCodecs,excludeMimeTypesVideoCodecs:this.excludeMimeTypesVideoCodecs})}subscribe(){this.bridgeEvents("auto-connect",this.autoConnectorManager),this.bridgeEvents("connection",this.connectionManager),this.bridgeEvents("call",this.callManager),this.bridgeEvents("api",this.apiManager),this.bridgeEvents("incoming-call",this.incomingCallManager),this.bridgeEvents("presentation",this.presentationManager),this.bridgeEvents("stats",this.statsManager),this.bridgeEvents("video-balancer",this.videoSendingBalancerManager)}bridgeEvents=(e,t)=>{t.events.eachTriggers((s,r)=>{t.on(r,i=>{this.events.trigger(`${e}:${r}`,i)})})};resolveHandleAddTransceiver=e=>async(t,s,r)=>{this.setCodecPreferences(t),await e?.(t,s,r)}}exports.ECallCause=X;exports.EStatsTypes=E;exports.EUseLicense=ie;exports.Originator=oe;exports.SipConnector=On;exports.StatsPeerConnection=_e;exports.disableDebug=be;exports.enableDebug=ye;exports.getCodecFromSender=Me;exports.hasCanceledStartPresentationError=ot;exports.hasNotReadyForConnectionError=Re;exports.logger=c;exports.prepareMediaStream=L;exports.setEncodingsToSender=J;exports.setParametersToSender=ge;
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { RTCSession } from '@krivega/jssip';
|
|
2
|
-
import { TEvents } from './eventNames';
|
|
3
|
-
import { ICallStrategy, TCallConfiguration } from './types';
|
|
4
|
-
export declare abstract class AbstractCallStrategy implements ICallStrategy {
|
|
5
|
-
protected isPendingCall: boolean;
|
|
6
|
-
protected isPendingAnswer: boolean;
|
|
7
|
-
protected rtcSession?: RTCSession;
|
|
8
|
-
protected remoteStreams: Record<string, MediaStream>;
|
|
9
|
-
protected readonly events: TEvents;
|
|
10
|
-
protected readonly callConfiguration: TCallConfiguration;
|
|
11
|
-
constructor(events: TEvents);
|
|
12
|
-
abstract get requested(): boolean;
|
|
13
|
-
abstract get connection(): RTCPeerConnection | undefined;
|
|
14
|
-
abstract get isCallActive(): boolean;
|
|
15
|
-
abstract getEstablishedRTCSession(): RTCSession | undefined;
|
|
16
|
-
/**
|
|
17
|
-
* Запуск исходящего звонка
|
|
18
|
-
*/
|
|
19
|
-
abstract startCall(ua: Parameters<ICallStrategy['startCall']>[0], getSipServerUrl: Parameters<ICallStrategy['startCall']>[1], params: Parameters<ICallStrategy['startCall']>[2]): Promise<RTCPeerConnection>;
|
|
20
|
-
/**
|
|
21
|
-
* Завершение звонка
|
|
22
|
-
*/
|
|
23
|
-
abstract endCall(): Promise<void>;
|
|
24
|
-
/**
|
|
25
|
-
* Ответ на входящий звонок
|
|
26
|
-
*/
|
|
27
|
-
abstract answerToIncomingCall(extractIncomingRTCSession: Parameters<ICallStrategy['answerToIncomingCall']>[0], params: Parameters<ICallStrategy['answerToIncomingCall']>[1]): Promise<RTCPeerConnection>;
|
|
28
|
-
/**
|
|
29
|
-
* Замена медиа-потока
|
|
30
|
-
*/
|
|
31
|
-
abstract replaceMediaStream(mediaStream: Parameters<ICallStrategy['replaceMediaStream']>[0], options?: Parameters<ICallStrategy['replaceMediaStream']>[1]): Promise<void>;
|
|
32
|
-
/**
|
|
33
|
-
* Получение конфигурации звонка
|
|
34
|
-
*/
|
|
35
|
-
abstract getCallConfiguration(): TCallConfiguration;
|
|
36
|
-
/**
|
|
37
|
-
* Получение удаленных медиа-потоков
|
|
38
|
-
*/
|
|
39
|
-
abstract getRemoteStreams(): MediaStream[] | undefined;
|
|
40
|
-
/**
|
|
41
|
-
* Добавление нового transceiver'а
|
|
42
|
-
*/
|
|
43
|
-
abstract addTransceiver(kind: 'audio' | 'video', options?: RTCRtpTransceiverInit): Promise<RTCRtpTransceiver>;
|
|
44
|
-
/**
|
|
45
|
-
* Перезапуск ICE-соединения
|
|
46
|
-
*/
|
|
47
|
-
abstract restartIce(options?: {
|
|
48
|
-
useUpdate?: boolean;
|
|
49
|
-
extraHeaders?: string[];
|
|
50
|
-
rtcOfferConstraints?: RTCOfferOptions;
|
|
51
|
-
sendEncodings?: RTCRtpEncodingParameters[];
|
|
52
|
-
degradationPreference?: RTCDegradationPreference;
|
|
53
|
-
}): Promise<boolean>;
|
|
54
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { AbstractCallStrategy } from './AbstractCallStrategy';
|
|
2
|
-
import { RTCSession } from '@krivega/jssip';
|
|
3
|
-
import { TEvents } from './eventNames';
|
|
4
|
-
import { ICallStrategy } from './types';
|
|
5
|
-
export declare class MCUCallStrategy extends AbstractCallStrategy {
|
|
6
|
-
private readonly remoteStreamsManager;
|
|
7
|
-
private readonly mcuSession;
|
|
8
|
-
constructor(events: TEvents);
|
|
9
|
-
get requested(): boolean;
|
|
10
|
-
get connection(): RTCPeerConnection | undefined;
|
|
11
|
-
get isCallActive(): boolean;
|
|
12
|
-
getEstablishedRTCSession: () => RTCSession | undefined;
|
|
13
|
-
startCall: ICallStrategy['startCall'];
|
|
14
|
-
endCall(): Promise<void>;
|
|
15
|
-
answerToIncomingCall: ICallStrategy['answerToIncomingCall'];
|
|
16
|
-
getCallConfiguration(): {
|
|
17
|
-
answer?: boolean;
|
|
18
|
-
number?: string;
|
|
19
|
-
};
|
|
20
|
-
getRemoteStreams(): MediaStream[] | undefined;
|
|
21
|
-
replaceMediaStream(mediaStream: Parameters<ICallStrategy['replaceMediaStream']>[0], options?: Parameters<ICallStrategy['replaceMediaStream']>[1]): Promise<void>;
|
|
22
|
-
restartIce(options?: {
|
|
23
|
-
useUpdate?: boolean;
|
|
24
|
-
extraHeaders?: string[];
|
|
25
|
-
rtcOfferConstraints?: RTCOfferOptions;
|
|
26
|
-
sendEncodings?: RTCRtpEncodingParameters[];
|
|
27
|
-
degradationPreference?: RTCDegradationPreference;
|
|
28
|
-
}): Promise<boolean>;
|
|
29
|
-
addTransceiver(kind: 'audio' | 'video', options?: RTCRtpTransceiverInit): Promise<RTCRtpTransceiver>;
|
|
30
|
-
private readonly reset;
|
|
31
|
-
}
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import { ApiManager, TRestartData } from '../ApiManager';
|
|
2
|
-
import { CallManager } from '../CallManager';
|
|
3
|
-
import { ITransceiverStorage } from './types';
|
|
4
|
-
/**
|
|
5
|
-
* Менеджер для управления RTCRtpTransceiver'ами
|
|
6
|
-
* Отвечает за хранение и классификацию transceiver'ов по типам:
|
|
7
|
-
* - mainAudio: основной transceiver для аудио (mid='0')
|
|
8
|
-
* - mainVideo: основной transceiver для видео (mid='1')
|
|
9
|
-
* - presentationVideo: transceiver для презентации видео (mid='2')
|
|
10
|
-
*/
|
|
11
|
-
export declare class TransceiverManager {
|
|
12
|
-
/**
|
|
13
|
-
* Хранилище основных transceiver'ов
|
|
14
|
-
*/
|
|
15
|
-
private readonly transceivers;
|
|
16
|
-
private readonly callManager;
|
|
17
|
-
private readonly apiManager;
|
|
18
|
-
constructor({ callManager, apiManager, }: {
|
|
19
|
-
callManager: CallManager;
|
|
20
|
-
apiManager: ApiManager;
|
|
21
|
-
});
|
|
22
|
-
/**
|
|
23
|
-
* Сохраняет transceiver в соответствующем хранилище в зависимости от типа трека и mid
|
|
24
|
-
*/
|
|
25
|
-
storeTransceiver(transceiver: RTCRtpTransceiver, track: MediaStreamTrack): void;
|
|
26
|
-
/**
|
|
27
|
-
* Возвращает все сохраненные transceiver'ы
|
|
28
|
-
*/
|
|
29
|
-
getTransceivers(): Readonly<ITransceiverStorage>;
|
|
30
|
-
/**
|
|
31
|
-
* Возвращает основной аудио transceiver
|
|
32
|
-
*/
|
|
33
|
-
getMainAudioTransceiver(): RTCRtpTransceiver | undefined;
|
|
34
|
-
/**
|
|
35
|
-
* Возвращает основной видео transceiver
|
|
36
|
-
*/
|
|
37
|
-
getMainVideoTransceiver(): RTCRtpTransceiver | undefined;
|
|
38
|
-
/**
|
|
39
|
-
* Возвращает презентационный видео transceiver
|
|
40
|
-
*/
|
|
41
|
-
getPresentationVideoTransceiver(): RTCRtpTransceiver | undefined;
|
|
42
|
-
/**
|
|
43
|
-
* Проверяет, есть ли сохраненный transceiver для указанного типа
|
|
44
|
-
*/
|
|
45
|
-
hasTransceiver(type: keyof ITransceiverStorage): boolean;
|
|
46
|
-
/**
|
|
47
|
-
* Очищает все сохраненные transceiver'ы
|
|
48
|
-
*/
|
|
49
|
-
clear(): void;
|
|
50
|
-
/**
|
|
51
|
-
* Возвращает количество сохраненных transceiver'ов
|
|
52
|
-
*/
|
|
53
|
-
getCount(): number;
|
|
54
|
-
/**
|
|
55
|
-
* Проверяет, пустое ли хранилище
|
|
56
|
-
*/
|
|
57
|
-
isEmpty(): boolean;
|
|
58
|
-
/**
|
|
59
|
-
* Обрабатывает событие restart от ApiManager
|
|
60
|
-
*/
|
|
61
|
-
readonly handleRestart: (restartData: TRestartData) => void;
|
|
62
|
-
/**
|
|
63
|
-
* Обновляет transceiver'ы в соответствии с данными restart
|
|
64
|
-
*/
|
|
65
|
-
private readonly updateTransceivers;
|
|
66
|
-
private subscribe;
|
|
67
|
-
private readonly handleTrack;
|
|
68
|
-
private readonly handleEnded;
|
|
69
|
-
}
|
|
70
|
-
export default TransceiverManager;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default as TransceiverManager } from './@TransceiverManager';
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Интерфейс для хранения основных transceiver'ов
|
|
3
|
-
*/
|
|
4
|
-
export interface ITransceiverStorage {
|
|
5
|
-
/** Основной transceiver для видео */
|
|
6
|
-
mainVideo?: RTCRtpTransceiver;
|
|
7
|
-
/** Основной transceiver для аудио */
|
|
8
|
-
mainAudio?: RTCRtpTransceiver;
|
|
9
|
-
/** Transceiver для презентации видео */
|
|
10
|
-
presentationVideo?: RTCRtpTransceiver;
|
|
11
|
-
}
|