#I’m interested in trying this out I’m

1 messages · Page 1 of 1 (latest)

spring snow
#

For sure. So you're looking for my front-end code, consuming and playing the streaming mp3?

rare nest
#

Yeah basically it would be what format the data is coming in and how you are formatting to play it and that should be good for me to translate to similar stuff in Godot

#

I’m wondering if it might be like the reverse of the wit.ai code I’m using which I mostly borrowed

spring snow
#

Sorry for the delay. Here's my backend node code for calling out and accepting the stream:

// Voice Synthesis service.
// Powered by Eleven Labs.

const axios = require('axios');

const ELEVEN_LABS_API_KEY = process.env.ELEVEN_LABS_API_KEY;
const ELEVEN_LABS_VOICE_ID = 'EXAVITQu4vr4xnSDxMaL'; // Bella. Try here: https://beta.elevenlabs.io/speech-synthesis

// Synthesize a voice from text.
// Note that this will attempt to read aloud any HTML/emoji/special characters you send in, so you may want to strip them out first.
// Returns a streaming audio buffer of type: audio/mpeg
exports.synthesizeVoice = async (text) => {
const options = {
method: 'POST',
url: https://api.elevenlabs.io/v1/text-to-speech/${ELEVEN_LABS_VOICE_ID}/stream,
headers: {
accept: 'audio/mpeg',
'content-type': 'application/json',
'xi-api-key': ELEVEN_LABS_API_KEY,
},
data: {
"text": text,
"voice_settings": {
"stability": 0.3, // 0-1. 0 is.. a little crazy. 1 sounds perfect but more like reading something.
"similarity_boost": 0
}
},
responseType: 'stream',
};

try {
    const res = await axios(options);
    return res.data;
} catch (error) {
    console.log(error);
    if (error.status == 401) {
        console.log("Eleven Labs: 401 (Authentication Error). Also happens when you hit your character quota for the month.");
    }
    throw error;
}

}

#

And here's how I process it one level up in the code:

exports.sendStreamingEventToClient = async (clientId, eventType, streamingResponse) => {
const client = clientModel.getClient(clientId);
if (client) {
// Listen to the data event and send chunks as they become available
streamingResponse.on('data', chunk => {
const data = { eventType, message: chunk.toString('base64') };
const eventString = data: ${JSON.stringify(data)}\n\n;
// This is dozens of entries per audio file coming back: console.log('Sending to client:', 'length:', eventString.length, 'start:', eventString.slice(0, 40), '...');
sendEventStringToClient(client, eventString);
});

    // Normally you would end the response after streaming, but it's our permanent EventSource
    // connection with the client, so we leave it open.

    // Handle errors in the stream
    streamingResponse.on('error', err => {
        console.error('Stream error', err);
        client.response.status(500).send('sendStreamingEventToClient: Internal Server Error while streaming');
    });
} else {
    console.log('ERROR: ClientCommService.sendEventToClient: unknown clientId: ' + clientId);
}

}