@vapi-ai/web 1.1.7 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/api.ts +2260 -780
- package/dist/api.d.ts +1895 -755
- package/dist/api.js +177 -45
- package/dist/vapi.d.ts +5 -3
- package/dist/vapi.js +28 -2
- package/package.json +1 -1
- package/update.sh +1 -1
- package/vapi.ts +35 -4
- package/dist/AtomicMediaSource.d.ts +0 -17
- package/dist/AtomicMediaSource.js +0 -78
- package/dist/player.d.ts +0 -10
- package/dist/player.js +0 -38
package/dist/api.js
CHANGED
|
@@ -10,30 +10,7 @@
|
|
|
10
10
|
* ---------------------------------------------------------------
|
|
11
11
|
*/
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
exports.Api = exports.HttpClient = exports.ContentType =
|
|
14
|
-
class CreateWebCallDTO {
|
|
15
|
-
/**
|
|
16
|
-
* This is the assistant that will be used for the call. To use a transient assistant, use `assistant` instead.
|
|
17
|
-
*/
|
|
18
|
-
assistantId;
|
|
19
|
-
/**
|
|
20
|
-
* Overrides for the assistant's settings and template variables.
|
|
21
|
-
*/
|
|
22
|
-
assistantOverrides;
|
|
23
|
-
/**
|
|
24
|
-
* This is the assistant that will be used for the call. To use an existing assistant, use `assistantId` instead.
|
|
25
|
-
*/
|
|
26
|
-
assistant;
|
|
27
|
-
/**
|
|
28
|
-
* This will expose SIP URI you can use to connect to the call. Disabled by default.
|
|
29
|
-
*/
|
|
30
|
-
sipEnabled;
|
|
31
|
-
/**
|
|
32
|
-
* This is the metadata associated with the call.
|
|
33
|
-
*/
|
|
34
|
-
metadata;
|
|
35
|
-
}
|
|
36
|
-
exports.CreateWebCallDTO = CreateWebCallDTO;
|
|
13
|
+
exports.Api = exports.HttpClient = exports.ContentType = void 0;
|
|
37
14
|
var ContentType;
|
|
38
15
|
(function (ContentType) {
|
|
39
16
|
ContentType["Json"] = "application/json";
|
|
@@ -325,6 +302,40 @@ class Api extends HttpClient {
|
|
|
325
302
|
format: 'json',
|
|
326
303
|
...params,
|
|
327
304
|
}),
|
|
305
|
+
/**
|
|
306
|
+
* No description
|
|
307
|
+
*
|
|
308
|
+
* @tags Calls
|
|
309
|
+
* @name CallControllerDeleteCallData
|
|
310
|
+
* @summary Delete Call Data
|
|
311
|
+
* @request DELETE:/call/{id}
|
|
312
|
+
* @secure
|
|
313
|
+
*/
|
|
314
|
+
callControllerDeleteCallData: (id, params = {}) => this.request({
|
|
315
|
+
path: `/call/${id}`,
|
|
316
|
+
method: 'DELETE',
|
|
317
|
+
secure: true,
|
|
318
|
+
format: 'json',
|
|
319
|
+
...params,
|
|
320
|
+
}),
|
|
321
|
+
/**
|
|
322
|
+
* No description
|
|
323
|
+
*
|
|
324
|
+
* @tags Calls
|
|
325
|
+
* @name CallControllerUpdate
|
|
326
|
+
* @summary Update Call
|
|
327
|
+
* @request PATCH:/call/{id}
|
|
328
|
+
* @secure
|
|
329
|
+
*/
|
|
330
|
+
callControllerUpdate: (id, data, params = {}) => this.request({
|
|
331
|
+
path: `/call/${id}`,
|
|
332
|
+
method: 'PATCH',
|
|
333
|
+
body: data,
|
|
334
|
+
secure: true,
|
|
335
|
+
type: ContentType.Json,
|
|
336
|
+
format: 'json',
|
|
337
|
+
...params,
|
|
338
|
+
}),
|
|
328
339
|
/**
|
|
329
340
|
* No description
|
|
330
341
|
*
|
|
@@ -591,58 +602,179 @@ class Api extends HttpClient {
|
|
|
591
602
|
...params,
|
|
592
603
|
}),
|
|
593
604
|
};
|
|
594
|
-
|
|
605
|
+
log = {
|
|
595
606
|
/**
|
|
596
607
|
* No description
|
|
597
608
|
*
|
|
598
|
-
* @tags
|
|
599
|
-
* @name
|
|
600
|
-
* @summary Get
|
|
601
|
-
* @request GET:/
|
|
609
|
+
* @tags Logs
|
|
610
|
+
* @name LoggingControllerGetLogs
|
|
611
|
+
* @summary Get Call Logs
|
|
612
|
+
* @request GET:/log
|
|
602
613
|
* @secure
|
|
603
614
|
*/
|
|
604
|
-
|
|
605
|
-
path: `/
|
|
615
|
+
loggingControllerGetLogs: (query, params = {}) => this.request({
|
|
616
|
+
path: `/log`,
|
|
606
617
|
method: 'GET',
|
|
618
|
+
query: query,
|
|
607
619
|
secure: true,
|
|
608
620
|
format: 'json',
|
|
609
621
|
...params,
|
|
610
622
|
}),
|
|
623
|
+
};
|
|
624
|
+
tool = {
|
|
611
625
|
/**
|
|
612
626
|
* No description
|
|
613
627
|
*
|
|
614
|
-
* @tags
|
|
615
|
-
* @name
|
|
616
|
-
* @summary
|
|
617
|
-
* @request POST:/
|
|
628
|
+
* @tags Tools
|
|
629
|
+
* @name ToolControllerCreate
|
|
630
|
+
* @summary Create Tool
|
|
631
|
+
* @request POST:/tool
|
|
618
632
|
* @secure
|
|
619
633
|
*/
|
|
620
|
-
|
|
621
|
-
path: `/
|
|
634
|
+
toolControllerCreate: (data, params = {}) => this.request({
|
|
635
|
+
path: `/tool`,
|
|
622
636
|
method: 'POST',
|
|
637
|
+
body: data,
|
|
623
638
|
secure: true,
|
|
639
|
+
type: ContentType.Json,
|
|
624
640
|
format: 'json',
|
|
625
641
|
...params,
|
|
626
642
|
}),
|
|
627
|
-
};
|
|
628
|
-
logging = {
|
|
629
643
|
/**
|
|
630
644
|
* No description
|
|
631
645
|
*
|
|
632
|
-
* @tags
|
|
633
|
-
* @name
|
|
634
|
-
* @summary
|
|
635
|
-
* @request GET:/
|
|
646
|
+
* @tags Tools
|
|
647
|
+
* @name ToolControllerFindAll
|
|
648
|
+
* @summary List Tools
|
|
649
|
+
* @request GET:/tool
|
|
636
650
|
* @secure
|
|
637
651
|
*/
|
|
638
|
-
|
|
639
|
-
path: `/
|
|
652
|
+
toolControllerFindAll: (query, params = {}) => this.request({
|
|
653
|
+
path: `/tool`,
|
|
640
654
|
method: 'GET',
|
|
641
655
|
query: query,
|
|
642
656
|
secure: true,
|
|
643
657
|
format: 'json',
|
|
644
658
|
...params,
|
|
645
659
|
}),
|
|
660
|
+
/**
|
|
661
|
+
* No description
|
|
662
|
+
*
|
|
663
|
+
* @tags Tools
|
|
664
|
+
* @name ToolControllerFindOne
|
|
665
|
+
* @summary Get Tool
|
|
666
|
+
* @request GET:/tool/{id}
|
|
667
|
+
* @secure
|
|
668
|
+
*/
|
|
669
|
+
toolControllerFindOne: (id, params = {}) => this.request({
|
|
670
|
+
path: `/tool/${id}`,
|
|
671
|
+
method: 'GET',
|
|
672
|
+
secure: true,
|
|
673
|
+
format: 'json',
|
|
674
|
+
...params,
|
|
675
|
+
}),
|
|
676
|
+
/**
|
|
677
|
+
* No description
|
|
678
|
+
*
|
|
679
|
+
* @tags Tools
|
|
680
|
+
* @name ToolControllerUpdate
|
|
681
|
+
* @summary Update Tool
|
|
682
|
+
* @request PATCH:/tool/{id}
|
|
683
|
+
* @secure
|
|
684
|
+
*/
|
|
685
|
+
toolControllerUpdate: (id, data, params = {}) => this.request({
|
|
686
|
+
path: `/tool/${id}`,
|
|
687
|
+
method: 'PATCH',
|
|
688
|
+
body: data,
|
|
689
|
+
secure: true,
|
|
690
|
+
type: ContentType.Json,
|
|
691
|
+
format: 'json',
|
|
692
|
+
...params,
|
|
693
|
+
}),
|
|
694
|
+
/**
|
|
695
|
+
* No description
|
|
696
|
+
*
|
|
697
|
+
* @tags Tools
|
|
698
|
+
* @name ToolControllerRemove
|
|
699
|
+
* @summary Delete Tool
|
|
700
|
+
* @request DELETE:/tool/{id}
|
|
701
|
+
* @secure
|
|
702
|
+
*/
|
|
703
|
+
toolControllerRemove: (id, params = {}) => this.request({
|
|
704
|
+
path: `/tool/${id}`,
|
|
705
|
+
method: 'DELETE',
|
|
706
|
+
secure: true,
|
|
707
|
+
format: 'json',
|
|
708
|
+
...params,
|
|
709
|
+
}),
|
|
710
|
+
};
|
|
711
|
+
file = {
|
|
712
|
+
/**
|
|
713
|
+
* No description
|
|
714
|
+
*
|
|
715
|
+
* @tags Files
|
|
716
|
+
* @name FileControllerCreate
|
|
717
|
+
* @summary Upload File
|
|
718
|
+
* @request POST:/file/upload
|
|
719
|
+
* @secure
|
|
720
|
+
*/
|
|
721
|
+
fileControllerCreate: (data, params = {}) => this.request({
|
|
722
|
+
path: `/file/upload`,
|
|
723
|
+
method: 'POST',
|
|
724
|
+
body: data,
|
|
725
|
+
secure: true,
|
|
726
|
+
type: ContentType.FormData,
|
|
727
|
+
format: 'json',
|
|
728
|
+
...params,
|
|
729
|
+
}),
|
|
730
|
+
/**
|
|
731
|
+
* No description
|
|
732
|
+
*
|
|
733
|
+
* @tags Files
|
|
734
|
+
* @name FileControllerFindAll
|
|
735
|
+
* @summary List Files
|
|
736
|
+
* @request GET:/file
|
|
737
|
+
* @secure
|
|
738
|
+
*/
|
|
739
|
+
fileControllerFindAll: (params = {}) => this.request({
|
|
740
|
+
path: `/file`,
|
|
741
|
+
method: 'GET',
|
|
742
|
+
secure: true,
|
|
743
|
+
format: 'json',
|
|
744
|
+
...params,
|
|
745
|
+
}),
|
|
746
|
+
/**
|
|
747
|
+
* No description
|
|
748
|
+
*
|
|
749
|
+
* @tags Files
|
|
750
|
+
* @name FileControllerFindOne
|
|
751
|
+
* @summary Get File
|
|
752
|
+
* @request GET:/file/{id}
|
|
753
|
+
* @secure
|
|
754
|
+
*/
|
|
755
|
+
fileControllerFindOne: (id, params = {}) => this.request({
|
|
756
|
+
path: `/file/${id}`,
|
|
757
|
+
method: 'GET',
|
|
758
|
+
secure: true,
|
|
759
|
+
format: 'json',
|
|
760
|
+
...params,
|
|
761
|
+
}),
|
|
762
|
+
/**
|
|
763
|
+
* No description
|
|
764
|
+
*
|
|
765
|
+
* @tags Files
|
|
766
|
+
* @name FileControllerRemove
|
|
767
|
+
* @summary Delete File
|
|
768
|
+
* @request DELETE:/file/{id}
|
|
769
|
+
* @secure
|
|
770
|
+
*/
|
|
771
|
+
fileControllerRemove: (id, params = {}) => this.request({
|
|
772
|
+
path: `/file/${id}`,
|
|
773
|
+
method: 'DELETE',
|
|
774
|
+
secure: true,
|
|
775
|
+
format: 'json',
|
|
776
|
+
...params,
|
|
777
|
+
}),
|
|
646
778
|
};
|
|
647
779
|
}
|
|
648
780
|
exports.Api = Api;
|
package/dist/vapi.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import { Call, CreateAssistantDTO, OverrideAssistantDTO } from './api';
|
|
2
|
+
import { Call, CreateAssistantDTO, CreateSquadDTO, OverrideAssistantDTO } from './api';
|
|
3
|
+
import { DailyCall } from '@daily-co/daily-js';
|
|
3
4
|
import type { ChatCompletionMessageParam } from 'openai/resources';
|
|
4
5
|
import EventEmitter from 'events';
|
|
5
6
|
export interface AddMessageMessage {
|
|
@@ -37,10 +38,9 @@ export default class Vapi extends VapiEventEmitter {
|
|
|
37
38
|
private started;
|
|
38
39
|
private call;
|
|
39
40
|
private speakingTimeout;
|
|
40
|
-
private averageSpeechLevel;
|
|
41
41
|
constructor(apiToken: string, apiBaseUrl?: string);
|
|
42
42
|
private cleanup;
|
|
43
|
-
start(assistant
|
|
43
|
+
start(assistant?: CreateAssistantDTO | string, assistantOverrides?: OverrideAssistantDTO, squad?: CreateSquadDTO | string): Promise<Call | null>;
|
|
44
44
|
private onAppMessage;
|
|
45
45
|
private handleRemoteParticipantsAudioLevel;
|
|
46
46
|
stop(): void;
|
|
@@ -48,5 +48,7 @@ export default class Vapi extends VapiEventEmitter {
|
|
|
48
48
|
setMuted(mute: boolean): void;
|
|
49
49
|
isMuted(): boolean;
|
|
50
50
|
say(message: string, endCallAfterSpoken?: boolean): void;
|
|
51
|
+
setInputDevicesAsync(options: Parameters<DailyCall['setInputDevicesAsync']>[0]): void;
|
|
52
|
+
setOutputDeviceAsync(options: Parameters<DailyCall['setOutputDeviceAsync']>[0]): void;
|
|
51
53
|
}
|
|
52
54
|
export {};
|
package/dist/vapi.js
CHANGED
|
@@ -60,7 +60,6 @@ class Vapi extends VapiEventEmitter {
|
|
|
60
60
|
started = false;
|
|
61
61
|
call = null;
|
|
62
62
|
speakingTimeout = null;
|
|
63
|
-
averageSpeechLevel = 0;
|
|
64
63
|
constructor(apiToken, apiBaseUrl) {
|
|
65
64
|
super();
|
|
66
65
|
client_1.client.baseUrl = apiBaseUrl ?? 'https://api.vapi.ai';
|
|
@@ -72,7 +71,10 @@ class Vapi extends VapiEventEmitter {
|
|
|
72
71
|
this.call = null;
|
|
73
72
|
this.speakingTimeout = null;
|
|
74
73
|
}
|
|
75
|
-
async start(assistant, assistantOverrides) {
|
|
74
|
+
async start(assistant, assistantOverrides, squad) {
|
|
75
|
+
if (!assistant && !squad) {
|
|
76
|
+
throw new Error('Assistant or Squad must be provided.');
|
|
77
|
+
}
|
|
76
78
|
if (this.started) {
|
|
77
79
|
return null;
|
|
78
80
|
}
|
|
@@ -82,6 +84,8 @@ class Vapi extends VapiEventEmitter {
|
|
|
82
84
|
assistant: typeof assistant === 'string' ? undefined : assistant,
|
|
83
85
|
assistantId: typeof assistant === 'string' ? assistant : undefined,
|
|
84
86
|
assistantOverrides,
|
|
87
|
+
squad: typeof squad === 'string' ? undefined : squad,
|
|
88
|
+
squadId: typeof squad === 'string' ? squad : undefined,
|
|
85
89
|
})).data;
|
|
86
90
|
if (this.call) {
|
|
87
91
|
this.cleanup();
|
|
@@ -133,6 +137,22 @@ class Vapi extends VapiEventEmitter {
|
|
|
133
137
|
this.handleRemoteParticipantsAudioLevel(e);
|
|
134
138
|
});
|
|
135
139
|
this.call.on('app-message', (e) => this.onAppMessage(e));
|
|
140
|
+
this.call.on('nonfatal-error', (e) => {
|
|
141
|
+
// https://docs.daily.co/reference/daily-js/events/meeting-events#type-audio-processor-error
|
|
142
|
+
if (e?.type === 'audio-processor-error') {
|
|
143
|
+
this.call
|
|
144
|
+
?.updateInputSettings({
|
|
145
|
+
audio: {
|
|
146
|
+
processor: {
|
|
147
|
+
type: 'none',
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
})
|
|
151
|
+
.then(() => {
|
|
152
|
+
this.call?.setLocalAudio(true);
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
});
|
|
136
156
|
this.call.updateInputSettings({
|
|
137
157
|
audio: {
|
|
138
158
|
processor: {
|
|
@@ -225,5 +245,11 @@ class Vapi extends VapiEventEmitter {
|
|
|
225
245
|
endCallAfterSpoken
|
|
226
246
|
});
|
|
227
247
|
}
|
|
248
|
+
setInputDevicesAsync(options) {
|
|
249
|
+
this.call?.setInputDevicesAsync(options);
|
|
250
|
+
}
|
|
251
|
+
setOutputDeviceAsync(options) {
|
|
252
|
+
this.call?.setOutputDeviceAsync(options);
|
|
253
|
+
}
|
|
228
254
|
}
|
|
229
255
|
exports.default = Vapi;
|
package/package.json
CHANGED
package/update.sh
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
npm version
|
|
1
|
+
npm version minor && npm run build && npm publish && cd ../landing && npm install @vapi-ai/web@latest && cd -
|
package/vapi.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Call, CreateAssistantDTO, OverrideAssistantDTO } from './api';
|
|
1
|
+
import { Call, CreateAssistantDTO, CreateSquadDTO, OverrideAssistantDTO } from './api';
|
|
2
2
|
import DailyIframe, {
|
|
3
3
|
DailyCall,
|
|
4
4
|
DailyEventObjectAppMessage,
|
|
@@ -103,7 +103,6 @@ export default class Vapi extends VapiEventEmitter {
|
|
|
103
103
|
private started: boolean = false;
|
|
104
104
|
private call: DailyCall | null = null;
|
|
105
105
|
private speakingTimeout: NodeJS.Timeout | null = null;
|
|
106
|
-
private averageSpeechLevel: number = 0;
|
|
107
106
|
|
|
108
107
|
constructor(apiToken: string, apiBaseUrl?: string) {
|
|
109
108
|
super();
|
|
@@ -119,13 +118,17 @@ export default class Vapi extends VapiEventEmitter {
|
|
|
119
118
|
}
|
|
120
119
|
|
|
121
120
|
async start(
|
|
122
|
-
assistant
|
|
121
|
+
assistant?: CreateAssistantDTO | string,
|
|
123
122
|
assistantOverrides?: OverrideAssistantDTO,
|
|
123
|
+
squad?: CreateSquadDTO | string,
|
|
124
124
|
): Promise<Call | null> {
|
|
125
|
+
if (!assistant && !squad) {
|
|
126
|
+
throw new Error('Assistant or Squad must be provided.');
|
|
127
|
+
}
|
|
128
|
+
|
|
125
129
|
if (this.started) {
|
|
126
130
|
return null;
|
|
127
131
|
}
|
|
128
|
-
|
|
129
132
|
this.started = true;
|
|
130
133
|
|
|
131
134
|
try {
|
|
@@ -134,6 +137,8 @@ export default class Vapi extends VapiEventEmitter {
|
|
|
134
137
|
assistant: typeof assistant === 'string' ? undefined : assistant,
|
|
135
138
|
assistantId: typeof assistant === 'string' ? assistant : undefined,
|
|
136
139
|
assistantOverrides,
|
|
140
|
+
squad: typeof squad === 'string' ? undefined : squad,
|
|
141
|
+
squadId: typeof squad === 'string' ? squad : undefined,
|
|
137
142
|
})
|
|
138
143
|
).data;
|
|
139
144
|
|
|
@@ -193,6 +198,23 @@ export default class Vapi extends VapiEventEmitter {
|
|
|
193
198
|
|
|
194
199
|
this.call.on('app-message', (e) => this.onAppMessage(e));
|
|
195
200
|
|
|
201
|
+
this.call.on('nonfatal-error', (e) => {
|
|
202
|
+
// https://docs.daily.co/reference/daily-js/events/meeting-events#type-audio-processor-error
|
|
203
|
+
if (e?.type === 'audio-processor-error') {
|
|
204
|
+
this.call
|
|
205
|
+
?.updateInputSettings({
|
|
206
|
+
audio: {
|
|
207
|
+
processor: {
|
|
208
|
+
type: 'none',
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
})
|
|
212
|
+
.then(() => {
|
|
213
|
+
this.call?.setLocalAudio(true);
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
|
|
196
218
|
this.call.updateInputSettings({
|
|
197
219
|
audio: {
|
|
198
220
|
processor: {
|
|
@@ -289,4 +311,13 @@ export default class Vapi extends VapiEventEmitter {
|
|
|
289
311
|
endCallAfterSpoken
|
|
290
312
|
})
|
|
291
313
|
}
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
public setInputDevicesAsync(options: Parameters<DailyCall['setInputDevicesAsync']>[0]) {
|
|
317
|
+
this.call?.setInputDevicesAsync(options)
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
public setOutputDeviceAsync(options: Parameters<DailyCall['setOutputDeviceAsync']>[0]) {
|
|
321
|
+
this.call?.setOutputDeviceAsync(options)
|
|
322
|
+
}
|
|
292
323
|
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import EventEmitter from "events";
|
|
3
|
-
declare global {
|
|
4
|
-
interface Window {
|
|
5
|
-
ManagedMediaSource: any;
|
|
6
|
-
}
|
|
7
|
-
}
|
|
8
|
-
declare class AtomicMediaSource extends EventEmitter {
|
|
9
|
-
mediaSource: any;
|
|
10
|
-
sourceBuffer: SourceBuffer | null;
|
|
11
|
-
private operationsQueue;
|
|
12
|
-
constructor();
|
|
13
|
-
appendBuffer(buffer: ArrayBuffer): void;
|
|
14
|
-
clearBuffer(): void;
|
|
15
|
-
private createOperationQueue;
|
|
16
|
-
}
|
|
17
|
-
export default AtomicMediaSource;
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const async_1 = __importDefault(require("async"));
|
|
7
|
-
const events_1 = __importDefault(require("events"));
|
|
8
|
-
// ManagedMediaSource needed for iOS Safari
|
|
9
|
-
function getMediaSource() {
|
|
10
|
-
if (window.ManagedMediaSource) {
|
|
11
|
-
return new window.ManagedMediaSource();
|
|
12
|
-
}
|
|
13
|
-
if (window.MediaSource) {
|
|
14
|
-
return new window.MediaSource();
|
|
15
|
-
}
|
|
16
|
-
return null;
|
|
17
|
-
}
|
|
18
|
-
class AtomicMediaSource extends events_1.default {
|
|
19
|
-
constructor() {
|
|
20
|
-
super();
|
|
21
|
-
this.sourceBuffer = null;
|
|
22
|
-
this.mediaSource = getMediaSource();
|
|
23
|
-
this.operationsQueue = this.createOperationQueue();
|
|
24
|
-
if (!this.mediaSource) {
|
|
25
|
-
console.error("MediaSource is not supported in your browser.");
|
|
26
|
-
// Display a message to the user, or handle this situation in another way
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
this.mediaSource.addEventListener("sourceopen", () => {
|
|
30
|
-
this.mediaSource.duration = Number.POSITIVE_INFINITY;
|
|
31
|
-
this.sourceBuffer = this.mediaSource.addSourceBuffer('audio/webm; codecs="opus"');
|
|
32
|
-
if (this.sourceBuffer) {
|
|
33
|
-
this.sourceBuffer.mode = "sequence";
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
appendBuffer(buffer) {
|
|
38
|
-
this.operationsQueue.push(() => {
|
|
39
|
-
return new Promise((resolve, reject) => {
|
|
40
|
-
if (this.sourceBuffer) {
|
|
41
|
-
this.sourceBuffer.addEventListener("updateend", () => {
|
|
42
|
-
resolve();
|
|
43
|
-
}, { once: true });
|
|
44
|
-
this.sourceBuffer.appendBuffer(buffer);
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
reject();
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
clearBuffer() {
|
|
53
|
-
// this.operationsQueue.push(() => {
|
|
54
|
-
// return new Promise((resolve, reject) => {
|
|
55
|
-
// if (this.sourceBuffer) {
|
|
56
|
-
// this.sourceBuffer.addEventListener(
|
|
57
|
-
// "updateend",
|
|
58
|
-
// () => {
|
|
59
|
-
// resolve();
|
|
60
|
-
// },
|
|
61
|
-
// { once: true }
|
|
62
|
-
// );
|
|
63
|
-
// if (this.sourceBuffer.buffered.length > 0) {
|
|
64
|
-
// this.sourceBuffer.remove(0, this.sourceBuffer.buffered.end(0));
|
|
65
|
-
// }
|
|
66
|
-
// } else {
|
|
67
|
-
// reject();
|
|
68
|
-
// }
|
|
69
|
-
// });
|
|
70
|
-
// });
|
|
71
|
-
}
|
|
72
|
-
createOperationQueue() {
|
|
73
|
-
return async_1.default.queue((task, callback) => {
|
|
74
|
-
task().then(() => callback());
|
|
75
|
-
}, 1);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
exports.default = AtomicMediaSource;
|
package/dist/player.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import EventEmitter from "events";
|
|
3
|
-
export declare class ContinuousPlayer extends EventEmitter {
|
|
4
|
-
private atomic;
|
|
5
|
-
private audio;
|
|
6
|
-
constructor();
|
|
7
|
-
start(): void;
|
|
8
|
-
playChunk(audioData: ArrayBuffer): void;
|
|
9
|
-
clear(): void;
|
|
10
|
-
}
|
package/dist/player.js
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.ContinuousPlayer = void 0;
|
|
7
|
-
const AtomicMediaSource_1 = __importDefault(require("./AtomicMediaSource"));
|
|
8
|
-
const events_1 = __importDefault(require("events"));
|
|
9
|
-
class ContinuousPlayer extends events_1.default {
|
|
10
|
-
constructor() {
|
|
11
|
-
super();
|
|
12
|
-
this.audio = document.createElement("audio");
|
|
13
|
-
this.audio.addEventListener("playing", () => this.emit("speech-start"));
|
|
14
|
-
this.audio.addEventListener("play", () => this.emit("speech-start"));
|
|
15
|
-
this.audio.addEventListener("canplay", () => {
|
|
16
|
-
this.audio.play();
|
|
17
|
-
});
|
|
18
|
-
this.audio.addEventListener("waiting", () => this.emit("speech-end"));
|
|
19
|
-
this.atomic = new AtomicMediaSource_1.default();
|
|
20
|
-
this.audio.src = URL.createObjectURL(this.atomic.mediaSource);
|
|
21
|
-
document.body.appendChild(this.audio);
|
|
22
|
-
}
|
|
23
|
-
start() {
|
|
24
|
-
this.audio.play();
|
|
25
|
-
}
|
|
26
|
-
playChunk(audioData) {
|
|
27
|
-
var _a;
|
|
28
|
-
(_a = this.atomic.sourceBuffer) === null || _a === void 0 ? void 0 : _a.addEventListener("updateend", () => {
|
|
29
|
-
this.audio.play().catch((error) => console.error("Play error:", error));
|
|
30
|
-
}, { once: true });
|
|
31
|
-
this.atomic.appendBuffer(audioData);
|
|
32
|
-
}
|
|
33
|
-
clear() {
|
|
34
|
-
this.audio.pause();
|
|
35
|
-
this.atomic.clearBuffer();
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
exports.ContinuousPlayer = ContinuousPlayer;
|