JSFiddle - React, Tailwind, and code Playground
HTML
<video src="http://media.jilion.com/videos/demo/midnight_sun_sv1_360p.mp4" width="960" height="540" loop="loop"></video>
<canvas width="960" height="100" style=""></canvas>
<br />
<input type="button" value="toggle" id="toggle" />
<input id="volume" type="range" min="0" max="100" value="100">
JavaScript
var video = document.querySelector('video'),
canvas = document.querySelector('canvas'),
toggle = document.getElementById('toggle'),
slider = document.getElementById('volume'),
context = new webkitAudioContext(),
volume = context.createGainNode(),
analyser = context.createAnalyser(),
tick = 0;
volume.gain.value = 0;
slider.value = Math.floor(volume.gain.value * 100);
canvas.context = canvas.getContext('2d');
function loop () {
var bar_width = 3,
context = canvas.context;
//context.globalAlpha = 0.05;
context.fillStyle = '#fff';
//context.fillRect(0, 0, canvas.width, canvas.height);
context.clearRect(0, 0, canvas.width, canvas.height);
//context.globalAlpha = .8;
context.fillStyle = 'rgb(' + ((tick + 130) % 255) + ',' + (tick % 255) + ',' + ((tick + 50) % 255) + ')';
var freqByteData = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(freqByteData);
var barCount = Math.round(canvas.width / bar_width);
for (var i = 0; i < barCount; i++) {
var magnitude = freqByteData[i];
context.fillRect(bar_width * i, canvas.height, bar_width - 2, -magnitude + 60);
}
tick++;
setTimeout(loop, 0);
}
video.addEventListener('canplaythrough', function () {
video.play();
source = context.createMediaElementSource(video);
volume.connect(context.destination);
source.connect(volume);
source.connect(analyser);
loop();
});
toggle.addEventListener('click', function () {
video[video.paused ? 'play' : 'pause']();
});
slider.addEventListener('change', function () {
volume.gain.value = this.value/100;
});
video.load();