在Node.js上播放来自Web Audio API的PCM流

时间:2014-01-02 04:03:59

标签: node.js audio stream pcm web-audio

我正在使用网络音频API播放录制的PCM音频。

我用binaryJS (websocket connection)将它流式传输到nodejs服务器,我正在尝试使用扬声器npm模块在服务器上播放该流。

这是我的客户。 The audio buffers are at first non-interleaved IEEE 32-bit linear PCM with a nominal range between -1 and +1。我从两个PCM通道中的一个开始并在下面流式传输。

var client = new BinaryClient('ws://localhost:9000');
var Stream = client.send();

recorder.onaudioprocess = function(AudioBuffer){
    var leftChannel = AudioBuffer.inputBuffer.getChannelData (0);
    Stream.write(leftChannel);
}

现在我将数据作为缓冲区接收,并尝试将其写入npm包中的扬声器对象。

var Speaker = require('speaker');

var speaker = new Speaker({
  channels: 1,          // 1 channel
  bitDepth: 32,         // 32-bit samples
  sampleRate: 48000,     // 48,000 Hz sample rate
  signed:true
});

server.on('connection', function(client){
    client.on('stream', function(stream, meta){
        stream.on('data', function(data){
            speaker.write(leftchannel);
        });
    });
});

结果是我的笔记本电脑的扬声器发出高音尖叫,这显然不是正在录制的内容。这也不是反馈。我可以确认客户端上的录制缓冲区是有效的,因为我尝试将它们写入WAV文件并且播放得很好。

问题docs for speakerdocs for the AudioBuffer

我已经被困了好几天了。有人可以弄清楚出了什么问题,或者可能提供不同的方法吗?

使用解决方案更新

首先,我错误地使用了websocket API。我上面更新了正确使用它。

我需要将音频缓冲区转换为整数的数组缓冲区。我选择使用Int16Array。由于给定的音频缓冲区的范围介于1和-1之间,因此只需乘以新ArrayBuffer(32767到-32768)的范围即可。

recorder.onaudioprocess = function(AudioBuffer){

    var left = AudioBuffer.inputBuffer.getChannelData (0);

    var l = left.length;
    var buf = new Int16Array(l)

    while (l--) {
        buf[l] = left[l]*0xFFFF;    //convert to 16 bit
    }

    Stream.write(buf.buffer);

}

1 个答案:

答案 0 :(得分:1)

看起来您正在将您的信息流作为meta对象发送。

根据文档,BinaryClient.send按顺序获取data对象(流)和meta对象。 stream事件的回调在第一个参数中接收流(作为BinaryStream对象,而不是Buffer),在第二个参数中接收meta对象。

您将send()字符串'channel'作为流传递,Float32ArraygetChannelData()传递为元对象。也许你要交换这两个参数(或者只是使用client.send(leftChannel))然后更改服务器代码以将stream传递给speaker.write而不是leftchannel(这应该是<}重命名为meta,如果不需要则删除,可能会有效。

请注意,由于Float32Array不是流或缓冲区对象,因此BinaryJS可能try to send it in one chunk。您可能希望发送leftChannel.bufferthe ArrayBuffer behind that object)。

让我知道这是否适合你;我现在无法测试您的确切设置。