1

There is a custom animated HTML audio analyzer graphic that plays an audio track and moves based on the frequencies of that audio.

This is the code from CodePen HERE, I've found out that it only works on HTTPS domain only.

Now the problem is: I don't need to upload an audio track like what the code does, I just need a simple audio track to play automatically and removing that upload button. let's say I have a track1.mp3 in the same directory on the server and want to play it when my HTML page is loaded.

  window.onload = function() {
  var file = document.getElementById("thefile");
  var audio = document.getElementById("audio");

  file.onchange = function() {
    var files = this.files;
    audio.src = URL.createObjectURL(files[0]);
    audio.load();
    audio.play();
    var context = new AudioContext();
    var src = context.createMediaElementSource(audio);
    var analyser = context.createAnalyser();

    var canvas = document.getElementById("canvas");
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    var ctx = canvas.getContext("2d");

    src.connect(analyser);
    analyser.connect(context.destination);

    analyser.fftSize = 256;

    var bufferLength = analyser.frequencyBinCount;
    console.log(bufferLength);

    var dataArray = new Uint8Array(bufferLength);

    var WIDTH = canvas.width;
    var HEIGHT = canvas.height;

    var barWidth = (WIDTH / bufferLength) * 2.5;
    var barHeight;
    var x = 0;

    function renderFrame() {
      requestAnimationFrame(renderFrame);

      x = 0;

      analyser.getByteFrequencyData(dataArray);

      ctx.fillStyle = "#000";
      ctx.fillRect(0, 0, WIDTH, HEIGHT);

      for (var i = 0; i < bufferLength; i++) {
        barHeight = dataArray[i];

        var r = barHeight + (25 * (i / bufferLength));
        var g = 250 * (i / bufferLength);
        var b = 50;

        ctx.fillStyle = "rgb(" + r + "," + g + "," + b + ")";
        ctx.fillRect(x, HEIGHT - barHeight, barWidth, barHeight);

        x += barWidth + 1;
      }
    }

    audio.play();
    renderFrame();
  };
};
#thefile {
  position: fixed;
  top: 10px;
  left: 10px;
  z-index: 100;
}

#canvas {
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
}

audio {
  position: fixed;
  left: 10px;
  bottom: 10px;
  width: calc(100% - 20px);
}
<div id="content">
  <input type="file" id="thefile" accept="audio/*" />
  <canvas id="canvas"></canvas>
  <audio id="audio" controls></audio>
