LukaVidakovic's picture
Create script.js
9939489
raw
history blame
No virus
5.03 kB
let audioContext;
let analyser;
let sourceNode;
let mediaRecorder;
let audioChunks = [];
document.addEventListener("DOMContentLoaded", () => {
const audioResponseElement = document.getElementById("audioResponse");
const micButton = document.getElementById("micButton");
const blobs = document.querySelectorAll(".blob");
initAudioContext(audioResponseElement);
function initAudioContext(audioElement) {
audioContext = new (window.AudioContext || window.webkitAudioContext)();
analyser = audioContext.createAnalyser();
analyser.fftSize = 64;
if (audioElement && !sourceNode) {
sourceNode = audioContext.createMediaElementSource(audioElement);
sourceNode.connect(analyser);
analyser.connect(audioContext.destination);
}
}
function startWaitAnimation() {
document.getElementById("thought-bubble").style.display = "block";
micButton.classList.add("disabled");
micButton.disabled = true;
}
function stopWaitAnimation() {
document.getElementById("thought-bubble").style.display = "none";
micButton.classList.remove("disabled");
micButton.disabled = false;
}
function enableMicButton() {
micButton.classList.remove("disabled");
micButton.disabled = false;
}
function hideBlobs() {
document.querySelector(".blob-container").style.display = "none";
}
function showBlobs() {
document.querySelector(".blob-container").style.display = "flex";
}
async function startRecording() {
audioChunks = [];
try {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
mediaRecorder = new MediaRecorder(stream);
mediaRecorder.ondataavailable = (event) => audioChunks.push(event.data);
mediaRecorder.start();
} catch (error) {
console.error("Error accessing audio devices:", error);
micButton.checked = false; // Uncheck the button in case of an error
stopWaitAnimation();
}
}
function stopRecording() {
mediaRecorder.stop();
mediaRecorder.onstop = async () => {
const audioBlob = new Blob(audioChunks, { type: "audio/wav" });
const audioBase64 = await blobToBase64(audioBlob);
sendAudioToServer(audioBase64);
};
}
function blobToBase64(blob) {
const reader = new FileReader();
return new Promise((resolve) => {
reader.onloadend = () => resolve(reader.result.split(",")[1]);
reader.readAsDataURL(blob);
});
}
function sendAudioToServer(audioBase64) {
fetch(
"https://h8v918qrvg.execute-api.eu-central-1.amazonaws.com/Prod/sts/question",
{
method: "POST",
headers: { "Content-Type": "text/plain" },
body: audioBase64,
}
)
.then((response) => response.text())
.then((data) => {
if (data.message === "Question not provided in POST body") {
console.error("Question not provided in POST body");
stopWaitAnimation();
enableMicButton(); // Re-enable the microphone button
return; // Stop further processing
}
const audioSrc = `data:audio/wav;base64,${data}`;
audioResponseElement.src = audioSrc;
audioResponseElement.play().then(() => {
visualize(); // Start the visualizer after the audio starts playing
});
})
.catch((error) => {
console.error("Error:", error);
stopWaitAnimation();
});
}
micButton.addEventListener("change", () => {
hideBlobs();
if (micButton.checked) {
startRecording();
} else {
stopRecording();
startWaitAnimation();
}
});
function visualize() {
if (!audioContext) {
console.error("AudioContext not initialized");
return;
}
if (!sourceNode) {
console.error("SourceNode not initialized");
return;
}
const bufferLength = analyser.frequencyBinCount;
const dataArray = new Uint8Array(bufferLength);
function draw() {
requestAnimationFrame(draw);
analyser.getByteFrequencyData(dataArray);
const segmentLength = Math.floor(bufferLength / blobs.length);
for (let i = 0; i < blobs.length; i++) {
// Use an average value of a segment of the dataArray for each blob
const dataValue = dataArray[(i * segmentLength) / 2] || 0;
// Fallback to 0 if undefined
const height = (dataValue / 128.0) * 50 + 50;
blobs[i].style.height = `${height}px`;
}
}
draw();
}
audioResponseElement.onended = () => {
hideBlobs(); // Hide the blobs once the audio has finished playing
stopWaitAnimation();
enableMicButton(); // Ensure thought bubble is not showing
};
audioResponseElement.onplay = () => {
showBlobs(); // Show the blobs when audio starts playing
stopWaitAnimation(); // Hide the thought bubble when audio starts playing
};
document.body.addEventListener("click", () => {
if (audioContext && audioContext.state === "suspended") {
audioContext.resume();
}
});
});