@wazo/sdk 1.0.0-alpha.1 → 1.0.0-alpha.11
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 +16 -7
- package/dist/wazo-sdk.js +6 -6
- package/esm/__tests__/__voice__/call.test.js +57 -2
- package/esm/api/auth.js +3 -0
- package/esm/checker/checks/webrtc.js +2 -2
- package/esm/domain/CallLog.js +2 -3
- package/esm/domain/Phone/CTIPhone.js +2 -2
- package/esm/domain/Phone/WebRTCPhone.js +64 -63
- package/esm/index.js +3 -1
- package/esm/service/CallApi.js +4 -4
- package/esm/simple/Auth.js +13 -3
- package/esm/simple/Phone.js +6 -5
- package/esm/simple/index.js +2 -1
- package/esm/simple/room/Room.js +2 -2
- package/esm/simple/room/SipRoom.js +2 -2
- package/esm/state-machine/call-state-machine.js +2 -2
- package/esm/state-machine/softphone-state-machine.js +1 -2
- package/esm/state-machine/utils.js +10 -4
- package/esm/types/api/auth.d.ts +3 -0
- package/esm/types/api/auth.d.ts.map +1 -1
- package/esm/types/checker/checks/index.d.ts +1 -1
- package/esm/types/checker/checks/webrtc-transport.d.ts +2 -2
- package/esm/types/checker/checks/webrtc-transport.d.ts.map +1 -1
- package/esm/types/domain/CallLog.d.ts.map +1 -1
- package/esm/types/domain/CallSession.d.ts +3 -3
- package/esm/types/domain/CallSession.d.ts.map +1 -1
- package/esm/types/domain/Phone/CTIPhone.d.ts.map +1 -1
- package/esm/types/domain/Phone/WebRTCPhone.d.ts +22 -22
- package/esm/types/domain/Phone/WebRTCPhone.d.ts.map +1 -1
- package/esm/types/domain/types.d.ts +0 -4
- package/esm/types/domain/types.d.ts.map +1 -1
- package/esm/types/index.d.ts +3 -1
- package/esm/types/index.d.ts.map +1 -1
- package/esm/types/lib/WazoSessionDescriptionHandler.d.ts +3 -3
- package/esm/types/lib/WazoSessionDescriptionHandler.d.ts.map +1 -1
- package/esm/types/service/CallApi.d.ts +5 -5
- package/esm/types/service/CallApi.d.ts.map +1 -1
- package/esm/types/simple/Auth.d.ts +6 -1
- package/esm/types/simple/Auth.d.ts.map +1 -1
- package/esm/types/simple/Phone.d.ts +8 -8
- package/esm/types/simple/Phone.d.ts.map +1 -1
- package/esm/types/simple/index.d.ts +3 -1
- package/esm/types/simple/index.d.ts.map +1 -1
- package/esm/types/state-machine/softphone-state-machine.d.ts +1 -2
- package/esm/types/state-machine/softphone-state-machine.d.ts.map +1 -1
- package/esm/types/state-machine/utils.d.ts +2 -2
- package/esm/types/state-machine/utils.d.ts.map +1 -1
- package/esm/types/utils/sdp.d.ts +3 -2
- package/esm/types/utils/sdp.d.ts.map +1 -1
- package/esm/types/utils/webrtc.d.ts +1 -0
- package/esm/types/utils/webrtc.d.ts.map +1 -1
- package/esm/types/voice/call.d.ts +30 -12
- package/esm/types/voice/call.d.ts.map +1 -1
- package/esm/types/voice/softphone.d.ts +25 -13
- package/esm/types/voice/softphone.d.ts.map +1 -1
- package/esm/types/web-rtc-client.d.ts +39 -38
- package/esm/types/web-rtc-client.d.ts.map +1 -1
- package/esm/utils/sdp.js +22 -9
- package/esm/utils/webrtc.js +23 -3
- package/esm/voice/call.js +131 -38
- package/esm/voice/softphone.js +145 -35
- package/esm/web-rtc-client.js +61 -58
- package/lib/__tests__/__voice__/call.test.js +56 -1
- package/lib/api/auth.js +3 -0
- package/lib/checker/checks/webrtc.js +1 -1
- package/lib/domain/CallLog.js +2 -3
- package/lib/domain/Phone/CTIPhone.js +2 -2
- package/lib/domain/Phone/WebRTCPhone.js +63 -62
- package/lib/index.js +7 -3
- package/lib/service/CallApi.js +2 -2
- package/lib/simple/Auth.js +15 -3
- package/lib/simple/Phone.js +3 -2
- package/lib/simple/index.js +2 -1
- package/lib/simple/room/Room.js +1 -1
- package/lib/simple/room/SipRoom.js +1 -1
- package/lib/state-machine/call-state-machine.js +2 -2
- package/lib/state-machine/softphone-state-machine.js +1 -2
- package/lib/state-machine/utils.js +10 -4
- package/lib/types/api/auth.d.ts +3 -0
- package/lib/types/api/auth.d.ts.map +1 -1
- package/lib/types/checker/checks/index.d.ts +1 -1
- package/lib/types/checker/checks/webrtc-transport.d.ts +2 -2
- package/lib/types/checker/checks/webrtc-transport.d.ts.map +1 -1
- package/lib/types/domain/CallLog.d.ts.map +1 -1
- package/lib/types/domain/CallSession.d.ts +3 -3
- package/lib/types/domain/CallSession.d.ts.map +1 -1
- package/lib/types/domain/Phone/CTIPhone.d.ts.map +1 -1
- package/lib/types/domain/Phone/WebRTCPhone.d.ts +22 -22
- package/lib/types/domain/Phone/WebRTCPhone.d.ts.map +1 -1
- package/lib/types/domain/types.d.ts +0 -4
- package/lib/types/domain/types.d.ts.map +1 -1
- package/lib/types/index.d.ts +3 -1
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/lib/WazoSessionDescriptionHandler.d.ts +3 -3
- package/lib/types/lib/WazoSessionDescriptionHandler.d.ts.map +1 -1
- package/lib/types/service/CallApi.d.ts +5 -5
- package/lib/types/service/CallApi.d.ts.map +1 -1
- package/lib/types/simple/Auth.d.ts +6 -1
- package/lib/types/simple/Auth.d.ts.map +1 -1
- package/lib/types/simple/Phone.d.ts +8 -8
- package/lib/types/simple/Phone.d.ts.map +1 -1
- package/lib/types/simple/index.d.ts +3 -1
- package/lib/types/simple/index.d.ts.map +1 -1
- package/lib/types/state-machine/softphone-state-machine.d.ts +1 -2
- package/lib/types/state-machine/softphone-state-machine.d.ts.map +1 -1
- package/lib/types/state-machine/utils.d.ts +2 -2
- package/lib/types/state-machine/utils.d.ts.map +1 -1
- package/lib/types/utils/sdp.d.ts +3 -2
- package/lib/types/utils/sdp.d.ts.map +1 -1
- package/lib/types/utils/webrtc.d.ts +1 -0
- package/lib/types/utils/webrtc.d.ts.map +1 -1
- package/lib/types/voice/call.d.ts +30 -12
- package/lib/types/voice/call.d.ts.map +1 -1
- package/lib/types/voice/softphone.d.ts +25 -13
- package/lib/types/voice/softphone.d.ts.map +1 -1
- package/lib/types/web-rtc-client.d.ts +39 -38
- package/lib/types/web-rtc-client.d.ts.map +1 -1
- package/lib/utils/sdp.js +25 -10
- package/lib/utils/webrtc.js +24 -3
- package/lib/voice/call.js +132 -36
- package/lib/voice/softphone.js +150 -35
- package/lib/web-rtc-client.js +59 -57
- package/package.json +1 -1
- package/src/__tests__/__voice__/call.test.ts +63 -2
- package/src/api/auth.ts +5 -0
- package/src/checker/checks/webrtc-transport.ts +2 -2
- package/src/checker/checks/webrtc.ts +2 -2
- package/src/domain/CallLog.ts +2 -3
- package/src/domain/CallSession.ts +3 -3
- package/src/domain/Phone/CTIPhone.ts +3 -2
- package/src/domain/Phone/WebRTCPhone.ts +95 -93
- package/src/domain/types.ts +0 -5
- package/src/index.ts +4 -1
- package/src/lib/WazoSessionDescriptionHandler.ts +3 -3
- package/src/service/CallApi.ts +7 -7
- package/src/simple/Auth.ts +15 -3
- package/src/simple/Phone.ts +12 -11
- package/src/simple/index.ts +2 -1
- package/src/simple/room/Room.ts +3 -3
- package/src/simple/room/SipRoom.ts +3 -3
- package/src/state-machine/call-state-machine.ts +2 -2
- package/src/state-machine/softphone-state-machine.ts +1 -2
- package/src/state-machine/utils.ts +14 -6
- package/src/utils/sdp.ts +26 -11
- package/src/utils/webrtc.ts +26 -4
- package/src/voice/call.ts +170 -50
- package/src/voice/softphone.ts +180 -41
- package/src/web-rtc-client.ts +106 -99
|
@@ -10,7 +10,7 @@ import { OutgoingByeRequest, OutgoingInviteRequest, OutgoingRequest } from 'sip.
|
|
|
10
10
|
import { Inviter, Invitation, Registerer } from 'sip.js/lib/api';
|
|
11
11
|
import Emitter from './utils/Emitter';
|
|
12
12
|
import Heartbeat from './utils/Heartbeat';
|
|
13
|
-
import type { MediaConfig, UserAgentConfigOverrides, WebRtcConfig,
|
|
13
|
+
import type { MediaConfig, UserAgentConfigOverrides, WebRtcConfig, SipCall } from './domain/types';
|
|
14
14
|
export declare const events: string[];
|
|
15
15
|
export declare const transportEvents: string[];
|
|
16
16
|
export declare class CanceledCallError extends Error {
|
|
@@ -35,7 +35,7 @@ export default class WebRTCClient extends Emitter {
|
|
|
35
35
|
heartbeatTimeoutCb: ((...args: Array<any>) => any) | null | undefined;
|
|
36
36
|
heartbeatCb: ((...args: Array<any>) => any) | null | undefined;
|
|
37
37
|
statsIntervals: Record<string, any>;
|
|
38
|
-
sipSessions: Record<string,
|
|
38
|
+
sipSessions: Record<string, SipCall>;
|
|
39
39
|
conferences: Record<string, boolean>;
|
|
40
40
|
skipRegister: boolean;
|
|
41
41
|
networkMonitoringInterval: Record<string, any>;
|
|
@@ -43,6 +43,7 @@ export default class WebRTCClient extends Emitter {
|
|
|
43
43
|
forceClosed: boolean;
|
|
44
44
|
ON_USER_AGENT: string;
|
|
45
45
|
REGISTERED: string;
|
|
46
|
+
REGISTERING: string;
|
|
46
47
|
UNREGISTERED: string;
|
|
47
48
|
REGISTRATION_FAILED: string;
|
|
48
49
|
INVITE: string;
|
|
@@ -60,7 +61,7 @@ export default class WebRTCClient extends Emitter {
|
|
|
60
61
|
ON_EARLY_MEDIA: string;
|
|
61
62
|
ON_PROGRESS: string;
|
|
62
63
|
ON_DISCONNECTED: string;
|
|
63
|
-
constructor(config: WebRtcConfig, session?:
|
|
64
|
+
constructor(config: WebRtcConfig, session?: SipCall, uaConfigOverrides?: UserAgentConfigOverrides);
|
|
64
65
|
configureMedia(media: MediaConfig): void;
|
|
65
66
|
setMediaConstraints(media: MediaStreamConstraints): void;
|
|
66
67
|
createUserAgent(uaConfigOverrides?: UserAgentConfigOverrides): UserAgent;
|
|
@@ -73,40 +74,40 @@ export default class WebRTCClient extends Emitter {
|
|
|
73
74
|
_monkeyPatchRegisterer(registerer: Registerer | null | undefined): void;
|
|
74
75
|
unregister(): Promise<void>;
|
|
75
76
|
stop(): Promise<void>;
|
|
76
|
-
call(number: string, enableVideo?: boolean, audioOnly?: boolean, conference?: boolean, options?: {}):
|
|
77
|
+
call(number: string, enableVideo?: boolean, audioOnly?: boolean, conference?: boolean, options?: {}): SipCall | null;
|
|
77
78
|
answer(session: Invitation, enableVideo?: boolean): Promise<void>;
|
|
78
|
-
hangup(session:
|
|
79
|
-
startNetworkMonitoring(session:
|
|
80
|
-
stopNetworkMonitoring(session:
|
|
81
|
-
reject(session:
|
|
79
|
+
hangup(session: SipCall): Promise<OutgoingByeRequest | null>;
|
|
80
|
+
startNetworkMonitoring(session: SipCall, interval?: number): void;
|
|
81
|
+
stopNetworkMonitoring(session: SipCall): void;
|
|
82
|
+
reject(session: SipCall): Promise<void>;
|
|
82
83
|
close(force?: boolean): Promise<void>;
|
|
83
|
-
mute(session:
|
|
84
|
-
unmute(session:
|
|
85
|
-
isAudioMuted(session:
|
|
86
|
-
toggleCameraOn(session:
|
|
87
|
-
toggleCameraOff(session:
|
|
88
|
-
hold(session:
|
|
89
|
-
unhold(session:
|
|
84
|
+
mute(session: SipCall): void;
|
|
85
|
+
unmute(session: SipCall): void;
|
|
86
|
+
isAudioMuted(session: SipCall): boolean;
|
|
87
|
+
toggleCameraOn(session: SipCall): void;
|
|
88
|
+
toggleCameraOff(session: SipCall): void;
|
|
89
|
+
hold(session: SipCall, isConference?: boolean, hadVideo?: boolean): Promise<OutgoingInviteRequest | void>;
|
|
90
|
+
unhold(session: SipCall, isConference?: boolean): Promise<OutgoingInviteRequest | void>;
|
|
90
91
|
getHeldSession(sessionId: string): any;
|
|
91
|
-
isCallHeld(session:
|
|
92
|
+
isCallHeld(session: SipCall): boolean;
|
|
92
93
|
isVideoRemotelyHeld(sessionId: string): boolean;
|
|
93
|
-
sendDTMF(session:
|
|
94
|
+
sendDTMF(session: SipCall, tone: string): boolean;
|
|
94
95
|
message(destination: string, message: string): void;
|
|
95
|
-
transfer(session:
|
|
96
|
-
atxfer(session:
|
|
97
|
-
sendMessage(sipSession:
|
|
96
|
+
transfer(session: SipCall, target: string): void;
|
|
97
|
+
atxfer(session: SipCall): Record<string, any>;
|
|
98
|
+
sendMessage(sipSession: SipCall | null | undefined, body: string, contentType?: string): void;
|
|
98
99
|
pingServer(): OutgoingRequest | void;
|
|
99
100
|
getState(): UserAgentState;
|
|
100
101
|
getContactIdentifier(): string | null;
|
|
101
102
|
changeAudioOutputVolume(volume: number): void;
|
|
102
103
|
changeAudioOutputDevice(id: string): Promise<void>;
|
|
103
|
-
changeAudioInputDevice(id: string, session:
|
|
104
|
-
changeVideoInputDevice(id: string, session?:
|
|
104
|
+
changeAudioInputDevice(id: string, session: SipCall | null | undefined, force?: boolean): Promise<MediaStream | null>;
|
|
105
|
+
changeVideoInputDevice(id: string, session?: SipCall): Promise<MediaStream | void>;
|
|
105
106
|
setVideoInputDevice(id: string): null | undefined;
|
|
106
|
-
changeSessionVideoInputDevice(id: string | null | undefined, session:
|
|
107
|
+
changeSessionVideoInputDevice(id: string | null | undefined, session: SipCall): Promise<MediaStream | void>;
|
|
107
108
|
getAudioDeviceId(): string | null | undefined;
|
|
108
109
|
getVideoDeviceId(): string | null;
|
|
109
|
-
reinvite(sipSession:
|
|
110
|
+
reinvite(sipSession: SipCall, newConstraints?: Record<string, any> | null | undefined, conference?: boolean, audioOnly?: boolean, iceRestart?: boolean): Promise<OutgoingInviteRequest | void>;
|
|
110
111
|
getUserMedia(constraints: Record<string, any>): Promise<MediaStream>;
|
|
111
112
|
getPeerConnection(sessionId: string): RTCPeerConnection | null | undefined;
|
|
112
113
|
getLocalStream(sessionId: string): MediaStream | null;
|
|
@@ -128,15 +129,15 @@ export default class WebRTCClient extends Emitter {
|
|
|
128
129
|
stopHeartbeat(): void;
|
|
129
130
|
setOnHeartbeatTimeout(cb: (...args: Array<any>) => any): void;
|
|
130
131
|
setOnHeartbeatCallback(cb: (...args: Array<any>) => any): void;
|
|
131
|
-
onCallEnded(session:
|
|
132
|
+
onCallEnded(session: SipCall): void;
|
|
132
133
|
attemptReconnection(): void;
|
|
133
|
-
storeSipSession(session:
|
|
134
|
-
getSipSession(id: string):
|
|
135
|
-
|
|
134
|
+
storeSipSession(session: SipCall): void;
|
|
135
|
+
getSipSession(id: string): SipCall | null | undefined;
|
|
136
|
+
getSipCallIds(): string[];
|
|
136
137
|
updateLocalStream(sipSessionId: string, newStream: MediaStream): Promise<void>;
|
|
137
138
|
isConference(sessionId: string): boolean;
|
|
138
139
|
createAudioElementFor(sessionId: string): Promise<HTMLAudioElement>;
|
|
139
|
-
_onTransportError(): void;
|
|
140
|
+
_onTransportError(reason?: string): void;
|
|
140
141
|
enableLogger(logConnector: (level: any, className: string, label: any, content: string) => void): void;
|
|
141
142
|
_onHeartbeat(message: string | Record<string, any>): void;
|
|
142
143
|
_onHeartbeatTimeout(): Promise<void>;
|
|
@@ -144,20 +145,20 @@ export default class WebRTCClient extends Emitter {
|
|
|
144
145
|
_getAudioConstraints(): MediaTrackConstraints | boolean;
|
|
145
146
|
_getVideoConstraints(video?: boolean): MediaTrackConstraints | boolean;
|
|
146
147
|
_connectIfNeeded(): Promise<any>;
|
|
147
|
-
_buildConfig(config: WebRtcConfig, session:
|
|
148
|
-
_setupSession(session:
|
|
149
|
-
_onProgress(session:
|
|
150
|
-
_onAccepted(session:
|
|
151
|
-
_setupMedias(session:
|
|
152
|
-
_cleanupMedia(session?:
|
|
148
|
+
_buildConfig(config: WebRtcConfig, session: SipCall | null | undefined): Promise<WebRtcConfig>;
|
|
149
|
+
_setupSession(session: SipCall): void;
|
|
150
|
+
_onProgress(session: SipCall, early?: boolean): Promise<void>;
|
|
151
|
+
_onAccepted(session: SipCall, sessionDialog?: SessionDialog, withEvent?: boolean, initAllTracks?: boolean): Promise<void>;
|
|
152
|
+
_setupMedias(session: SipCall, newStream?: MediaStream | null | undefined): Promise<void>;
|
|
153
|
+
_cleanupMedia(session?: SipCall): void;
|
|
153
154
|
_cleanupRegister(): void;
|
|
154
|
-
_startSendingStats(session:
|
|
155
|
-
_stopSendingStats(session:
|
|
155
|
+
_startSendingStats(session: SipCall): void;
|
|
156
|
+
_stopSendingStats(session: SipCall): void;
|
|
156
157
|
_disconnectTransport(force?: boolean): Promise<void>;
|
|
157
158
|
_fetchNetworkStats(sessionId: string): Promise<Record<string, any> | null | undefined>;
|
|
158
159
|
_accept(session: Invitation, options?: InvitationAcceptOptions): Promise<void>;
|
|
159
160
|
_reject(session: Invitation, options?: InvitationRejectOptions): Promise<void>;
|
|
160
161
|
_cancel(session: Inviter, options?: InviterCancelOptions): Promise<void>;
|
|
161
|
-
_bye(session:
|
|
162
|
+
_bye(session: SipCall, options?: SessionByeOptions): Promise<OutgoingByeRequest | null>;
|
|
162
163
|
}
|
|
163
164
|
//# sourceMappingURL=web-rtc-client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-rtc-client.d.ts","sourceRoot":"","sources":["../../src/web-rtc-client.ts"],"names":[],"mappings":"AAGA,OAAO,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,0CAA0C,CAAC;AACxF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAClF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAC5E,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,0CAA0C,CAAC;AACxF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAG5E,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAIjE,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAStD,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAC7F,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAoC,MAAM,gBAAgB,CAAC;AACnG,OAAO,OAAO,MAAM,iBAAiB,CAAC;AAGtC,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAE1C,OAAO,KAAK,EAAE,WAAW,EAAE,wBAAwB,EAAE,YAAY,EAAoC,
|
|
1
|
+
{"version":3,"file":"web-rtc-client.d.ts","sourceRoot":"","sources":["../../src/web-rtc-client.ts"],"names":[],"mappings":"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"}
|
package/esm/utils/sdp.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
/* eslint-disable no-underscore-dangle */
|
|
1
2
|
import sdpParser from 'sdp-transform';
|
|
2
3
|
import { UserAgent } from 'sip.js/lib/api/user-agent';
|
|
3
|
-
import { Inviter } from 'sip.js/lib/api';
|
|
4
|
-
export const SIP_ID_LENGTH = 36;
|
|
4
|
+
import { Inviter, Invitation } from 'sip.js/lib/api';
|
|
5
5
|
export const getCandidates = (rawSdp) => {
|
|
6
6
|
if (!rawSdp) {
|
|
7
7
|
return [];
|
|
@@ -105,22 +105,23 @@ export const addIcesInAllBundles = (sdp) => {
|
|
|
105
105
|
}));
|
|
106
106
|
return sdpParser.write(parsedSdp);
|
|
107
107
|
};
|
|
108
|
-
export const
|
|
108
|
+
export const getSipCallId = (sipSession) => {
|
|
109
109
|
if (!sipSession) {
|
|
110
110
|
return '';
|
|
111
111
|
}
|
|
112
|
-
const message = sipSession.message;
|
|
113
|
-
if (message?.callId) {
|
|
114
|
-
return message.callId.substring(0, SIP_ID_LENGTH);
|
|
115
|
-
}
|
|
116
112
|
// For Inviter
|
|
117
113
|
// @ts-ignore: private
|
|
118
114
|
if (sipSession instanceof Inviter && sipSession.outgoingRequestMessage) {
|
|
119
115
|
// @ts-ignore: private
|
|
120
|
-
return sipSession.outgoingRequestMessage.callId
|
|
116
|
+
return sipSession.outgoingRequestMessage.callId;
|
|
121
117
|
}
|
|
122
118
|
// For Invitation
|
|
123
|
-
|
|
119
|
+
// @ts-ignore: private
|
|
120
|
+
if (sipSession instanceof Invitation && sipSession.incomingInviteRequest.message) {
|
|
121
|
+
// @ts-ignore: private
|
|
122
|
+
return sipSession.incomingInviteRequest.message.callId;
|
|
123
|
+
}
|
|
124
|
+
return sipSession.id;
|
|
124
125
|
};
|
|
125
126
|
// We need to replace 0.0.0.0 to 127.0.0.1 in the sdp to avoid MOH during a createOffer.
|
|
126
127
|
export const replaceLocalIpModifier = (description) => Promise.resolve({
|
|
@@ -128,3 +129,15 @@ export const replaceLocalIpModifier = (description) => Promise.resolve({
|
|
|
128
129
|
sdp: description.sdp.replace('c=IN IP4 0.0.0.0', 'c=IN IP4 127.0.0.1'),
|
|
129
130
|
});
|
|
130
131
|
export const makeURI = (target, host) => UserAgent.makeURI(`sip:${target}@${host}`);
|
|
132
|
+
export const getCallNumber = (sipCall) => {
|
|
133
|
+
// eslint-disable-next-line
|
|
134
|
+
const identity = sipCall ? sipCall.remoteIdentity || sipCall.assertedIdentity : null;
|
|
135
|
+
// @ts-ignore: private
|
|
136
|
+
return identity ? identity.uri._normal.user : null;
|
|
137
|
+
};
|
|
138
|
+
export const getCallDisplayName = (sipCall) => {
|
|
139
|
+
// eslint-disable-next-line
|
|
140
|
+
const identity = sipCall ? sipCall.remoteIdentity || sipCall.assertedIdentity : null;
|
|
141
|
+
const number = getCallNumber(sipCall);
|
|
142
|
+
return identity ? identity.displayName || number : number;
|
|
143
|
+
};
|
package/esm/utils/webrtc.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defaultPeerConnectionConfiguration } from 'sip.js/lib/platform/web/session-description-handler/peer-connection-configuration-default';
|
|
2
2
|
import { stripVideo } from 'sip.js/lib/platform/web';
|
|
3
3
|
import WazoSessionDescriptionHandler, { wazoMediaStreamFactory } from '../lib/WazoSessionDescriptionHandler';
|
|
4
|
-
import { getVideoDirection, hasAnActiveVideo, makeURI, replaceLocalIpModifier } from './sdp';
|
|
4
|
+
import { getSipCallId, getVideoDirection, hasAnActiveVideo, makeURI, replaceLocalIpModifier } from './sdp';
|
|
5
5
|
import IssueReporter from '../service/IssueReporter';
|
|
6
6
|
import { lastIndexOf } from './array';
|
|
7
7
|
const logger = IssueReporter.loggerFor('webrtc');
|
|
@@ -173,12 +173,32 @@ export const toggleVideo = (sipCall, muteCamera) => {
|
|
|
173
173
|
});
|
|
174
174
|
}
|
|
175
175
|
};
|
|
176
|
+
export const isVideoMuted = (sipCall) => {
|
|
177
|
+
const sdh = sipCall.sessionDescriptionHandler;
|
|
178
|
+
const pc = sdh?.peerConnection;
|
|
179
|
+
if (pc?.getSenders) {
|
|
180
|
+
for (const sender of pc.getSenders()) {
|
|
181
|
+
if (sender && sender.track && sender.track.kind === 'video') {
|
|
182
|
+
return !sender.track.enabled;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
for (const stream of pc.getLocalStreams()) {
|
|
188
|
+
// eslint-disable-next-line no-unreachable-loop
|
|
189
|
+
for (const track of stream.getVideoTracks()) {
|
|
190
|
+
return !track.enabled;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return true;
|
|
195
|
+
};
|
|
176
196
|
export const cleanupStream = (stream) => {
|
|
177
197
|
stream.getTracks().filter(track => track.enabled).forEach(track => track.stop());
|
|
178
198
|
};
|
|
179
199
|
export const setLocalMediaStream = (sipCall, newStream) => {
|
|
180
200
|
logger.info('setting local media stream', {
|
|
181
|
-
id: sipCall
|
|
201
|
+
id: getSipCallId(sipCall),
|
|
182
202
|
tracks: newStream ? newStream.getTracks() : null,
|
|
183
203
|
});
|
|
184
204
|
if (sipCall.sessionDescriptionHandler) {
|
|
@@ -191,7 +211,7 @@ export const updateRemoteStream = (sipCall, allTracks = true) => {
|
|
|
191
211
|
const remoteStream = getRemoteStream(sipCall);
|
|
192
212
|
const pc = getPeerConnection(sipCall);
|
|
193
213
|
logger.info('Updating remote stream', {
|
|
194
|
-
id: sipCall
|
|
214
|
+
id: getSipCallId(sipCall),
|
|
195
215
|
tracks: remoteStream ? remoteStream.getTracks() : null,
|
|
196
216
|
receiverTracks: pc && pc.getReceivers ? pc.getReceivers().map((receiver) => receiver.track) : null,
|
|
197
217
|
});
|
package/esm/voice/call.js
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
/* eslint-disable no-underscore-dangle */
|
|
2
2
|
import { EventEmitter } from 'events';
|
|
3
3
|
import { createActor } from 'xstate';
|
|
4
|
+
import { Inviter } from 'sip.js/lib/api/inviter';
|
|
4
5
|
import { Invitation } from 'sip.js/lib/api/invitation';
|
|
5
6
|
import { SessionState } from 'sip.js/lib/api/session-state';
|
|
6
7
|
import callStateMachine, { Actions, EstablishedActions, States, EstablishedStates } from '../state-machine/call-state-machine';
|
|
8
|
+
import newFrom from '../utils/new-from';
|
|
9
|
+
import updateFrom from '../utils/update-from';
|
|
7
10
|
import IssueReporter from '../service/IssueReporter';
|
|
8
|
-
import
|
|
11
|
+
import softphone from './softphone';
|
|
12
|
+
import { getCallDisplayName, getCallNumber, getSipCallId } from '../utils/sdp';
|
|
9
13
|
import { assertCan, assertState, getState } from '../state-machine/utils';
|
|
10
|
-
import { downgradeToAudio, getLocalStream, getLocalVideoStream, getPeerConnection, getRemoteStream, getRemoteVideoStream, getStreamFromConstraints, getWebRtcStats, hasALocalVideoTrack, hasLocalVideo, hasRemoteVideo, isVideoRemotelyHeld, setLocalMediaStream, toggleVideo, upgradeToVideo } from '../utils/webrtc';
|
|
14
|
+
import { downgradeToAudio, getLocalStream, getLocalVideoStream, getPeerConnection, getRemoteStream, getRemoteVideoStream, getStreamFromConstraints, getWebRtcStats, hasALocalVideoTrack, hasLocalVideo, hasRemoteVideo, isVideoMuted, isVideoRemotelyHeld, setLocalMediaStream, toggleVideo, upgradeToVideo } from '../utils/webrtc';
|
|
11
15
|
const logger = IssueReporter.loggerFor('call');
|
|
12
16
|
// Events
|
|
13
|
-
export const
|
|
17
|
+
export const EVENT_CALL_REMOTLY_ACCEPTED = 'remotelyAccepted';
|
|
18
|
+
export const EVENT_CALL_LOCALLY_ACCEPTED = 'locallyAccepted';
|
|
14
19
|
export const EVENT_CALL_CANCELED = 'canceled';
|
|
15
20
|
export const EVENT_PROGRESS = 'progress';
|
|
16
21
|
export const EVENT_EARLY_MEDIA = 'earlyMedia';
|
|
@@ -33,12 +38,10 @@ export const EVENT_SHARE_SCREEN_ENDED = 'onScreenShareEnded';
|
|
|
33
38
|
export const EVENT_WEB_RTC_STATS = 'webRtcStats';
|
|
34
39
|
export const EVENT_CAMERA_RESUMED = 'onCameraResumed';
|
|
35
40
|
export const EVENT_CAMERA_DISABLED = 'onCameraDisabled';
|
|
36
|
-
export const EVENT_TERMINATE_SOUND = 'terminateSound';
|
|
37
41
|
export const MESSAGE_TYPE_CHAT = 'message/TYPE_CHAT';
|
|
38
42
|
export const MESSAGE_TYPE_SIGNAL = 'message/TYPE_SIGNAL';
|
|
39
43
|
export const MESSAGE_TRACK_UPDATED = 'onTrackUpdated';
|
|
40
44
|
class Call extends EventEmitter {
|
|
41
|
-
eventEmitter;
|
|
42
45
|
callActor;
|
|
43
46
|
// Wazo call id, used in Wazo Websocket and API
|
|
44
47
|
apiId;
|
|
@@ -49,7 +52,54 @@ class Call extends EventEmitter {
|
|
|
49
52
|
endTime;
|
|
50
53
|
phone;
|
|
51
54
|
shouldSendReinvite = false;
|
|
55
|
+
recording = false;
|
|
56
|
+
displayName;
|
|
57
|
+
number;
|
|
52
58
|
currentScreenShare;
|
|
59
|
+
static newFrom(call) {
|
|
60
|
+
return newFrom(call, Call);
|
|
61
|
+
}
|
|
62
|
+
static parseCall(apiCall) {
|
|
63
|
+
const sipCall = {
|
|
64
|
+
id: apiCall.sipCallId,
|
|
65
|
+
stateChange: {
|
|
66
|
+
addListener: () => { },
|
|
67
|
+
},
|
|
68
|
+
remoteIdentity: {
|
|
69
|
+
uri: {
|
|
70
|
+
_normal: {
|
|
71
|
+
user: apiCall.calleeNumber,
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
// Mock sdk so `hasLocalVideo` will return true.
|
|
76
|
+
sessionDescriptionHandler: {
|
|
77
|
+
localMediaStream: {
|
|
78
|
+
getTracks: () => (apiCall.isVideo ? [{ kind: 'video', readyState: 'live' }] : []),
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
const call = new Call(sipCall, softphone);
|
|
83
|
+
call.apiId = apiCall.id;
|
|
84
|
+
call.answerTime = new Date(+apiCall.startingTime);
|
|
85
|
+
// Update call state
|
|
86
|
+
const snapshot = call.callActor.getSnapshot();
|
|
87
|
+
if (apiCall.isUp()) {
|
|
88
|
+
snapshot.value = { [States.ESTABLISHED]: EstablishedStates.ONGOING };
|
|
89
|
+
}
|
|
90
|
+
if (apiCall.muted) {
|
|
91
|
+
snapshot.value = { [States.ESTABLISHED]: EstablishedStates.MUTED };
|
|
92
|
+
}
|
|
93
|
+
if (apiCall.isRinging()) {
|
|
94
|
+
snapshot.value = States.RINGING;
|
|
95
|
+
}
|
|
96
|
+
if (apiCall.isRecording()) {
|
|
97
|
+
call.recording = true;
|
|
98
|
+
}
|
|
99
|
+
// @ts-ignore
|
|
100
|
+
call.callActor.update(snapshot);
|
|
101
|
+
return call;
|
|
102
|
+
}
|
|
53
103
|
constructor(sipCall, phone) {
|
|
54
104
|
super();
|
|
55
105
|
this.callActor = createActor(callStateMachine);
|
|
@@ -57,7 +107,8 @@ class Call extends EventEmitter {
|
|
|
57
107
|
this.creationTime = new Date();
|
|
58
108
|
this.phone = phone;
|
|
59
109
|
this.sipCall = sipCall;
|
|
60
|
-
this.
|
|
110
|
+
this.number = getCallNumber(sipCall);
|
|
111
|
+
this.displayName = getCallDisplayName(sipCall);
|
|
61
112
|
}
|
|
62
113
|
async accept(options = {}) {
|
|
63
114
|
assertCan(this.callActor, Actions.ACCEPT);
|
|
@@ -68,6 +119,7 @@ class Call extends EventEmitter {
|
|
|
68
119
|
this.answerTime = new Date();
|
|
69
120
|
return this.phone.client.answer(this.sipCall, options.withCamera).then(() => {
|
|
70
121
|
logger.info('call - accepted', { id: this.id, ...options });
|
|
122
|
+
this.emit(EVENT_CALL_LOCALLY_ACCEPTED, this);
|
|
71
123
|
return this.id;
|
|
72
124
|
}).catch(e => {
|
|
73
125
|
logger.error(e);
|
|
@@ -78,16 +130,18 @@ class Call extends EventEmitter {
|
|
|
78
130
|
async reject() {
|
|
79
131
|
assertCan(this.callActor, Actions.REJECT);
|
|
80
132
|
logger.info('call - reject', { id: this.id });
|
|
81
|
-
this.
|
|
82
|
-
this.shouldSendReinvite = false;
|
|
83
|
-
return this.hangup();
|
|
133
|
+
return this._terminate();
|
|
84
134
|
}
|
|
85
135
|
async hangup() {
|
|
86
136
|
assertCan(this.callActor, Actions.HANGUP);
|
|
87
137
|
logger.info('call - hangup', { id: this.id });
|
|
138
|
+
return this._terminate();
|
|
139
|
+
}
|
|
140
|
+
async _terminate() {
|
|
88
141
|
await this.phone.client.hangup(this.sipCall);
|
|
142
|
+
this.shouldSendReinvite = false;
|
|
89
143
|
// Remove this call from softphone's calls
|
|
90
|
-
this.phone.
|
|
144
|
+
this.phone.onCallTerminated(this);
|
|
91
145
|
return true;
|
|
92
146
|
}
|
|
93
147
|
forceCancel() {
|
|
@@ -99,7 +153,7 @@ class Call extends EventEmitter {
|
|
|
99
153
|
logger.info('call - force cancel, error', e);
|
|
100
154
|
}
|
|
101
155
|
}
|
|
102
|
-
startConference(withCalls) {
|
|
156
|
+
startConference( /* withCalls: Call[] */) {
|
|
103
157
|
// @TODO
|
|
104
158
|
// const participants = [this, ...withCalls].reduce((acc: Record<string, any>, call: Call) => {
|
|
105
159
|
// acc[call.talkingToIds[0]] = call;
|
|
@@ -117,14 +171,14 @@ class Call extends EventEmitter {
|
|
|
117
171
|
logger.info('call - mute', { id: this.id });
|
|
118
172
|
this._sendAction(EstablishedActions.MUTE);
|
|
119
173
|
this.phone.client.mute(this.sipCall);
|
|
120
|
-
this.
|
|
174
|
+
this.emit(EVENT_CALL_MUTED);
|
|
121
175
|
}
|
|
122
176
|
unMute() {
|
|
123
177
|
assertCan(this.callActor, EstablishedActions.UN_MUTE);
|
|
124
178
|
logger.info('call - un-mute', { id: this.id });
|
|
125
179
|
this._sendAction(EstablishedActions.UN_MUTE);
|
|
126
180
|
this.phone.client.unmute(this.sipCall);
|
|
127
|
-
this.
|
|
181
|
+
this.emit(EVENT_CALL_UN_MUTED);
|
|
128
182
|
}
|
|
129
183
|
async hold() {
|
|
130
184
|
assertCan(this.callActor, EstablishedActions.HOLD);
|
|
@@ -140,7 +194,7 @@ class Call extends EventEmitter {
|
|
|
140
194
|
await downgradeToAudio(this.sipCall);
|
|
141
195
|
}
|
|
142
196
|
const promise = this.phone.client.hold(this.sipCall, this.isConference(), hasVideo);
|
|
143
|
-
this.
|
|
197
|
+
this.emit(EVENT_CALL_HELD);
|
|
144
198
|
return promise;
|
|
145
199
|
}
|
|
146
200
|
async resume() {
|
|
@@ -167,7 +221,7 @@ class Call extends EventEmitter {
|
|
|
167
221
|
this._onScreenSharing(stream, hadVideo, wasDesktop);
|
|
168
222
|
}
|
|
169
223
|
};
|
|
170
|
-
this.
|
|
224
|
+
this.emit(EVENT_CALL_RESUMED);
|
|
171
225
|
return promise.then(() => {
|
|
172
226
|
const stream = this.getLocalVideoStream();
|
|
173
227
|
if (wasScreensharing) {
|
|
@@ -180,19 +234,37 @@ class Call extends EventEmitter {
|
|
|
180
234
|
assertState(this.callActor, States.ESTABLISHED);
|
|
181
235
|
logger.info('call - turn camera on', { id: this.id });
|
|
182
236
|
toggleVideo(this.sipCall, true);
|
|
183
|
-
this.
|
|
237
|
+
this.emit(EVENT_CAMERA_RESUMED);
|
|
184
238
|
}
|
|
185
239
|
turnCameraOff() {
|
|
186
240
|
assertState(this.callActor, States.ESTABLISHED);
|
|
187
241
|
logger.info('call - turn camera off', { id: this.id });
|
|
188
242
|
toggleVideo(this.sipCall, false);
|
|
189
|
-
this.
|
|
243
|
+
this.emit(EVENT_CAMERA_DISABLED);
|
|
244
|
+
}
|
|
245
|
+
isMuted() {
|
|
246
|
+
return this._hasEstablishedState(EstablishedStates.MUTED);
|
|
247
|
+
}
|
|
248
|
+
isCameraMuted() {
|
|
249
|
+
return isVideoMuted(this.sipCall);
|
|
190
250
|
}
|
|
191
251
|
isHeld() {
|
|
192
|
-
return
|
|
252
|
+
return this._hasEstablishedState(EstablishedStates.HELD);
|
|
253
|
+
}
|
|
254
|
+
isEstablishing() {
|
|
255
|
+
return this.sipCall.state === SessionState.Establishing;
|
|
193
256
|
}
|
|
194
257
|
isEstablished() {
|
|
195
|
-
return
|
|
258
|
+
return typeof this.state === 'object' && States.ESTABLISHED in this.state;
|
|
259
|
+
}
|
|
260
|
+
isRinging() {
|
|
261
|
+
return this.state === States.RINGING;
|
|
262
|
+
}
|
|
263
|
+
isOutgoing() {
|
|
264
|
+
return this.sipCall instanceof Inviter;
|
|
265
|
+
}
|
|
266
|
+
isIncoming() {
|
|
267
|
+
return !this.isOutgoing();
|
|
196
268
|
}
|
|
197
269
|
isConference() {
|
|
198
270
|
return getPeerConnection(this.sipCall)?.sfu;
|
|
@@ -200,7 +272,7 @@ class Call extends EventEmitter {
|
|
|
200
272
|
transfer(target) {
|
|
201
273
|
assertState(this.callActor, States.ESTABLISHED);
|
|
202
274
|
logger.info('call - transfer', { id: this.id, target });
|
|
203
|
-
this.phone.client.transfer(this.sipCall, target);
|
|
275
|
+
return this.phone.client.transfer(this.sipCall, target);
|
|
204
276
|
}
|
|
205
277
|
atxfer() {
|
|
206
278
|
assertState(this.callActor, States.ESTABLISHED);
|
|
@@ -320,7 +392,7 @@ class Call extends EventEmitter {
|
|
|
320
392
|
catch (e) {
|
|
321
393
|
console.warn(e);
|
|
322
394
|
}
|
|
323
|
-
this.
|
|
395
|
+
this.emit(EVENT_SHARE_SCREEN_ENDED);
|
|
324
396
|
this.currentScreenShare = null;
|
|
325
397
|
return reinvited;
|
|
326
398
|
}
|
|
@@ -329,9 +401,13 @@ class Call extends EventEmitter {
|
|
|
329
401
|
logger.info('call - updrading directly in screensharing mode', { id: this.id, tracks: localStream?.getTracks() });
|
|
330
402
|
this._onScreenSharing(localStream, false, desktop);
|
|
331
403
|
}
|
|
404
|
+
onMakeCall() {
|
|
405
|
+
this._bindEvents();
|
|
406
|
+
this._sendAction(Actions.MAKE_CALL);
|
|
407
|
+
}
|
|
332
408
|
onAccepted() {
|
|
333
409
|
this._sendAction(Actions.REMOTLY_ACCEPTED);
|
|
334
|
-
this.emit(
|
|
410
|
+
this.emit(EVENT_CALL_REMOTLY_ACCEPTED);
|
|
335
411
|
}
|
|
336
412
|
onProgress() {
|
|
337
413
|
this.emit(EVENT_PROGRESS);
|
|
@@ -345,10 +421,14 @@ class Call extends EventEmitter {
|
|
|
345
421
|
onError(error) {
|
|
346
422
|
this.emit(EVENT_CALL_ERROR, error);
|
|
347
423
|
}
|
|
424
|
+
onCallIncoming() {
|
|
425
|
+
this._bindEvents();
|
|
426
|
+
this._sendAction(Actions.INCOMING_CALL);
|
|
427
|
+
}
|
|
348
428
|
onRejected() {
|
|
349
429
|
this.endTime = new Date();
|
|
350
430
|
this.emit(EVENT_CALL_REJECTED);
|
|
351
|
-
this.phone.
|
|
431
|
+
this.phone.onCallTerminated(this);
|
|
352
432
|
}
|
|
353
433
|
onNetworkStats(stats, previousStats) {
|
|
354
434
|
this.emit(EVENT_WEB_RTC_STATS, stats, previousStats);
|
|
@@ -380,13 +460,24 @@ class Call extends EventEmitter {
|
|
|
380
460
|
onReinvite(request, updatedCalleeName, updatedNumber, hadRemoteVideo) {
|
|
381
461
|
this.emit(EVENT_REINVITE, request, updatedCalleeName, updatedNumber, hadRemoteVideo);
|
|
382
462
|
}
|
|
463
|
+
updateFrom(call) {
|
|
464
|
+
updateFrom(this, call);
|
|
465
|
+
}
|
|
466
|
+
is(otherCall) {
|
|
467
|
+
return otherCall && this.id && this.id === otherCall.id;
|
|
468
|
+
}
|
|
469
|
+
shouldAutoAnswer() {
|
|
470
|
+
return !!this.sipCall.request?.getHeader('alert-info');
|
|
471
|
+
}
|
|
383
472
|
get id() {
|
|
384
|
-
return
|
|
473
|
+
return getSipCallId(this.sipCall);
|
|
474
|
+
}
|
|
475
|
+
get state() {
|
|
476
|
+
return getState(this.callActor);
|
|
385
477
|
}
|
|
386
|
-
|
|
387
|
-
const
|
|
388
|
-
|
|
389
|
-
return identity ? identity.uri._normal.user : null;
|
|
478
|
+
_hasEstablishedState(establishedState) {
|
|
479
|
+
const state = this.state;
|
|
480
|
+
return typeof state === 'object' && States.ESTABLISHED in state && state[States.ESTABLISHED] === establishedState;
|
|
390
481
|
}
|
|
391
482
|
_bindEvents() {
|
|
392
483
|
if (this.sipCall instanceof Invitation) {
|
|
@@ -396,21 +487,22 @@ class Call extends EventEmitter {
|
|
|
396
487
|
logger.trace('call - on sip session canceled', { callId: message.callId, id: this.id });
|
|
397
488
|
onCancel(message);
|
|
398
489
|
const elsewhere = message.data.indexOf('cause=26') !== -1 && message.data.indexOf('completed elsewhere') !== -1;
|
|
399
|
-
this.
|
|
490
|
+
this.emit(EVENT_CALL_CANCELED, elsewhere);
|
|
400
491
|
};
|
|
401
492
|
}
|
|
402
|
-
this.sipCall
|
|
493
|
+
this.sipCall?.stateChange?.addListener((newState) => {
|
|
403
494
|
switch (newState) {
|
|
404
495
|
case SessionState.Terminating:
|
|
405
496
|
logger.info('call - terminating', { id: this.id });
|
|
406
|
-
this.
|
|
497
|
+
this.emit(EVENT_CALL_TERMINATING);
|
|
407
498
|
break;
|
|
408
499
|
case SessionState.Terminated:
|
|
409
500
|
{
|
|
410
501
|
logger.info('call - terminated', { id: this.id });
|
|
411
502
|
// Should be called before `_onCallTerminated` or the callCount will not decrement...
|
|
412
503
|
this.endTime = new Date();
|
|
413
|
-
|
|
504
|
+
this.emit(EVENT_CALL_ENDED);
|
|
505
|
+
return this.phone.onCallTerminated(this);
|
|
414
506
|
}
|
|
415
507
|
default:
|
|
416
508
|
break;
|
|
@@ -437,18 +529,17 @@ class Call extends EventEmitter {
|
|
|
437
529
|
kind,
|
|
438
530
|
});
|
|
439
531
|
if (kind === 'audio') {
|
|
440
|
-
return this.
|
|
532
|
+
return this.emit(EVENT_AUDIO_STREAM, stream);
|
|
441
533
|
}
|
|
442
|
-
return this.
|
|
534
|
+
return this.emit(EVENT_VIDEO_STREAM, stream, event.track.id, event);
|
|
443
535
|
};
|
|
444
536
|
peerConnection.onremovestream = (event) => {
|
|
445
537
|
logger.info('call - on remove stream called on the peer connection', {
|
|
446
538
|
id: event.stream.id,
|
|
447
539
|
tracks: event.stream.getTracks(),
|
|
448
540
|
});
|
|
449
|
-
this.
|
|
541
|
+
this.emit(EVENT_REMOVE_STREAM, event.stream);
|
|
450
542
|
};
|
|
451
|
-
// Client events
|
|
452
543
|
}
|
|
453
544
|
_downgradeToAudio(withMessage = true) {
|
|
454
545
|
assertState(this.callActor, States.ESTABLISHED);
|
|
@@ -508,7 +599,7 @@ class Call extends EventEmitter {
|
|
|
508
599
|
if (screenTrack) {
|
|
509
600
|
screenTrack.onended = () => {
|
|
510
601
|
logger.info('call - on screenshare ended', { hadVideo, id: this.id, screenTrack });
|
|
511
|
-
this.
|
|
602
|
+
this.emit(EVENT_SHARE_SCREEN_ENDING);
|
|
512
603
|
};
|
|
513
604
|
}
|
|
514
605
|
this.currentScreenShare = {
|
|
@@ -518,10 +609,12 @@ class Call extends EventEmitter {
|
|
|
518
609
|
desktop,
|
|
519
610
|
};
|
|
520
611
|
setLocalMediaStream(this.sipCall, screenStream);
|
|
521
|
-
this.
|
|
612
|
+
this.emit(EVENT_SHARE_SCREEN_STARTED, screenStream);
|
|
522
613
|
}
|
|
523
614
|
_sendAction(action) {
|
|
615
|
+
const was = this.state;
|
|
524
616
|
this.callActor.send({ type: action });
|
|
617
|
+
logger.trace('call - send action', { action, was, state: this.state });
|
|
525
618
|
}
|
|
526
619
|
}
|
|
527
620
|
export default Call;
|