</div>
Sara Ree
  • 3,417
  • 12
  • 48
  • *" let's say I have a track1.mp3 in the same directory and want to play it when my page is loaded."* Let;s say is this folder on a server or your desktop? – zer00ne Jan 11 '19 at 16:25
  • Server with a HTTPS domain – Sara Ree Jan 11 '19 at 16:27
  • Ok, test it out it's ready. I could only load it to a certain point because this site isn't a proper environment for [Same Origin Policy](https://stackoverflow.com/a/35553666/2813224) concerns, so let me know if you run into any problems, good luck. – zer00ne Jan 11 '19 at 17:44

1 Answers1

1

Google Forces Yet Another Policy

Nothing is sacred to these guys -- as of Dec 2018 New autoplay policies have been enacted upon Chrome users developing Web Audio API. If the AudioContext(); is created before the user interacts with a gesture (click, tap, burp, snore, etc), the AudioContext(); will be suspended until the user does so.

So to adjust for this engineering marvel I added a play button and wrapped everything in an eventListener.


Changing src

"Now the problem is: I don't need to upload an audio track like what the code does, I just need a simple audio track to play automatically and removing that upload button. let's say I have a track1.mp3 in the same directory and want to play it when my page is loaded."

OK, the demo has been adapted to load a normal url, you'll need to change this line so that it points to the location of the file on your server:

audio.src = "https://host.top/path/to/file.mp3";

The new line that's above the previously mentioned line is added for certain conflicts with CORS:

audio.crossOrigin = "anonymous";


Plunker

Demo

Note: If this Stack Snippet has no sound, then go to this Plunker

document.getElementById('load').addEventListener('click', audioViz);

function audioViz(e) {

  var player = document.getElementById("player");

  player.crossOrigin = "anonymous";
  player.src = "https://glsbx.s3-us-west-1.amazonaws.com/-/dd.mp3";
  player.load();
  player.play();

  var context = new AudioContext();
  var src = context.createMediaElementSource(player);
  var analyser = context.createAnalyser();

  var canvas = document.getElementById("canvas");
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
  var ctx = canvas.getContext("2d");

  src.connect(analyser);
  analyser.connect(context.destination);

  analyser.fftSize = 256;

  var bufferLength = analyser.frequencyBinCount;
  console.log(bufferLength);

  var dataArray = new Uint8Array(bufferLength);

  var WIDTH = canvas.width;
  var HEIGHT = canvas.height;

  var barWidth = (WIDTH / bufferLength) * 2.5;
  var barHeight;
  var x = 0;

  function renderFrame() {

    requestAnimationFrame(renderFrame);

    x = 0;

    analyser.getByteFrequencyData(dataArray);

    ctx.fillStyle = "#000";
    ctx.fillRect(0, 0, WIDTH, HEIGHT);

    for (var i = 0; i < bufferLength; i++) {
      barHeight = dataArray[i];

      var r = barHeight + (25 * (i / bufferLength));
      var g = 250 * (i / bufferLength);
      var b = 50;

      ctx.fillStyle = "rgb(" + r + "," + g + "," + b + ")";
      ctx.fillRect(x, HEIGHT - barHeight, barWidth, barHeight);

      x += barWidth + 1;
    }
  }

  player.play();
  renderFrame();
}
button {
  position: fixed;
  top: 46px;
  left: 46px;
  z-index: 100;
  display: inline-block;
  font-size: 48px;
  border: none;
  background: none;
  color: rgba(223, 6, 39, 0.8);
  cursor: pointer;
}

button:hover {
  color: rgba(255, 0, 128, 0.8);
}

button:focus {
  outline: 0
}

#canvas {
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
}

#player {
  position: fixed;
  left: 10px;
  bottom: 10px;
  width: calc(100% - 20px);
}
<button id='load' class='load' type='button'>▶</button>
<canvas id="canvas"></canvas>
<audio id="player" controls>
  <source src='about:blank'>
</audio>
zer00ne
  • 41,936
  • 6
  • 41
  • 68
  • Thank you for your reply... unfortunately, the code above doesn't work. here is the link where I tested it. https://reed123.000webhostapp.com/Index.html – Sara Ree Jan 11 '19 at 17:53
  • When I added var audio = new Audio(); it plays the audio but the bars NO... they're not there – Sara Ree Jan 11 '19 at 18:00
  • The script already has an audio object there's no need to make another – zer00ne Jan 11 '19 at 18:03
  • @SaraRee There's a new policy google enacted [concerning Web Audio Dec 2018](https://developers.google.com/web/updates/2017/09/autoplay-policy-changes#webaudio), hold on... – zer00ne Jan 11 '19 at 18:12
  • @SaraRee Ok try now...wait...sorry. – zer00ne Jan 11 '19 at 18:51
  • Sorry... still I'm unable to see the bars and autoplay doesn't work too. Although I've added audio.autoplay = true; . Here is the result: https://reed123.000webhostapp.com/Index.html – Sara Ree Jan 11 '19 at 19:27
  • You added `autoplay`? Don't add anything but the url otherwise it gets progressively more difficult to debug, There's no point in autoplay if you are required to have the user click a button or nothing happens. – zer00ne Jan 11 '19 at 20:12
  • Ok @SaraRee it works ***but remember that auto-play has been severely crippled*** in Chrome and most likely the the other browsers will follow suit if they haven't already. I posted a couple of links [concerning this](https://developers.google.com/web/updates/2017/09/autoplay-policy-changes#webaudio) – zer00ne Jan 12 '19 at 11:21