MP3 stream and FFT analyser

Simple streaming mp3 using audio tag.

by fxi

HTML

<input id='speed' type='range' min=0 max=3 step=0.1 value=1>

<button id="play">play/pause</button>
<div id="fft"></div>

CSS

body,
html {
  color: #eea244;
  background: #474747;
  width: 100%;
  height: 100%;
}

JavaScript

var url = "https://hirschmilch.de:7001/chillout.mp3";
var elPlay = document.getElementById('play');
var elSpeed = document.getElementById('speed');
var elFft = document.getElementById('fft');


elPlay.addEventListener('click', function() {
  player.toggle();
})

elSpeed.addEventListener('input', function(e) {
  player.setPlaybackRate(e.target.value*1);
})

function Player(url, opt) {
  var p = this;
  p.opt = Object.assign({}, {
    mode: 'wave',
    size: 256,
    onData: console.log
  }, opt);
  p.url = url;
  p.init();
  return p
}


Player.prototype.init = function() {
  var p = this;
  p._playing = false;
  p.elAudio = document.createElement('audio');
  p.elAudio.crossOrigin = "anonymous";
 
  p.ctx = new AudioContext();
  p.source = p.ctx.createMediaElementSource(p.elAudio);
  p.analyser = p.ctx.createAnalyser();
  p.source.connect(p.analyser);
  p.source.connect(p.ctx.destination);
  p.setSize();
}

Player.prototype.setSize = function(size) {
  var p = this;
  p.opt.size = size || p.opt.size;
  p.analyser.fftSize = p.opt.size * 2;
  p.data = new Float32Array(p.opt.size);
}

Player.prototype.setMode = function(mode) {
  var p = this;
  p.opt.mode = mode || p.opt.mode;
}


Player.prototype.getData = function() {
  var p = this;
  if (p.opt.mode === 'fft') {
    p.analyser.getFloatFrequencyData(p.data);
  } else {
    p.analyser.getFloatTimeDomainData(p.data);
  }
  return p.data;
}


Player.prototype.toggle = function() {
  p = this;
  if (p._playing) {
    p.elAudio.pause();
    p._playing = false;
  } else {
    p.elAudio.src = p.url;
    p.elAudio.play();
    p._playing = true;
    p.render();

  }
}

Player.prototype.render = function() {
  var p = this;
  if (!p._playing) {
    return;
  }
  p.opt.onData(p.getData());
  window.requestAnimationFrame(p.render.bind(p));
}

Player.prototype.setPlaybackRate = function(v){
  var p = this;
  p.elAudio.playbackRate = v
  //p.ctx.playbackRate.value = v;
}


var player = new Player(url, {
  size: 16,
  mode:...