<script>
// Create a new instance of an audio object and adjust some of its properties
var audio = new Audio();
audio.src = 'http://subdomain.domain.org:port/;stream/1';
audio.controls = true;
audio.loop = true;
audio.autoplay = true;
audio.crossorigin="anonymous";
// 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 (window.AudioContext || window.webkitAudioContext)(); // AudioContext object instance // 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.crossOrigin = 'anonymous'
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(){
(requestAnimationFrame || webkitRequestAnimationFrame)(frameLooper);
fbc_array = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(fbc_array);//get frequency
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);
}
}
</script>
Audio API gives MediaElementAudioSource outputs zeroes due to CORS access restrictions because I'm trying to play a SHOUTcast URL. I don't know what to do; I have tried all solutions on the internet but nothing worked. Any help will be appreciated.
The URL works perfectly with audio element so its not about the URL; I have even tried something like http://subdomain.domain.org:port/file.mp3
. And I found on the internet people using Icecast which is .ogg
have same problem. How to fix this?
In my response I will assume the following setup:
To get this working you need:
*
audio
tag crossOrigin
property to "anonymous" audio.crossOrigin="anonymous"
;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:
That is an HTTP header. You would configure your webserver or webapp to send this header. Perhaps in htaccess or PHP. remove the below line
<header name = "Access-Control-Allow-Origin" value = "*" />
SHOUTcast servers do not support CORS. There is nothing you can do to change this if you are going to continue to use SHOUTcast.
First of all, MediaElementAudioSource doesn't have a property named "crossOrigin".
I just find this problem, and mad with the Message:MediaElementAudioSource outputs zeroes due to CORS access restrictions for. But it's just a message, i can still hear the audio. And I googled lots of this, think this link will be helpful:http://www.codingforums.com/javascript-programming/342454-audio-api-js.html
The createMediaElementSource method should create an object that uses the MediaElementAudioSourceNode interface. Such objects are subject to Cross-Origin Resource Sharing (CORS) restrictions based on the latest draft of the Web Audio API spec. (Note that this restriction doesn't appear to be in the outdated W3C version of the spec.) According to the spec, silence should be played when CORS restrictions block access to a resource, which would explain the "outputs zeroes" message; presumably, zero is equivalent to no sound.
To lift the restriction, the owner of the page at http://morebassradio.no-ip.org:8214/;stream/1 would need to configure their server to output an Access-Control-Allow-Origin header with either a list of domains (including yours) or the * value to lift it for all domains. Given that this stream appears to already be unrestricted, public-facing content, maybe you can convince the owners to output that header. You can test whether the header is being sent by pressing Ctrl+Shift+Q in Firefox to open the Network panel, loading the stream through the address bar, and then inspecting the headers associated with that HTTP request in the Network panel.
Note that they can't use a meta element here since the audio stream is, obviously, not an HTML document; that technique only works for HTML and XHTML documents.
(While you're messing with Firefox panels, you may want to make sure Security errors and warnings are enabled (by clicking the Security button or its arrow) in the Console panel (Ctrl+Shift+K). I'm not sure if there's a corresponding CORS message in Firefox like in Chrome, but there might be. I wasted a bunch of time wondering why a page wasn't working one day while troubleshooting a similar technology, Content Security Policy (CSP), only to find that I had the relevant Firefox messages hidden.)
You shouldn't need to mess with the crossorigin property/attribute unless you set crossorigin = "use-credentials" (JavaScript) or crossorigin="use-credentials" (HTML) somewhere, but you probably didn't do that because that part of the HTML spec isn't finalized yet, and it would almost certainly cause your content to "break" after doing so since credentials would be required at that point.
I'm not familiar with the Web Audio API, so I wasn't able to figure out how to output a MediaElementAudioSourceNode and trigger an error message for my own troubleshooting. If I use createMediaElementSource with an HTMLMediaElement (HTMLAudioElement), the result doesn't seem to be a MediaElementAudioSourceNode based on testing using the instanceof operator even though the spec says it should be if I'm reading it right.
Then in my situation, i get the HTTP response Header:
HTTP/1.1 206 Partial Content
Date: Thu, 02 Jun 2016 06:50:43 GMT
Content-Type: audio/mpeg
Accept-Ranges: bytes
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: X-Log, X-Reqid
Access-Control-Max-Age: 2592000
Content-Disposition: inline; filename="653ab5685893b4bf.mp3"
Content-Transfer-Encoding: binary
Last-Modified: Mon, 16 May 2016 02:00:05 GMT
Server: nginx
Cache-Control: public, max-age=31536000
ETag: "FpGQqtcf_s2Ce8W_4Mv6ZqSVkVTK"
X-Log: mc.g;IO:2/304
X-Reqid: 71cAAFQgUBiJMVQU
X-Qiniu-Zone: 0
Content-Range: bytes 0-1219327/1219328
Content-Length: 1219328
Age: 1
X-Via: 1.1 xinxiazai211:88 (Cdn Cache Server V2.0), 1.1 hn13:8 (Cdn Cache Server V2.0)
Connection: keep-alive
Note that "Access-Control-Allow-Origin: *", i think this just the right thing, but i still get the message. Hope it help you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With