2022-08-13 16:00:08 +02:00
|
|
|
/**
|
|
|
|
* Credits to:
|
|
|
|
* https://codepen.io/jakealbaugh/pen/jvQweW
|
|
|
|
*/
|
|
|
|
|
2022-08-18 05:45:38 +02:00
|
|
|
const ICECAST_URL = '/stream';
|
|
|
|
|
2022-08-13 16:00:08 +02:00
|
|
|
var started = false;
|
2022-08-16 07:05:49 +02:00
|
|
|
try {
|
|
|
|
var spectro_button = document.getElementById('spectro-button');
|
|
|
|
spectro_button.addEventListener('click', () => {
|
|
|
|
if (started) return;
|
|
|
|
started = true;
|
|
|
|
console.log("starting spectro");
|
|
|
|
initialize();
|
2022-08-18 05:45:38 +02:00
|
|
|
})
|
2022-08-16 07:05:49 +02:00
|
|
|
} catch {
|
2022-08-16 19:28:19 +02:00
|
|
|
console.debug("spectro not found");
|
2022-08-16 07:05:49 +02:00
|
|
|
}
|
2022-08-13 16:00:08 +02:00
|
|
|
|
|
|
|
function initialize() {
|
2022-08-18 05:45:38 +02:00
|
|
|
const AUDIO_ELEMENT = document.getElementById('player');
|
2022-08-13 16:00:08 +02:00
|
|
|
const CVS = document.getElementById('spectro-canvas');
|
|
|
|
const CTX = CVS.getContext('2d');
|
|
|
|
const W = CVS.width = window.innerWidth;
|
|
|
|
const H = CVS.height = window.innerHeight;
|
|
|
|
|
|
|
|
const ACTX = new AudioContext();
|
|
|
|
const ANALYSER = ACTX.createAnalyser();
|
|
|
|
|
2022-08-18 05:45:38 +02:00
|
|
|
ANALYSER.fftSize = 4096;
|
|
|
|
|
|
|
|
// navigator.mediaDevices
|
|
|
|
// .getUserMedia({ audio: true })
|
|
|
|
// .then(process);
|
|
|
|
|
|
|
|
// Add icecast stream
|
|
|
|
// var audio = new Audio(ICECAST_URL);
|
|
|
|
let stream;
|
|
|
|
AUDIO_ELEMENT.src = ICECAST_URL;
|
|
|
|
AUDIO_ELEMENT.play();
|
|
|
|
AUDIO_ELEMENT.onplay = function () {
|
|
|
|
if (navigator.userAgent.indexOf('Firefox') > -1) {
|
|
|
|
stream = AUDIO_ELEMENT.mozCaptureStream();
|
|
|
|
} else {
|
|
|
|
console.debug('Not a firefox browser, defaults to `captureStream()`');
|
|
|
|
stream = AUDIO_ELEMENT.captureStream();
|
|
|
|
}
|
|
|
|
process(AUDIO_ELEMENT);
|
|
|
|
}
|
2022-08-13 16:00:08 +02:00
|
|
|
|
2022-08-18 05:45:38 +02:00
|
|
|
function process(audio) {
|
|
|
|
const SOURCE = ACTX.createMediaElementSource(audio);
|
2022-08-13 16:00:08 +02:00
|
|
|
SOURCE.connect(ANALYSER);
|
|
|
|
const DATA = new Uint8Array(ANALYSER.frequencyBinCount);
|
|
|
|
const LEN = DATA.length;
|
|
|
|
const h = H / LEN;
|
|
|
|
const x = W - 1;
|
|
|
|
CTX.fillStyle = 'hsl(280, 100%, 10%)';
|
|
|
|
CTX.fillRect(0, 0, W, H);
|
|
|
|
|
|
|
|
loop();
|
|
|
|
|
|
|
|
function loop() {
|
|
|
|
window.requestAnimationFrame(loop);
|
|
|
|
let imgData = CTX.getImageData(1, 0, W - 1, H);
|
|
|
|
CTX.fillRect(0, 0, W, H);
|
|
|
|
CTX.putImageData(imgData, 0, 0);
|
|
|
|
ANALYSER.getByteFrequencyData(DATA);
|
|
|
|
for (let i = 0; i < LEN; i++) {
|
|
|
|
let rat = DATA[i] / 255;
|
|
|
|
let hue = Math.round((rat * 120) + 280 % 360);
|
|
|
|
let sat = '100%';
|
|
|
|
let lit = 10 + (70 * rat) + '%';
|
|
|
|
CTX.beginPath();
|
|
|
|
CTX.strokeStyle = `hsl(${hue}, ${sat}, ${lit})`;
|
|
|
|
CTX.moveTo(x, H - (i * h));
|
|
|
|
CTX.lineTo(x, H - (i * h + h));
|
|
|
|
CTX.stroke();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|