我想从发送未知总长度的声音数据包的网络插口播放音频。播放应在第一个包到达时立即开始,并且不应被新包中断。
到目前为止,我所做的工作如下:
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);
};
但是,据我所知,不可能扩展ArrayBuffer
和Uint8Array
的大小。我必须创建一个新的blob,对象URL,并将其分配给音频元素。但我猜,这会中断音频回放。
在的MDN页面上,有一个关于MediaStream
的提示,它看起来很有前途。但是,我不太确定如何将数据写入媒体流,以及如何将媒体流连接到音频元素。
目前是否有可能使用JS编写类似管道的东西,在其中我可以在一端输入数据,然后将其流式传输给消费者?如何在JS中实现无缝流(最好没有大量的微管理代码)?
发布于 2021-11-18 09:07:43
正如@Kaiido在评论中指出的,我可以使用MediaSource
对象。将MediaSource
对象连接到DOM中的<audio>
元素后,可以将SourceBuffer
添加到打开的MediaSource
对象,然后将ArrayBuffer
附加到SourceBuffer
。
示例:
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
。
https://stackoverflow.com/questions/70002015
复制相似问题