Overview
CORS (Cross-Origin Resource Sharing) configuration is essential for enabling Web Audio API features like the audio visualizer. Without proper CORS headers, browsers will block access to audio stream data for security reasons.
Current Issue: Without CORS headers, you may see:MediaElementAudioSource outputs zeroes due to CORS access restrictions
The audio will still play, but visual effects won’t be reactive to the music.
System URLs
La Urban uses the following URL structure:
- Frontend:
laurban.cl
- Stream URL:
https://stream.laurban.cl:8000/media
- API:
azura.laurban.cl
Server Configuration
Choose your server type
Select the appropriate configuration based on your streaming server setup.
Apply CORS headers
Configure the headers according to your server type below.
Verify configuration
Test that CORS headers are being sent correctly.
Option 1: Nginx (Recommended)
If your stream is behind Nginx, add these headers to your server configuration:
server {
listen 8000 ssl;
server_name stream.laurban.cl;
location /media {
# CORS headers for Web Audio API
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Range, Content-Type' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length, Content-Range' always;
# Handle OPTIONS preflight requests
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
# Your existing proxy configuration (Icecast, Shoutcast, etc.)
proxy_pass http://localhost:8000/media;
# ... rest of configuration
}
}
Option 2: Apache
For Apache servers, add to .htaccess or VirtualHost configuration:
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods "GET, OPTIONS"
Header set Access-Control-Allow-Headers "Range, Content-Type"
Header set Access-Control-Expose-Headers "Content-Length, Content-Range"
</IfModule>
Option 3: Icecast
For Icecast streaming servers, edit /etc/icecast2/icecast.xml:
<http-headers>
<header name="Access-Control-Allow-Origin" value="*" />
<header name="Access-Control-Allow-Methods" value="GET, OPTIONS" />
<header name="Access-Control-Allow-Headers" value="Range, Content-Type" />
</http-headers>
Option 4: Cloudflare
If using Cloudflare as a proxy:
Navigate to Transform Rules
Go to Rules → Transform Rules → HTTP Response Headers
Create a new rule
Create a rule for your stream domain:
- Set static:
Access-Control-Allow-Origin → *
- Set static:
Access-Control-Allow-Methods → GET, OPTIONS
Traefik Configuration
Basic CORS Middleware
Add these labels to your Traefik configuration:
# CORS Headers - Traefik v3 syntax
traefik.http.middlewares.azuracast-cors.headers.customresponseheaders.Access-Control-Allow-Origin=*
traefik.http.middlewares.azuracast-cors.headers.customresponseheaders.Access-Control-Allow-Methods=GET,HEAD,OPTIONS
traefik.http.middlewares.azuracast-cors.headers.customresponseheaders.Access-Control-Allow-Headers=*
traefik.http.middlewares.azuracast-cors.headers.customresponseheaders.Access-Control-Max-Age=3600
# Standard headers (maintain these)
traefik.http.middlewares.azuracast-cors.headers.accesscontrolallowheaders=*
traefik.http.middlewares.azuracast-cors.headers.accesscontrolallowmethods=GET,HEAD,OPTIONS
traefik.http.middlewares.azuracast-cors.headers.accesscontrolmaxage=100
traefik.http.middlewares.azuracast-cors.headers.addvaryheader=true
Mobile-Optimized CORS
For maximum mobile compatibility (especially iOS Safari):
# CORS optimized for mobile devices
traefik.http.middlewares.azuracast-cors.headers.accesscontrolalloworigin=https://laurban.cl
traefik.http.middlewares.azuracast-cors.headers.accesscontrolallowmethods=GET,POST,OPTIONS,HEAD
traefik.http.middlewares.azuracast-cors.headers.accesscontrolallowheaders=Origin,Content-Type,Accept,Authorization,Cache-Control,X-Requested-With,Range
traefik.http.middlewares.azuracast-cors.headers.accesscontrolexposeheaders=Content-Length,Content-Range,Accept-Ranges,Icy-Br,Icy-Description,Icy-Genre,Icy-MetaInt,Icy-Name,Icy-Pub,Icy-Url
traefik.http.middlewares.azuracast-cors.headers.accesscontrolallowcredentials=false
traefik.http.middlewares.azuracast-cors.headers.accesscontrolmaxage=3600
traefik.http.middlewares.azuracast-cors.headers.addvaryheader=true
Docker Compose Example
services:
azuracast:
labels:
# ... your existing labels ...
# Add these CORS headers:
- "traefik.http.middlewares.azuracast-cors.headers.accesscontrolalloworigin=*"
- "traefik.http.middlewares.azuracast-cors.headers.accesscontrolallowcredentials=false"
- "traefik.http.middlewares.azuracast-cors.headers.accesscontrolexposeheaders=Content-Length,Content-Range,Icy-Br,Icy-Description,Icy-Genre,Icy-MetaInt,Icy-Name,Icy-Pub,Icy-Url"
Verification
Command Line Test
After applying changes, verify CORS headers are present:
curl -I https://stream.laurban.cl:8000/media
You should see:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, OPTIONS
Browser Console Test
Test from your browser’s developer console:
fetch('https://stream.laurban.cl:8000/media', { method: 'HEAD' })
.then(r => console.log(r.headers.get('Access-Control-Allow-Origin')))
Mobile Verification
Test with mobile user agent:
curl -H "Origin: https://laurban.cl" \
-H "User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X)" \
-I https://stream.laurban.cl:8000/media
Expected output:
access-control-allow-origin: *
access-control-allow-methods: GET,POST,OPTIONS,HEAD
access-control-expose-headers: Content-Length,Content-Range...
Testing After Configuration
Restart your server
Restart the streaming server or reverse proxy to apply changes.
Clear browser cache
Clear your browser cache or test in incognito/private mode.
Test on mobile
For mobile testing, clear cache and test in private browsing mode.
Verify visualization
The logo should react to audio with pulsing, rotation, and glow effects.
Important Notes
Cross-Origin Attribute: The HTML <audio> element must include crossorigin="anonymous" to request CORS headers from the server.
iOS Safari: iOS Safari is the most strict browser with CORS policies. The Access-Control-Allow-Origin header is mandatory for iOS compatibility.
Current Implementation Status
- ✅ HTML:
crossorigin="anonymous" added to <audio> element
- ✅ JavaScript: Visualizer gracefully degrades if CORS is blocked
- ✅ Fallback: Uses CSS animation when Web Audio API is unavailable
- ⏳ Server: CORS headers need to be configured on streaming server
What works:
- Audio playback continues normally
- Basic player controls function
- Metadata updates work
What doesn’t work:
- Audio-reactive logo visualization
- Frequency-based visual effects
- Real-time audio analysis
Fallback behavior:
- Simple CSS pulse animation
- Static visual effects
- No frequency detection
Once CORS is properly configured, the logo will react to audio with:
- 🎵 Pulse with bass/kick detection
- 🎸 Rotation with mid frequencies
- ✨ Brightness with highs
- 💫 Dynamic shadow effects
- 🎨 Color saturation changes