MediaElementAudioSource outputs zeroes due to CORS access restrictions

In my response I will assume the following setup:

To get this working you need:

  1. Set the “Access-Control-Allow-Origin” header of your stream to your domain or *
  2. In javascript, set audio tag crossOrigin property to “anonymous” audio.crossOrigin="anonymous";
  3. Another option it to move you stream URL to the original domain using reverse proxy.

With Icecast you cat set the “Access-Control-Allow-Origin” header using configuration file, just add the following lines to your icecast.xml, I usually add them right after the opening <icecast> tag:

<http-headers>
        <header name="Access-Control-Allow-Origin" value="*" />
        <header name="Access-Control-Allow-Headers" value="Origin, Accept, X-Requested-With, Content-Type, If-Modified-Since" />
        <header name="Access-Control-Allow-Methods" value="GET, OPTIONS, HEAD" />
</http-headers>

Don’t forget to restart Icecast after these changes. When your Icecast will be back online you can check the headers with this command:

lynx -head -dump http://stream.radio.com:8000/mount 

Response should look something like this:

Server: Icecast 2.4.2
....
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Origin, Accept, X-Requested-With, Content-Type, If
-Modified-Since
Access-Control-Allow-Methods: GET, OPTIONS, HEAD

As you can see, “Access-Control-Allow-Origin: *” header is present.

Shoutcast

Unfortunately, Shoutcast does not allow you to set HTTP headers (.htaccess is not an option too), but we can create a reverse proxy in web server configuration, this will allow you to host the stream from the main domain – radio.com. I will provide proxy configurations for Nginx and Apache.

Nginx

You can add additional headers with “proxy_set_header”, but the basic example is:

server {
    listen   80;
    server_name radio.com;
    ....
    location /stream { 
       proxy_set_header X-Forwarded-For $remote_addr; 
       proxy_pass http://stream.radio.com:8000/mount; 
    }
    ....
}

Apache

Activate Apache proxy modules, and update radio.com virtual host configuration configuration:

<VirtualHost *:80>
   ServerName radio.com
   ....
   ProxyPass /stream http://stream.radio.com:8000/mount
</VirtualHost>

Now you can access your stream using http://radio.com/stream URL and the CORS policy will not apply. This solution also brings some additional perks:

  • you can convert your http Shoutcast/Icecast stream to https, so the browsers will not complain about accessing unsecure content when you will embed your stream to the page hosted with https. (Icecast supports SSL configuration itself)
  • 8000 port will be replaced with port 80, that will allow listeners with 8000 port behind firewall to access your stream.

Leave a Comment