Ondographics loopback function readBands() { analyser.getByteFrequencyData(bands); var out = []; for (var i = 0; i < 32; i += 1) { var from = Math.floor(Math.pow(bands.length, i / 32)); var to = Math.max(from + 1, Math.floor(Math.pow(bands.length, (i + 1) / 32))); var sum = 0; for (var j = from; j < to; j += 1) sum += bands[j]; out.push(Math.min(1, (sum / (to - from) / 255) * 1.45)); } return out; } function readWave() { if (!timeDomain) timeDomain = new Uint8Array(analyser.fftSize); analyser.getByteTimeDomainData(timeDomain); var step = Math.floor(timeDomain.length / 96); for (var i = 0; i < 96; i += 1) wave[i] = (timeDomain[i * step] - 128) / 128; return wave; } function tick() { if (analyser) { var list = readBands(); post({ bands: list, wave: readWave(), level: list.reduce(function (a, b) { return a + b; }, 0) / list.length, at: performance.now(), }); } setTimeout(tick, 50); } async function start() { var stream = await navigator.mediaDevices.getDisplayMedia({ video: true, audio: true }); stream.getVideoTracks().forEach(function (track) { track.stop(); stream.removeTrack(track); }); var Ctx = window.AudioContext || window.webkitAudioContext; audioCtx = new Ctx(); var source = audioCtx.createMediaStreamSource(stream); analyser = audioCtx.createAnalyser(); analyser.fftSize = 2048; analyser.smoothingTimeConstant = 0.75; bands = new Uint8Array(analyser.frequencyBinCount); source.connect(analyser); if (audioCtx.state === 'suspended') audioCtx.resume(); post({ ready: true }); } start().catch(function (err) { post({ error: String((err && err.message) || err) }); }); tick(); })();