首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >流入<audio>元素

流入<audio>元素
EN

Stack Overflow用户
提问于 2021-11-17 09:42:31
回答 1查看 59关注 0票数 0

我想从发送未知总长度的声音数据包的网络插口播放音频。播放应在第一个包到达时立即开始,并且不应被新包中断。

到目前为止,我所做的工作如下:

代码语言:javascript
运行
复制
ws.onmessage = e => {
  const soundDataBase64 = JSON.parse(e.data);
  const bytes = window.atob(soundDataBase64);
  const arrayBuffer = new window.ArrayBuffer(bytes.length);
  const bufferView = new window.Uint8Array(arrayBuffer);
  for (let i = 0; i < bytes.length; i++) {
    bufferView[i] = bytes.charCodeAt(i);
  }
  const blob = new Blob([arrayBuffer], {"type": "audio/mp3"});
  const objectURL = window.URL.createObjectURL(blob);
  const audio = document.createElement("audio");
  audio.src = objectURL;
  audio.controls = "controls";
  document.body.appendChild(audio);
};

但是,据我所知,不可能扩展ArrayBufferUint8Array的大小。我必须创建一个新的blob,对象URL,并将其分配给音频元素。但我猜,这会中断音频回放。

在的MDN页面上,有一个关于MediaStream的提示,它看起来很有前途。但是,我不太确定如何将数据写入媒体流,以及如何将媒体流连接到音频元素。

目前是否有可能使用JS编写类似管道的东西,在其中我可以在一端输入数据,然后将其流式传输给消费者?如何在JS中实现无缝流(最好没有大量的微管理代码)?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-11-18 09:07:43

正如@Kaiido在评论中指出的,我可以使用MediaSource对象。将MediaSource对象连接到DOM中的<audio>元素后,可以将SourceBuffer添加到打开的MediaSource对象,然后将ArrayBuffer附加到SourceBuffer

示例:

代码语言:javascript
运行
复制
const ws = new window.WebSocket(url);
ws.onmessage = _ => {
  console.log("Media source not ready yet... discard this package");
};

const mediaSource = new window.MediaSource();
const audio = document.createElement("audio");
audio.src = window.URL.createObjectURL(mediaSource);
audio.controls = true;
document.body.appendChild(audio);

mediaSource.onsourceopen = _ => {
  const sourceBuffer = mediaSource.addSourceBuffer("audio/mpeg"); // mpeg appears to not work in Firefox, unfortunately :(
  ws.onmessage = e => {
    const soundDataBase64 = JSON.parse(e.data);
    const bytes = window.atob(soundDataBase64);
    const arrayBuffer = new window.ArrayBuffer(bytes.length);
    const bufferView = new window.Uint8Array(arrayBuffer);
    for (let i = 0; i < bytes.length; i++) {
      bufferView[i] = bytes.charCodeAt(i);
    }
    sourceBuffer.appendBuffer(arrayBuffer);
  };
};

我在Google Chrome94上成功地测试了这一点。不幸的是,在Firefox92中,MIME类型audio/mpeg似乎不起作用。在那里,我得到了error Uncaught DOMException: MediaSource.addSourceBuffer: Type not supported in MediaSource和warning Cannot play media. No decoders for requested formats: audio/mpeg

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70002015

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档