How can I set CORS access for an audio file on my Linux webserver with apache2?

I am trying to create an audio visualization project on codepen. I tried hosting the audio file with OneDrive, but I was receiving CORS restriction errors. Now I have gone a step further and created my own web server (http://publicwebserverdemo.hopto.org) where I have the audio file hosted (http://publicwebserverdemo.hopto.org/publicAudio/audio.mp3). I have tried several sets of instructions across the internet for implementing CORS with the .htaccess file but I haven't had any luck with that. How can I grant CORS access to codepen for the audio file?

I am using Apache (with the whole LAMP package) on Ubuntu Mate 14.04.

Here is a replication of the sample codepen (I grabbed the code for testing CORS from some place on the internet).

Open your web inspector console and notice the CORS notice:

MediaElementAudioSource outputs zeroes due to CORS access restrictions for http://publicwebserverdemo.hopto.org/publicAudio/audio.mp3

Thank you for your help :)

// Create a new instance of an audio object and adjust some of its properties
var audio = new Audio();
audio.src = 'http://publicwebserverdemo.hopto.org/publicAudio/audio.mp3';
audio.controls = true;
audio.loop = true;
audio.autoplay = 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
	ctx.fillStyle = '#00CCFF'; // 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; }
<div id="mp3_player">
  <div id="audio_box"></div>
  <canvas id="analyser_render"></canvas>
</div>

Answers


I eventually figured out what to do after hours and hours of research and experimenting. There is very little documentation, as of this writing, available online showing how to do this. I hope people will find this helpful.

Understanding CORS:

CORS is an acronym for Cross Origin Resoruce Sharing. CORS is a new standard for sharing/accessing information between different domains. CORS basically is a method of using server headers to tell the browser if it is permitted to access or interact with a specific file on another server. While you can load most things without worrying about CORS (like images, audio, videos, and even other web pages), interaction with these elements requires special permission from the server. In my case, I was attempting to read frequencies from an audio file on another server. In this instance, I was attempting to access information which required authorization from special headers on the server.

Browser support is very good but, if you are supporting older browsers, you may want to see support tables here (http://caniuse.com/#search=cors)

What I did:

Enabled the use of .htaccess (I think you can accomplish the same thing with apache2.conf or 000-default.conf but .htaccess files are much easier to edit and maintain). These files are used to set headers and settings for apache. I enabled the use of .htaccess files by going to /etc/apache2/ and edited apache2.conf. Make sure your entry matches the following:

<Directory /var/www/>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
</Directory>

I set the headers in my .htaccess file to allow access from Codepen. Create a .htaccess file in the same directory as the file you want to share. You only want to share what you have to or you might create a security risk. Type this in your .htaccess file:

Header set Access-Control-Allow-Origin: "http://websiteWantingToAccessYourFile.com".

Save your file. Restart Apache with this command sudo service apache2 restart. Enter your password if prompted. With the audio, I added the crossorigin="anonymous" attribute. You can read more about CORS settings (crossorigin) here (https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) I imagine you can set this with ajax and xhr requests. Different versions of apache may have different file names or standards. Check to make sure this is correct for your version. I am running Apache 2.4.18 on my Ubuntu server.

Please tell me if this can be improved. I have spent a lot of time understanding this but I am not an expert. Post your suggestions in the comments. :)


Need Your Help

Returning an array with every other number

java

I'm trying to make a program that takes an array as input and removes all the odd indices. It compiles but does not run. For some reason it flags the while loop. I am nor sure how to fix this probl...

How to parse returned php data

php arrays

I am accessing an external PHP server feed (not a real link):