Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: handle blob responses, construct wav header in example #338

Merged
merged 3 commits into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 29 additions & 5 deletions examples/node-speak-live/index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,38 @@
const fs = require("fs");
const { createClient, LiveTTSEvents } = require("../../dist/main/index");

// Add a wav audio container header to the file if you want to play the audio
// using the AudioContext or media player like VLC, Media Player, or Apple Music
// Without this header in the Chrome browser case, the audio will not play.
// prettier-ignore
const wavHeader = [
0x52, 0x49, 0x46, 0x46, // "RIFF"
0x00, 0x00, 0x00, 0x00, // Placeholder for file size
0x57, 0x41, 0x56, 0x45, // "WAVE"
0x66, 0x6D, 0x74, 0x20, // "fmt "
0x10, 0x00, 0x00, 0x00, // Chunk size (16)
0x01, 0x00, // Audio format (1 for PCM)
0x01, 0x00, // Number of channels (1)
0x80, 0xBB, 0x00, 0x00, // Sample rate (48000)
0x00, 0xEE, 0x02, 0x00, // Byte rate (48000 * 2)
0x02, 0x00, // Block align (2)
0x10, 0x00, // Bits per sample (16)
0x64, 0x61, 0x74, 0x61, // "data"
0x00, 0x00, 0x00, 0x00 // Placeholder for data size
];

const live = async () => {
const text = "Hello, how can I help you today?";

const deepgram = createClient(process.env.DEEPGRAM_API_KEY);

const dgConnection = deepgram.speak.live({ model: "aura-asteria-en" });
const dgConnection = deepgram.speak.live({
model: "aura-asteria-en",
encoding: "linear16",
sample_rate: 48000,
});

let audioBuffer = Buffer.alloc(0);
let audioBuffer = Buffer.from(wavHeader);

dgConnection.on(LiveTTSEvents.Open, () => {
console.log("Connection opened");
Expand Down Expand Up @@ -47,14 +71,14 @@ const live = async () => {

const writeFile = () => {
if (audioBuffer.length > 0) {
fs.writeFile("output.mp3", audioBuffer, (err) => {
fs.writeFile("output.wav", audioBuffer, (err) => {
if (err) {
console.error("Error writing audio file:", err);
} else {
console.log("Audio file saved as output.mp3");
console.log("Audio file saved as output.wav");
}
});
audioBuffer = Buffer.alloc(0); // Reset buffer after writing
audioBuffer = Buffer.from(wavHeader); // Reset buffer after writing
}
};
};
Expand Down
10 changes: 7 additions & 3 deletions src/packages/SpeakLiveClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export class SpeakLiveClient extends AbstractLiveClient {
* Handles binary messages received from the WebSocket connection.
* @param data - The binary data.
*/
protected handleBinaryMessage(data: ArrayBuffer): void {
protected handleBinaryMessage(data: Buffer): void {
this.emit(LiveTTSEvents.Audio, data);
}

Expand Down Expand Up @@ -148,10 +148,14 @@ export class SpeakLiveClient extends AbstractLiveClient {
error,
});
}
} else if (event.data instanceof Blob) {
event.data.arrayBuffer().then((buffer) => {
this.handleBinaryMessage(Buffer.from(buffer));
});
} else if (event.data instanceof ArrayBuffer) {
this.handleBinaryMessage(event.data);
this.handleBinaryMessage(Buffer.from(event.data));
} else if (Buffer.isBuffer(event.data)) {
this.handleBinaryMessage(event.data.buffer);
this.handleBinaryMessage(event.data);
} else {
console.log("Received unknown data type", event.data);
this.emit(LiveTTSEvents.Error, {
Expand Down
Loading