0

I'm trying to code this particular audio visualization: https://codepen.io/nfj525/pen/rVBaab .

I'm struggling because instead of uploading the audio file like in the example, I want the code to run by clicking the play button of the audio. I want to use my own pre existing audio and play that and not have to upload a file. I'm new to coding and i'm not sure how to edit the javascript to do that.

This is the html I added in the audio I want to be played, "song.mp3"

<div id="content">
  <input type="file" id="thefile" accept="audio/*" />
  <canvas id="canvas"></canvas>
  <audio src="song.mp3" id="audio" controls></audio>
</div>

and this is the js for it

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();
  };
};
Vid
  • 1
  • 1

1 Answers1

0

So, for this you don't need the file input element anymore in your html, so your first piece becomes:

    <div id="content">
      <canvas id="canvas"></canvas>
      <audio src="song.mp3" id="audio" controls></audio>
    </div>

As for the Javascript, there is a little more work. In summary, we will extract and name the function that actually does the entire work, and then call it on the window.onload event. So your script section should look like:

<script>
    function playAudio() {
            var audio = document.getElementById("audio");
            // var files = this.files;  // not needed
            // audio.src = URL.createObjectURL(files[0]);  // not needed
            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();
          };

        window.onload = function () {
          // start playing audio once the page is fully loaded
          playAudio();
        };
</script>

Note that this will have to be hosted on some server.

sal
  • 3,515
  • 1
  • 10
  • 21
  • Would there be a way to do it without a server? – Vid May 18 '20 at 03:32
  • I'm afraid, not much. It's a security thing. You can read more about it [here](https://stackoverflow.com/questions/8192159/cross-origin-get-from-local-file) and [here](https://stackoverflow.com/questions/25504851/how-to-enable-cors-on-firefox) – sal May 18 '20 at 04:59