I want to have a recorder running on a website where every few seconds a post request is send to an api call to transcribe it.
However, the first time it works, but after that it will give this error:
"Error code: 400 - {'error': {'message': 'The audio file could not be decoded or its format is not supported.', 'type': 'invalid_request_error', 'param': None, 'code': None}}"
I tried to give it every time an temporary file name, but that did not work. I tried making the interval longer or shorter.
let mediaRecorder;
let audioChunks = [];
let sendInterval;
document.getElementById('recordBtn').addEventListener('click', async () => {
if (mediaRecorder && mediaRecorder.state === "recording") {
mediaRecorder.stop();
clearInterval(sendInterval); // Clear the interval when stopping
document.getElementById('recordBtn').textContent = 'Start Recording';
} else {
try {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
mediaRecorder = new MediaRecorder(stream);
mediaRecorder.ondataavailable = event => {
if (event.data.size > 0) {
audioChunks.push(event.data);
console.log('Chunk received:', event.data.size);
}
};
// Start recording with timeslice to ensure chunks are generated at regular intervals
mediaRecorder.start(3000);
document.getElementById('recordBtn').textContent = 'Stop Recording';
var x = 1;
const sendAudioChunks = async () => {
if (audioChunks.length > 0) {
console.log('Sending chunks:', audioChunks.length);
const audioBlob = new Blob(audioChunks, { 'type': 'audio/wav' });
audioChunks = []; // Clear chunks after sending
const formData = new FormData();
formData.append('audio_file', audioBlob, 'audio.wav');
try {
// Inside your try block within sendAudioChunks
const response = await fetch('/transcribe', {
method: 'POST',
body: formData,
});
if (!response.ok) {
// Log or handle non-200 responses here
console.error('Server responded with non-200 status:', response.status);
}
const data = await response.json();
console.log('Server response:', data);
document.getElementById('transcriptionContainer').textContent = data.transcription || 'Transcription failed or was empty.';
} catch (error) {
console.error('Failed to send audio chunks:', error);
}
} else {
console.log('No chunks to send');
}
};
clearInterval(sendInterval);
sendInterval = setInterval(sendAudioChunks, 3000);
mediaRecorder.onstop = async () => {
clearInterval(sendInterval); // Clear the interval when stopping
await sendAudioChunks(); // Send any remaining chunks
};
} catch (error) {
console.error('Error accessing media devices:', error);
}
}
});
Media files don't work that way. To process a file, you need the beginning and the end.
If minor breaks in the audio are acceptable, you can restart the recording for every chunk. Start recording. Stop after N seconds. Store/Send it. Start recording. Repeat.
Else you need to change the api so it joins the chunks before transcribing. Api gets first N seconds, transcribes it, get the next chunks, appends it to the existing one, transcribes the last N seconds, repeat.