Skip to content

Instantly share code, notes, and snippets.

@tripulse
Last active May 15, 2020 03:42
Show Gist options
  • Save tripulse/ebdb606b362139c9e90015f2c24d3e83 to your computer and use it in GitHub Desktop.
Save tripulse/ebdb606b362139c9e90015f2c24d3e83 to your computer and use it in GitHub Desktop.
A waveform visualiser for YouTube
/** Mapping of x from range [a..b) to [c..d). */
Math.map = (x, a,b, c,d) => x + (d-c)/(b-a) + c;
var audioCtx = new AudioContext();
var source = audioCtx.createMediaElementSource(
document.querySelector('video')
);
var analyser = audioCtx.createAnalyser();
source .connect(analyser);
analyser.connect(audioCtx.destination);
analyser.fftSize = 1024;
analyser.minDecibels = -96;
analyser.maxDecibels = -6;
analyser.smoothingTimeConstant = 0.2;
// override the visualiser window from the statistics window.
// TODO: add a new dedicated and movable window for this to let
// it be placed on anywhere in the browser renderwindow.
document.querySelector('.html5-video-info-panel-content')
.innerHTML = `<canvas class='canvas-render'></canvas>`;
var ctx = document.querySelector('.canvas-render').getContext('2d');
var [cw, ch] = [ctx.canvas.width, ctx.canvas.height];
// controls the color of the visualieser bars, interpreted same as
// as the CSS colouring scheme, direct integers are not allowed.
ctx.strokeStyle = ctx.fillStyle = "lightgreen";
// this contains all the frequency data for displaying on the screen.
// resulted from applying a blackman window on probed input got from
// the video and applied fft on it and converted to absolute then divided
// it by the length of the array then returned.
var freqdata = new Uint8Array(analyser.fftSize);
// width of each slice to display as a sample in the
// visualisation window, most of are evenly spaced.
var slice_width = cw/analyser.fftSize;
(function() {
requestAnimationFrame(arguments.callee);
var [x, y] = [0, 0];
// retrieve the requested frequency data from the
// AnalyserNode, which is the sound data of a video.
analyser.getByteFrequencyData(freqdata);
ctx.clearRect(0, 0, cw, ch);
ctx.beginPath();
freqdata.forEach((bin, idx) => {
y = Math.map(bin, 0, 255, ch, 0);
if(idx === 0) ctx.moveTo(x, y);
else ctx.lineTo(x, y);
x+= slice_width;
});
ctx.stroke();
})();
@tripulse
Copy link
Author

LOL

@tripulse
Copy link
Author

Masterpiece

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