|
|
|
// set up basic variables for app
|
|
|
|
|
|
|
|
var record = document.querySelector('.record');
|
|
|
|
var stop = document.querySelector('.stop');
|
|
|
|
var soundClips = document.querySelector('.sound-clips');
|
|
|
|
var canvas = document.querySelector('.visualizer');
|
|
|
|
var mainSection = document.querySelector('.main-controls');
|
|
|
|
|
|
|
|
// disable stop button while not recording
|
|
|
|
|
|
|
|
stop.disabled = true;
|
|
|
|
|
|
|
|
// visualiser setup - create web audio api context and canvas
|
|
|
|
|
|
|
|
var audioCtx = new (window.AudioContext || webkitAudioContext)();
|
|
|
|
var canvasCtx = canvas.getContext("2d");
|
|
|
|
|
|
|
|
//main block for doing the audio recording
|
|
|
|
|
|
|
|
if (navigator.mediaDevices.getUserMedia) {
|
|
|
|
console.log('getUserMedia supported.');
|
|
|
|
|
|
|
|
var constraints = { audio: true };
|
|
|
|
var chunks = [];
|
|
|
|
|
|
|
|
var onSuccess = function(stream) {
|
|
|
|
var mediaRecorder = new MediaRecorder(stream);
|
|
|
|
|
|
|
|
visualize(stream);
|
|
|
|
|
|
|
|
record.onclick = function() {
|
|
|
|
mediaRecorder.start();
|
|
|
|
console.log(mediaRecorder.state);
|
|
|
|
console.log("recorder started");
|
|
|
|
record.style.background = "red";
|
|
|
|
|
|
|
|
stop.disabled = false;
|
|
|
|
record.disabled = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
stop.onclick = function() {
|
|
|
|
mediaRecorder.stop();
|
|
|
|
console.log(mediaRecorder.state);
|
|
|
|
console.log("recorder stopped");
|
|
|
|
record.style.background = "";
|
|
|
|
record.style.color = "";
|
|
|
|
// mediaRecorder.requestData();
|
|
|
|
|
|
|
|
stop.disabled = true;
|
|
|
|
record.disabled = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
mediaRecorder.onstop = function(e) {
|
|
|
|
console.log("data available after MediaRecorder.stop() called.");
|
|
|
|
|
|
|
|
var clipName = prompt('Enter a name for your sound clip?','My unnamed clip');
|
|
|
|
console.log(clipName);
|
|
|
|
var clipContainer = document.createElement('article');
|
|
|
|
var clipLabel = document.createElement('p');
|
|
|
|
var audio = document.createElement('audio');
|
|
|
|
var deleteButton = document.createElement('button');
|
|
|
|
|
|
|
|
clipContainer.classList.add('clip');
|
|
|
|
audio.setAttribute('controls', '');
|
|
|
|
deleteButton.textContent = 'Delete';
|
|
|
|
deleteButton.className = 'delete';
|
|
|
|
|
|
|
|
if(clipName === null) {
|
|
|
|
clipLabel.textContent = 'My unnamed clip';
|
|
|
|
} else {
|
|
|
|
clipLabel.textContent = clipName;
|
|
|
|
}
|
|
|
|
|
|
|
|
clipContainer.appendChild(audio);
|
|
|
|
clipContainer.appendChild(clipLabel);
|
|
|
|
clipContainer.appendChild(deleteButton);
|
|
|
|
soundClips.appendChild(clipContainer);
|
|
|
|
|
|
|
|
audio.controls = true;
|
|
|
|
var blob = new Blob(chunks, { 'type' : 'audio/ogg; codecs=opus' });
|
|
|
|
chunks = [];
|
|
|
|
var audioURL = window.URL.createObjectURL(blob);
|
|
|
|
console.log('audio',audioURL)
|
|
|
|
audio.src = audioURL;
|
|
|
|
console.log("recorder stopped");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// var url = (window.URL || window.webkitURL).createObjectURL(blob);
|
|
|
|
// console.log(url);
|
|
|
|
|
|
|
|
// var filename = <?php echo $filename;?>;
|
|
|
|
// var data = new FormData();
|
|
|
|
// data.append('file', blob);
|
|
|
|
|
|
|
|
// $.ajax({
|
|
|
|
// url : "vocal.php",
|
|
|
|
// type: 'POST',
|
|
|
|
// data: data,
|
|
|
|
// contentType: false,
|
|
|
|
// processData: false,
|
|
|
|
// success: function(data) {
|
|
|
|
// alert("boa!");
|
|
|
|
// },
|
|
|
|
// error: function() {
|
|
|
|
// alert("not so boa!");
|
|
|
|
// }
|
|
|
|
// });
|
|
|
|
|
|
|
|
// var xhr = new XMLHttpRequest();
|
|
|
|
// xhr.open('POST', 'audio/', true);
|
|
|
|
// xhr.onload = function(e) {
|
|
|
|
// console.log('Sent');
|
|
|
|
// };
|
|
|
|
// xhr.send(blob)
|
|
|
|
|
|
|
|
|
|
|
|
// request blob
|
|
|
|
// var xhr = new XMLHttpRequest();
|
|
|
|
// xhr.open('GET', audioURL, true);
|
|
|
|
// xhr.responseType = 'blob';
|
|
|
|
// xhr.onload = function(e) {
|
|
|
|
// if (this.status == 200) {
|
|
|
|
// var myBlob = this.response;
|
|
|
|
// // myBlob is now the blob that the object URL pointed to.
|
|
|
|
// }
|
|
|
|
// };
|
|
|
|
// xhr.send();
|
|
|
|
|
|
|
|
// let file = await fetch(audioURL).then(r => r.blob()).then(blobFile => new File([blobFile], "audio/", { type: "audio/ogg; codecs=opus" })
|
|
|
|
|
|
|
|
|
|
|
|
// var xhr = new XMLHttpRequest();
|
|
|
|
// xhr.open('GET',
|
|
|
|
// audioURL,
|
|
|
|
// true);
|
|
|
|
// xhr.responseType = "blob";
|
|
|
|
// xhr.onload = function(e){ //Stringify blob...
|
|
|
|
// //reload the icon from storage
|
|
|
|
// var fr = new FileReader();
|
|
|
|
// fr.onload =
|
|
|
|
// function(e) {
|
|
|
|
// localStorage['audio/'] = e.target.result;
|
|
|
|
// document.getElementById("myicon").src = localStorage['audio/'];
|
|
|
|
// }
|
|
|
|
// fr.readAsDataURL(xhr.response);
|
|
|
|
// }
|
|
|
|
// xhr.send(null);
|
|
|
|
|
|
|
|
deleteButton.onclick = function(e) {
|
|
|
|
evtTgt = e.target;
|
|
|
|
evtTgt.parentNode.parentNode.removeChild(evtTgt.parentNode);
|
|
|
|
}
|
|
|
|
|
|
|
|
clipLabel.onclick = function() {
|
|
|
|
var existingName = clipLabel.textContent;
|
|
|
|
var newClipName = prompt('Enter a new name for your sound clip?');
|
|
|
|
if(newClipName === null) {
|
|
|
|
clipLabel.textContent = existingName;
|
|
|
|
} else {
|
|
|
|
clipLabel.textContent = newClipName;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mediaRecorder.ondataavailable = function(e) {
|
|
|
|
chunks.push(e.data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var onError = function(err) {
|
|
|
|
console.log('The following error occured: ' + err);
|
|
|
|
}
|
|
|
|
|
|
|
|
navigator.mediaDevices.getUserMedia(constraints).then(onSuccess, onError);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
console.log('getUserMedia not supported on your browser!');
|
|
|
|
}
|
|
|
|
|
|
|
|
function visualize(stream) {
|
|
|
|
var source = audioCtx.createMediaStreamSource(stream);
|
|
|
|
|
|
|
|
var analyser = audioCtx.createAnalyser();
|
|
|
|
analyser.fftSize = 2048;
|
|
|
|
var bufferLength = analyser.frequencyBinCount;
|
|
|
|
var dataArray = new Uint8Array(bufferLength);
|
|
|
|
|
|
|
|
source.connect(analyser);
|
|
|
|
//analyser.connect(audioCtx.destination);
|
|
|
|
|
|
|
|
draw()
|
|
|
|
|
|
|
|
function draw() {
|
|
|
|
WIDTH = canvas.width
|
|
|
|
HEIGHT = canvas.height;
|
|
|
|
|
|
|
|
requestAnimationFrame(draw);
|
|
|
|
|
|
|
|
analyser.getByteTimeDomainData(dataArray);
|
|
|
|
|
|
|
|
canvasCtx.fillStyle = 'rgb(200, 200, 200)';
|
|
|
|
canvasCtx.fillRect(0, 0, WIDTH, HEIGHT);
|
|
|
|
|
|
|
|
canvasCtx.lineWidth = 2;
|
|
|
|
canvasCtx.strokeStyle = 'rgb(0, 0, 0)';
|
|
|
|
|
|
|
|
canvasCtx.beginPath();
|
|
|
|
|
|
|
|
var sliceWidth = WIDTH * 1.0 / bufferLength;
|
|
|
|
var x = 0;
|
|
|
|
|
|
|
|
|
|
|
|
for(var i = 0; i < bufferLength; i++) {
|
|
|
|
|
|
|
|
var v = dataArray[i] / 128.0;
|
|
|
|
var y = v * HEIGHT/2;
|
|
|
|
|
|
|
|
if(i === 0) {
|
|
|
|
canvasCtx.moveTo(x, y);
|
|
|
|
} else {
|
|
|
|
canvasCtx.lineTo(x, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
x += sliceWidth;
|
|
|
|
}
|
|
|
|
|
|
|
|
canvasCtx.lineTo(canvas.width, canvas.height/2);
|
|
|
|
canvasCtx.stroke();
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
window.onresize = function() {
|
|
|
|
canvas.width = mainSection.offsetWidth;
|
|
|
|
}
|
|
|
|
|
|
|
|
window.onresize();
|