@wazo/sdk 1.0.0-alpha.1 → 1.0.0-alpha.10
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 +8 -3
- 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 +130 -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 +8 -3
- 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 +131 -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 +12 -5
- package/src/utils/sdp.ts +26 -11
- package/src/utils/webrtc.ts +26 -4
- package/src/voice/call.ts +169 -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
|
@@ -4,13 +4,17 @@ import { createActor } from 'xstate';
|
|
|
4
4
|
import { Invitation } from 'sip.js/lib/api/invitation';
|
|
5
5
|
import { SessionState } from 'sip.js/lib/api/session-state';
|
|
6
6
|
import callStateMachine, { Actions, EstablishedActions, States, EstablishedStates } from '../state-machine/call-state-machine';
|
|
7
|
+
import newFrom from '../utils/new-from';
|
|
8
|
+
import updateFrom from '../utils/update-from';
|
|
7
9
|
import IssueReporter from '../service/IssueReporter';
|
|
8
|
-
import
|
|
10
|
+
import softphone from './softphone';
|
|
11
|
+
import { getCallDisplayName, getCallNumber, getSipCallId } from '../utils/sdp';
|
|
9
12
|
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';
|
|
13
|
+
import { downgradeToAudio, getLocalStream, getLocalVideoStream, getPeerConnection, getRemoteStream, getRemoteVideoStream, getStreamFromConstraints, getWebRtcStats, hasALocalVideoTrack, hasLocalVideo, hasRemoteVideo, isVideoMuted, isVideoRemotelyHeld, setLocalMediaStream, toggleVideo, upgradeToVideo } from '../utils/webrtc';
|
|
11
14
|
const logger = IssueReporter.loggerFor('call');
|
|
12
15
|
// Events
|
|
13
|
-
export const
|
|
16
|
+
export const EVENT_CALL_REMOTLY_ACCEPTED = 'remotelyAccepted';
|
|
17
|
+
export const EVENT_CALL_LOCALLY_ACCEPTED = 'locallyAccepted';
|
|
14
18
|
export const EVENT_CALL_CANCELED = 'canceled';
|
|
15
19
|
export const EVENT_PROGRESS = 'progress';
|
|
16
20
|
export const EVENT_EARLY_MEDIA = 'earlyMedia';
|
|
@@ -33,12 +37,10 @@ export const EVENT_SHARE_SCREEN_ENDED = 'onScreenShareEnded';
|
|
|
33
37
|
export const EVENT_WEB_RTC_STATS = 'webRtcStats';
|
|
34
38
|
export const EVENT_CAMERA_RESUMED = 'onCameraResumed';
|
|
35
39
|
export const EVENT_CAMERA_DISABLED = 'onCameraDisabled';
|
|
36
|
-
export const EVENT_TERMINATE_SOUND = 'terminateSound';
|
|
37
40
|
export const MESSAGE_TYPE_CHAT = 'message/TYPE_CHAT';
|
|
38
41
|
export const MESSAGE_TYPE_SIGNAL = 'message/TYPE_SIGNAL';
|
|
39
42
|
export const MESSAGE_TRACK_UPDATED = 'onTrackUpdated';
|
|
40
43
|
class Call extends EventEmitter {
|
|
41
|
-
eventEmitter;
|
|
42
44
|
callActor;
|
|
43
45
|
// Wazo call id, used in Wazo Websocket and API
|
|
44
46
|
apiId;
|
|
@@ -49,7 +51,54 @@ class Call extends EventEmitter {
|
|
|
49
51
|
endTime;
|
|
50
52
|
phone;
|
|
51
53
|
shouldSendReinvite = false;
|
|
54
|
+
recording = false;
|
|
55
|
+
displayName;
|
|
56
|
+
number;
|
|
52
57
|
currentScreenShare;
|
|
58
|
+
static newFrom(call) {
|
|
59
|
+
return newFrom(call, Call);
|
|
60
|
+
}
|
|
61
|
+
static parseCall(apiCall) {
|
|
62
|
+
const sipCall = {
|
|
63
|
+
id: apiCall.sipCallId,
|
|
64
|
+
stateChange: {
|
|
65
|
+
addListener: () => { },
|
|
66
|
+
},
|
|
67
|
+
remoteIdentity: {
|
|
68
|
+
uri: {
|
|
69
|
+
_normal: {
|
|
70
|
+
user: apiCall.calleeNumber,
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
// Mock sdk so `hasLocalVideo` will return true.
|
|
75
|
+
sessionDescriptionHandler: {
|
|
76
|
+
localMediaStream: {
|
|
77
|
+
getTracks: () => (apiCall.isVideo ? [{ kind: 'video', readyState: 'live' }] : []),
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
const call = new Call(sipCall, softphone);
|
|
82
|
+
call.apiId = apiCall.id;
|
|
83
|
+
call.answerTime = new Date(+apiCall.startingTime);
|
|
84
|
+
// Update call state
|
|
85
|
+
const snapshot = call.callActor.getSnapshot();
|
|
86
|
+
if (apiCall.isUp()) {
|
|
87
|
+
snapshot.value = { [States.ESTABLISHED]: EstablishedStates.ONGOING };
|
|
88
|
+
}
|
|
89
|
+
if (apiCall.muted) {
|
|
90
|
+
snapshot.value = { [States.ESTABLISHED]: EstablishedStates.MUTED };
|
|
91
|
+
}
|
|
92
|
+
if (apiCall.isRinging()) {
|
|
93
|
+
snapshot.value = States.RINGING;
|
|
94
|
+
}
|
|
95
|
+
if (apiCall.isRecording()) {
|
|
96
|
+
call.recording = true;
|
|
97
|
+
}
|
|
98
|
+
// @ts-ignore
|
|
99
|
+
call.callActor.update(snapshot);
|
|
100
|
+
return call;
|
|
101
|
+
}
|
|
53
102
|
constructor(sipCall, phone) {
|
|
54
103
|
super();
|
|
55
104
|
this.callActor = createActor(callStateMachine);
|
|
@@ -57,7 +106,8 @@ class Call extends EventEmitter {
|
|
|
57
106
|
this.creationTime = new Date();
|
|
58
107
|
this.phone = phone;
|
|
59
108
|
this.sipCall = sipCall;
|
|
60
|
-
this.
|
|
109
|
+
this.number = getCallNumber(sipCall);
|
|
110
|
+
this.displayName = getCallDisplayName(sipCall);
|
|
61
111
|
}
|
|
62
112
|
async accept(options = {}) {
|
|
63
113
|
assertCan(this.callActor, Actions.ACCEPT);
|
|
@@ -68,6 +118,7 @@ class Call extends EventEmitter {
|
|
|
68
118
|
this.answerTime = new Date();
|
|
69
119
|
return this.phone.client.answer(this.sipCall, options.withCamera).then(() => {
|
|
70
120
|
logger.info('call - accepted', { id: this.id, ...options });
|
|
121
|
+
this.emit(EVENT_CALL_LOCALLY_ACCEPTED, this);
|
|
71
122
|
return this.id;
|
|
72
123
|
}).catch(e => {
|
|
73
124
|
logger.error(e);
|
|
@@ -78,16 +129,18 @@ class Call extends EventEmitter {
|
|
|
78
129
|
async reject() {
|
|
79
130
|
assertCan(this.callActor, Actions.REJECT);
|
|
80
131
|
logger.info('call - reject', { id: this.id });
|
|
81
|
-
this.
|
|
82
|
-
this.shouldSendReinvite = false;
|
|
83
|
-
return this.hangup();
|
|
132
|
+
return this._terminate();
|
|
84
133
|
}
|
|
85
134
|
async hangup() {
|
|
86
135
|
assertCan(this.callActor, Actions.HANGUP);
|
|
87
136
|
logger.info('call - hangup', { id: this.id });
|
|
137
|
+
return this._terminate();
|
|
138
|
+
}
|
|
139
|
+
async _terminate() {
|
|
88
140
|
await this.phone.client.hangup(this.sipCall);
|
|
141
|
+
this.shouldSendReinvite = false;
|
|
89
142
|
// Remove this call from softphone's calls
|
|
90
|
-
this.phone.
|
|
143
|
+
this.phone.onCallTerminated(this);
|
|
91
144
|
return true;
|
|
92
145
|
}
|
|
93
146
|
forceCancel() {
|
|
@@ -99,7 +152,7 @@ class Call extends EventEmitter {
|
|
|
99
152
|
logger.info('call - force cancel, error', e);
|
|
100
153
|
}
|
|
101
154
|
}
|
|
102
|
-
startConference(withCalls) {
|
|
155
|
+
startConference( /* withCalls: Call[] */) {
|
|
103
156
|
// @TODO
|
|
104
157
|
// const participants = [this, ...withCalls].reduce((acc: Record<string, any>, call: Call) => {
|
|
105
158
|
// acc[call.talkingToIds[0]] = call;
|
|
@@ -117,14 +170,14 @@ class Call extends EventEmitter {
|
|
|
117
170
|
logger.info('call - mute', { id: this.id });
|
|
118
171
|
this._sendAction(EstablishedActions.MUTE);
|
|
119
172
|
this.phone.client.mute(this.sipCall);
|
|
120
|
-
this.
|
|
173
|
+
this.emit(EVENT_CALL_MUTED);
|
|
121
174
|
}
|
|
122
175
|
unMute() {
|
|
123
176
|
assertCan(this.callActor, EstablishedActions.UN_MUTE);
|
|
124
177
|
logger.info('call - un-mute', { id: this.id });
|
|
125
178
|
this._sendAction(EstablishedActions.UN_MUTE);
|
|
126
179
|
this.phone.client.unmute(this.sipCall);
|
|
127
|
-
this.
|
|
180
|
+
this.emit(EVENT_CALL_UN_MUTED);
|
|
128
181
|
}
|
|
129
182
|
async hold() {
|
|
130
183
|
assertCan(this.callActor, EstablishedActions.HOLD);
|
|
@@ -140,7 +193,7 @@ class Call extends EventEmitter {
|
|
|
140
193
|
await downgradeToAudio(this.sipCall);
|
|
141
194
|
}
|
|
142
195
|
const promise = this.phone.client.hold(this.sipCall, this.isConference(), hasVideo);
|
|
143
|
-
this.
|
|
196
|
+
this.emit(EVENT_CALL_HELD);
|
|
144
197
|
return promise;
|
|
145
198
|
}
|
|
146
199
|
async resume() {
|
|
@@ -167,7 +220,7 @@ class Call extends EventEmitter {
|
|
|
167
220
|
this._onScreenSharing(stream, hadVideo, wasDesktop);
|
|
168
221
|
}
|
|
169
222
|
};
|
|
170
|
-
this.
|
|
223
|
+
this.emit(EVENT_CALL_RESUMED);
|
|
171
224
|
return promise.then(() => {
|
|
172
225
|
const stream = this.getLocalVideoStream();
|
|
173
226
|
if (wasScreensharing) {
|
|
@@ -180,19 +233,37 @@ class Call extends EventEmitter {
|
|
|
180
233
|
assertState(this.callActor, States.ESTABLISHED);
|
|
181
234
|
logger.info('call - turn camera on', { id: this.id });
|
|
182
235
|
toggleVideo(this.sipCall, true);
|
|
183
|
-
this.
|
|
236
|
+
this.emit(EVENT_CAMERA_RESUMED);
|
|
184
237
|
}
|
|
185
238
|
turnCameraOff() {
|
|
186
239
|
assertState(this.callActor, States.ESTABLISHED);
|
|
187
240
|
logger.info('call - turn camera off', { id: this.id });
|
|
188
241
|
toggleVideo(this.sipCall, false);
|
|
189
|
-
this.
|
|
242
|
+
this.emit(EVENT_CAMERA_DISABLED);
|
|
243
|
+
}
|
|
244
|
+
isMuted() {
|
|
245
|
+
return this._hasEstablishedState(EstablishedStates.MUTED);
|
|
246
|
+
}
|
|
247
|
+
isCameraMuted() {
|
|
248
|
+
return isVideoMuted(this.sipCall);
|
|
190
249
|
}
|
|
191
250
|
isHeld() {
|
|
192
|
-
return
|
|
251
|
+
return this._hasEstablishedState(EstablishedStates.HELD);
|
|
252
|
+
}
|
|
253
|
+
isEstablishing() {
|
|
254
|
+
return this.sipCall.state === SessionState.Establishing;
|
|
193
255
|
}
|
|
194
256
|
isEstablished() {
|
|
195
|
-
return
|
|
257
|
+
return typeof this.state === 'object' && States.ESTABLISHED in this.state;
|
|
258
|
+
}
|
|
259
|
+
isRinging() {
|
|
260
|
+
return this.state === States.RINGING;
|
|
261
|
+
}
|
|
262
|
+
isOutgoing() {
|
|
263
|
+
return this.sipCall instanceof Invitation;
|
|
264
|
+
}
|
|
265
|
+
isIncoming() {
|
|
266
|
+
return !this.isOutgoing();
|
|
196
267
|
}
|
|
197
268
|
isConference() {
|
|
198
269
|
return getPeerConnection(this.sipCall)?.sfu;
|
|
@@ -200,7 +271,7 @@ class Call extends EventEmitter {
|
|
|
200
271
|
transfer(target) {
|
|
201
272
|
assertState(this.callActor, States.ESTABLISHED);
|
|
202
273
|
logger.info('call - transfer', { id: this.id, target });
|
|
203
|
-
this.phone.client.transfer(this.sipCall, target);
|
|
274
|
+
return this.phone.client.transfer(this.sipCall, target);
|
|
204
275
|
}
|
|
205
276
|
atxfer() {
|
|
206
277
|
assertState(this.callActor, States.ESTABLISHED);
|
|
@@ -320,7 +391,7 @@ class Call extends EventEmitter {
|
|
|
320
391
|
catch (e) {
|
|
321
392
|
console.warn(e);
|
|
322
393
|
}
|
|
323
|
-
this.
|
|
394
|
+
this.emit(EVENT_SHARE_SCREEN_ENDED);
|
|
324
395
|
this.currentScreenShare = null;
|
|
325
396
|
return reinvited;
|
|
326
397
|
}
|
|
@@ -329,9 +400,13 @@ class Call extends EventEmitter {
|
|
|
329
400
|
logger.info('call - updrading directly in screensharing mode', { id: this.id, tracks: localStream?.getTracks() });
|
|
330
401
|
this._onScreenSharing(localStream, false, desktop);
|
|
331
402
|
}
|
|
403
|
+
onMakeCall() {
|
|
404
|
+
this._bindEvents();
|
|
405
|
+
this._sendAction(Actions.MAKE_CALL);
|
|
406
|
+
}
|
|
332
407
|
onAccepted() {
|
|
333
408
|
this._sendAction(Actions.REMOTLY_ACCEPTED);
|
|
334
|
-
this.emit(
|
|
409
|
+
this.emit(EVENT_CALL_REMOTLY_ACCEPTED);
|
|
335
410
|
}
|
|
336
411
|
onProgress() {
|
|
337
412
|
this.emit(EVENT_PROGRESS);
|
|
@@ -345,10 +420,14 @@ class Call extends EventEmitter {
|
|
|
345
420
|
onError(error) {
|
|
346
421
|
this.emit(EVENT_CALL_ERROR, error);
|
|
347
422
|
}
|
|
423
|
+
onCallIncoming() {
|
|
424
|
+
this._bindEvents();
|
|
425
|
+
this._sendAction(Actions.INCOMING_CALL);
|
|
426
|
+
}
|
|
348
427
|
onRejected() {
|
|
349
428
|
this.endTime = new Date();
|
|
350
429
|
this.emit(EVENT_CALL_REJECTED);
|
|
351
|
-
this.phone.
|
|
430
|
+
this.phone.onCallTerminated(this);
|
|
352
431
|
}
|
|
353
432
|
onNetworkStats(stats, previousStats) {
|
|
354
433
|
this.emit(EVENT_WEB_RTC_STATS, stats, previousStats);
|
|
@@ -380,13 +459,24 @@ class Call extends EventEmitter {
|
|
|
380
459
|
onReinvite(request, updatedCalleeName, updatedNumber, hadRemoteVideo) {
|
|
381
460
|
this.emit(EVENT_REINVITE, request, updatedCalleeName, updatedNumber, hadRemoteVideo);
|
|
382
461
|
}
|
|
462
|
+
updateFrom(call) {
|
|
463
|
+
updateFrom(this, call);
|
|
464
|
+
}
|
|
465
|
+
is(otherCall) {
|
|
466
|
+
return otherCall && this.id && this.id === otherCall.id;
|
|
467
|
+
}
|
|
468
|
+
shouldAutoAnswer() {
|
|
469
|
+
return !!this.sipCall.request?.getHeader('alert-info');
|
|
470
|
+
}
|
|
383
471
|
get id() {
|
|
384
|
-
return
|
|
472
|
+
return getSipCallId(this.sipCall);
|
|
473
|
+
}
|
|
474
|
+
get state() {
|
|
475
|
+
return getState(this.callActor);
|
|
385
476
|
}
|
|
386
|
-
|
|
387
|
-
const
|
|
388
|
-
|
|
389
|
-
return identity ? identity.uri._normal.user : null;
|
|
477
|
+
_hasEstablishedState(establishedState) {
|
|
478
|
+
const state = this.state;
|
|
479
|
+
return typeof state === 'object' && States.ESTABLISHED in state && state[States.ESTABLISHED] === establishedState;
|
|
390
480
|
}
|
|
391
481
|
_bindEvents() {
|
|
392
482
|
if (this.sipCall instanceof Invitation) {
|
|
@@ -396,21 +486,22 @@ class Call extends EventEmitter {
|
|
|
396
486
|
logger.trace('call - on sip session canceled', { callId: message.callId, id: this.id });
|
|
397
487
|
onCancel(message);
|
|
398
488
|
const elsewhere = message.data.indexOf('cause=26') !== -1 && message.data.indexOf('completed elsewhere') !== -1;
|
|
399
|
-
this.
|
|
489
|
+
this.emit(EVENT_CALL_CANCELED, elsewhere);
|
|
400
490
|
};
|
|
401
491
|
}
|
|
402
|
-
this.sipCall
|
|
492
|
+
this.sipCall?.stateChange?.addListener((newState) => {
|
|
403
493
|
switch (newState) {
|
|
404
494
|
case SessionState.Terminating:
|
|
405
495
|
logger.info('call - terminating', { id: this.id });
|
|
406
|
-
this.
|
|
496
|
+
this.emit(EVENT_CALL_TERMINATING);
|
|
407
497
|
break;
|
|
408
498
|
case SessionState.Terminated:
|
|
409
499
|
{
|
|
410
500
|
logger.info('call - terminated', { id: this.id });
|
|
411
501
|
// Should be called before `_onCallTerminated` or the callCount will not decrement...
|
|
412
502
|
this.endTime = new Date();
|
|
413
|
-
|
|
503
|
+
this.emit(EVENT_CALL_ENDED);
|
|
504
|
+
return this.phone.onCallTerminated(this);
|
|
414
505
|
}
|
|
415
506
|
default:
|
|
416
507
|
break;
|
|
@@ -437,18 +528,17 @@ class Call extends EventEmitter {
|
|
|
437
528
|
kind,
|
|
438
529
|
});
|
|
439
530
|
if (kind === 'audio') {
|
|
440
|
-
return this.
|
|
531
|
+
return this.emit(EVENT_AUDIO_STREAM, stream);
|
|
441
532
|
}
|
|
442
|
-
return this.
|
|
533
|
+
return this.emit(EVENT_VIDEO_STREAM, stream, event.track.id, event);
|
|
443
534
|
};
|
|
444
535
|
peerConnection.onremovestream = (event) => {
|
|
445
536
|
logger.info('call - on remove stream called on the peer connection', {
|
|
446
537
|
id: event.stream.id,
|
|
447
538
|
tracks: event.stream.getTracks(),
|
|
448
539
|
});
|
|
449
|
-
this.
|
|
540
|
+
this.emit(EVENT_REMOVE_STREAM, event.stream);
|
|
450
541
|
};
|
|
451
|
-
// Client events
|
|
452
542
|
}
|
|
453
543
|
_downgradeToAudio(withMessage = true) {
|
|
454
544
|
assertState(this.callActor, States.ESTABLISHED);
|
|
@@ -508,7 +598,7 @@ class Call extends EventEmitter {
|
|
|
508
598
|
if (screenTrack) {
|
|
509
599
|
screenTrack.onended = () => {
|
|
510
600
|
logger.info('call - on screenshare ended', { hadVideo, id: this.id, screenTrack });
|
|
511
|
-
this.
|
|
601
|
+
this.emit(EVENT_SHARE_SCREEN_ENDING);
|
|
512
602
|
};
|
|
513
603
|
}
|
|
514
604
|
this.currentScreenShare = {
|
|
@@ -518,10 +608,12 @@ class Call extends EventEmitter {
|
|
|
518
608
|
desktop,
|
|
519
609
|
};
|
|
520
610
|
setLocalMediaStream(this.sipCall, screenStream);
|
|
521
|
-
this.
|
|
611
|
+
this.emit(EVENT_SHARE_SCREEN_STARTED, screenStream);
|
|
522
612
|
}
|
|
523
613
|
_sendAction(action) {
|
|
614
|
+
const was = this.state;
|
|
524
615
|
this.callActor.send({ type: action });
|
|
616
|
+
logger.trace('call - send action', { action, was, state: this.state });
|
|
525
617
|
}
|
|
526
618
|
}
|
|
527
619
|
export default Call;
|