<canvas id="canvas"></canvas>
<div>
<button id="start">Start recording</button>
<button id="stop" disabled>Stop recording</button>
</div>
canvas {
width: 100%;
height: 256px;
}
button {
padding: 0.5em 1em;
border-width: 0;
border-radius: 0.25em;
font-size: 1em;
background-color: #dfdfdf;
color: #333;
}
button[disabled] {
color: #aaa;
}
const start = document.querySelector('#start');
const stop = document.querySelector('#stop');
const canvas = document.querySelector('#canvas');
const drawContext = canvas.getContext('2d');
const cw = canvas.width;
const ch = canvas.height;
let mediaRecorder = null;
let mediaStream = null;
start.addEventListener('click', () => {
start.disabled = true;
stop.disabled = false;
const chunks = [];
mediaRecorder = new MediaRecorder(mediaStream, {
mimeType: 'audio/webm'
});
mediaRecorder.addEventListener('dataavailable', e => {
if (e.data.size > 0) {
chunks.push(e.data);
}
});
mediaRecorder.addEventListener('stop', () => {
const a = document.createElement('a');
a.href = URL.createObjectURL(new Blob(chunks));
a.download = 'test.webm';
a.click();
});
mediaRecorder.start();
});
stop.addEventListener('click', () => {
if (mediaRecorder === null) {
return;
}
start.disabled = false;
stop.disabled = true;
mediaRecorder.stop();
mediaRecorder = null;
});
navigator.mediaDevices.getUserMedia({ audio: true }).then(stream => {
mediaStream = stream;
const audioContext = new AudioContext();
const sourceNode = audioContext.createMediaStreamSource(stream);
const analyserNode = audioContext.createAnalyser();
analyserNode.fftSize = 2048;
sourceNode.connect(analyserNode);
function draw() {
const array = new Uint8Array(analyserNode.fftSize);
analyserNode.getByteTimeDomainData(array);
const barWidth = cw / analyserNode.fftSize;
drawContext.fillStyle = 'rgba(0, 0, 0, 1)';
drawContext.fillRect(0, 0, cw, ch);
for (let i = 0; i < analyserNode.fftSize; ++i) {
const value = array[i];
const percent = value / 255;
const height = ch * percent;
const offset = ch - height;
drawContext.fillStyle = 'lime';
drawContext.fillRect(i * barWidth, offset, barWidth, 2);
}
requestAnimationFrame(draw);
}
draw();
}).catch(error => {
console.log(error);
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.