Skip to content

Instantly share code, notes, and snippets.

@daniel-j
Last active March 14, 2021 19:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save daniel-j/f69a9da5f87d3e99baabaca02e363ac8 to your computer and use it in GitHub Desktop.
Save daniel-j/f69a9da5f87d3e99baabaca02e363ac8 to your computer and use it in GitHub Desktop.
OBS-Studio Audio Visualizer. Add --enable-media-stream to Linux Browser command line arguments.
<!DOCTYPE html>
<html>
<head>
<title>Visualizer</title>
<style type="text/css">
html, body {
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
#visualizer {
width: 100%;
height: 100%;
display: block;
opacity: 1.00;
}
</style>
</head>
<body>
<div id="debug"></div>
<div id="visualizer"></div>
<script type="text/javascript">
let debug = document.getElementById('debug')
navigator.getUserMedia = navigator.getUserMedia
let acx, canvas, ctx, analyzer, liveFreqData
let visualizerDiv = document.getElementById('visualizer')
function log10 (num) {
return Math.log(num) / Math.LN10
}
function initializeVisualizer () {
acx = new AudioContext()
canvas = document.createElement('canvas')
ctx = canvas.getContext('2d')
visualizerDiv.appendChild(canvas)
analyzer = acx.createAnalyser()
analyzer.fftSize = 2048
analyzer.smoothingTimeConstant = 0.6
liveFreqData = new Float32Array(analyzer.frequencyBinCount)
}
function update () {
canvas.width = visualizerDiv.offsetWidth - 50
canvas.height = visualizerDiv.offsetHeight
ctx.clearRect(0, 0, canvas.width, canvas.height)
window.requestAnimationFrame(update.bind(this), canvas)
analyzer.getFloatFrequencyData(liveFreqData)
let widthScale = canvas.width / 2.5
for (let i = 0; i < liveFreqData.length; i++) {
// let freq = i*acx.sampleRate/analyzer.fftSize
let x = Math.floor(log10((i + 2) / 2) * widthScale | 0)
let dw = Math.ceil(log10((i + 3) / 2) * widthScale - log10((i + 2) / 2) * widthScale)
let magnitude = Math.min(Math.max((liveFreqData[i] - analyzer.minDecibels) / 95, 0), 1)
// ctx.fillStyle = 'hsl('+Math.min(Math.floor((i/(liveFreqData.length*0.7))*360), 359)+', 100%, '+Math.floor(magnitude*100-10)+'%)'
ctx.fillStyle = 'hsl(' + (Math.floor((i / liveFreqData.length) * 20) + 35) + ', 100%, ' + Math.max(magnitude * 100 + 0, 0) + '%)'
ctx.fillRect(x, canvas.height, dw, -magnitude * canvas.height | 0)
// PR hue: 38
}
}
initializeVisualizer()
if (navigator.getUserMedia) {
navigator.getUserMedia({ audio: {
autoGainControl: false,
channelCount: 2,
echoCancellation: false,
latency: 0,
noiseSuppression: false,
sampleRate: 48000,
sampleSize: 16,
volume: 1.0
} }, function (stream) {
var source = acx.createMediaStreamSource(stream)
source.connect(analyzer)
update()
debug.innerHTML = ""
}, function (err) {
debug.innerHTML += "The following error occurred: " + err.name + "<br/>"
});
} else {
debug.innerHTML += "getUserMedia not supported" + "<br/>"
}
</script>
</body>
</html>
Copy link

ghost commented Mar 22, 2019

If I use your script, ill always get: NotFoundError or OverconstrainedError even if I specify with the deviceId, do u know some workaround for it?
codepen exampe starts at line 72

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment