使用 audio.srcObject 和 MediaStream 播放来自 ajax 通话的音频

Play audio from ajax call using audio.srcObject and a MediaStream

我在 php 中实现了一个 HTTPS 端点,returns mp3 数据。然后,在 ajax 调用 javascript 之后,我通过以下方式播放它:

let blob = new Blob([response.value], { type: 'audio/mp3' });

 cleanup = () => {
   // Not 100% sure this is needed:
   audio.src = '';
   // But this is:
   URL.revokeObjectURL(url);
 };

 let url = URL.createObjectURL(blob)
 let audio = new Audio();

 audio.addEventListener('ended', cleanup);

 audio.src = url;

 audio.play();

这似乎有点奏效,但我在 Fx 播放错误和一些 Chrome devtools 崩溃中遇到了一些浏览器问题。我假设这些问题可能是基于我对 URL.createObject() 的使用。听起来将来这样做的方法是设置 audio.srcObject,而不是 it's not ready in Chrome yet,至少 Blob 不会。 MediaStream 受支持,但我无法从请求的响应正文中找到创建 MediaStream 的方法。

所以,我的问题是:有没有办法使用 audio.srcObject = someMediaStream 播放我的 mp3?或者我是否需要坚持使用 URL.createObjectURL 直到支持 audio.srcObject = new Blob()?这只会是 运行 in Chrome.

您可以使用 MediaElement.captureStream() 方法从播放来自 blob:// URI 的媒体的 AudioElement 创建一个 MediaStream,但这将达不到目的,因为您仍然必须在源上播放该媒体<音频> 元素。

您还可以将 Blob 读取为 ArrayBuffer,然后使用 AudioContext 及其 decodeAudioData() method, then passing the resulting AudioBuffer to an AudioBufferSourceNode and finally connecting this latter to a MediaStreamSourceNode.

解码该媒体的音频数据

但是...您描述的错误很可能不是由您使用 blob:// URI 引起的,这确实是目前播放音频媒体的最佳方式.

希望有一天浏览器会完全实现规范,我们将能够将其他对象作为 srcObject 传递,甚至可能会看到它传播到其他元素,但是几年前我就不再屏息了...

所以是的,继续使用 blob:// URIfile reports 向 Chromium 团队报告他们的错误。



Ps:如果可以,将 src 直接设置为使用 AJAX 获取的 URL 实际上是最佳选择。