@vapi-ai/web 1.0.7 → 1.0.8

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/dist/player.d.ts CHANGED
@@ -1,12 +1,9 @@
1
1
  /// <reference types="node" />
2
2
  import EventEmitter from "events";
3
3
  export declare class ContinuousPlayer extends EventEmitter {
4
- private audioCtx;
5
- private nextStartTime;
6
- private audioQueue;
7
- private crossFadeDuration;
8
- constructor(crossFadeDuration?: number);
9
- private createQueue;
4
+ private mediaSource;
5
+ private sourceBuffer;
6
+ constructor();
10
7
  playChunk(audioData: ArrayBuffer): void;
11
8
  clear(): Promise<void>;
12
9
  }
package/dist/player.js CHANGED
@@ -13,55 +13,28 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.ContinuousPlayer = void 0;
16
- const async_1 = require("async"); // You need to install the async package
17
16
  const events_1 = __importDefault(require("events"));
18
17
  class ContinuousPlayer extends events_1.default {
19
- constructor(crossFadeDuration = 0.5) {
18
+ constructor() {
20
19
  super();
21
- this.audioCtx = new AudioContext();
22
- this.nextStartTime = 0;
23
- this.audioQueue = this.createQueue();
24
- this.crossFadeDuration = crossFadeDuration;
25
- }
26
- createQueue() {
27
- const q = (0, async_1.queue)((audioPromise, callback) => __awaiter(this, void 0, void 0, function* () {
28
- const audioBuffer = yield audioPromise;
29
- const source = this.audioCtx.createBufferSource();
30
- source.buffer = audioBuffer;
31
- source.connect(this.audioCtx.destination);
32
- // Create a gain node for crossfading
33
- const gainNode = this.audioCtx.createGain();
34
- source.connect(gainNode);
35
- gainNode.connect(this.audioCtx.destination);
36
- // Start the source at the next start time
37
- source.start(this.nextStartTime);
38
- // Schedule the crossfade
39
- gainNode.gain.setValueAtTime(0, this.nextStartTime);
40
- gainNode.gain.linearRampToValueAtTime(1, this.nextStartTime + this.crossFadeDuration);
41
- gainNode.gain.setValueAtTime(1, this.nextStartTime + audioBuffer.duration - this.crossFadeDuration);
42
- gainNode.gain.linearRampToValueAtTime(0, this.nextStartTime + audioBuffer.duration);
43
- source.onended = () => {
44
- this.nextStartTime += audioBuffer.duration;
45
- callback();
46
- };
47
- }), 1);
48
- q.drain(() => {
49
- this.emit("speech-end");
50
- });
51
- q.saturated(() => {
52
- this.emit("speech-start");
53
- });
54
- return q;
20
+ this.sourceBuffer = null;
21
+ this.mediaSource = new MediaSource();
22
+ this.mediaSource.onsourceopen = () => {
23
+ this.sourceBuffer = this.mediaSource.addSourceBuffer('audio/webm; codecs="opus"');
24
+ };
55
25
  }
56
26
  playChunk(audioData) {
57
- const decodePromise = this.audioCtx.decodeAudioData(audioData);
58
- this.audioQueue.push(decodePromise);
27
+ if (!this.sourceBuffer)
28
+ return;
29
+ if (this.mediaSource.readyState === "open" && !this.sourceBuffer.updating) {
30
+ this.sourceBuffer.appendBuffer(audioData);
31
+ }
59
32
  }
60
33
  clear() {
61
34
  return __awaiter(this, void 0, void 0, function* () {
62
- this.audioQueue.kill();
63
- this.audioQueue = this.createQueue();
64
- this.nextStartTime = 0;
35
+ if (this.sourceBuffer && this.mediaSource.readyState === "open") {
36
+ this.sourceBuffer.remove(0, this.sourceBuffer.buffered.end(0));
37
+ }
65
38
  });
66
39
  }
67
40
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vapi-ai/web",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "",
5
5
  "main": "dist/vapi.js",
6
6
  "types": "dist/vapi.d.ts",
package/player.ts CHANGED
@@ -1,78 +1,29 @@
1
- import { QueueObject, queue } from "async"; // You need to install the async package
2
-
3
1
  import EventEmitter from "events";
4
2
 
5
3
  export class ContinuousPlayer extends EventEmitter {
6
- private audioCtx: AudioContext;
7
- private nextStartTime: number;
8
- private audioQueue: QueueObject<Promise<AudioBuffer>>;
9
- private crossFadeDuration: number; // Duration of the crossfade
4
+ private mediaSource: MediaSource;
5
+ private sourceBuffer: SourceBuffer | null = null;
10
6
 
11
- constructor(crossFadeDuration = 0.5) {
7
+ constructor() {
12
8
  super();
13
- this.audioCtx = new AudioContext();
14
- this.nextStartTime = 0;
15
- this.audioQueue = this.createQueue();
16
- this.crossFadeDuration = crossFadeDuration;
17
- }
18
-
19
- private createQueue() {
20
- const q = queue(
21
- async (audioPromise: Promise<AudioBuffer>, callback: Function) => {
22
- const audioBuffer = await audioPromise;
23
- const source = this.audioCtx.createBufferSource();
24
- source.buffer = audioBuffer;
25
- source.connect(this.audioCtx.destination);
26
-
27
- // Create a gain node for crossfading
28
- const gainNode = this.audioCtx.createGain();
29
- source.connect(gainNode);
30
- gainNode.connect(this.audioCtx.destination);
31
-
32
- // Start the source at the next start time
33
- source.start(this.nextStartTime);
34
-
35
- // Schedule the crossfade
36
- gainNode.gain.setValueAtTime(0, this.nextStartTime);
37
- gainNode.gain.linearRampToValueAtTime(
38
- 1,
39
- this.nextStartTime + this.crossFadeDuration
40
- );
41
- gainNode.gain.setValueAtTime(
42
- 1,
43
- this.nextStartTime + audioBuffer.duration - this.crossFadeDuration
44
- );
45
- gainNode.gain.linearRampToValueAtTime(
46
- 0,
47
- this.nextStartTime + audioBuffer.duration
48
- );
49
-
50
- source.onended = () => {
51
- this.nextStartTime += audioBuffer.duration;
52
- callback();
53
- };
54
- },
55
- 1
56
- );
57
-
58
- q.drain(() => {
59
- this.emit("speech-end");
60
- });
61
- q.saturated(() => {
62
- this.emit("speech-start");
63
- });
64
-
65
- return q;
9
+ this.mediaSource = new MediaSource();
10
+ this.mediaSource.onsourceopen = () => {
11
+ this.sourceBuffer = this.mediaSource.addSourceBuffer(
12
+ 'audio/webm; codecs="opus"'
13
+ );
14
+ };
66
15
  }
67
16
 
68
17
  playChunk(audioData: ArrayBuffer) {
69
- const decodePromise = this.audioCtx.decodeAudioData(audioData);
70
- this.audioQueue.push(decodePromise);
18
+ if (!this.sourceBuffer) return;
19
+ if (this.mediaSource.readyState === "open" && !this.sourceBuffer.updating) {
20
+ this.sourceBuffer.appendBuffer(audioData);
21
+ }
71
22
  }
72
23
 
73
24
  async clear() {
74
- this.audioQueue.kill();
75
- this.audioQueue = this.createQueue();
76
- this.nextStartTime = 0;
25
+ if (this.sourceBuffer && this.mediaSource.readyState === "open") {
26
+ this.sourceBuffer.remove(0, this.sourceBuffer.buffered.end(0));
27
+ }
77
28
  }
78
29
  }