由于 CORS 访问限制,MediaElementAudioSource 输出零
Posted
技术标签:
【中文标题】由于 CORS 访问限制,MediaElementAudioSource 输出零【英文标题】:MediaElementAudioSource outputs zeroes due to CORS access restrictions 【发布时间】:2015-09-14 00:41:38 【问题描述】:<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>
由于 CORS 访问限制,音频 API 将 MediaElementAudioSource 输出为零,因为我正在尝试播放 SHOUTcast URL。我不知道该怎么办;我已经尝试了互联网上的所有解决方案,但没有任何效果。任何帮助将不胜感激。
URL 与音频元素完美配合,因此与 URL 无关;我什至尝试过http://subdomain.domain.org:port/file.mp3
之类的东西。我在互联网上发现使用 .ogg
的 Icecast 的人也有同样的问题。如何解决这个问题?
【问题讨论】:
我在使用我正在试验的一支笔时遇到了 codepen.io 这个问题。有什么建议吗? 对不起,我想投票,我点击了向下按钮,所以不会让我改变它.. 【参考方案1】:这是一个 HTTP 标头。您将配置您的网络服务器或网络应用程序以发送此标头。也许在 htaccess 或 php 中。删除下面的行
<header name = "Access-Control-Allow-Origin" value = "*" />
【讨论】:
所以我把SHOUTcast 服务器不支持 CORS。如果您要继续使用 SHOUTcast,则无法更改此设置。
【讨论】:
我做了一些事情,但感觉不对。我在播放器的同一目录中制作了一个代理脚本并播放了这个脚本 @user1531557 是的,如果您使用的是 SHOUTcast,这是唯一的方法。这是一种常用的方法。为此,我实际上创建了自己的流媒体服务器。如果您想尝试,请发送电子邮件至 brad@audiopump.co。我正在努力在今年晚些时候推出一项托管服务,但它现在已经以有限的容量启动并运行了。【参考方案3】:首先,MediaElementAudiosource 没有名为“crossOrigin”的属性。
我只是发现了这个问题,并且对 Message:MediaElementAudioSource 由于 CORS 访问限制而输出零感到愤怒。但这只是一条消息,我仍然可以听到音频。 我用谷歌搜索了很多,认为这个链接会有所帮助:http://www.codingforums.com/javascript-programming/342454-audio-api-js.html
createMediaElementSource 方法应该创建一个使用 MediaElementAudioSourceNode 接口的对象。此类对象受基于 Web 音频 API 规范最新草案的跨域资源共享 (CORS) 限制。 (请注意,此限制似乎不在规范的过时 W3C 版本中。)根据规范,当 CORS 限制阻止对资源的访问时应该播放静音,这将解释“输出零”消息;据推测,零相当于没有声音。
要解除限制,页面的所有者位于 http://morebas-s-radio.no-ip.org:8214/;stream/1 需要配置 他们的服务器输出一个 Access-Control-Allow-Origin 标头 域列表(包括您的域)或用于提升它的 * 值 对于所有域。鉴于此流似乎已经 不受限制的,面向公众的内容,也许您可以说服所有者 输出该标题。您可以测试是否正在发送标头 通过在 Firefox 中按 Ctrl+Shift+Q 打开 Network 面板,加载 通过地址栏的流,然后检查标题 在“网络”面板中与该 HTTP 请求相关联。
请注意,他们不能在这里使用元元素,因为音频流 显然,它不是 HTML 文档;该技术仅适用于 HTML 和 XHTML 文档。
(当您在使用 Firefox 面板时,您可能需要确保 启用安全错误和警告(通过单击安全 按钮或其箭头)在控制台面板 (Ctrl+Shift+K)。我不知道 如果 Firefox 中像 Chrome 一样有相应的 CORS 消息,但是 可能有。我浪费了很多时间想知道为什么页面没有 一天工作,同时对类似技术进行故障排除,内容 安全策略(CSP),才发现我有相关的火狐 消息已隐藏。)
您不需要弄乱跨域属性/属性 除非您设置 crossorigin = "use-credentials" (JavaScript) 或 crossorigin="use-credentials" (HTML) 某处,但你可能 没有这样做是因为 HTML 规范的那部分还没有最终确定, 它几乎肯定会导致您的内容在之后“中断” 这样做是因为那时需要凭据。
我不熟悉 Web Audio API,所以我无法弄清楚 找出如何输出 MediaElementAudioSourceNode 并触发错误 我自己的故障排除消息。如果我使用 createMediaElementSource 使用 HTMLMediaElement (HTMLAudioElement),结果似乎没有 成为基于使用测试的 MediaElementAudioSourceNode instanceof 运算符,即使规范说如果我是 没看错。
然后在我的情况下,我得到了 HTTP 响应标头:
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
请注意“Access-Control-Allow-Origin: *”,我认为这是正确的,但我仍然收到消息。希望对你有帮助。
【讨论】:
【参考方案4】:在我的回复中,我将假设以下设置:
您的直播网址是 http://stream.radio.com:8000/mount(或 http://stream.radio.com:8000/;stream/1 用于 Shoutcast) 放置 HTML/JS 代码的页面 URL 是 http://radio.com/player要完成这项工作,您需要:
-
将流的“Access-Control-Allow-Origin”标头设置为您的域或
*
在javascript中,将audio
标签crossOrigin
属性设置为“匿名”audio.crossOrigin="anonymous"
;
另一个选项是使用反向代理将您的流式 URL 移动到原始域。
使用Icecast,您可以使用配置文件设置“Access-Control-Allow-Origin”标头,只需将以下行添加到您的icecast.xml,我通常在打开后添加它们@ 987654329@标签:
<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>
在进行这些更改后不要忘记重新启动 Icecast。当您的 Icecast 重新上线时,您可以使用以下命令检查标题:
lynx -head -dump http://stream.radio.com:8000/mount
响应应如下所示:
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
如您所见,存在“Access-Control-Allow-Origin: *”标头。
大喊大叫
不幸的是,Shoutcast 不允许您设置 HTTP 标头(.htaccess 也不是一个选项),但我们可以在 Web 服务器配置中创建一个反向代理,这将允许您托管来自主域的流 - @ 987654333@。我将为 Nginx 和 Apache 提供代理配置。
Nginx
您可以使用“proxy_set_header”添加其他标头,但基本示例是:
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 代理模块,并更新 radio.com 虚拟主机配置配置:
<VirtualHost *:80>
ServerName radio.com
....
ProxyPass /stream http://stream.radio.com:8000/mount
</VirtualHost>
现在您可以使用http://radio.com/stream URL 访问您的流媒体,CORS 政策将不适用。此解决方案还带来了一些额外的好处:
您可以将 http Shoutcast/Icecast 流转换为 https,因此当您将流嵌入到使用 https 托管的页面时,浏览器不会抱怨访问不安全的内容。 (Icecast 本身支持 SSL 配置) 8000 端口将被替换为 80 端口,这将允许具有 8000 端口在防火墙后面的侦听器访问您的流。【讨论】:
以上是关于由于 CORS 访问限制,MediaElementAudioSource 输出零的主要内容,如果未能解决你的问题,请参考以下文章
由于 CORS 访问限制本地 mp3 文件,MediaElementAudioSource 输出零