Skip to content

Instantly share code, notes, and snippets.

@daniel-j
Last active March 14, 2021 19:09
Show Gist options
  • Select an option

  • Save daniel-j/f69a9da5f87d3e99baabaca02e363ac8 to your computer and use it in GitHub Desktop.

Select an option

Save daniel-j/f69a9da5f87d3e99baabaca02e363ac8 to your computer and use it in GitHub Desktop.

Revisions

  1. daniel-j revised this gist Mar 14, 2021. 1 changed file with 10 additions and 1 deletion.
    11 changes: 10 additions & 1 deletion obs-visualizer.html
    Original file line number Diff line number Diff line change
    @@ -77,7 +77,16 @@
    initializeVisualizer()

    if (navigator.getUserMedia) {
    navigator.getUserMedia({ audio: true }, function (stream) {
    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()
  2. daniel-j created this gist Dec 20, 2017.
    94 changes: 94 additions & 0 deletions obs-visualizer.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,94 @@
    <!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: true }, 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>