javascript - WebSocket 的 Webaudio 播放出现中断

标签 javascript websocket web-audio-api aurora.js

我有一个软件定义的 radio ,播放来自 WebSocket 服务器的音频流,以及一个使用 AudioBufferSourceNode 消耗数据并播放数据的客户端。

它基本上有效。唯一的问题是每隔几秒就会出现短暂的丢失,这可能是由于创建每个连续的 AudioBufferSourceNode 实例所涉及的开销造成的。 WebAudio 草案规范规定,AudioBuffer 应该用于播放不超过一分钟左右的声音,而较长的声音应该使用 MediaElementSourceNode 来播放。这对我不起作用,因为我需要从 WebSocket 源播放音频,而且我不知道如何使媒体元素(例如 HTML5 音频元素)与 WebSocket 一起工作。

也许我正在尝试做一些 WebAudio 无法支持的事情,方法是将 AudioBufferSourceNode 实例串在一起并期望它们一个接一个地无缝播放。但似乎应该有一种方法可以通过WebAudio播放WebSocket数据,确实auroa.js (与 aurora-websocket.js 插件一起)似乎可以做到这一点。我使用 aurora.js 编写了一个客户端,但遇到了其他问题,为此我在 Github 上创建了 auroa.js 问题。与此同时,我希望我可以在我的客户端中使用 WebAudio 从 WebSocket 无缝播放数据,就像他们所做的那样。

这是我的代码的省略 View ,以显示我正在使用的实现。

var context = ...
var gainNode = ...

var playBuffer = function(buf) {
   var source = context.createBufferSource();
   source.buffer = buf;
   source.connect(gainNode);
   source.start();
};

var socket = ...
socket.binaryType = 'arraybuffer';
socket.addBinaryListener(function (data) {
     context.decodeAudioData(data, playBuffer);
});
socket.connect...

我还尝试了一种实现,其中我跟踪来自 WebSocket 的传入缓冲区,并在从前一个 AudioBufferSourceNode 接收到“结束”事件后,通过 AudioBufferSourceNode 按接收的顺序播放它们。这与上述实现具有相同的丢失问题。

最佳答案

您的流真的能保证在每个网络 block 中获取完整的音频文件吗? (decodeAudioData 不适用于部分 MP3 block 。)

看起来(从上面的代码片段来看)您只是依靠网络计时来在正确的时间启动流 block ?这保证不会正确排列;您需要在流中保留一点延迟(以处理不一致的网络),并仔细调度每个 block 。 (上面让我感到畏缩的一点是 source.start() - 没有时间参数来保持 block 一个接一个地安排。即:

var nextStartTime = 0;

function addChunkToQueue( buffer ) {
    if (!nextStartTime) {
        // we've not yet started the queue - just queue this up,
        // leaving a "latency gap" so we're not desperately trying
        // to keep up.  Note if the network is slow, this is going
        // to fail.  Latency gap here is 1 second.
        nextStartTime = audioContext.currentTime + 1; 
    }
    var bsn = audioContext.createBufferSource();
    bsn.buffer = buffer;
    bsn.connect( audioContext.destination );
    bsn.start( nextStartTime );

    // Ensure the next chunk will start at the right time
    nextStartTime += buffer.duration;
}

此外,根据您的 block 有多大,我想知道垃圾收集是否不会导致问题。您应该在分析器中检查一下。

单向路径不会很好地工作;它依赖于 JS 事件处理,并且仅在音频系统播放完毕后触发;所以总会有一个差距。

最后 - 如果声音流与默认音频设备的采样率不匹配,这将无法正常工作;总会有点击声,因为解码音频数据将根据设备速率重新采样,这不会有完美的持续时间。它会工作,但可能会出现诸如 block 边界处的点击之类的伪影。您需要一个尚未指定或实现的功能 - 可选择的 AudioContext 采样率 - 才能解决此问题。

关于javascript - WebSocket 的 Webaudio 播放出现中断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27430615/

相关文章:

node.js - nginx ws 无效的 URL 前缀

web-audio-api - 是否可以更改 MediaRecorder 的流?

javascript - AnalyserNode 在什么时候执行 FFT?

javascript - JS insertBefore() 并传递一个包含 html 的字符串

SSL 响应被分成两个回调

websocket - 为什么 HTTP + Websockets 不适合作为消息传递协议(protocol)?

javascript - 网络音频启动和停止振荡器然后再次启动它

javascript - PHP - 上传图像和$_files变量

javascript - 将 Backbone 集合与数组进行比较

javascript - 提示用户将输出下载为 txt 文件