我有一个软件定义的无线电播放来自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接收事件。这与上述实现具有相同的丢失问题。
答案 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采样率 - 以便解决此问题。