来自WebSocket的Webaudio播放有辍学

时间:2014-12-11 19:13:45

标签: javascript websocket web-audio aurora.js

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

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

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

以下是我的代码的省略视图,以显示我正在使用的实现。

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接收事件。这与上述实现具有相同的丢失问题。

1 个答案:

答案 0 :(得分:1)

您的流确实可以在每个网络块中获得完整的音频文件? (decodeAudioData不适用于部分MP3块。)

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

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

此外,根据您的块数有多大,我不知道垃圾收集是否会导致问题。你应该在分析器中查看它。

开辟的道路不会运作良好;它依赖于JS事件处理,并且仅在音频系统播放完毕后触发;所以总会有差距。

最后 - 如果声音流与默认音频设备的采样率不匹配,这将无法正常工作;总会有点击,因为decodeAudioData将重新采样到设备速率,这将没有一个完美的持续时间。它将工作,但可能会出现像块边界点击的工件。您需要一个尚未规范或实施的功能 - 可选择的AudioContext采样率 - 以便解决此问题。