How to make AudioContext() and RequestAnimationFrame() running in current browsers

1.1k views Asked by At

I am trying to create a visualiser using HTML5 Audio and frequencies based on a canvas. It is working fine on chrome and safari. But I want to make it working on IE and Firefox as well.

// Create a new instance of an audio object and adjust some of its properties
var audio = new Audio();
audio.crossOrigin = "anonymous";
audio.src = 'http://www.streaming507.com:8072/stream';
audio.controls = true;
audio.loop = true;

// Establish all variables that your Analyser will use
var canvas, ctx, source, context, analyser, fbc_array, bars, bar_x, bar_width, bar_height;
// Initialize the MP3 player after the page loads all of its HTML into the window
window.addEventListener("load", initMp3Player, false);

function initMp3Player() {
  document.getElementById('audio_box').appendChild(audio);
  context = new webkitAudioContext(); // AudioContext object instance
  analyser = context.createAnalyser(); // AnalyserNode method
  canvas = document.getElementById('analyser_render');
  ctx = canvas.getContext('2d');
  // Re-route audio playback into the processing graph of the AudioContext
  source = context.createMediaElementSource(audio);
  source.connect(analyser);
  analyser.connect(context.destination);
  //frameLooper();
}
// frameLooper() animates any style of graphics you wish to the audio frequency
// Looping at the default frame rate that the browser provides(approx. 60 FPS)
function frameLooper() {
  window.webkitRequestAnimationFrame(frameLooper);
  fbc_array = new Uint8Array(analyser.frequencyBinCount);
  analyser.getByteFrequencyData(fbc_array);
  ctx.clearRect(0, 0, canvas.width, canvas.height); // Clear the canvas
  var my_gradient = ctx.createLinearGradient(0, 0, 170, 0);
  my_gradient.addColorStop(0, "black");
  my_gradient.addColorStop(0.5, "red");
  my_gradient.addColorStop(1, "white");
  ctx.fillStyle = my_gradient; // Color of the bars
  bars = 100;
  for (var i = 0; i < bars; i++) {
    bar_x = i * 3;
    bar_width = 2;
    bar_height = -(fbc_array[i] / 2);
    //  fillRect( x, y, width, height ) // Explanation of the parameters below
    ctx.fillRect(bar_x, canvas.height, bar_width, bar_height);
  }
}
div#mp3_player {
  width: 500px;
  height: 60px;
  background: #000;
  padding: 5px;
  margin: 50px auto;
}

div#mp3_player > div > audio {
  width: 500px;
  background: #000;
  float: left;
}

div#mp3_player > canvas {
  width: 500px;
  height: 30px;
  background: #002D3C;
  float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="mp3_player">
  <div id="audio_box"></div>
  <canvas id="analyser_render"></canvas>
</div>

Please note, it does not show the visualisation on stack overflow, but it work on local host. Basically the issue that it does not show on IE and Moz is webkitAudioContext(), and webkitRequestAnimationFrame(). removing webkit from the first one makes it working on chrome and IE but stops working on Safari.

Is there any idea how to make it working in current browsers like Chrome, Safari, Firefox and IE.

1

There are 1 answers

4
AudioBubble On BEST ANSWER

Try to allocate the AudioContext this way:

var Actx;
try {
  Actx = (AudioContext || webkitAudioContext);
}
catch(err) {
  // sorry, no visualizer for you...
}

if (Actx) {
  context = new Actx();
  // ... continue here
}
else {
  // optionally rub it in here instead of in catch...
}

For requestAnimationFrame you can use this polyfill, then use it without prefix:

function frameLooper() {
  window.requestAnimationFrame(frameLooper);
  ...

You probably also want to wait for the audio element's "canplay" event.