由于CORS访问限制,无法使用MediaElementAudioSource
我正在尝试使用音频API,但无法播放音频。由于CORS访问限制,无法使用MediaElementAudioSource
Here是该问题的再现。如果您打开js控制台,在触发播放/暂停视频后,您会看到一条消息,说明VM374:1MediaElementAudioSource outputs zeroes due to CORS access restrictions for https://s3.amazonaws.com/mettavr/dev/VfE_html5.mp4
,并且不播放音频。 (这不是一个错误,而只是一个信息日志)
我发现了几个SO问题,如this one或this one。这听起来应该将标志crossorigin
设置为anonymous
,并且服务器权限应该允许跨源。
我从S3桶似乎已经打开足够的权限服务文件:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>http://*</AllowedOrigin>
<AllowedOrigin>https://*</AllowedOrigin>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<ExposeHeader>Content-Range</ExposeHeader>
<ExposeHeader>Content-Length</ExposeHeader>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
不过,我不能发挥出自己的声音
======
编辑1:说明信息消息何时出现
例如,如果您不想使用WebRTC将音频流式传输到对等设备,则不需要使用AudioContext.createMediaStreamDestination()
。
该功能将创建与WebRTC MediaStream
关联的MediaStreamAudioDestinationNode
,表示可存储在文件中或发送到另一计算机/浏览器的音频流。一种常见的用法是使用RTCPeerConnection addStream()
方法将其发送到远程对等端。
对于您的情况,如果您只是想输出声音以播放音频,则可以使用AudioContext
的destination
属性。它通常代表一个实际的音频渲染设备,例如您的设备的扬声器。
var audioCtx = new AudioContext();
var source = audioCtx.createMediaElementSource(document.getElementById('video'));
var gainNode = audioCtx.createGain();
gainNode.gain.value = 0.5;
source.connect(gainNode);
gainNode.connect(audioCtx.destination);
您可以在上查看结果。
啊谢谢!任何有关流式音频的CORS限制的想法? – Guig
可以请求资源作为ArrayBuffer
或使用fetch
或XMLHttpRequest
一个Blob
,并从<video>
src
同时设置在当时的<video>
和AudioContext
或负载AudioContext
。
使用.decodeAudioData
代替ArrayBuffer
或使用URL.createObjectURL
和Blob
作为参数。这是针对Why aren't Safari or Firefox able to process audio data from MediaElementSource?中描述的问题的解决方法?见this Answer。另请参阅Getting Started with Web Audio API。下面
在加载方式既<video>
和AudioContext
使用Blob
,至Blob
转换为ArrayBuffer
。还请注意source.start(0)
开始音频上下文播放。
包含<input type="range">
元素调整gainNode
value
一旦AudioContext
加载。
TODO
,进度处理程序和视频和音频加载时显示。
<label>adjust audio gain<br>
<input type="range" min="0" max="5" value="2.5" step=".5" disabled /></label>
<video src="" id="video" controls="true" crossorigin="anonymous" />
var src = "https://s3.amazonaws.com/mettavr/dev/VfE_html5.mp4";
fetch(src)
.then(response => response.blob())
.then(blob => {
video.src = URL.createObjectURL(blob);
var audioCtx = new AudioContext();
var reader = new FileReader();
reader.onload = (e) => {
audioCtx.decodeAudioData(e.target.result, (buffer) => {
console.log(buffer); // `AudioBuffer`
// creates a sound source
var source = audioCtx.createBufferSource();
source.buffer = buffer;
gainNode = audioCtx.createGain();
gainNode.gain.value = 2.5;
// tell the source which sound to play
source.connect(gainNode);
// connect the gainNode to the context's destination
// (the speakers)
gainNode.connect(audioCtx.destination);
source.start(0);
console.log(source, audioCtx);
range.removeAttribute("disabled")
});
}
reader.readAsArrayBuffer(blob);
});
的jsfiddle https://jsfiddle.net/m305au2d/2/
@Guig版本使用'ArrayBuffer'不带'Blob' https://jsfiddle.net/m305au2d/5/ – guest271314
我不明白在铬FWIW ... – dandavis
该链路上的任何错误,做你的声音?我没有听到任何声音,过了一段时间,我在控制台中收到一条消息(不是错误),说MediaElementAudioSource输出为零,因为......' – Guig
的CORS访问限制没有声音,但也没有错误消息。 – dandavis