Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

HELP JavaScript nerds! MediaElementAudioSource outputs zeroes due to CORS access restrictions for

Hi, I am trying to add two pieces of code together and it was working out fine at first. There is one slight problem tho and it's the error (MediaElementAudioSource outputs zeroes due to CORS access restrictions for). My code is for an audio application and I am using a custom audio player and an analyser renderer. However the error is shown, it is probably because of the files location but I am not sure. I did some research but I got nothing from it. Here is my javascript code. I wrote all the code but I don't understand all of it as I was watching tutorials with it.

Full code

var music = new Audio(); 
music.src = 'mysong.mp3';
music.controls = false;
music.loop = false;
music.autoplay = false;

var duration; 
var pButton = document.getElementById('pButton'); 

var playhead = document.getElementById('playhead'); 

var timeline = document.getElementById('timeline'); 

var timelineWidth = timeline.offsetWidth - playhead.offsetWidth;


music.addEventListener("timeupdate", timeUpdate, false);


timeline.addEventListener("click", function (event) {
    moveplayhead(event);
    music.currentTime = duration * clickPercent(event);
}, false);


function clickPercent(e) {
    return (e.pageX - timeline.offsetLeft) / timelineWidth;
}

// Makes playhead draggable 
playhead.addEventListener('mousedown', mouseDown, false);
window.addEventListener('mouseup', mouseUp, false);

var onplayhead = false;

function mouseDown() {
    onplayhead = true;
    window.addEventListener('mousemove', moveplayhead, true);
    music.removeEventListener('timeupdate', timeUpdate, false);
}

function mouseUp(e) {
    if (onplayhead == true) {
        moveplayhead(e);
        window.removeEventListener('mousemove', moveplayhead, true);

        music.currentTime = duration * clickPercent(e);
        music.addEventListener('timeupdate', timeUpdate, false);
    }
    onplayhead = false;
}

function moveplayhead(e) {
    var newMargLeft = e.pageX - timeline.offsetLeft;
    if (newMargLeft >= 0 && newMargLeft <= timelineWidth) {
        playhead.style.marginLeft = newMargLeft + "px";
    }
    if (newMargLeft < 0) {
        playhead.style.marginLeft = "0px";
    }
    if (newMargLeft > timelineWidth) {
        playhead.style.marginLeft = timelineWidth + "px";
    }
}

function timeUpdate() {
    var playPercent = timelineWidth * (music.currentTime / duration);
    playhead.style.marginLeft = playPercent + "px";
    if (music.currentTime == duration) {
        pButton.className = "";
        pButton.className = "play";
    }
}


function play() {

    if (music.paused) {
        music.play();

        pButton.className = "";
        pButton.className = "pause";
    } else {
        music.pause();

        pButton.className = "";
        pButton.className = "play";
    }
}


music.addEventListener("canplaythrough", function () {
    duration = music.duration;  
}, false);



var canvas, ctx, source, context, analyser, fbc_array, bars, bar_x, bar_width, bar_height;
        window.addEventListener("load", initMp3Player, false);
        function initMp3Player(){
            document.getElementById('audio_box').appendChild(music);
            context = new AudioContext(); 
            analyser = context.createAnalyser(); 
            canvas = document.getElementById('analyser_render');
            ctx = canvas.getContext('2d');

            source = context.createMediaElementSource(music);

            source.connect(analyser);
            analyser.connect(context.destination);
            frameLooper();
        }
        function frameLooper(){
            window.requestAnimationFrame(frameLooper);
            fbc_array = new Uint8Array(analyser.frequencyBinCount);
            analyser.getByteFrequencyData(fbc_array);
            ctx.clearRect(0, 0, canvas.width, canvas.height); 
            ctx.fillStyle = '#d4002a'; 
            bars = 100;
            for (var i = 0; i < bars; i++) {
              bar_x = i * 3;
              bar_width = 2;
              bar_height = -(fbc_array[i] / 2);
              ctx.fillRect(bar_x, canvas.height, bar_width, bar_height);
            }
        }

Where I think the problems lie

var music = new Audio();

source = context.createMediaElementSource(music);

I know this is pretty complex but I might just be missing something.

Can you show me the directory/file structure of your project? Something like this:

  • public_html (dir)
    • index.html
    • my_song.mp3
    • js (dir)
      • audio.js
    • css (dir)
      • style.css

I just created a simple HTML file:

<!DOCTYPE html>
<html>
<head>
  <title>Audio Test</title>
</head>
<body>
<script type="text/javascript" src="audio.js"></script>
</body>
</html>

And an audio.js file:

var music = new Audio();
music.src = 'mysong.mp3';

var context = new AudioContext();
var source = context.createMediaElementSource(music);

With directory structure:

  • public_html
    • index.html
    • audio.js
    • mysong.mp3

And I don't get any error, so the createMediaElementSource method is running correctly. I verified this in Chromium using the JavaScript console by checking the value of source.

I did get the error when I ran the script by simply opening the file with my browser, instead of routing it through the server through the localhost. So this may be your problem. Does your browser's address bar start with file:// ? If so, that is the problem, NOT your code. If you're running on a local server the browser's address bar should start with localhost.

Hope that helps, feel free to comment with any more questions!

That's the same as me, but for some reason it still does not work... The file structure is in both flask and static, I tried both.

2 Answers

Let me see the exact console error. Here is the one I get:

MediaElementAudioSource outputs zeroes due to CORS access restrictions for file:///home/daniel/src/public_html/treehouse_forum/mysong.mp3

And your browser's address bar when you get the error. Mine is:

file:///home/daniel/src/public_html/treehouse_forum/index.html

Yes that is the one.

OK, then that means you are not running the script through a server, but are instead simply opening the file in your browser. You need to be running it through a local server like Apache or Nginx to not see this error with your code as is. Simply opening the file in your browser won't work. However, if you add this line to the JavaScript file:

music.crossOrigin = 'anonymous';

Then you won't get the error anymore. I don't really understand why, but after googling around for awhile that solution seems to work on my end.

You should really start running things through a local server soon though, it is great practice for when you have to actually upload a site to a server on the web!

Well, I am testing the audio player locally but I have a flask python server running locally where the actuall application is, what do I do if any errors appear there?

OK, I don't know anything about Flask severs, but did you try adding this:

music.crossOrigin = 'anonymous';

to the JavaScript file?