由于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:说明信息消息何时出现

+1

我不明白在铬FWIW ... – dandavis

+0

该链路上的任何错误,做你的声音?我没有听到任何声音,过了一段时间,我在控制台中收到一条消息(不是错误),说MediaElementAudioSource输出为零,因为......' – Guig

+0

的CORS访问限制没有声音,但也没有错误消息。 – dandavis

例如,如果您不想使用WebRTC将音频流式传输到对等设备,则不需要使用AudioContext.createMediaStreamDestination()

该功能将创建与WebRTC MediaStream关联的MediaStreamAudioDestinationNode,表示可存储在文件中或发送到另一计算机/浏览器的音频流。一种常见的用法是使用RTCPeerConnection addStream()方法将其发送到远程对等端。

对于您的情况,如果您只是想输出声音以播放音频,则可以使用AudioContextdestination属性。它通常代表一个实际的音频渲染设备,例如您的设备的扬声器。

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); 

您可以在​​上查看结果。

+0

啊谢谢!任何有关流式音频的CORS限制的想法? – Guig

可以请求资源作为ArrayBuffer或使用fetchXMLHttpRequest一个Blob,并从<video>src同时设置在当时的<video>AudioContext或负载AudioContext

使用.decodeAudioData代替ArrayBuffer或使用URL.createObjectURLBlob作为参数。这是针对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">元素调整gainNodevalue一旦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/

+0

@Guig版本使用'ArrayBuffer'不带'Blob' https://jsfiddle.net/m305au2d/5/ – guest271314