我有一臺服務器通過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