gUM audioCapture
by jib1
HTML
<audio id="audio" controls width="160" height="120" autoplay></audio><br>
Hit pause above to see that the audio comes from the element in this tab
<div id="container"></div>
<div id="div"></div>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
JavaScript
const gUM = c => navigator.mediaDevices.getUserMedia(c);
// Requires media.getusermedia.audiocapture.enabled=true
(async () => {
audio.srcObject = await gUM({audio: true, fake:true});
spectrum(await gUM({audio: {mediaSource: "audioCapture"}}));
})().catch(e => log(e));
function spectrum(stream) {
const audioCtx = new AudioContext();
const analyser = audioCtx.createAnalyser();
audioCtx.createMediaStreamSource(stream).connect(analyser);
const [track] = stream.getAudioTracks();
track.onended = () => audioCtx.close();
track.stop_ = track.stop;
track.stop = () => track.stop_(audioCtx.close());
const canvas = container.appendChild(document.createElement("canvas"));
canvas.width = audio.clientWidth;
canvas.height = 200;
const ctx = canvas.getContext("2d");
const data = new Uint8Array(canvas.width);
ctx.strokeStyle = 'rgb(0, 125, 0)';
setInterval(() => {
ctx.fillStyle = "#a0a0a0";
ctx.fillRect(0, 0, canvas.width, canvas.height);
analyser.getByteFrequencyData(data);
ctx.lineWidth = 2;
let x = 0;
for (let d of data) {
const y = canvas.height - (d / 128) * canvas.height / 4;
const c = Math.floor((x*255)/canvas.width);
ctx.fillStyle = `rgb(${c},0,${255-x})`;
ctx.fillRect(x++, y, 2, canvas.height - y)
}
analyser.getByteTimeDomainData(data);
ctx.lineWidth = 5;
ctx.beginPath();
x = 0;
for (let d of data) {
const y = canvas.height - (d / 128) * canvas.height / 2;
x ? ctx.lineTo(x++, y) : ctx.moveTo(x++, y);
}
ctx.stroke();
}, 1000 * canvas.width / audioCtx.sampleRate);
return stream;
};
function log(msg) { div.innerHTML += "<br>" + msg; }