var micEl, infoButEl, formButEl, canvasEl; var formDialogEl, infoDialogEl; let chunks = []; var cContext; var xie = 1; var mediaRecorder = false; var recordEls; var state = "idle"; var sendFile = function (blob) { const formData = new FormData(); formData.append('userfile', blob, new Date() + ".webm"); return fetch('', { method: 'POST', body: formData }); } var analyser, dataArray, barW, waves; var initVisual = function (stream) { waves = []; var audioContext = new AudioContext(); const ms = audioContext.createMediaStreamSource(stream); analyser = audioContext.createAnalyser(); ms.connect(analyser); analyser.connect(audioContext.destination); analyser.fftSize = 128; var bufferLength = analyser.frequencyBinCount; dataArray = new Uint8Array(bufferLength); barW = 29; } var animateVisual = function () { var cHeight = canvasEl.height; cContext.clearRect(0, 0, canvasEl.width, canvasEl.height); // scale from 0 to 255 analyser.getByteFrequencyData(dataArray); // analyser.getByteTimeDomainData(dataArray); var hRatio = (canvasEl.height) / 255; cContext.beginPath(); cContext.fill(); cContext.fillStyle = "#231F20"; waves.push(dataArray[0]); var max = 144; if (waves.length > (max + 1)) { waves.shift(); } var barWidth = Math.ceil(canvasEl.width / max); // first value is oldest value for (var i = waves.length; i > 0; i--) { var x = canvasEl.width - ((waves.length - i) * barWidth); var y = canvasEl.height / 2; var bHeight = waves[i] * hRatio; cContext.fillRect(x, y - (bHeight / 2), barWidth, bHeight) } if (state === "recording") { requestAnimationFrame(animateVisual); } else { cContext.clearRect(0, 0, canvasEl.width, canvasEl.height); } } var initRecording = function (autostart) { if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { navigator.mediaDevices .getUserMedia({ audio: true }) .then((stream) => { initVisual(stream); mediaRecorder = new MediaRecorder(stream); mediaRecorder.ondataavailable = (e) => { chunks.push(e.data); }; mediaRecorder.onstop = (e) => { const blob = new Blob(chunks, { type: mediaRecorder.mimeType }); chunks = []; sendFile(blob).then((response) => { if (response.status == 200) { console.log("all went well"); } else { alert("Ooops (" + response.status + ").... something went wrong. we are saving the file on your device instead"); var a = document.createElement("a"); document.body.appendChild(a); a.style = "display: none"; var url = window.URL.createObjectURL(blob); a.href = url; a.download = new Date() + ".webm"; a.click(); window.URL.revokeObjectURL(url); } state = "finished"; updateAllStates(state); }); } if (autostart) { mediaRecorder.start(); animateVisual(); } }) } else { console.error("not supported"); } } var startRecording = function () { if (!mediaRecorder) { console.log("did not initalise"); initRecording(false); } else { if (mediaRecorder.state === "recording") { console.log("recording was already happening") mediaRecorder.stop(); state = "uploading"; updateAllStates(state); } else { console.log("not yet recording, about tos tart"); mediaRecorder.start(); animateVisual(); } } } var updateAllStates = function (newState) { document.body.setAttribute("state", newState); recordEls.forEach((el) => { el.setAttribute("state", newState) }) } var onRecordElsClick = function (e) { console.log(e.currentTarget) var target = e.currentTarget.getAttribute("target"); if (state === "idle") { state = "waiting"; initRecording(false); e.currentTarget.setAttribute("state", state); document.body.setAttribute("state", state + "--" + e.currentTarget.getAttribute("target")); } else if (state === "waiting") { if (e.currentTarget.getAttribute("state") === "waiting") { state = "idle"; e.currentTarget.setAttribute("state", state); document.body.setAttribute("state", state); } else { state = "recording"; startRecording(); updateAllStates(state); } } else if (state === "recording") { state === "uploading"; updateAllStates(state); mediaRecorder.stop(); } } window.onload = function () { console.log("load app"); recordEls = document.querySelectorAll(".fn-touch-record"); document.body.setAttribute("state", state); recordEls.forEach((el) => { el.addEventListener("click", onRecordElsClick) }) canvasEl = document.querySelector('canvas'); canvasEl.width = window.innerWidth; cContext = canvasEl.getContext("2d"); formDialogEl = document.querySelector('.fn-dialog-form'); document.querySelectorAll('.fn-open-dialog-form').forEach((button) => { button.addEventListener("click", function (e) { e.preventDefault(); formDialogEl.showModal(); }) }) }