我有一台服务器通过websocket发送原始音频块。我们的想法是检索并播放它们,以尽可能平滑播放。流式处理原始音频数据期间在webaudio播放中出现裂缝
这里是代码最重要的一块:
ws.onmessage = function (event) {
var view = new Int16Array(event.data);
var viewf = new Float32Array(view.length);
audioBuffer = audioCtx.createBuffer(1, viewf.length, 22050);
audioBuffer.getChannelData(0).set(viewf);
source = audioCtx.createBufferSource();
source.buffer = audioBuffer;
source.connect(audioCtx.destination);
source.start(0);
};
这工作体面的好,但也有在播放一些裂缝:网络延迟并不恒定,所以数据的最新块没有按”到达前一个正在播放的结尾,所以我可以结束两个缓冲区一起玩一会儿或者根本不玩。
我想:
- 勾
source.onended
玩下一个,但它不是无缝的:有每块的尾部裂纹,而每个接缝的整体累积使回放越说越比流更晚。 - 将新数据追加到当前正在播放的缓冲区中,但这似乎是被禁止的:缓冲区的大小是固定的。
有没有适当的解决方案来解决这个问题?唯一的要求是播放来自websocket的未压缩音频。
编辑:解决方法:鉴于我知道我的缓冲区长度,我可以安排播放这样:
if(nextStartTime == 0) nextStartTime = audioCtx.currentTime + (audioBuffer.length/audioBuffer.sampleRate)/2;
source.start(nextStartTime);
nextStartTime += audioBuffer.length/audioBuffer.sampleRate;
第一次,我安排播放的开始半个buffer-以后再允许最大的意外延迟。然后,我将下一个缓冲区开始时间存储在缓冲区末尾。
谢谢,这是我所做的,而不是简单的“现在玩”。我现在有一些听起来更好的东西! – Ploppe