-
Notifications
You must be signed in to change notification settings - Fork 78
Expand file tree
/
Copy pathCallingSoundSubscriber.ts
More file actions
121 lines (110 loc) · 3.64 KB
/
CallingSoundSubscriber.ts
File metadata and controls
121 lines (110 loc) · 3.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { CallCommon } from '@azure/communication-calling';
import { CallingSounds } from './CallAdapter';
/* @conditional-compile-remove(calling-sounds) */
import { isPhoneNumberIdentifier } from '@azure/communication-common';
import { CommunicationIdentifier } from '@azure/communication-common';
type CallingSoundsLoaded = {
callEndedSound?: HTMLAudioElement;
callRingingSound?: HTMLAudioElement;
callBusySound?: HTMLAudioElement;
};
const CALL_REJECTED_CODE = 603;
/**
* @private
*/
export class CallingSoundSubscriber {
private call: CallCommon;
private soundsLoaded?: CallingSoundsLoaded;
private callee: CommunicationIdentifier[] | undefined;
constructor(call: CallCommon, callee?: CommunicationIdentifier[], sounds?: CallingSounds) {
this.call = call;
this.callee = callee;
if (sounds) {
this.soundsLoaded = this.loadSounds(sounds);
this.subscribeCallSoundEvents();
}
}
private onCallStateChanged = (): void => {
this.call.on('stateChanged', () => {
if (isPSTNCall(this.call, this.callee) && this.soundsLoaded?.callRingingSound) {
this.soundsLoaded.callRingingSound.loop = true;
this.playSound(this.soundsLoaded.callRingingSound);
}
if (
(this.call.state === 'Connected' || this.call.state === 'Disconnected') &&
this.soundsLoaded?.callRingingSound
) {
this.soundsLoaded.callRingingSound.loop = false;
this.soundsLoaded.callRingingSound.pause();
}
if (this.call.state === 'Disconnecting') {
if (this.soundsLoaded?.callRingingSound) {
this.soundsLoaded.callRingingSound.pause();
}
}
if (this.call.state === 'Disconnected') {
if (this.soundsLoaded?.callBusySound && this.call.callEndReason?.code === CALL_REJECTED_CODE) {
this.playSound(this.soundsLoaded.callBusySound);
} else if (this.soundsLoaded?.callEndedSound) {
this.playSound(this.soundsLoaded.callEndedSound);
}
}
});
};
private subscribeCallSoundEvents(): void {
this.onCallStateChanged();
}
public unsubscribeAll(): void {
this.call.off('stateChanged', this.onCallStateChanged);
if (this.soundsLoaded?.callRingingSound) {
this.soundsLoaded.callRingingSound.pause();
}
}
private loadSounds(sounds?: CallingSounds): CallingSoundsLoaded | undefined {
let callEndedSound;
if (sounds?.callEnded) {
callEndedSound = new Audio(sounds?.callEnded?.url);
callEndedSound.preload = 'auto';
}
let callRingingSound;
if (sounds?.callRinging) {
callRingingSound = new Audio(sounds?.callRinging?.url);
callRingingSound.preload = 'auto';
}
let callBusySound;
if (sounds?.callBusy) {
callBusySound = new Audio(sounds?.callBusy?.url);
callBusySound.preload = 'auto';
}
return {
callEndedSound,
callRingingSound,
callBusySound
};
}
private playSound(sound: HTMLAudioElement): void {
sound.play().catch((e) => {
console.error(e, 'Failed to play sound, check loader config to make sure it is correct');
});
}
}
/**
* Helper function to allow the calling sound subscriber to determine when to play the ringing
* sound when making an outbound call.
*/
const isPSTNCall = (call: CallCommon, callee?: CommunicationIdentifier[]): boolean => {
/* @conditional-compile-remove(calling-sounds) */
if (
callee &&
callee.length >= 1 &&
!isPhoneNumberIdentifier(callee[0]) &&
(call.state === 'Ringing' || call.state === 'Connecting')
) {
return true;
} else {
return false;
}
return false;
};