I am attempting to use the ElevenLabs API and Websockets to stream audio to the browser. response.audio
does return a generated partial MP3 audio chunk encoded as a base64 string, but I am stuck on trying to properly decode and play it. This is my current attempt:
Main notes:
- The API does return a response of base64 string successfully
- I keep receiving the error on Chrome:
Uncaught (in promise) DOMException: Failed to load because no supported source was found.
- My blob url returns a 404 error
Here is my code:
"use client";
import React, { useRef, useState } from 'react';
const StreamingAudioTest: React.FC = () => {
const [isPlaying, setIsPlaying] = useState(false);
const audioRef = useRef<HTMLAudioElement | null>(null);
const handlePlayButtonClick = () => {
const voiceId = "<voice-id>";
const model = 'eleven_monolingual_v1';
const wsUrl = `wss://api.elevenlabs.io/v1/text-to-speech/${voiceId}/stream-input?model_id=${model}`;
const socket = new WebSocket(wsUrl);
socket.onopen = function (event) {
const bosMessage = {
"text": " ",
"voice_settings": {
"stability": 0.5,
"similarity_boost": true
},
"xi_api_key": "<api-key>", // replace with your API key
};
socket.send(JSON.stringify(bosMessage));
const textMessage = {
"text": "Hello ",
"try_trigger_generation": true,
};
socket.send(JSON.stringify(textMessage));
const eosMessage = {
"text": ""
};
socket.send(JSON.stringify(eosMessage));
};
socket.onmessage = async function (event) {
const response = await JSON.parse(event.data);
if (response.audio) {
const audioChunk = atob(response.audio); // decode base64
console.log("Recieved audio chunk")
if (audioRef.current) {
const blob = new Blob([audioChunk], { type: 'audio/mp3' });
audioRef.current.src = URL.createObjectURL(blob);
audioRef.current.play();
}
}
if (response.isFinal) {
// Handle generation completion
}
if (response.normalizedAlignment) {
// Handle alignment info if needed
}
};
socket.onerror = function (error) {
console.error(`WebSocket Error: ${error}`);
};
socket.onclose = function (event) {
if (event.wasClean) {
console.info(`Connection closed cleanly, code=${event.code}, reason=${event.reason}`);
} else {
console.warn('Connection died');
}
};
// Cleanup the WebSocket when the component unmounts
return () => {
socket.close();
};
};
return (
<div className='text-red-500'>
<h1>Text-to-Speech Audio Player</h1>
<button onClick={handlePlayButtonClick} disabled={isPlaying}>
{isPlaying ? 'Playing...' : 'Play Audio'}
</button>
{/* <audio ref={audioRef} controls /> */}
<audio ref={audioRef} autoPlay controls />
</div>
);
};
export default StreamingAudioTest;
Via Active questions tagged javascript - Stack Overflow https://ift.tt/t9AZyWC
Comments
Post a Comment