我通过来自服务器的web-Socket以块的形式传输音频数据
ws.on('message', function incoming(message) {
var readStream = fs.createReadStream("angular/data/google.mp3",
{
'flags': 'r',
'highWaterMark': 128 * 1024
}
);
readStream.on('data', function(data) {
ws.send(data);
});
readStream.on('end', function() {
ws.send('end');
});
readStream.on('error', function(err) {
console.log(err)
});
});
在客户端
var chunks = [];
var context = new AudioContext();
var soundSource;
var ws = new WebSocket(url);
ws.binaryType = "arraybuffer";
ws.onmessage = function(message) {
if (message.data instanceof ArrayBuffer) {
chunks.push(message.data)
} else {
createSoundSource(chunks);
}
};
function createSoundSource(audioData) {
soundSource = context.createBufferSource();
for (var i=0; i < audioData.length;i++) {
context.decodeAudioData(audioData[i], function(soundBuffer){
soundSource.buffer = soundBuffer;
soundSource.connect(context.destination);
soundSource.start(0);
});
}
}
但是第二次设置缓冲区soundSource.buffer = soundBuffer;
导致错误
未捕获的DOMException:无法设置&#39;缓冲区&#39; &#39; AudioBufferSourceNode&#39;:无法在设置缓冲区后设置缓冲区
对于如何最好地使用新音频数据进行update
网络音频API播放的任何建议或见解将不胜感激。
答案 0 :(得分:1)
一旦设置了AudioBufferSourceNode
,就无法重置缓冲区。就像一劳永逸。每次您要播放不同的缓冲区时,都必须创建一个新的AudioBufferSourceNode
才能继续播放。这些节点非常轻巧,因此即使创建大量节点也不必担心性能。
为此,您可以修改createSoundSource
函数,以简单地为循环体内的每个块创建一个AudioBufferSourceNode
,如下所示:
function createSoundSource(audioData) {
for (var i=0; i < audioData.length;i++) {
context.decodeAudioData(audioData[i], function(soundBuffer){
var soundSource = context.createBufferSource();
soundSource.buffer = soundBuffer;
soundSource.connect(context.destination);
soundSource.start(0);
});
}
}
我试图使代码样式尽可能接近原始样式,但现在是2020年,利用现代功能的功能实际上看起来像这样:
async function createSoundSource(audioData) {
await Promise.all(
audioData.map(async (chunk) => {
const soundBuffer = await context.decodeAudioData(chunk);
const soundSource = context.createBufferSource();
soundSource.buffer = soundBuffer;
soundSource.connect(context.destination);
soundSource.start(0);
})
);
}
如果您想在新数据到达后立即停止旧节点(通过重置.buffer
来实现这一点,但我不确定),则必须存储它们并调用{ {1}}在所有时候都开始。
答案 1 :(得分:0)
不是肯定的,但是我认为您在处理流式websocket缓冲区时必须有所不同。也许websocket-streaming-audio软件包的源代码可以为您提供有关如何处理方案的更好的线索。