I'm using a text-to-speech API and I'm trying to serve the audio response to the client and have it play from there, but I'm constantly being met with this error:
GET blob:http://localhost:5173/8788f478-32ef-4e76-80a1-93c4f1a6a3a8 net::ERR_REQUEST_RANGE_NOT_SATISFIABLE
localhost/:1 Uncaught (in promise) DOMException: Failed to load because no supported source was found.
My client code looks like:
// +page.svelte
<script lang="ts">
let audio: any;
const handleClick = async () => {
const what = await fetch('/api/speech', {
method: 'POST',
headers: {
'Content-Type': 'audio/mpeg'
}
});
/**
* Play audio from blob
*/
const blob = await what.blob();
const url = URL.createObjectURL(blob);
audio.src = url;
audio.play();
};
</script>
<button on:click={handleClick}> Clicky </button>
<audio bind:this={audio}>
<source class="track" src="" type="audio/mpeg" />
</audio>
And my server code looks like:
// routes/api/speech/+server.ts
import AWS from 'aws-sdk';
export const POST = async () => {
const awsConfig = new AWS.Config(...);
const polly = new AWS.Polly(awsConfig);
const input = {
Engine: 'standard',
LanguageCode: 'en-US',
OutputFormat: 'mp3',
TextType: 'text',
VoiceId: 'Ivy',
Text: `hello hello`
};
const speech = (await polly.synthesizeSpeech(input, (err, data: any) => {
if (err) {
new Response(String('err'));
}
/**
* Return data in a way that's consumable by the browser
*/
if (data) {
if (data.AudioStream instanceof Buffer) {
// fs.writeFile('speech.mp3', data.AudioStream, function (err) {
// if (err) {
// return console.log(err);
// }
// console.log('The file was saved!');
// });
return data;
}
}
})) as any;
return new Response(speech.AudioStream, {
headers: {
'Content-Type': 'audio/mpeg'
}
});
};
If I write the generated file to disk it works and plays properly, but if I use the same data from the generated response and serve it as a Response it doesn't work. What am I doing wrong or is there something I'm missing?
Switching over to AWS SDK v3 made it much simpler. Just had to adjust the server code to:
import { PollyClient, SynthesizeSpeechCommand } from '@aws-sdk/client-polly';
const pollyClient = new PollyClient(...);
const input = {
Engine: 'standard',
LanguageCode: 'en-US',
OutputFormat: 'mp3',
TextType: 'text',
VoiceId: 'Ivy',
Text: `hi, I'm beepbooper`
};
const pollyCommand = new SynthesizeSpeechCommand(input);
const response = (await pollyClient.send(pollyCommand)) as any;
return new Response(response.AudioStream, {
headers: {
'Content-Type': 'audio/mpeg'
}
});