2

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

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,但它还没有在 Chrome 中准备好,至少对于Blobs. MediaStreams 受支持,但我找不到MediaStream从请求的响应正文中创建 s 的方法。

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

4

1 回答 1

3

您可以从使用 MediaElement 从 blob:// URI 播放媒体的 AudioElement 创建 MediaStream captureStream()方法,但这会破坏目的,因为您仍然必须在源 <audio> 元素上播放该媒体。

您还可以将 Blob 读取为 ArrayBuffer,然后使用 AudioContext 及其decodeAudioData()方法解码此媒体的音频数据,然后将生成的 AudioBuffer 传递给 AudioBufferSourceNode,最后将后者连接到MediaStreamSourceNode。

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

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

所以是的,继续使用 blob:// URI,并向 chromium 团队报告他们的错误。



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

于 2020-08-04T01:54:49.740 回答