html - 原始音频数据流式传输期间网络音频播放出现裂纹

标签 html html5-audio audio-streaming web-audio-api

我有一个服务器通过 websocket 发送大块的原始音频。我们的想法是检索这些内容并以尽可能流畅的播放方式播放它们。

这是最重要的一段代码:

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);
};

这工作得很好,但在播放时有一些问题:网络延迟并不总是恒定的,所以最新的数据 block 不会恰好在前一个正在播放的结束时到达,所以我可以结束要么两个缓冲区一起播放很短的时间,要么根本不播放。

我试过:

  • Hook source.onended 播放下一个,但它不是无缝的:每个 block 的末尾都有裂缝,每个接缝都在整体上累积,所以播放越来越多与流相比晚了。
  • 将新数据附加到当前播放的缓冲区,但这似乎是被禁止的:缓冲区的大小是固定的。

是否有解决该播放问题的合适解决方案?唯一的要求是播放来自 websocket 的未压缩音频。

编辑:解决方案:如果我知道我的缓冲区长度,我可以这样安排播放:

if(nextStartTime == 0) nextStartTime = audioCtx.currentTime + (audioBuffer.length / audioBuffer.sampleRate)/2;
source.start(nextStartTime);
nextStartTime += audioBuffer.length / audioBuffer.sampleRate;

第一次,我将回放的开始时间安排在半个缓冲区之后,以允许最大的意外延迟。然后,我将下一个缓冲区开始时间存储在缓冲区结束的最后。

最佳答案

您可能应该从 https://www.html5rocks.com/en/tutorials/audio/scheduling/ 开始这很好地解释了如何在 WebAudio 中安排事情。

对于您的用例,您还应该利用以下事实:您知道 PCM 样本的采样率并且知道您读取了多少样本。这决定了播放缓冲区需要多长时间。用它来确定何时安排下一个缓冲区。

(但请注意,如果 PCM 采样率与 audioCtx.sampleRate 不同,数据将被重新采样,这可能会打乱您的计时。

关于html - 原始音频数据流式传输期间网络音频播放出现裂纹,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43366627/

相关文章:

html - 使用 html 5 最小化流式音频的延迟

javascript - jquery 删除 div 和以前的标签?

html - 将值从 Express NodeJS 传递到 AngularJS Controller 变量

html - 使用 "display:block"但无法使我的图像与文本保持在同一水平面上

ios - 如何使用 AudioFileStreamSeek 处理流文件?

android - Android:java.lang.RuntimeException:无法实例化 Activity ComponentInfo:java.lang.NullPointerException

audio - 使用 FFMPEG 的音频流中的麦克风问题

javascript - 下拉菜单的关键帧或 JScript

javascript - OSX Safari/quicktime 不发送带有媒体文件请求的 cookie

javascript - SoundManager2 - 停止声音时失真