I'm building a sentence recognizer in javascript / python. The process is simple:
Here is the code:
let recorder;
let stream;
let hk;
let chunks = [];
function recoverAudio(cks) {
const blob = new Blob(cks, {type: "audio/ogg"});
const http = new XMLHttpRequest();
const fd = new FormData();
fd.set("audio", blob);
http.open("POST", "/api/recognize");
http.onreadystatechange = () => {
};
http.send(fd);
chunks = [];
}
function record(e) {
chunks.push(e.data);
console.log(e);
}
window.addEventListener("load", async () => {
let el = document.querySelector(".footer-main-button");
[stream, recorder] = await prepareRecorder();
recorder.ondataavailable = record;
hk = hark(stream);
hk.on("stopped_speaking", () => {
console.log("stopped speaking");
el.style.removeProperty("color")
setTimeout(() => {
hk.suspend();
recorder.stop();
recoverAudio(chunks);
}, 1000); // Wait for the last chunk to be recorded
});
el.addEventListener("click", e => {
if (recorder.state !== "recording") {
recorder.start(1000);
hk.resume();
el.style.color = "red";
}
});
}, true);
On the server side (with flask), i read the file as so:
@app.route("/api/recognize", methods=["POST"])
def recognize():
audio = flask.request.files["audio"]
if not audio:
return flask.abort(400)
audio.save("./resources/temp/audio.ogg")
But while the first time I record something, everything works fine, as soon as I rerecord something, the file ./resources/temp/audio.ogg
is empty. I've checked the DevTools Network, the request contains the valid audio. Even weirder, if I reload the window the code works fine again the first time but not after.
Any ideas why? (As a reference here is the github containing the whole project: https://github.com/atzitz-amos/TM)
I made your code works ok as follows:
let recorder;
let stream;
let hk;
let chunks = [];
function recoverAudio(cks) {
const blob = new Blob(cks, {type: "audio/ogg"});
const http = new XMLHttpRequest();
const fd = new FormData();
fd.set("audio", blob);
http.open("POST", "/api/recognize");
http.onreadystatechange = () => {
};
http.send(fd);
chunks = []; // EVEN WITH THIS AFTER FIRST RECORDING THERE IS 1 Blob WHEN START THE ENXT RECORDING (REMOVE THIS LINE OF CODE)
}
function record(e) {
chunks.push(e.data);
console.log(e);
}
window.addEventListener("load", async () => {
let el = document.querySelector(".footer-main-button");
[stream, recorder] = await prepareRecorder();
recorder.ondataavailable = record;
hk = hark(stream);
hk.on("stopped_speaking", () => {
console.log("stopped speaking");
el.style.removeProperty("color")
setTimeout(() => {
hk.suspend();
recorder.stop();
recoverAudio(chunks);
}, 1000); // Wait for the last chunk to be recorded
});
el.addEventListener("click", e => {
if (recorder.state !== "recording") {
console.log(`chunks.length before recorder.start: ${chunks.length}`) // <== Second time ==> chunks.length before recorder.start: 1
chunks = []; // RESET chunks HERE // <== THIS MADE FOLLOWING RECORDS WORKS OK
recorder.start(1000);
hk.resume();
el.style.color = "red";
}
});
}, true);