我正在使用网络音频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 speaker和docs 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);
}
答案 0 :(得分:1)
看起来您正在将您的信息流作为meta
对象发送。
根据文档,BinaryClient.send
按顺序获取data
对象(流)和meta
对象。 stream
事件的回调在第一个参数中接收流(作为BinaryStream
对象,而不是Buffer
),在第二个参数中接收meta
对象。
您将send()
字符串'channel'
作为流传递,Float32Array
从getChannelData()
传递为元对象。也许你要交换这两个参数(或者只是使用client.send(leftChannel)
)然后更改服务器代码以将stream
传递给speaker.write
而不是leftchannel
(这应该是<}重命名为meta
,如果不需要则删除,可能会有效。
请注意,由于Float32Array
不是流或缓冲区对象,因此BinaryJS可能try to send it in one chunk。您可能希望发送leftChannel.buffer
(the ArrayBuffer
behind that object)。
让我知道这是否适合你;我现在无法测试您的确切设置。